List:Commits« Previous MessageNext Message »
From:msvensson Date:August 24 2007 2:59pm
Subject:bk commit into 5.0 tree (msvensson:1.2517) BUG#28812
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of msvensson. When msvensson does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-08-24 16:59:25+02:00, msvensson@pilot.(none) +7 -0
  Bug#28812 rpl_ssl fails due to assert in extra/yassl/src/socket_wrapper.cpp:117
   - Remove three assert's from yaSSL
   - Merge sslaccept and sslconnect.
   - Atomically "reset" bio to VIO_TYPE_SSL when the SSL connection has
     suceeded, this avoids hving to revert anything and thus protects
     against "close_active_vio" in the middle.
   - Protect against yaSSL::receive returns -1 
   - Add some variance to the testcase

  extra/yassl/include/openssl/prefix_ssl.h@stripped, 2007-08-24 16:59:23+02:00, msvensson@pilot.(none) +1 -0
    Add 'SSL_get_fd'

  extra/yassl/include/openssl/ssl.h@stripped, 2007-08-24 16:59:23+02:00, msvensson@pilot.(none) +1 -0
    Add 'SSL_get_fd'

  extra/yassl/src/handshake.cpp@stripped, 2007-08-24 16:59:23+02:00, msvensson@pilot.(none) +4 -0
    Return with error if 'receive' returns -1. Since the -1 is returned as uint
    it was interpreted by buffer.add_size by a very large value and
    "blow the buffer" by hitting an assert put in place to detect things like this. 

  extra/yassl/src/socket_wrapper.cpp@stripped, 2007-08-24 16:59:23+02:00, msvensson@pilot.(none) +0 -4
    Remove "assert(socket_ != INVALID_SOCKET)", it's ok to call recv, send
    or shutdown with socket set to INVALID_SOCKET, they will just return 
    -1 and set errno.

  extra/yassl/src/ssl.cpp@stripped, 2007-08-24 16:59:23+02:00, msvensson@pilot.(none) +5 -0
    Add 'SSL_get_fd'

  mysql-test/t/rpl_ssl.test@stripped, 2007-08-24 16:59:23+02:00, msvensson@pilot.(none) +16 -1
    Increase number of loops to start/stop the slave
    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@stripped, 2007-08-24 16:59:23+02:00, msvensson@pilot.(none) +46 -96
    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).

diff -Nrup a/extra/yassl/include/openssl/prefix_ssl.h b/extra/yassl/include/openssl/prefix_ssl.h
--- a/extra/yassl/include/openssl/prefix_ssl.h	2006-11-29 09:21:33 +01:00
+++ b/extra/yassl/include/openssl/prefix_ssl.h	2007-08-24 16:59:23 +02:00
@@ -30,6 +30,7 @@
 #define SSL_CTX_new yaSSL_CTX_new
 #define SSL_new yaSSL_new
 #define SSL_set_fd yaSSL_set_fd
+#define SSL_get_fd yaSSL_get_fd
 #define SSL_connect yaSSL_connect
 #define SSL_write yaSSL_write
 #define SSL_read yaSSL_read
diff -Nrup a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
--- a/extra/yassl/include/openssl/ssl.h	2007-07-13 04:06:31 +02:00
+++ b/extra/yassl/include/openssl/ssl.h	2007-08-24 16:59:23 +02:00
@@ -201,6 +201,7 @@ typedef int YASSL_SOCKET_T;
 SSL_CTX* SSL_CTX_new(SSL_METHOD*);
 SSL* SSL_new(SSL_CTX*);
 int  SSL_set_fd (SSL*, YASSL_SOCKET_T);
+YASSL_SOCKET_T SSL_get_fd(const SSL*);
 int  SSL_connect(SSL*);
 int  SSL_write(SSL*, const void*, int);
 int  SSL_read(SSL*, void*, int);
diff -Nrup a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp
--- a/extra/yassl/src/handshake.cpp	2007-01-25 19:34:38 +01:00
+++ b/extra/yassl/src/handshake.cpp	2007-08-24 16:59:23 +02:00
@@ -719,6 +719,10 @@ int DoProcessReply(SSL& ssl)
 
     // add new data
     uint read  = ssl.useSocket().receive(buffer.get_buffer() + buffSz, ready);
+    if (read == static_cast<uint>(-1)) {
+        ssl.SetError(receive_error);
+        return 0;
+    }
     buffer.add_size(read);
     uint offset = 0;
     const MessageFactory& mf = ssl.getFactory().getMessage();
diff -Nrup a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp
--- a/extra/yassl/src/socket_wrapper.cpp	2007-01-25 19:39:15 +01:00
+++ b/extra/yassl/src/socket_wrapper.cpp	2007-08-24 16:59:23 +02:00
@@ -114,8 +114,6 @@ uint Socket::send(const byte* buf, unsig
     const byte* pos = buf;
     const byte* end = pos + sz;
 
-    assert(socket_ != INVALID_SOCKET);
-
     while (pos != end) {
         int sent = ::send(socket_, reinterpret_cast<const char *>(pos),
                           static_cast<int>(end - pos), flags);
@@ -132,7 +130,6 @@ uint Socket::send(const byte* buf, unsig
 
 uint Socket::receive(byte* buf, unsigned int sz, int flags)
 {
-    assert(socket_ != INVALID_SOCKET);
     wouldBlock_ = false;
 
     int recvd = ::recv(socket_, reinterpret_cast<char *>(buf), sz, flags);
@@ -163,7 +160,6 @@ bool Socket::wait()
 
 void Socket::shutDown(int how)
 {
-    assert(socket_ != INVALID_SOCKET);
     shutdown(socket_, how);
 }
 
diff -Nrup a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
--- a/extra/yassl/src/ssl.cpp	2007-07-13 04:06:31 +02:00
+++ b/extra/yassl/src/ssl.cpp	2007-08-24 16:59:23 +02:00
@@ -238,6 +238,11 @@ int SSL_set_fd(SSL* ssl, YASSL_SOCKET_T 
     return SSL_SUCCESS;
 }
 
+YASSL_SOCKET_T SSL_get_fd(const SSL* ssl)
+{
+    return ssl->getSocket().get_fd();
+}
+
 
 int SSL_connect(SSL* ssl)
 {
diff -Nrup a/mysql-test/t/rpl_ssl.test b/mysql-test/t/rpl_ssl.test
--- a/mysql-test/t/rpl_ssl.test	2007-06-15 13:09:26 +02:00
+++ b/mysql-test/t/rpl_ssl.test	2007-08-24 16:59:23 +02:00
@@ -41,24 +41,39 @@ select * from t1;
 
 # Do the same thing a number of times
 disable_query_log;
-let $i= 100;
+disable_result_log;
+let $i= 1000;
 while ($i)
 {
   start slave;
   connection master;
   insert into t1 values (NULL);
+  select * from t1; # Some variance
   connection slave;
+  select * from t1; # Some variance
   stop slave;
   dec $i;
 }
 start slave;
 enable_query_log;
+enable_result_log;
 connection master;
 insert into t1 values (NULL);
+let $master_count= `select count(*) from t1`;
+
 sync_slave_with_master;
 --source include/wait_for_slave_to_start.inc
 --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT
 --replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 #
 query_vertical show slave status;
+
+let $slave_count= `select count(*) from t1`;
+
+if (`select $slave_count != $master_count`)
+{
+  echo master and slave differed in number of rows;
+  echo master: $master_count;
+  echo slave: $slave_count;
+}
 
 --echo End of 5.0 tests
diff -Nrup a/vio/viossl.c b/vio/viossl.c
--- a/vio/viossl.c	2007-07-13 04:06:31 +02:00
+++ b/vio/viossl.c	2007-08-24 16:59:23 +02:00
@@ -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, 
 {
   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 suceeded. 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 suceeded"));
+    DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));
+
+    if ((cert= SSL_get_peer_certificate (ssl)))
+    {
+      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",("Peer does not have certificate."));
 
-    if ((server_cert= SSL_get_peer_certificate (ssl)))
+    if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
     {
-      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",("shared_ciphers: '%s'", buf));
     }
     else
-      DBUG_PRINT("info",("Server does not have certificate."));
+      DBUG_PRINT("info",("no shared ciphers!"));
   }
 #endif
 
Thread
bk commit into 5.0 tree (msvensson:1.2517) BUG#28812msvensson24 Aug
  • Re: bk commit into 5.0 tree (msvensson:1.2517) BUG#28812Andrei Elkin27 Aug