summaryrefslogtreecommitdiff
path: root/vio
diff options
context:
space:
mode:
authorunknown <msvensson@pilot.(none)>2007-08-28 11:34:43 +0200
committerunknown <msvensson@pilot.(none)>2007-08-28 11:34:43 +0200
commit9c3a03a239da3b3757d461f908674df79f379c9f (patch)
tree861b3b15273dd18f5260c6da570da63da37493c3 /vio
parente878be4cc9608b2879cb8ed84052dfe19aa4f375 (diff)
downloadmariadb-git-9c3a03a239da3b3757d461f908674df79f379c9f.tar.gz
Bug#28812 rpl_ssl fails due to assert in extra/yassl/src/socket_wrapper.cpp:117
- Merge sslaccept and sslconnect. - Atomically "reset" vio to VIO_TYPE_SSL when the SSL connection has succeeded, this avoids having to revert anything and thus protects against "close_active_vio" in the middle. - Add some variance to the testcase mysql-test/t/rpl_ssl.test: Add some variance by running two selects before stopping the slave Check that number of records in t1 are equal on master and slave vio/viossl.c: Rewrite sslconnect and sslaccept to automically "reset" the vio to VIO_TYPE_SSL. Also use the fd from 'SSL_get_fd' to avoid setting vio->sd to -1, that previously occured when "close_active_vio" was called during connect/accept. Merge the two function since they were exactly the same except for one line. Update the DBUG printouts to be generic(i.e use peer instead of client/server).
Diffstat (limited to 'vio')
-rw-r--r--vio/viossl.c142
1 files changed, 46 insertions, 96 deletions
diff --git a/vio/viossl.c b/vio/viossl.c
index 861989136d3..c178d9e9d1b 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -172,78 +172,10 @@ void vio_ssl_delete(Vio *vio)
vio_delete(vio);
}
-
int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
{
- SSL *ssl;
- my_bool unused;
- my_bool net_blocking;
- enum enum_vio_type old_type;
DBUG_ENTER("sslaccept");
- DBUG_PRINT("enter", ("sd: %d ptr: 0x%lx, timeout: %ld",
- vio->sd, (long) ptr, timeout));
-
- old_type= vio->type;
- net_blocking= vio_is_blocking(vio);
- vio_blocking(vio, 1, &unused); /* Must be called before reset */
- vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
-
- if (!(ssl= SSL_new(ptr->ssl_context)))
- {
- DBUG_PRINT("error", ("SSL_new failure"));
- report_errors(ssl);
- vio_reset(vio, old_type,vio->sd,0,FALSE);
- vio_blocking(vio, net_blocking, &unused);
- DBUG_RETURN(1);
- }
- vio->ssl_arg= (void*)ssl;
- DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
- SSL_clear(ssl);
- SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
- SSL_set_fd(ssl, vio->sd);
- if (SSL_accept(ssl) < 1)
- {
- DBUG_PRINT("error", ("SSL_accept failure"));
- report_errors(ssl);
- SSL_free(ssl);
- vio->ssl_arg= 0;
- vio_reset(vio, old_type,vio->sd,0,FALSE);
- vio_blocking(vio, net_blocking, &unused);
- DBUG_RETURN(1);
- }
-
-#ifndef DBUG_OFF
- {
- char buf[1024];
- X509 *client_cert;
- DBUG_PRINT("info",("cipher_name= '%s'", SSL_get_cipher_name(ssl)));
-
- if ((client_cert= SSL_get_peer_certificate (ssl)))
- {
- DBUG_PRINT("info",("Client certificate:"));
- X509_NAME_oneline (X509_get_subject_name (client_cert),
- buf, sizeof(buf));
- DBUG_PRINT("info",("\t subject: %s", buf));
-
- X509_NAME_oneline (X509_get_issuer_name (client_cert),
- buf, sizeof(buf));
- DBUG_PRINT("info",("\t issuer: %s", buf));
-
- X509_free (client_cert);
- }
- else
- DBUG_PRINT("info",("Client does not have certificate."));
-
- if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
- {
- DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
- }
- else
- DBUG_PRINT("info",("no shared ciphers!"));
- }
-#endif
-
- DBUG_RETURN(0);
+ DBUG_RETURN(sslconnect(ptr, vio, timeout));
}
@@ -251,57 +183,75 @@ int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
{
SSL *ssl;
my_bool unused;
- my_bool net_blocking;
- enum enum_vio_type old_type;
+ my_bool was_blocking;
DBUG_ENTER("sslconnect");
- DBUG_PRINT("enter", ("sd: %d ptr: 0x%lx ctx: 0x%lx",
- vio->sd, (long) ptr, (long) ptr->ssl_context));
+ DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx",
+ (long) ptr, vio->sd, (long) ptr->ssl_context));
+
+ /* Set socket to blocking if not already set */
+ vio_blocking(vio, 1, &was_blocking);
- old_type= vio->type;
- net_blocking= vio_is_blocking(vio);
- vio_blocking(vio, 1, &unused); /* Must be called before reset */
- vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
if (!(ssl= SSL_new(ptr->ssl_context)))
{
DBUG_PRINT("error", ("SSL_new failure"));
report_errors(ssl);
- vio_reset(vio, old_type, vio->sd, 0, FALSE);
- vio_blocking(vio, net_blocking, &unused);
+ vio_blocking(vio, was_blocking, &unused);
DBUG_RETURN(1);
}
- vio->ssl_arg= (void*)ssl;
DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
SSL_clear(ssl);
SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
SSL_set_fd(ssl, vio->sd);
- if (SSL_connect(ssl) < 1)
+
+ /*
+ SSL_do_handshake will select between SSL_connect
+ or SSL_accept depending on server or client side
+ */
+ if (SSL_do_handshake(ssl) < 1)
{
- DBUG_PRINT("error", ("SSL_connect failure"));
+ DBUG_PRINT("error", ("SSL_do_handshake failure"));
report_errors(ssl);
SSL_free(ssl);
- vio->ssl_arg= 0;
- vio_reset(vio, old_type, vio->sd, 0, FALSE);
- vio_blocking(vio, net_blocking, &unused);
+ vio_blocking(vio, was_blocking, &unused);
DBUG_RETURN(1);
}
+
+ /*
+ Connection succeeded. Install new function handlers,
+ change type, set sd to the fd used when connecting
+ and set pointer to the SSL structure
+ */
+ vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), 0, 0);
+ vio->ssl_arg= (void*)ssl;
+
#ifndef DBUG_OFF
{
- X509 *server_cert;
- DBUG_PRINT("info",("cipher_name: '%s'" , SSL_get_cipher_name(ssl)));
+ /* Print some info about the peer */
+ X509 *cert;
+ char buf[512];
+
+ DBUG_PRINT("info",("SSL connection succeeded"));
+ DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));
- if ((server_cert= SSL_get_peer_certificate (ssl)))
+ if ((cert= SSL_get_peer_certificate (ssl)))
{
- char buf[256];
- DBUG_PRINT("info",("Server certificate:"));
- X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
- DBUG_PRINT("info",("\t subject: %s", buf));
- X509_NAME_oneline (X509_get_issuer_name(server_cert), buf, sizeof(buf));
- DBUG_PRINT("info",("\t issuer: %s", buf));
- X509_free (server_cert);
+ DBUG_PRINT("info",("Peer certificate:"));
+ X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
+ DBUG_PRINT("info",("\t subject: '%s'", buf));
+ X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
+ DBUG_PRINT("info",("\t issuer: '%s'", buf));
+ X509_free(cert);
}
else
- DBUG_PRINT("info",("Server does not have certificate."));
+ DBUG_PRINT("info",("Peer does not have certificate."));
+
+ if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
+ {
+ DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
+ }
+ else
+ DBUG_PRINT("info",("no shared ciphers!"));
}
#endif