Commit 1e32574c authored by Staale Smedseng's avatar Staale Smedseng

Bug #45770 errors reading server SSL files are printed, but

not logged
        
Errors encountered during initialization of the SSL subsystem
are printed to stderr, rather than to the error log.
        
This patch adds a parameter to several SSL init functions to
report the error (if any) out to the caller. The function
init_ssl() in mysqld.cc is moved after the initialization of
the log subsystem, so that any error messages can be logged to
the error log. Printing of messages to stderr has been 
retained to get diagnostic output in a client context.


include/violite.h:
  Adding an enumeration for the various errors that can
  occur during initialization of the SSL module.
sql/mysqld.cc:
  Adding more logging of SSL init errors, and moving
  init_ssl() till after initialization of logging 
  subsystem.
vio/viosslfactories.c:
  Define error strings, provide an access method for these
  strings, and maintain an error parameter in several funcs
  to return the error (if any) to the caller.
parent dbe855d0
...@@ -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);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#ifdef HAVE_SMEM #ifdef HAVE_SMEM
......
...@@ -3249,14 +3249,17 @@ static void init_ssl() ...@@ -3249,14 +3249,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;
} }
...@@ -3747,7 +3750,6 @@ int main(int argc, char **argv) ...@@ -3747,7 +3750,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);
...@@ -3804,6 +3806,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); ...@@ -3804,6 +3806,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())
exit(1); exit(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;
...@@ -243,7 +263,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -243,7 +263,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);
...@@ -257,7 +278,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -257,7 +278,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));
...@@ -270,7 +292,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -270,7 +292,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));
...@@ -278,7 +301,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, ...@@ -278,7 +301,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();
...@@ -306,6 +329,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, ...@@ -306,6 +329,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
...@@ -315,7 +339,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, ...@@ -315,7 +339,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;
} }
...@@ -336,12 +360,12 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, ...@@ -336,12 +360,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