diff options
-rw-r--r-- | include/violite.h | 10 | ||||
-rw-r--r-- | sql/mysqld.cc | 7 | ||||
-rw-r--r-- | vio/viosslfactories.c | 60 |
3 files changed, 56 insertions, 21 deletions
diff --git a/include/violite.h b/include/violite.h index d49d0302b5e..f833606233c 100644 --- a/include/violite.h +++ b/include/violite.h @@ -109,6 +109,14 @@ typedef my_socket YASSL_SOCKET_T; #include <openssl/ssl.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 { SSL_CTX *ssl_context; @@ -124,7 +132,7 @@ struct st_VioSSLFd struct st_VioSSLFd *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, 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); #endif /* HAVE_OPENSSL */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f7ee7b025f9..7e61527a19b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3651,14 +3651,17 @@ static void init_ssl() #ifdef HAVE_OPENSSL if (opt_use_ssl) { + enum enum_ssl_init_error error= SSL_INITERR_NOERROR; + /* having ssl_acceptor_fd != 0 signals the use of SSL */ ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, 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)); if (!ssl_acceptor_fd) { sql_print_warning("Failed to setup SSL"); + sql_print_warning("SSL error: %s", sslGetErrString(error)); opt_use_ssl = 0; have_ssl= SHOW_OPTION_DISABLED; } @@ -4300,7 +4303,6 @@ int main(int argc, char **argv) select_thread=pthread_self(); select_thread_in_use=1; - init_ssl(); #ifdef HAVE_LIBWRAP 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."); if (init_server_components()) unireg_abort(1); + init_ssl(); network_init(); #ifdef __WIN__ diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 9ffe600beb8..6a6e08818c6 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -73,9 +73,28 @@ report_errors() 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 -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_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) { 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);); - fprintf(stderr, "SSL error: Unable to get certificate from '%s'\n", + fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), cert_file); fflush(stderr); DBUG_RETURN(1); @@ -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) { - 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);); - fprintf(stderr, "SSL error: Unable to get private key from '%s'\n", + fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), key_file); fflush(stderr); DBUG_RETURN(1); @@ -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)) { - DBUG_PRINT("error", - ("Private key does not match the certificate public key")); + *error= SSL_INITERR_NOMATCH; + DBUG_PRINT("error", ("%s",sslGetErrString(*error))); DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); - fprintf(stderr, - "SSL error: " - "Private key does not match the certificate public key\n"); + fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error)); fflush(stderr); DBUG_RETURN(1); } @@ -229,7 +248,8 @@ static void check_ssl_init() static struct st_VioSSLFd * new_VioSSLFd(const char *key_file, const char *cert_file, 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; struct st_VioSSLFd *ssl_fd; @@ -251,7 +271,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, 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(); my_free((void*)ssl_fd,MYF(0)); DBUG_RETURN(0); @@ -265,7 +286,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, if (cipher && 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(); SSL_CTX_free(ssl_fd->ssl_context); my_free((void*)ssl_fd,MYF(0)); @@ -278,7 +300,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); 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(); SSL_CTX_free(ssl_fd->ssl_context); my_free((void*)ssl_fd,MYF(0)); @@ -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")); report_errors(); @@ -314,6 +337,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; + enum enum_ssl_init_error dummy; /* Turn off verification of servers certificate if both @@ -323,7 +347,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, verify= SSL_VERIFY_NONE; 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; } @@ -344,12 +368,12 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd * new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, 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; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; 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; } |