Commit a1f5a109 authored by unknown's avatar unknown

OpenSSL changes


BitKeeper/etc/ignore:
  Added vio/test-sslclient vio/test-sslserver to the ignore list
client/mysql.cc:
  Let make mysql client tell user about cipher in use
sql/mini_client.cc:
  Synced SSL stuff with libmysql code
sql/mysqld.cc:
  Preaparations to turn replication SSL on
  Stuff to output SSL variables with SHOW STATUS command
sql/sql_show.cc:
  Stuff to output SSL variables with SHOW STATUS command
sql/structs.h:
  Stuff to output SSL variables with SHOW STATUS command
vio/viossl.c:
  Major modifications
vio/viosslfactories.c:
  SSL fixes
parent d853390e
......@@ -393,3 +393,5 @@ tmp/*
vio/viotest-ssl
=6
libmysqld/ha_innobase.cc
vio/test-sslclient
vio/test-sslserver
......@@ -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)
......
......@@ -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 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
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));
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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};
......
......@@ -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("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("error", ("BIO_new_socket failure"));
report_errors();
SSL_free(sd->ssl_);
sd->ssl_=0;
DBUG_RETURN(sd);
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;
}
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_);
}
usleep(100);
}
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("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("error", ("BIO_new_socket failure"));
report_errors();
SSL_free(sd->ssl_);
sd->ssl_=0;
DBUG_RETURN(sd);
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;
}
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_);
}
usleep(100);
}
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;
}
......
......@@ -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)
......@@ -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)
{
......
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