Commit 47a9a252 authored by Staale Smedseng's avatar Staale Smedseng

Merge from 5.0

parents e9bf99d0 63ab8415
...@@ -109,6 +109,14 @@ typedef my_socket YASSL_SOCKET_T; ...@@ -109,6 +109,14 @@ typedef my_socket YASSL_SOCKET_T;
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
enum enum_ssl_init_error
{
SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY,
SSL_INITERR_NOMATCH, SSL_INITERR_BAD_PATHS, SSL_INITERR_CIPHERS,
SSL_INITERR_MEMFAIL, SSL_INITERR_LASTERR
};
const char* sslGetErrString(enum enum_ssl_init_error err);
struct st_VioSSLFd struct st_VioSSLFd
{ {
SSL_CTX *ssl_context; SSL_CTX *ssl_context;
...@@ -124,7 +132,7 @@ struct st_VioSSLFd ...@@ -124,7 +132,7 @@ struct st_VioSSLFd
struct st_VioSSLFd struct st_VioSSLFd
*new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
const char *ca_file,const char *ca_path, const char *ca_file,const char *ca_path,
const char *cipher); const char *cipher, enum enum_ssl_init_error* error);
void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd); void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
......
...@@ -3651,14 +3651,17 @@ static void init_ssl() ...@@ -3651,14 +3651,17 @@ static void init_ssl()
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
{ {
enum enum_ssl_init_error error= SSL_INITERR_NOERROR;
/* having ssl_acceptor_fd != 0 signals the use of SSL */ /* having ssl_acceptor_fd != 0 signals the use of SSL */
ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
opt_ssl_ca, opt_ssl_capath, opt_ssl_ca, opt_ssl_capath,
opt_ssl_cipher); opt_ssl_cipher, &error);
DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd)); DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
if (!ssl_acceptor_fd) if (!ssl_acceptor_fd)
{ {
sql_print_warning("Failed to setup SSL"); sql_print_warning("Failed to setup SSL");
sql_print_warning("SSL error: %s", sslGetErrString(error));
opt_use_ssl = 0; opt_use_ssl = 0;
have_ssl= SHOW_OPTION_DISABLED; have_ssl= SHOW_OPTION_DISABLED;
} }
...@@ -4300,7 +4303,6 @@ int main(int argc, char **argv) ...@@ -4300,7 +4303,6 @@ int main(int argc, char **argv)
select_thread=pthread_self(); select_thread=pthread_self();
select_thread_in_use=1; select_thread_in_use=1;
init_ssl();
#ifdef HAVE_LIBWRAP #ifdef HAVE_LIBWRAP
libwrapName= my_progname+dirname_length(my_progname); libwrapName= my_progname+dirname_length(my_progname);
...@@ -4355,6 +4357,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); ...@@ -4355,6 +4357,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
if (init_server_components()) if (init_server_components())
unireg_abort(1); unireg_abort(1);
init_ssl();
network_init(); network_init();
#ifdef __WIN__ #ifdef __WIN__
......
...@@ -73,9 +73,28 @@ report_errors() ...@@ -73,9 +73,28 @@ report_errors()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
static const char*
ssl_error_string[] =
{
"No error",
"Unable to get certificate",
"Unable to get private key",
"Private key does not match the certificate public key"
"SSL_CTX_set_default_verify_paths failed",
"Failed to set ciphers to use",
"SSL_CTX_new failed"
};
const char*
sslGetErrString(enum enum_ssl_init_error e)
{
DBUG_ASSERT(SSL_INITERR_NOERROR < e && e < SSL_INITERR_LASTERR);
return ssl_error_string[e];
}
static int static int
vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
enum enum_ssl_init_error* error)
{ {
DBUG_ENTER("vio_set_cert_stuff"); DBUG_ENTER("vio_set_cert_stuff");
DBUG_PRINT("enter", ("ctx: 0x%lx cert_file: %s key_file: %s", DBUG_PRINT("enter", ("ctx: 0x%lx cert_file: %s key_file: %s",
...@@ -84,9 +103,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) ...@@ -84,9 +103,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
{ {
if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0)
{ {
DBUG_PRINT("error",("unable to get certificate from '%s'", cert_file)); *error= SSL_INITERR_CERT;
DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file));
DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE););
fprintf(stderr, "SSL error: Unable to get certificate from '%s'\n", fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error),
cert_file); cert_file);
fflush(stderr); fflush(stderr);
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -97,9 +117,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) ...@@ -97,9 +117,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0)
{ {
DBUG_PRINT("error", ("unable to get private key from '%s'", key_file)); *error= SSL_INITERR_KEY;
DBUG_PRINT("error", ("%s from file '%s'", sslGetErrString(*error), key_file));
DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE););
fprintf(stderr, "SSL error: Unable to get private key from '%s'\n", fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error),
key_file); key_file);
fflush(stderr); fflush(stderr);
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -111,12 +132,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) ...@@ -111,12 +132,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
*/ */
if (!SSL_CTX_check_private_key(ctx)) if (!SSL_CTX_check_private_key(ctx))
{ {
DBUG_PRINT("error", *error= SSL_INITERR_NOMATCH;
("Private key does not match the certificate public key")); DBUG_PRINT("error", ("%s",sslGetErrString(*error)));
DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE););
fprintf(stderr, fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error));
"SSL error: "
"Private key does not match the certificate public key\n");
fflush(stderr); fflush(stderr);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -229,7 +248,8 @@ static void check_ssl_init() ...@@ -229,7 +248,8 @@ static void check_ssl_init()
static struct st_VioSSLFd * static struct st_VioSSLFd *
new_VioSSLFd(const char *key_file, const char *cert_file, new_VioSSLFd(const char *key_file, const char *cert_file,
const char *ca_file, const char *ca_path, const char *ca_file, const char *ca_path,
const char *cipher, SSL_METHOD *method) const char *cipher, SSL_METHOD *method,
enum enum_ssl_init_error* error)
{ {
DH *dh; DH *dh;
struct st_VioSSLFd *ssl_fd; struct st_VioSSLFd *ssl_fd;
...@@ -251,7 +271,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -251,7 +271,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
if (!(ssl_fd->ssl_context= SSL_CTX_new(method))) if (!(ssl_fd->ssl_context= SSL_CTX_new(method)))
{ {
DBUG_PRINT("error", ("SSL_CTX_new failed")); *error= SSL_INITERR_MEMFAIL;
DBUG_PRINT("error", ("%s", sslGetErrString(*error)));
report_errors(); report_errors();
my_free((void*)ssl_fd,MYF(0)); my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -265,7 +286,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -265,7 +286,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
if (cipher && if (cipher &&
SSL_CTX_set_cipher_list(ssl_fd->ssl_context, cipher) == 0) SSL_CTX_set_cipher_list(ssl_fd->ssl_context, cipher) == 0)
{ {
DBUG_PRINT("error", ("failed to set ciphers to use")); *error= SSL_INITERR_CIPHERS;
DBUG_PRINT("error", ("%s", sslGetErrString(*error)));
report_errors(); report_errors();
SSL_CTX_free(ssl_fd->ssl_context); SSL_CTX_free(ssl_fd->ssl_context);
my_free((void*)ssl_fd,MYF(0)); my_free((void*)ssl_fd,MYF(0));
...@@ -278,7 +300,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -278,7 +300,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0) if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0)
{ {
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); *error= SSL_INITERR_BAD_PATHS;
DBUG_PRINT("error", ("%s", sslGetErrString(*error)));
report_errors(); report_errors();
SSL_CTX_free(ssl_fd->ssl_context); SSL_CTX_free(ssl_fd->ssl_context);
my_free((void*)ssl_fd,MYF(0)); my_free((void*)ssl_fd,MYF(0));
...@@ -286,7 +309,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -286,7 +309,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
} }
} }
if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file)) if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file, error))
{ {
DBUG_PRINT("error", ("vio_set_cert_stuff failed")); DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
report_errors(); report_errors();
...@@ -314,6 +337,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, ...@@ -314,6 +337,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
{ {
struct st_VioSSLFd *ssl_fd; struct st_VioSSLFd *ssl_fd;
int verify= SSL_VERIFY_PEER; int verify= SSL_VERIFY_PEER;
enum enum_ssl_init_error dummy;
/* /*
Turn off verification of servers certificate if both Turn off verification of servers certificate if both
...@@ -323,7 +347,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, ...@@ -323,7 +347,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
verify= SSL_VERIFY_NONE; verify= SSL_VERIFY_NONE;
if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
ca_path, cipher, TLSv1_client_method()))) ca_path, cipher, TLSv1_client_method(), &dummy)))
{ {
return 0; return 0;
} }
...@@ -344,12 +368,12 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, ...@@ -344,12 +368,12 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
struct st_VioSSLFd * struct st_VioSSLFd *
new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
const char *ca_file, const char *ca_path, const char *ca_file, const char *ca_path,
const char *cipher) const char *cipher, enum enum_ssl_init_error* error)
{ {
struct st_VioSSLFd *ssl_fd; struct st_VioSSLFd *ssl_fd;
int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
ca_path, cipher, TLSv1_server_method()))) ca_path, cipher, TLSv1_server_method(), error)))
{ {
return 0; return 0;
} }
......
Markdown is supported
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