Commit 9f8aec7a authored by Otto Kekäläinen's avatar Otto Kekäläinen
Browse files

Merge tag 'upstream/5.5.49' into ubuntu-14.04

Upstream version 5.5.49
parents 516ad142 d97fe3f6
...@@ -12,6 +12,23 @@ before calling SSL_new(); ...@@ -12,6 +12,23 @@ before calling SSL_new();
*** end Note *** *** end Note ***
yaSSL Release notes, version 2.3.9b (2/03/2016)
This release of yaSSL fixes the OpenSSL compatibility function
X509_NAME_get_index_by_NID() to use the actual index of the common name
instead of searching on the format prefix. Thanks for the report from
yashwant.sahu@oracle.com . Anyone using this function should update.
yaSSL Release notes, version 2.3.9 (12/01/2015)
This release of yaSSL fixes two client side Diffie-Hellman problems.
yaSSL was only handling the cases of zero or one leading zeros for the key
agreement instead of potentially any number. This caused about 1 in 50,000
connections to fail when using DHE cipher suites. The second problem was
the case where a server would send a public value shorter than the prime
value, causing about 1 in 128 client connections to fail, and also
caused the yaSSL client to read off the end of memory. All client side
DHE cipher suite users should update.
Thanks to Adam Langely (agl@imperialviolet.org) for the detailed report!
yaSSL Release notes, version 2.3.8 (9/17/2015) yaSSL Release notes, version 2.3.8 (9/17/2015)
This release of yaSSL fixes a high security vulnerability. All users This release of yaSSL fixes a high security vulnerability. All users
SHOULD update. If using yaSSL for TLS on the server side with private SHOULD update. If using yaSSL for TLS on the server side with private
......
...@@ -378,6 +378,7 @@ public: ...@@ -378,6 +378,7 @@ public:
uint get_agreedKeyLength() const; uint get_agreedKeyLength() const;
const byte* get_agreedKey() const; const byte* get_agreedKey() const;
uint get_publicKeyLength() const;
const byte* get_publicKey() const; const byte* get_publicKey() const;
void makeAgreement(const byte*, unsigned int); void makeAgreement(const byte*, unsigned int);
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include "rsa.h" #include "rsa.h"
#define YASSL_VERSION "2.3.8" #define YASSL_VERSION "2.3.9b"
#if defined(__cplusplus) #if defined(__cplusplus)
......
...@@ -191,14 +191,18 @@ private: ...@@ -191,14 +191,18 @@ private:
class X509_NAME { class X509_NAME {
char* name_; char* name_;
size_t sz_; size_t sz_;
int cnPosition_; // start of common name, -1 is none
int cnLen_; // length of above
ASN1_STRING entry_; ASN1_STRING entry_;
public: public:
X509_NAME(const char*, size_t sz); X509_NAME(const char*, size_t sz, int pos, int len);
~X509_NAME(); ~X509_NAME();
const char* GetName() const; const char* GetName() const;
ASN1_STRING* GetEntry(int i); ASN1_STRING* GetEntry(int i);
size_t GetLength() const; size_t GetLength() const;
int GetCnPosition() const { return cnPosition_; }
int GetCnLength() const { return cnLen_; }
private: private:
X509_NAME(const X509_NAME&); // hide copy X509_NAME(const X509_NAME&); // hide copy
X509_NAME& operator=(const X509_NAME&); // and assign X509_NAME& operator=(const X509_NAME&); // and assign
...@@ -226,7 +230,7 @@ class X509 { ...@@ -226,7 +230,7 @@ class X509 {
StringHolder afterDate_; // not valid after StringHolder afterDate_; // not valid after
public: public:
X509(const char* i, size_t, const char* s, size_t, X509(const char* i, size_t, const char* s, size_t,
const char* b, int, const char* a, int); const char* b, int, const char* a, int, int, int, int, int);
~X509() {} ~X509() {}
X509_NAME* GetIssuer(); X509_NAME* GetIssuer();
......
...@@ -293,7 +293,10 @@ int CertManager::Validate() ...@@ -293,7 +293,10 @@ int CertManager::Validate()
int aSz = (int)strlen(cert.GetAfterDate()) + 1; int aSz = (int)strlen(cert.GetAfterDate()) + 1;
peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(), peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
sSz, cert.GetBeforeDate(), bSz, sSz, cert.GetBeforeDate(), bSz,
cert.GetAfterDate(), aSz); cert.GetAfterDate(), aSz,
cert.GetIssuerCnStart(), cert.GetIssuerCnLength(),
cert.GetSubjectCnStart(), cert.GetSubjectCnLength()
);
if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) { if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) {
X509_STORE_CTX store; X509_STORE_CTX store;
...@@ -345,7 +348,9 @@ void CertManager::setPeerX509(X509* x) ...@@ -345,7 +348,9 @@ void CertManager::setPeerX509(X509* x)
peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(), peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
subject->GetName(), subject->GetLength(), (const char*) before->data, subject->GetName(), subject->GetLength(), (const char*) before->data,
before->length, (const char*) after->data, after->length); before->length, (const char*) after->data, after->length,
issuer->GetCnPosition(), issuer->GetCnLength(),
subject->GetCnPosition(), subject->GetCnLength());
} }
......
...@@ -751,9 +751,10 @@ struct DiffieHellman::DHImpl { ...@@ -751,9 +751,10 @@ struct DiffieHellman::DHImpl {
byte* publicKey_; byte* publicKey_;
byte* privateKey_; byte* privateKey_;
byte* agreedKey_; byte* agreedKey_;
uint pubKeyLength_;
DHImpl(TaoCrypt::RandomNumberGenerator& r) : ranPool_(r), publicKey_(0), DHImpl(TaoCrypt::RandomNumberGenerator& r) : ranPool_(r), publicKey_(0),
privateKey_(0), agreedKey_(0) {} privateKey_(0), agreedKey_(0), pubKeyLength_(0) {}
~DHImpl() ~DHImpl()
{ {
ysArrayDelete(agreedKey_); ysArrayDelete(agreedKey_);
...@@ -762,7 +763,7 @@ struct DiffieHellman::DHImpl { ...@@ -762,7 +763,7 @@ struct DiffieHellman::DHImpl {
} }
DHImpl(const DHImpl& that) : dh_(that.dh_), ranPool_(that.ranPool_), DHImpl(const DHImpl& that) : dh_(that.dh_), ranPool_(that.ranPool_),
publicKey_(0), privateKey_(0), agreedKey_(0) publicKey_(0), privateKey_(0), agreedKey_(0), pubKeyLength_(0)
{ {
uint length = dh_.GetByteLength(); uint length = dh_.GetByteLength();
AllocKeys(length, length, length); AllocKeys(length, length, length);
...@@ -810,7 +811,7 @@ DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g, ...@@ -810,7 +811,7 @@ DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g,
using TaoCrypt::Integer; using TaoCrypt::Integer;
pimpl_->dh_.Initialize(Integer(p, pSz).Ref(), Integer(g, gSz).Ref()); pimpl_->dh_.Initialize(Integer(p, pSz).Ref(), Integer(g, gSz).Ref());
pimpl_->publicKey_ = NEW_YS opaque[pubSz]; pimpl_->publicKey_ = NEW_YS opaque[pimpl_->pubKeyLength_ = pubSz];
memcpy(pimpl_->publicKey_, pub, pubSz); memcpy(pimpl_->publicKey_, pub, pubSz);
} }
...@@ -869,6 +870,10 @@ const byte* DiffieHellman::get_agreedKey() const ...@@ -869,6 +870,10 @@ const byte* DiffieHellman::get_agreedKey() const
return pimpl_->agreedKey_; return pimpl_->agreedKey_;
} }
uint DiffieHellman::get_publicKeyLength() const
{
return pimpl_->pubKeyLength_;
}
const byte* DiffieHellman::get_publicKey() const const byte* DiffieHellman::get_publicKey() const
{ {
......
...@@ -1351,15 +1351,13 @@ int ASN1_STRING_type(ASN1_STRING *x) ...@@ -1351,15 +1351,13 @@ int ASN1_STRING_type(ASN1_STRING *x)
int X509_NAME_get_index_by_NID(X509_NAME* name,int nid, int lastpos) int X509_NAME_get_index_by_NID(X509_NAME* name,int nid, int lastpos)
{ {
int idx = -1; // not found int idx = -1; // not found
const char* start = &name->GetName()[lastpos + 1]; int cnPos = -1;
switch (nid) { switch (nid) {
case NID_commonName: case NID_commonName:
const char* found = strstr(start, "/CN="); cnPos = name->GetCnPosition();
if (found) { if (lastpos < cnPos)
found += 4; // advance to str idx = cnPos;
idx = found - start + lastpos + 1;
}
break; break;
} }
...@@ -1471,10 +1469,6 @@ int SSL_peek(SSL* ssl, void* buffer, int sz) ...@@ -1471,10 +1469,6 @@ int SSL_peek(SSL* ssl, void* buffer, int sz)
int SSL_pending(SSL* ssl) int SSL_pending(SSL* ssl)
{ {
// Just in case there's pending data that hasn't been processed yet...
char c;
SSL_peek(ssl, &c, 1);
return ssl->bufferedData(); return ssl->bufferedData();
} }
......
...@@ -109,14 +109,11 @@ void ClientDiffieHellmanPublic::build(SSL& ssl) ...@@ -109,14 +109,11 @@ void ClientDiffieHellmanPublic::build(SSL& ssl)
uint keyLength = dhClient.get_agreedKeyLength(); // pub and agree same uint keyLength = dhClient.get_agreedKeyLength(); // pub and agree same
alloc(keyLength, true); alloc(keyLength, true);
dhClient.makeAgreement(dhServer.get_publicKey(), keyLength); dhClient.makeAgreement(dhServer.get_publicKey(),
dhServer.get_publicKeyLength());
c16toa(keyLength, Yc_); c16toa(keyLength, Yc_);
memcpy(Yc_ + KEY_OFFSET, dhClient.get_publicKey(), keyLength); memcpy(Yc_ + KEY_OFFSET, dhClient.get_publicKey(), keyLength);
// because of encoding first byte might be zero, don't use it for preMaster
if (*dhClient.get_agreedKey() == 0)
ssl.set_preMaster(dhClient.get_agreedKey() + 1, keyLength - 1);
else
ssl.set_preMaster(dhClient.get_agreedKey(), keyLength); ssl.set_preMaster(dhClient.get_agreedKey(), keyLength);
} }
...@@ -321,10 +318,6 @@ void ClientDiffieHellmanPublic::read(SSL& ssl, input_buffer& input) ...@@ -321,10 +318,6 @@ void ClientDiffieHellmanPublic::read(SSL& ssl, input_buffer& input)
} }
dh.makeAgreement(Yc_, keyLength); dh.makeAgreement(Yc_, keyLength);
// because of encoding, first byte might be 0, don't use for preMaster
if (*dh.get_agreedKey() == 0)
ssl.set_preMaster(dh.get_agreedKey() + 1, dh.get_agreedKeyLength() - 1);
else
ssl.set_preMaster(dh.get_agreedKey(), dh.get_agreedKeyLength()); ssl.set_preMaster(dh.get_agreedKey(), dh.get_agreedKeyLength());
ssl.makeMasterSecret(); ssl.makeMasterSecret();
} }
......
...@@ -807,6 +807,19 @@ void SSL::set_random(const opaque* random, ConnectionEnd sender) ...@@ -807,6 +807,19 @@ void SSL::set_random(const opaque* random, ConnectionEnd sender)
// store client pre master secret // store client pre master secret
void SSL::set_preMaster(const opaque* pre, uint sz) void SSL::set_preMaster(const opaque* pre, uint sz)
{ {
uint i(0); // trim leading zeros
uint fullSz(sz);
while (i++ < fullSz && *pre == 0) {
sz--;
pre++;
}
if (sz == 0) {
SetError(bad_input);
return;
}
secure_.use_connection().AllocPreSecret(sz); secure_.use_connection().AllocPreSecret(sz);
memcpy(secure_.use_connection().pre_master_secret_, pre, sz); memcpy(secure_.use_connection().pre_master_secret_, pre, sz);
} }
...@@ -924,6 +937,8 @@ void SSL::order_error() ...@@ -924,6 +937,8 @@ void SSL::order_error()
// Create and store the master secret see page 32, 6.1 // Create and store the master secret see page 32, 6.1
void SSL::makeMasterSecret() void SSL::makeMasterSecret()
{ {
if (GetError()) return;
if (isTLS()) if (isTLS())
makeTLSMasterSecret(); makeTLSMasterSecret();
else { else {
...@@ -1540,7 +1555,9 @@ void SSL_SESSION::CopyX509(X509* x) ...@@ -1540,7 +1555,9 @@ void SSL_SESSION::CopyX509(X509* x)
peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(), peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
subject->GetName(), subject->GetLength(), (const char*) before->data, subject->GetName(), subject->GetLength(), (const char*) before->data,
before->length, (const char*) after->data, after->length); before->length, (const char*) after->data, after->length,
issuer->GetCnPosition(), issuer->GetCnLength(),
subject->GetCnPosition(), subject->GetCnLength());
} }
...@@ -2457,8 +2474,8 @@ void Security::set_resuming(bool b) ...@@ -2457,8 +2474,8 @@ void Security::set_resuming(bool b)
} }
X509_NAME::X509_NAME(const char* n, size_t sz) X509_NAME::X509_NAME(const char* n, size_t sz, int pos, int len)
: name_(0), sz_(sz) : name_(0), sz_(sz), cnPosition_(pos), cnLen_(len)
{ {
if (sz) { if (sz) {
name_ = NEW_YS char[sz]; name_ = NEW_YS char[sz];
...@@ -2488,8 +2505,9 @@ size_t X509_NAME::GetLength() const ...@@ -2488,8 +2505,9 @@ size_t X509_NAME::GetLength() const
X509::X509(const char* i, size_t iSz, const char* s, size_t sSz, X509::X509(const char* i, size_t iSz, const char* s, size_t sSz,
const char* b, int bSz, const char* a, int aSz) const char* b, int bSz, const char* a, int aSz, int issPos,
: issuer_(i, iSz), subject_(s, sSz), int issLen, int subPos, int subLen)
: issuer_(i, iSz, issPos, issLen), subject_(s, sSz, subPos, subLen),
beforeDate_(b, bSz), afterDate_(a, aSz) beforeDate_(b, bSz), afterDate_(a, aSz)
{} {}
...@@ -2523,17 +2541,19 @@ ASN1_STRING* X509_NAME::GetEntry(int i) ...@@ -2523,17 +2541,19 @@ ASN1_STRING* X509_NAME::GetEntry(int i)
if (i < 0 || i >= int(sz_)) if (i < 0 || i >= int(sz_))
return 0; return 0;
if (i != cnPosition_ || cnLen_ <= 0) // only entry currently supported
return 0;
if (cnLen_ > int(sz_-i)) // make sure there's room in read buffer
return 0;
if (entry_.data) if (entry_.data)
ysArrayDelete(entry_.data); ysArrayDelete(entry_.data);
entry_.data = NEW_YS byte[sz_]; // max size; entry_.data = NEW_YS byte[cnLen_+1]; // max size;
memcpy(entry_.data, &name_[i], sz_ - i); memcpy(entry_.data, &name_[i], cnLen_);
if (entry_.data[sz_ -i - 1]) { entry_.data[cnLen_] = 0;
entry_.data[sz_ - i] = 0; entry_.length = cnLen_;
entry_.length = int(sz_) - i;
}
else
entry_.length = int(sz_) - i - 1;
entry_.type = 0; entry_.type = 0;
return &entry_; return &entry_;
......
...@@ -283,6 +283,10 @@ public: ...@@ -283,6 +283,10 @@ public:
const byte* GetHash() const { return subjectHash_; } const byte* GetHash() const { return subjectHash_; }
const char* GetBeforeDate() const { return beforeDate_; } const char* GetBeforeDate() const { return beforeDate_; }
const char* GetAfterDate() const { return afterDate_; } const char* GetAfterDate() const { return afterDate_; }
int GetSubjectCnStart() const { return subCnPos_; }
int GetIssuerCnStart() const { return issCnPos_; }
int GetSubjectCnLength() const { return subCnLen_; }
int GetIssuerCnLength() const { return issCnLen_; }
void DecodeToKey(); void DecodeToKey();
private: private:
...@@ -292,6 +296,10 @@ private: ...@@ -292,6 +296,10 @@ private:
word32 sigLength_; // length of signature word32 sigLength_; // length of signature
word32 signatureOID_; // sum of algorithm object id word32 signatureOID_; // sum of algorithm object id
word32 keyOID_; // sum of key algo object id word32 keyOID_; // sum of key algo object id
int subCnPos_; // subject common name start, -1 is none
int subCnLen_; // length of above
int issCnPos_; // issuer common name start, -1 is none
int issCnLen_; // length of above
byte subjectHash_[SHA_SIZE]; // hash of all Names byte subjectHash_[SHA_SIZE]; // hash of all Names
byte issuerHash_[SHA_SIZE]; // hash of all Names byte issuerHash_[SHA_SIZE]; // hash of all Names
byte* signature_; byte* signature_;
......
...@@ -474,8 +474,9 @@ void DH_Decoder::Decode(DH& key) ...@@ -474,8 +474,9 @@ void DH_Decoder::Decode(DH& key)
CertDecoder::CertDecoder(Source& s, bool decode, SignerList* signers, CertDecoder::CertDecoder(Source& s, bool decode, SignerList* signers,
bool noVerify, CertType ct) bool noVerify, CertType ct)
: BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0), : BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0), subCnPos_(-1),
signature_(0), verify_(!noVerify) subCnLen_(0), issCnPos_(-1), issCnLen_(0), signature_(0),
verify_(!noVerify)
{ {
issuer_[0] = 0; issuer_[0] = 0;
subject_[0] = 0; subject_[0] = 0;
...@@ -796,6 +797,13 @@ void CertDecoder::GetName(NameType nt) ...@@ -796,6 +797,13 @@ void CertDecoder::GetName(NameType nt)
case COMMON_NAME: case COMMON_NAME:
if (!(ptr = AddTag(ptr, buf_end, "/CN=", 4, strLen))) if (!(ptr = AddTag(ptr, buf_end, "/CN=", 4, strLen)))
return; return;
if (nt == ISSUER) {
issCnPos_ = (int)(ptr - strLen - issuer_);
issCnLen_ = (int)strLen;
} else {
subCnPos_ = (int)(ptr - strLen - subject_);
subCnLen_ = (int)strLen;
}
break; break;
case SUR_NAME: case SUR_NAME:
if (!(ptr = AddTag(ptr, buf_end, "/SN=", 4, strLen))) if (!(ptr = AddTag(ptr, buf_end, "/SN=", 4, strLen)))
......
...@@ -470,10 +470,28 @@ inline void showPeer(SSL* ssl) ...@@ -470,10 +470,28 @@ inline void showPeer(SSL* ssl)
char* issuer = X509_NAME_oneline(X509_get_issuer_name(peer), 0, 0); char* issuer = X509_NAME_oneline(X509_get_issuer_name(peer), 0, 0);
char* subject = X509_NAME_oneline(X509_get_subject_name(peer), 0, 0); char* subject = X509_NAME_oneline(X509_get_subject_name(peer), 0, 0);
printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer, X509_NAME_ENTRY* se = NULL;
subject); ASN1_STRING* sd = NULL;
char* subCN = NULL;
X509_NAME* sub = X509_get_subject_name(peer);
int lastpos = -1;
if (sub)
lastpos = X509_NAME_get_index_by_NID(sub, NID_commonName, lastpos);
if (lastpos >= 0) {
se = X509_NAME_get_entry(sub, lastpos);
if (se)
sd = X509_NAME_ENTRY_get_data(se);
if (sd)
subCN = (char*)ASN1_STRING_data(sd);
}
printf("peer's cert info:\n issuer : %s\n subject: %s\n"
" subject cn: %s\n", issuer, subject, subCN);
free(subject); free(subject);
free(issuer); free(issuer);
} }
else else
printf("peer has no cert!\n"); printf("peer has no cert!\n");
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define MY_CONTEXT_USE_X86_64_GCC_ASM #define MY_CONTEXT_USE_X86_64_GCC_ASM
#elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__) #elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__)
#define MY_CONTEXT_USE_I386_GCC_ASM #define MY_CONTEXT_USE_I386_GCC_ASM
#elif defined(HAVE_UCONTEXT) #elif defined(HAVE_UCONTEXT_H)
#define MY_CONTEXT_USE_UCONTEXT #define MY_CONTEXT_USE_UCONTEXT
#else #else
#define MY_CONTEXT_DISABLE #define MY_CONTEXT_DISABLE
......
...@@ -207,20 +207,6 @@ ...@@ -207,20 +207,6 @@
#define likely(x) __builtin_expect(((x) != 0),1) #define likely(x) __builtin_expect(((x) != 0),1)
#define unlikely(x) __builtin_expect(((x) != 0),0) #define unlikely(x) __builtin_expect(((x) != 0),0)
/*
now let's figure out if inline functions are supported
autoconf defines 'inline' to be empty, if not
*/
#define inline_test_1(X) X ## 1
#define inline_test_2(X) inline_test_1(X)
#if inline_test_2(inline) != 1
#define HAVE_INLINE
#else
#error Compiler does not support inline!
#endif
#undef inline_test_2
#undef inline_test_1
/* Fix problem with S_ISLNK() on Linux */ /* Fix problem with S_ISLNK() on Linux */
#if defined(TARGET_OS_LINUX) || defined(__GLIBC__) #if defined(TARGET_OS_LINUX) || defined(__GLIBC__)
#undef _GNU_SOURCE #undef _GNU_SOURCE
...@@ -436,7 +422,7 @@ extern "C" int madvise(void *addr, size_t len, int behav); ...@@ -436,7 +422,7 @@ extern "C" int madvise(void *addr, size_t len, int behav);
#endif #endif
#ifndef STDERR_FILENO #ifndef STDERR_FILENO
#define STDERR_FILENO 2 #define STDERR_FILENO fileno(stderr)
#endif #endif
/* /*
......
...@@ -86,10 +86,12 @@ typedef volatile LONG my_pthread_once_t; ...@@ -86,10 +86,12 @@ typedef volatile LONG my_pthread_once_t;
#define MY_PTHREAD_ONCE_INPROGRESS 1 #define MY_PTHREAD_ONCE_INPROGRESS 1
#define MY_PTHREAD_ONCE_DONE 2 #define MY_PTHREAD_ONCE_DONE 2
#if !STRUCT_TIMESPEC_HAS_TV_SEC || !STRUCT_TIMESPEC_HAS_TV_NSEC
struct timespec { struct timespec {
time_t tv_sec; time_t tv_sec;
long tv_nsec; long tv_nsec;
}; };
#endif
int win_pthread_mutex_trylock(pthread_mutex_t *mutex); int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_create(pthread_t *, const pthread_attr_t *, pthread_handler, void *); int pthread_create(pthread_t *, const pthread_attr_t *, pthread_handler, void *);
......
...@@ -123,6 +123,10 @@ typedef my_socket YASSL_SOCKET_T; ...@@ -123,6 +123,10 @@ typedef my_socket YASSL_SOCKET_T;
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
#ifdef HAVE_ERR_remove_thread_state
#define ERR_remove_state(X) ERR_remove_thread_state(NULL)
#endif
enum enum_ssl_init_error enum enum_ssl_init_error
{ {
SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY, SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY,
......
/* Copyright (c) 2011, 2015, Oracle and/or its affiliates. /* Copyright (c) 2011, 2016, Oracle and/or its affiliates.
Copyright (c) 2011, 2015, MariaDB Copyright (c) 2011, 2016, MariaDB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#ifndef _welcome_copyright_notice_h_ #ifndef _welcome_copyright_notice_h_
#define _welcome_copyright_notice_h_ #define _welcome_copyright_notice_h_
#define COPYRIGHT_NOTICE_CURRENT_YEAR "2015" #define COPYRIGHT_NOTICE_CURRENT_YEAR "2016"
/* /*
This define specifies copyright notice which is displayed by every MySQL This define specifies copyright notice which is displayed by every MySQL
......
...@@ -251,6 +251,25 @@ SET(CLIENT_API_FUNCTIONS ...@@ -251,6 +251,25 @@ SET(CLIENT_API_FUNCTIONS
) )
IF(CMAKE_SYSTEM_NAME MATCHES "Linux") IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
IF (NOT DISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING)
INCLUDE (CheckCSourceCompiles)
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.ld"
"VERSION {\nlibmysqlclient_18 {\nglobal: *;\n};\n}\n")
SET(CMAKE_REQUIRED_LIBRARIES "-Wl,src.ld")
CHECK_C_SOURCE_COMPILES("int main() { return 0; }"
SUPPORTS_VERSION_IN_LINK_SCRIPT)
SET(CMAKE_REQUIRED_LIBRARIES)
IF (NOT SUPPORTS_VERSION_IN_LINK_SCRIPT)
# https://sourceware.org/bugzilla/show_bug.cgi?id=16895
MESSAGE(SEND_ERROR "Your current linker does not support VERSION "
"command in linker scripts like a GNU ld or any compatible linker "
"should. Perhaps you're using gold? Either switch to GNU ld compatible "
"linker or run cmake with -DDISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING=TRUE "
"to be able to complete the build")
ENDIF (NOT SUPPORTS_VERSION_IN_LINK_SCRIPT)
# When building RPM, or DEB package on Debian, use ELF symbol versioning # When building RPM, or DEB package on Debian, use ELF symbol versioning
# for compatibility with distribution packages, so client shared library can # for compatibility with distribution packages, so client shared library can
# painlessly replace the one supplied by the distribution. # painlessly replace the one supplied by the distribution.
...@@ -335,14 +354,26 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") ...@@ -335,14 +354,26 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
make_scrambled_password_323 make_scrambled_password_323
) )
# Linker script to version symbols in Fedora- and Debian- compatible way, MDEV-5529
SET(VERSION_SCRIPT_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/libmysql_versions.ld.in)
# Generate version script. # Generate version script.
# Create semicolon separated lists of functions to export from # Create semicolon separated lists of functions to export from
# Since RPM packages use separate versioning for 5.1 API # Since RPM packages use separate versioning for 5.1 API
# and 5.5 API (libmysqlclient_16 vs libmysqlclient_18), # and 5.5 API (libmysqlclient_16 vs libmysqlclient_18),
# we need 2 lists. # we need 2 lists.
SET (VERSION_HEADER
"VERSION {
libmysqlclient_18 {
global:")
SET (VERSION_FOOTER
" local:
*;
};
libmysqlclient_16 {
/* empty here. aliases are added above */
};
}
")
SET (CLIENT_API_5_1_LIST) SET (CLIENT_API_5_1_LIST)
SET (CLIENT_API_5_1_ALIASES) SET (CLIENT_API_5_1_ALIASES)
FOREACH (f ${CLIENT_API_FUNCTIONS_5_1} ${CLIENT_API_5_1_EXTRA}) FOREACH (f ${CLIENT_API_FUNCTIONS_5_1} ${CLIENT_API_5_1_EXTRA})
...@@ -355,6 +386,13 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") ...@@ -355,6 +386,13 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SET(CLIENT_API_5_5_LIST "${CLIENT_API_5_5_LIST}\t${f};\n") SET(CLIENT_API_5_5_LIST "${CLIENT_API_5_5_LIST}\t${f};\n")
ENDFOREACH() ENDFOREACH()
ELSE (NOT DISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING)
SET (CLIENT_API_5_1_ALIASES "/* Versioning disabled per user request. MDEV-5982 */")
ENDIF (NOT DISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING)
# Linker script to version symbols in Fedora- and Debian- compatible way, MDEV-5529
SET(VERSION_SCRIPT_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/libmysql_versions.ld.in)
CONFIGURE_FILE( CONFIGURE_FILE(
${VERSION_SCRIPT_TEMPLATE} ${VERSION_SCRIPT_TEMPLATE}
${CMAKE_CURRENT_BINARY_DIR}/libmysql_versions.ld ${CMAKE_CURRENT_BINARY_DIR}/libmysql_versions.ld
...@@ -363,7 +401,7 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") ...@@ -363,7 +401,7 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SET(VERSION_SCRIPT_LINK_FLAGS SET(VERSION_SCRIPT_LINK_FLAGS
"-Wl,${CMAKE_CURRENT_BINARY_DIR}/libmysql_versions.ld") "-Wl,${CMAKE_CURRENT_BINARY_DIR}/libmysql_versions.ld")
ENDIF() ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SET(CLIENT_SOURCES SET(CLIENT_SOURCES
......
...@@ -88,7 +88,7 @@ const char *client_errors[]= ...@@ -88,7 +88,7 @@ const char *client_errors[]=
"" ""
}; };
const char** get_client_errmsgs() const char** get_client_errmsgs(void)
{ {
return client_errors; return client_errors;
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment