diff options
-rw-r--r-- | .bzrignore | 2 | ||||
-rw-r--r-- | client/mysql.cc | 11 | ||||
-rw-r--r-- | sql/mini_client.cc | 62 | ||||
-rw-r--r-- | sql/mysqld.cc | 39 | ||||
-rw-r--r-- | sql/sql_show.cc | 87 | ||||
-rw-r--r-- | sql/structs.h | 13 | ||||
-rw-r--r-- | vio/viossl.c | 206 | ||||
-rw-r--r-- | vio/viosslfactories.c | 8 |
8 files changed, 334 insertions, 94 deletions
diff --git a/.bzrignore b/.bzrignore index 08eb86adb8a..863682099d3 100644 --- a/.bzrignore +++ b/.bzrignore @@ -393,3 +393,5 @@ tmp/* vio/viotest-ssl =6 libmysqld/ha_innobase.cc +vio/test-sslclient +vio/test-sslserver diff --git a/client/mysql.cc b/client/mysql.cc index 3d28ec1bff0..ffc12f22da8 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -40,6 +40,7 @@ #include <getopt.h> #include "my_readline.h" #include <signal.h> +#include <violite.h> const char *VER="11.15"; @@ -327,6 +328,16 @@ int main(int argc,char *argv[]) mysql_thread_id(&mysql),mysql_get_server_info(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO); +#ifdef HAVE_OPENSSL + if(SSL_get_cipher(mysql.net.vio->ssl_)) { + sprintf((char*) glob_buffer.ptr(), + "SSL cipher in use is %s\n", SSL_get_cipher(mysql.net.vio->ssl_)); + put_info((char*) glob_buffer.ptr(),INFO_INFO); + } else + put_info("SSL is not in use\n",INFO_INFO); +#endif /* HAVE_OPENSSL */ + + #ifdef HAVE_READLINE initialize_readline(my_progname); if (!status.batch && !quick && !opt_html && !opt_xml) diff --git a/sql/mini_client.cc b/sql/mini_client.cc index d52dc40f6a8..31181ee2580 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -766,23 +766,36 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, mysql->client_flag=client_flag; #ifdef HAVE_OPENSSL + if ((mysql->server_capabilities & CLIENT_SSL) && + (mysql->options.use_ssl || (client_flag & CLIENT_SSL))) + { + DBUG_PRINT("info", ("Changing IO layer to SSL")); + client_flag |= CLIENT_SSL; + } + else + { + if (client_flag & CLIENT_SSL) + { + DBUG_PRINT("info", ("Leaving IO layer intact because server doesn't support SSL")); + } + client_flag &= ~CLIENT_SSL; + } /* Oops.. are we careful enough to not send ANY information */ /* without encryption? */ -/* if (client_flag & CLIENT_SSL) + if (client_flag & CLIENT_SSL) { if (my_net_write(net,buff,(uint) (2)) || net_flush(net)) - goto error;*/ + goto error; /* Do the SSL layering. */ - /* DBUG_PRINT("info", ("IO layer change in progress...")); - VioSSLConnectorFd* connector_fd = (VioSSLConnectorFd*) - (mysql->connector_fd); - VioSocket* vio_socket = (VioSocket*)(mysql->net.vio); - VioSSL* vio_ssl = connector_fd->connect(vio_socket); - mysql->net.vio = (NetVio*)(vio_ssl); - }*/ + DBUG_PRINT("info", ("IO layer change in progress...")); + DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_)); + sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio); + DBUG_PRINT("info", ("IO layer change done!")); + } #endif /* HAVE_OPENSSL */ - int3store(buff+2,max_allowed_packet); + + if (user && user[0]) strmake(buff+5,user,32); else @@ -821,6 +834,32 @@ error: DBUG_RETURN(0); } + +#ifdef HAVE_OPENSSL +/* +************************************************************************** +** Free strings in the SSL structure and clear 'use_ssl' flag. +** NB! Errors are not reported until you do mysql_real_connect. +************************************************************************** +*/ +int STDCALL +mysql_ssl_clear(MYSQL *mysql) +{ + my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); + mysql->options.ssl_key = 0; + mysql->options.ssl_cert = 0; + mysql->options.ssl_ca = 0; + mysql->options.ssl_capath = 0; + mysql->options.use_ssl = FALSE; + my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR)); + mysql->connector_fd = 0; + return 0; +} +#endif /* HAVE_OPENSSL */ + /************************************************************************* ** Send a QUIT to the server and close the connection ** If handle is alloced by mysql connect free it. @@ -849,8 +888,7 @@ mc_mysql_close(MYSQL *mysql) bzero((char*) &mysql->options,sizeof(mysql->options)); mysql->net.vio = 0; #ifdef HAVE_OPENSSL -/* ((VioConnectorFd*)(mysql->connector_fd))->delete(); - mysql->connector_fd = 0;*/ + mysql_ssl_clear(mysql); #endif /* HAVE_OPENSSL */ if (mysql->free_me) my_free((gptr) mysql,MYF(0)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a036c885f4b..18de8c19c89 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -279,13 +279,14 @@ volatile ulong cached_thread_count=0; // replication parameters, if master_host is not NULL, we are a slave my_string master_user = (char*) "test", master_password = 0, master_host=0, - master_info_file = (char*) "master.info"; + master_info_file = (char*) "master.info", master_ssl_key=0, master_ssl_cert=0; my_string report_user = 0, report_password = 0, report_host=0; const char *localhost=LOCAL_HOST; const char *delayed_user="DELAYED"; uint master_port = MYSQL_PORT, master_connect_retry = 60; uint report_port = MYSQL_PORT; +bool master_ssl = 0; ulong max_tmp_tables,max_heap_table_size; ulong bytes_sent = 0L, bytes_received = 0L; @@ -707,7 +708,6 @@ void clean_up(bool print_message) my_free(opt_ssl_cert,MYF(0)); my_free(opt_ssl_ca,MYF(0)); my_free(opt_ssl_capath,MYF(0)); -// my_free(ssl_acceptor_fd,MYF(0)); opt_ssl_key=opt_ssl_cert=opt_ssl_ca=opt_ssl_capath=0; #endif /* HAVE_OPENSSL */ free_defaults(defaults_argv); @@ -2495,6 +2495,10 @@ enum options { OPT_MASTER_HOST, OPT_MASTER_USER, OPT_MASTER_PASSWORD, OPT_MASTER_PORT, OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY, +#ifdef HAVE_OPENSSL + OPT_MASTER_SSL, OPT_MASTER_SSL_KEY, + OPT_MASTER_SSL_CERT, +#endif /* HAVE_OPESSSL*/ OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB, OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES, OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB, @@ -2601,6 +2605,9 @@ static struct option long_options[] = { {"master-port", required_argument, 0, (int) OPT_MASTER_PORT}, {"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY}, {"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE}, + {"master-ssl", optional_argument, 0, (int) OPT_MASTER_SSL}, + {"master-ssl-key", optional_argument, 0, (int) OPT_MASTER_SSL_KEY}, + {"master-ssl-cert", optional_argument, 0, (int) OPT_MASTER_SSL_CERT}, {"myisam-recover", optional_argument, 0, (int) OPT_MYISAM_RECOVER}, {"memlock", no_argument, 0, (int) OPT_MEMLOCK}, // needs to be available for the test case to pass in non-debugging mode @@ -3017,6 +3024,23 @@ struct show_var_st status_vars[]= { {"Sort_range", (char*) &filesort_range_count, SHOW_LONG}, {"Sort_rows", (char*) &filesort_rows, SHOW_LONG}, {"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG}, +#ifdef HAVE_OPENSSL + {"SSL_CTX_sess_accept", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, + {"SSL_CTX_sess_accept_good", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, + {"SSL_CTX_sess_accept_renegotiate", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, + {"SSL_CTX_sess_cb_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, + {"SSL_CTX_sess_number", (char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, + {"SSL_CTX_get_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, + {"SSL_CTX_sess_get_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, + {"SSL_CTX_get_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, + {"SSL_CTX_get_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, + {"SSL_get_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, + {"SSL_get_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, + {"SSL_session_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, + {"SSL_get_version", (char*) 0, SHOW_SSL_GET_VERSION}, + {"SSL_get_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, + {"SSL_get_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, +#endif /* HAVE_OPENSSL */ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST}, @@ -3855,6 +3879,17 @@ static void get_options(int argc,char **argv) case OPT_MASTER_PORT: master_port= atoi(optarg); break; +#ifdef HAVE_OPENSSL + case OPT_MASTER_SSL: + master_ssl=atoi(optarg); + break; + case OPT_MASTER_SSL_KEY: + master_ssl_key=optarg; + break; + case OPT_MASTER_SSL_CERT: + master_ssl_cert=optarg; + break; +#endif /* HAVE_OPENSSL */ case OPT_REPORT_HOST: report_host=optarg; break; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 79a93da8c15..a6e0c8a01f4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -17,6 +17,7 @@ /* Function with list databases, tables or fields */ +#include "global.h" #include "mysql_priv.h" #include "sql_select.h" // For select_describe #include "sql_acl.h" @@ -45,6 +46,8 @@ store_create_info(THD *thd, TABLE *table, String *packet); static void append_identifier(THD *thd, String *packet, const char *name); +extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; + /**************************************************************************** ** Send list of databases ** A database is a directory in the mysql_data_home directory @@ -1151,6 +1154,90 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) net_store_data(&packet2,convert, value ? value : ""); break; } +#ifdef HAVE_OPENSSL + case SHOW_SSL_CTX_SESS_ACCEPT: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_ACCEPT_GOOD: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_GET_VERSION: + net_store_data(&packet2, + SSL_get_version(thd->net.vio->ssl_)); + break; + case SHOW_SSL_CTX_SESS_CB_HITS: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_NUMBER: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_SESSION_REUSED: + net_store_data(&packet2,(uint32) + SSL_session_reused(thd->net.vio->ssl_)); + break; + case SHOW_SSL_GET_DEFAULT_TIMEOUT: + net_store_data(&packet2,(uint32) + SSL_get_default_timeout(thd->net.vio->ssl_)); + break; + case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_GET_VERIFY_MODE: + net_store_data(&packet2,(uint32) + SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_GET_VERIFY_MODE: + net_store_data(&packet2,(uint32) + SSL_get_verify_mode(thd->net.vio->ssl_)); + break; + case SHOW_SSL_CTX_GET_VERIFY_DEPTH: + net_store_data(&packet2,(uint32) + SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_GET_VERIFY_DEPTH: + net_store_data(&packet2,(uint32) + SSL_get_verify_depth(thd->net.vio->ssl_)); + break; + case SHOW_SSL_GET_CIPHER: + net_store_data(&packet2, SSL_get_cipher(thd->net.vio->ssl_)); + break; + case SHOW_SSL_CTX_GET_SESSION_CACHE_MODE: + switch(SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context_)) + { + case SSL_SESS_CACHE_OFF: + net_store_data(&packet2,"OFF" ); + break; + case SSL_SESS_CACHE_CLIENT: + net_store_data(&packet2,"CLIENT" ); + break; + case SSL_SESS_CACHE_SERVER: + net_store_data(&packet2,"SERVER" ); + break; + case SSL_SESS_CACHE_BOTH: + net_store_data(&packet2,"BOTH" ); + break; + case SSL_SESS_CACHE_NO_AUTO_CLEAR: + net_store_data(&packet2,"NO_AUTO_CLEAR" ); + break; + case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP: + net_store_data(&packet2,"NO_INTERNAL_LOOKUP" ); + break; + default: + net_store_data(&packet2,"Unknown"); + break; + } + break; + +#endif /* HAVE_OPENSSL */ } if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length())) goto err; /* purecov: inspected */ diff --git a/sql/structs.h b/sql/structs.h index 594432134b2..12ba5004a2e 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -125,7 +125,18 @@ typedef struct { enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL, SHOW_MY_BOOL,SHOW_OPENTABLES,SHOW_STARTTIME,SHOW_QUESTION, - SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE}; + SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE +#ifdef HAVE_OPENSSL + ,SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD + ,SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE + ,SHOW_SSL_CTX_SESS_CB_HITS, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE + ,SHOW_SSL_CTX_SESS_NUMBER, SHOW_SSL_SESSION_REUSED + ,SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER + ,SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE + ,SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH + ,SHOW_SSL_CTX_GET_VERIFY_DEPTH +#endif /* HAVE_OPENSSL */ +}; enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED}; diff --git a/vio/viossl.c b/vio/viossl.c index 50d46689ba5..8b1a51845be 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -70,15 +70,20 @@ report_errors() unsigned long l; const char* file; const char* data; - int line,flags; + int line,flags, any_ssl_error = 0; DBUG_ENTER("report_errors"); while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0) { char buf[200]; + any_ssl_error = 1; DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf), file,line,(flags&ERR_TXT_STRING)?data:"")) ; } + if (!any_ssl_error) { + DBUG_PRINT("info", ("No OpenSSL errors.")); + } + DBUG_PRINT("info", ("BTW, errno=%d", errno)); DBUG_VOID_RETURN; } @@ -107,11 +112,10 @@ int vio_ssl_read(Vio * vio, gptr buf, int size) DBUG_ENTER("vio_ssl_read"); DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d, ssl_=%p", vio->sd, buf, size, vio->ssl_)); - DBUG_ASSERT(vio->ssl_!= 0); - DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" - ,SSL_get_cipher_name(vio->ssl_))); - +#ifndef DBUG_OFF + errno = 0; +#endif /* DBUG_OFF */ r = SSL_read(vio->ssl_, buf, size); #ifndef DBUG_OFF if ( r< 0) @@ -127,9 +131,10 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size) int r; DBUG_ENTER("vio_ssl_write"); DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size)); - DBUG_ASSERT(vio->ssl_!=0); - DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'", - SSL_get_cipher_name(vio->ssl_))); + +#ifndef DBUG_OFF + errno = 0; +#endif /* DBUG_OFF */ r = SSL_write(vio->ssl_, buf, size); #ifndef DBUG_OFF if (r<0) @@ -293,58 +298,79 @@ my_bool vio_ssl_poll_read(Vio *vio,uint timeout) #endif } - -/* FIXME: There are some duplicate code in - * sslaccept()/sslconnect() which maybe can be eliminated - */ -void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* sd) +void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio) { X509* client_cert; char *str; + int i; +// const int blocking = vio_is_blocking(vio); DBUG_ENTER("sslaccept"); - DBUG_PRINT("enter", ("sd=%s ptr=%p", sd->sd,ptr)); - vio_reset(sd,VIO_TYPE_SSL,sd->sd,0,FALSE); - sd->ssl_=0; - sd->open_=FALSE; - DBUG_ASSERT(sd != 0); - DBUG_ASSERT(ptr != 0); - DBUG_ASSERT(ptr->ssl_context_ != 0); - if (!(sd->ssl_ = SSL_new(ptr->ssl_context_))) + DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr)); + vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); + vio->ssl_=0; + vio->open_=FALSE; + if (!(vio->ssl_ = SSL_new(ptr->ssl_context_))) { DBUG_PRINT("error", ("SSL_new failure")); report_errors(); DBUG_VOID_RETURN; } - DBUG_PRINT("info", ("ssl_=%p",sd->ssl_)); - SSL_set_fd(sd->ssl_,sd->sd); -/* SSL_accept(sd->ssl_); */ -/* if (!(ptr->bio_ = BIO_new_socket(sd->sd, BIO_NOCLOSE))) - { - DBUG_PRINT("error", ("BIO_new_socket failure")); - report_errors(); - SSL_free(sd->ssl_); - sd->ssl_=0; - DBUG_RETURN(sd); + DBUG_PRINT("info", ("ssl_=%p",vio->ssl_)); + vio_blocking(vio, FALSE); + SSL_set_fd(vio->ssl_,vio->sd); + SSL_set_accept_state(vio->ssl_); + + /* FIXME possibly infinite loop */ + while (SSL_is_init_finished(vio->ssl_)) { + DBUG_PRINT("info",("SSL_is_init_finished(vio->ssl_) is not 1")); + if((i=SSL_do_handshake(vio->ssl_))!=SSL_ERROR_NONE) + { + DBUG_PRINT("info",("*** errno %d",errno)); + switch (SSL_get_error(vio->ssl_,i)) + { + case SSL_ERROR_NONE: + DBUG_PRINT("info",("SSL_ERROR_NONE: handshake finished")); + break; + case SSL_ERROR_SSL: + DBUG_PRINT("info",("SSL_ERROR_SSL: SSL protocol error ")); + break; + case SSL_ERROR_WANT_CONNECT: + DBUG_PRINT("info",("SSL_ERROR_WANT_CONNECT:If you are doing non-blocking connects call again when the connection is established")); + break; + case SSL_ERROR_WANT_READ: + DBUG_PRINT("info",("SSL_ERROR_WANT_READ: if non-blocking etc, call again when data is available")); + break; + case SSL_ERROR_WANT_WRITE: + DBUG_PRINT("info",("SSL_ERROR_WANT_WRITE: if non-blocking etc, call again when data is available to write")); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + DBUG_PRINT("info",("SSL_ERROR_WANT_X509_LOOKUP: /* not used yet but could be :-) */")); + break; + case SSL_ERROR_SYSCALL: + DBUG_PRINT("info",("SSL_ERROR_SYSCALL: An error than the error code can be found in errno (%d)",errno)); + break; + case SSL_ERROR_ZERO_RETURN: + DBUG_PRINT("info",("SSL_ERROR_ZERO_RETURN: 0 returned on the read, normally means the socket is closed :-) */")); + break; + default: + DBUG_PRINT("info",("Unknown SSL error returned")); + break; + } + } + usleep(100); } - SSL_set_bio(sd->ssl_, ptr->bio_, ptr->bio_);*/ - SSL_set_accept_state(sd->ssl_); -/* - sprintf(ptr->desc_, "VioSSL(%d)", sd->sd); - sd->ssl_cip_ = SSL_get_cipher(sd->ssl_); -*/ - sd->open_ = TRUE; - - - client_cert = SSL_get_peer_certificate (sd->ssl_); + vio->open_ = TRUE; +#ifndef DBUF_OFF + DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" + ,SSL_get_cipher_name(vio->ssl_))); + client_cert = SSL_get_peer_certificate (vio->ssl_); if (client_cert != NULL) { DBUG_PRINT("info",("Client certificate:")); str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0); - /* CHK_NULL(str); */ DBUG_PRINT("info",("\t subject: %s", str)); free (str); str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0); - /* CHK_NULL(str); */ DBUG_PRINT("info",("\t issuer: %s", str)); free (str); @@ -354,47 +380,78 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* sd) X509_free (client_cert); } else DBUG_PRINT("info",("Client does not have certificate.")); - +#endif DBUG_VOID_RETURN; } -void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* sd) +void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio) { char *str; +// char s[]="abc"; +int i; X509* server_cert; + const int blocking = vio_is_blocking(vio); DBUG_ENTER("sslconnect"); - DBUG_PRINT("enter", ("sd=%s ptr=%p ctx: %p", sd->sd,ptr,ptr->ssl_context_)); - vio_reset(sd,VIO_TYPE_SSL,sd->sd,0,FALSE); - - sd->bio_=0; - sd->ssl_=0; - sd->open_=FALSE; - DBUG_ASSERT(sd != 0); - DBUG_ASSERT(ptr != 0); - DBUG_ASSERT(ptr->ssl_context_ != 0); + DBUG_PRINT("enter", ("sd=%d ptr=%p ctx: %p", vio->sd,ptr,ptr->ssl_context_)); + vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); - if (!(sd->ssl_ = SSL_new(ptr->ssl_context_))) + vio->ssl_=0; + vio->open_=FALSE; + if (!(vio->ssl_ = SSL_new(ptr->ssl_context_))) { DBUG_PRINT("error", ("SSL_new failure")); report_errors(); DBUG_VOID_RETURN; } - DBUG_PRINT("info", ("ssl_=%p",sd->ssl_)); - printf("ssl_=%p\n",sd->ssl_); -/* if (!(sd->bio_ = BIO_new_socket(sd->sd, BIO_NOCLOSE))) - { - DBUG_PRINT("error", ("BIO_new_socket failure")); - report_errors(); - SSL_free(sd->ssl_); - sd->ssl_=0; - DBUG_RETURN(sd); + DBUG_PRINT("info", ("ssl_=%p",vio->ssl_)); + vio_blocking(vio, FALSE); + SSL_set_fd (vio->ssl_, vio->sd); + SSL_set_connect_state(vio->ssl_); + + /* FIXME possibly infinite loop */ + while (SSL_is_init_finished(vio->ssl_)) { + DBUG_PRINT("info",("SSL_is_init_finished(vio->ssl_) is not 1")); + if((i=SSL_do_handshake(vio->ssl_))!=SSL_ERROR_NONE) + { + DBUG_PRINT("info",("*** errno %d",errno)); + switch (SSL_get_error(vio->ssl_,i)) + { + case SSL_ERROR_NONE: + DBUG_PRINT("info",("SSL_ERROR_NONE: handshake finished")); + break; + case SSL_ERROR_SSL: + DBUG_PRINT("info",("SSL_ERROR_SSL: SSL protocol error ")); + break; + case SSL_ERROR_WANT_CONNECT: + DBUG_PRINT("info",("SSL_ERROR_WANT_CONNECT:If you are doing non-blocking connects call again when the connection is established")); + break; + case SSL_ERROR_WANT_READ: + DBUG_PRINT("info",("SSL_ERROR_WANT_READ: if non-blocking etc, call again when data is available")); + break; + case SSL_ERROR_WANT_WRITE: + DBUG_PRINT("info",("SSL_ERROR_WANT_WRITE: if non-blocking etc, call again when data is available to write")); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + DBUG_PRINT("info",("SSL_ERROR_WANT_X509_LOOKUP: /* not used yet but could be :-) */")); + break; + case SSL_ERROR_SYSCALL: + DBUG_PRINT("info",("SSL_ERROR_SYSCALL: An error than the error code can be found in errno (%d)",errno)); + break; + case SSL_ERROR_ZERO_RETURN: + DBUG_PRINT("info",("SSL_ERROR_ZERO_RETURN: 0 returned on the read, normally means the socket is closed :-) */")); + break; + default: + DBUG_PRINT("info",("Unknown SSL error returned")); + break; + } + } + usleep(100); } - SSL_set_bio(sd->ssl_, sd->bio_, sd->bio_);*/ - - SSL_set_fd (sd->ssl_, sd->sd); - SSL_set_connect_state(sd->ssl_); - - server_cert = SSL_get_peer_certificate (sd->ssl_); + vio->open_ = TRUE; +#ifndef DBUG_OFF + DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" + ,SSL_get_cipher_name(vio->ssl_))); + server_cert = SSL_get_peer_certificate (vio->ssl_); if (server_cert != NULL) { DBUG_PRINT("info",("Server certificate:")); str = X509_NAME_oneline (X509_get_subject_name (server_cert), 0, 0); @@ -402,18 +459,17 @@ void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* sd) free (str); str = X509_NAME_oneline (X509_get_issuer_name (server_cert), 0, 0); - DBUG_PRINT("info",("\t issuer: %s\n", str)); + DBUG_PRINT("info",("\t issuer: %s", str)); free (str); /* We could do all sorts of certificate verification stuff here before * deallocating the certificate. */ - X509_free(server_cert); + X509_free (server_cert); } else DBUG_PRINT("info",("Server does not have certificate.")); - - /* sd->ssl_cip_ = SSL_get_cipher(sd->ssl_); */ - sd->open_ = TRUE; +#endif + vio_blocking(vio, blocking); DBUG_VOID_RETURN; } diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 5285dd0f7b1..d10814417c1 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -55,7 +55,7 @@ static int vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) { DBUG_ENTER("vio_set_cert_stuff"); - DBUG_PRINT("enter", ("ctx=%p, cert_file=%p, key_file=%p", + DBUG_PRINT("enter", ("ctx=%p, cert_file=%s, key_file=%s", ctx, cert_file, key_file)); if (cert_file != NULL) { @@ -170,7 +170,7 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, ssl_error_strings_loaded = TRUE; SSL_load_error_strings(); } - ptr->ssl_method_ = SSLv23_client_method(); + ptr->ssl_method_ = TLSv1_client_method(); ptr->ssl_context_ = SSL_CTX_new(ptr->ssl_method_); DBUG_PRINT("info", ("ssl_context_: %p",ptr->ssl_context_)); if (ptr->ssl_context_ == 0) @@ -200,7 +200,7 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, report_errors(); goto ctor_failure; } - } + } DBUG_RETURN(ptr); ctor_failure: DBUG_PRINT("exit", ("there was an error")); @@ -246,7 +246,7 @@ new_VioSSLAcceptorFd(const char* key_file, ssl_error_strings_loaded = TRUE; SSL_load_error_strings(); } - ptr->ssl_method_ = SSLv23_server_method(); + ptr->ssl_method_ = TLSv1_server_method(); ptr->ssl_context_ = SSL_CTX_new(ptr->ssl_method_); if (ptr->ssl_context_==0) { |