List:Commits« Previous MessageNext Message »
From:Tatjana Azundris Nuernberg Date:May 11 2011 11:46pm
Subject:bzr commit into mysql-5.5-bugteam branch (tatjana.nuernberg:3229) Bug#21287
Bug#11745920
View as plain text  
#At file:///Users/tnurnberg/forest/21287/55-21287/ based on revid:dao-gang.qu@stripped

 3229 Tatjana Azundris Nuernberg	2011-05-12
      Bug#11745920/Bug#21287: "SSL connection error" is not helpful! (ssl-verify-server-cert=true vs localhos)
      
      SSL errors on client and now more specific to aid end-user
      with debugging. Also restructures error handling for
      compliance with SSL docs.
     @ include/violite.h
        new_VioSSLConnectorFd/sslaccept/sslconnect return more elaborate status
     @ libmysql/errmsg.c
        SSL errors now extended, more specific
     @ mysql-test/r/openssl_1.result
        SSL error messages now more specific
     @ sql-common/client.c
        ssl_verify_server_cert: we work out what's wrong, might as
        well tell the user.
        
        Do more detailed error reporting for setup, connect, and
        server cert verifying phases.
     @ sql/sql_acl.cc
        sslaccept() signature has changed
     @ vio/vio_priv.h
        We're using the same reporter for both viossl and viosslfactories now.
     @ vio/viossl.c
        Don't just print low level SSL problems to debug trace,
        save the error code and return it to callers of sslaccept
        and sslconnect!
        
        Also splits SSL I/O error handling from other errors, for
        compliance with the SSL docs.
        
        Lastly for SSL I/O, use actual function returns for more
        precise error messages.
     @ vio/viosslfactories.c
        new_VioSSLConnectorFd() now returns error codes from 
        new_VioSSLFd() rather than to discard them.

    modified:
      include/violite.h
      libmysql/errmsg.c
      mysql-test/r/openssl_1.result
      sql-common/client.c
      sql/sql_acl.cc
      vio/test-ssl.c
      vio/test-sslclient.c
      vio/test-sslserver.c
      vio/vio_priv.h
      vio/viossl.c
      vio/viosslfactories.c
      vio/viotest-ssl.c
=== modified file 'include/violite.h'
--- a/include/violite.h	2010-06-07 14:01:39 +0000
+++ b/include/violite.h	2011-05-11 23:46:04 +0000
@@ -132,13 +132,13 @@ struct st_VioSSLFd
   SSL_CTX *ssl_context;
 };
 
-int sslaccept(struct st_VioSSLFd*, Vio *, long timeout);
-int sslconnect(struct st_VioSSLFd*, Vio *, long timeout);
+int sslaccept(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr);
+int sslconnect(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr);
 
 struct st_VioSSLFd
 *new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
 		       const char *ca_file,  const char *ca_path,
-		       const char *cipher);
+		       const char *cipher, enum enum_ssl_init_error *error);
 struct st_VioSSLFd
 *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
 		      const char *ca_file,const char *ca_path,

=== modified file 'libmysql/errmsg.c'
--- a/libmysql/errmsg.c	2010-11-24 10:23:44 +0000
+++ b/libmysql/errmsg.c	2011-05-11 23:46:04 +0000
@@ -51,7 +51,7 @@ const char *client_errors[]=
   "Error on SHOW SLAVE HOSTS:",
   "Error connecting to slave:",
   "Error connecting to master:",
-  "SSL connection error",
+  "SSL connection error: %100s",
   "Malformed packet",
   "This client library is licensed only for use with MySQL servers having '%s' license",
   "Invalid use of null pointer",

=== modified file 'mysql-test/r/openssl_1.result'
--- a/mysql-test/r/openssl_1.result	2010-01-29 14:54:27 +0000
+++ b/mysql-test/r/openssl_1.result	2011-05-11 23:46:04 +0000
@@ -44,13 +44,13 @@ ERROR 42000: DELETE command denied to us
 drop user ssl_user1@localhost, ssl_user2@localhost,
 ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost;
 drop table t1;
-mysqltest: Could not open connection 'default': 2026 SSL connection error
-mysqltest: Could not open connection 'default': 2026 SSL connection error
-mysqltest: Could not open connection 'default': 2026 SSL connection error
+mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation
+mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation
+mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation
 SSL error: Unable to get private key from ''
-mysqltest: Could not open connection 'default': 2026 SSL connection error
+mysqltest: Could not open connection 'default': 2026 SSL connection error: Unable to get private key
 SSL error: Unable to get certificate from ''
-mysqltest: Could not open connection 'default': 2026 SSL connection error
+mysqltest: Could not open connection 'default': 2026 SSL connection error: Unable to get certificate
 SHOW STATUS LIKE 'Ssl_cipher';
 Variable_name	Value
 Ssl_cipher	DHE-RSA-AES256-SHA
@@ -83,7 +83,7 @@ Ssl_cipher	AES128-SHA
 SHOW STATUS LIKE 'Ssl_cipher';
 Variable_name	Value
 Ssl_cipher	AES128-SHA
-mysqltest: Could not open connection 'default': 2026 SSL connection error
+mysqltest: Could not open connection 'default': 2026 SSL connection error: SSL_CTX_new failed
 CREATE TABLE t1(a int);
 INSERT INTO t1 VALUES (1), (2);
 
@@ -189,7 +189,7 @@ UNLOCK TABLES;
 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
 
 SSL error: Unable to get private key from 'MYSQL_TEST_DIR/std_data/client-cert.pem'
-mysqldump: Got error: 2026: SSL connection error when trying to connect
+mysqldump: Got error: 2026: SSL connection error: Unable to get private key when trying to connect
 DROP TABLE t1;
 Variable_name	Value
 Ssl_cipher	DHE-RSA-AES256-SHA

=== modified file 'sql-common/client.c'
--- a/sql-common/client.c	2010-11-10 15:21:51 +0000
+++ b/sql-common/client.c	2011-05-11 23:46:04 +0000
@@ -1850,6 +1850,8 @@ mysql_get_ssl_cipher(MYSQL *mysql __attr
   ssl_verify_server_cert()
     vio              pointer to a SSL connected vio
     server_hostname  name of the server that we connected to
+    errptr           if we fail, we'll return (a pointer to a string
+                     describing) the reason here
 
   RETURN VALUES
    0 Success
@@ -1859,7 +1861,7 @@ mysql_get_ssl_cipher(MYSQL *mysql __attr
 
 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
 
-static int ssl_verify_server_cert(Vio *vio, const char* server_hostname)
+static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const char **errptr)
 {
   SSL *ssl;
   X509 *server_cert;
@@ -1870,19 +1872,19 @@ static int ssl_verify_server_cert(Vio *v
 
   if (!(ssl= (SSL*)vio->ssl_arg))
   {
-    DBUG_PRINT("error", ("No SSL pointer found"));
+    *errptr= "No SSL pointer found";
     DBUG_RETURN(1);
   }
 
   if (!server_hostname)
   {
-    DBUG_PRINT("error", ("No server hostname supplied"));
+    *errptr= "No server hostname supplied";
     DBUG_RETURN(1);
   }
 
   if (!(server_cert= SSL_get_peer_certificate(ssl)))
   {
-    DBUG_PRINT("error", ("Could not get server certificate"));
+    *errptr= "Could not get server certificate";
     DBUG_RETURN(1);
   }
 
@@ -1911,7 +1913,7 @@ static int ssl_verify_server_cert(Vio *v
       DBUG_RETURN(0);
     }
   }
-  DBUG_PRINT("error", ("SSL certificate validation failure"));
+  *errptr= "SSL certificate validation failure";
   DBUG_RETURN(1);
 }
 
@@ -2492,6 +2494,9 @@ static int send_client_reply_packet(MCPV
     /* Do the SSL layering. */
     struct st_mysql_options *options= &mysql->options;
     struct st_VioSSLFd *ssl_fd;
+    enum enum_ssl_init_error ssl_init_error;
+    const char *cert_error;
+    unsigned long ssl_error;
 
     /*
       Send mysql->client_flag, max_packet_size - unencrypted otherwise
@@ -2511,9 +2516,11 @@ static int send_client_reply_packet(MCPV
                                         options->ssl_cert,
                                         options->ssl_ca,
                                         options->ssl_capath,
-                                        options->ssl_cipher)))
+                                        options->ssl_cipher,
+                                        &ssl_init_error)))
     {
-      set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+      set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
+                               ER(CR_SSL_CONNECTION_ERROR), sslGetErrString(ssl_init_error));
       goto error;
     }
     mysql->connector_fd= (unsigned char *) ssl_fd;
@@ -2521,18 +2528,24 @@ static int send_client_reply_packet(MCPV
     /* Connect to the server */
     DBUG_PRINT("info", ("IO layer change in progress..."));
     if (sslconnect(ssl_fd, net->vio,
-                   (long) (mysql->options.connect_timeout)))
-    {    
-      set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+                   (long) (mysql->options.connect_timeout), &ssl_error))
+    {
+      char buf[512];
+      ERR_error_string_n(ssl_error, buf, 512);
+      buf[511]= 0;
+      set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
+                               ER(CR_SSL_CONNECTION_ERROR),
+                               buf);
       goto error;
-    }    
+    }
     DBUG_PRINT("info", ("IO layer change done!"));
 
     /* Verify server cert */
     if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
-        ssl_verify_server_cert(net->vio, mysql->host))
+        ssl_verify_server_cert(net->vio, mysql->host, &cert_error))
     {
-      set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+      set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
+                               ER(CR_SSL_CONNECTION_ERROR), cert_error);
       goto error;
     }
   }
@@ -3061,7 +3074,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
                       VIO_LOCALHOST | VIO_BUFFERED_READ);
     if (!net->vio)
     {
-      DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
+      DBUG_PRINT("error",("Unknown protocol %d ", mysql->options.protocol));
       set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
       closesocket(sock);
       goto error;
@@ -3237,7 +3250,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
     net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
     if (! net->vio )
     {
-      DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
+      DBUG_PRINT("error",("Unknown protocol %d ", mysql->options.protocol));
       set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
       closesocket(sock);
       goto error;
@@ -3247,7 +3260,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
   DBUG_PRINT("info", ("net->vio: %p", net->vio));
   if (!net->vio)
   {
-    DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
+    DBUG_PRINT("error",("Unknown protocol %d ",mysql->options.protocol));
     set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
     goto error;
   }

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2010-12-17 11:11:34 +0000
+++ b/sql/sql_acl.cc	2011-05-11 23:46:04 +0000
@@ -8394,16 +8394,24 @@ static ulong parse_client_handshake_pack
   DBUG_PRINT("info", ("client capabilities: %lu", mpvio->client_capabilities));
   if (mpvio->client_capabilities & CLIENT_SSL)
   {
-    char error_string[1024] __attribute__((unused));
+    unsigned long errptr;
 
     /* Do the SSL layering. */
     if (!ssl_acceptor_fd)
       return packet_error;
 
     DBUG_PRINT("info", ("IO layer change in progress..."));
-    if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
+    if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, &errptr))
     {
       DBUG_PRINT("error", ("Failed to accept new SSL connection"));
+
+      if (global_system_variables.log_warnings > 1)
+      {
+        char buf[512];
+        ERR_error_string_n(errptr, buf, 512);
+        buf[511]= 0;
+        sql_print_warning("SSL connection error: %s", buf);
+      }
       return packet_error;
     }
 

=== modified file 'vio/test-ssl.c'
--- a/vio/test-ssl.c	2010-07-15 11:13:30 +0000
+++ b/vio/test-ssl.c	2011-05-11 23:46:04 +0000
@@ -59,6 +59,9 @@ main(int argc, char**	argv)
   struct st_VioSSLFd* ssl_acceptor= 0;
   struct st_VioSSLFd* ssl_connector= 0;
   Vio* client_vio=0, *server_vio=0;
+  enum enum_ssl_init_error ssl_init_error;
+  unsigned long ssl_error;
+
   MY_INIT(argv[0]);
   DBUG_PROCESS(argv[0]);
   DBUG_PUSH(default_dbug_option);
@@ -91,16 +94,16 @@ main(int argc, char**	argv)
   ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file,
 				      ca_path, cipher);
   ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file,
-					ca_path, cipher);
+					ca_path, cipher, &ssl_init_error);
 
   client_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
   client_vio->sd = sv[0];
   client_vio->vioblocking(client_vio, 0, &unused);
-  sslconnect(ssl_connector,client_vio,60L);
+  sslconnect(ssl_connector,client_vio,60L,&ssl_error);
   server_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
   server_vio->sd = sv[1];
   server_vio->vioblocking(client_vio, 0, &unused);
-  sslaccept(ssl_acceptor,server_vio,60L);
+  sslaccept(ssl_acceptor,server_vio,60L, &ssl_error);
 
   printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);
 

=== modified file 'vio/test-sslclient.c'
--- a/vio/test-sslclient.c	2010-07-08 21:20:08 +0000
+++ b/vio/test-sslclient.c	2011-05-11 23:46:04 +0000
@@ -50,6 +50,9 @@ main(	int	argc __attribute__((unused)),
 	Vio* client_vio=0;
 	int err;
 	char	xbuf[100]="Ohohhhhoh1234";
+        enum enum_ssl_init_error ssl_init_error;
+        unsigned long ssl_error;
+
 	MY_INIT(argv[0]);
         DBUG_PROCESS(argv[0]);
         DBUG_PUSH(default_dbug_option);
@@ -60,7 +63,8 @@ main(	int	argc __attribute__((unused)),
 	if (ca_path!=0)
 		printf("CApath          : %s\n", ca_path);
 
-	ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher);
+	ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher,
+                                              &ssl_init_error);
 	if(!ssl_connector) {
                  fatal_error("client:new_VioSSLConnectorFd failed");
 	}
@@ -81,7 +85,7 @@ main(	int	argc __attribute__((unused)),
 	/* ----------------------------------------------- */
 	/* Now we have TCP conncetion. Start SSL negotiation. */
 	read(client_vio->sd,xbuf, sizeof(xbuf));
-        sslconnect(ssl_connector,client_vio,60L);
+        sslconnect(ssl_connector,client_vio,60L,&ssl_error);
 	err = vio_read(client_vio,xbuf, sizeof(xbuf));
 	if (err<=0) {
 		my_free(ssl_connector);

=== modified file 'vio/test-sslserver.c'
--- a/vio/test-sslserver.c	2010-07-08 21:20:08 +0000
+++ b/vio/test-sslserver.c	2011-05-11 23:46:04 +0000
@@ -52,6 +52,7 @@ do_ssl_stuff(	TH_ARGS*	args)
 	const char*	s = "Huhuhuhuuu";
 	Vio*		server_vio;
 	int		err;
+        unsigned long   ssl_error;
 	DBUG_ENTER("do_ssl_stuff");
 
 	server_vio = vio_new(args->sd, VIO_TYPE_TCPIP, TRUE);
@@ -60,7 +61,7 @@ do_ssl_stuff(	TH_ARGS*	args)
 	/* TCP connection is ready. Do server side SSL. */
 
 	err = write(server_vio->sd,(uchar*)s, strlen(s));
-	sslaccept(args->ssl_acceptor,server_vio,60L);
+	sslaccept(args->ssl_acceptor,server_vio,60L,&ssl_error);
 	err = server_vio->write(server_vio,(uchar*)s, strlen(s));
 	DBUG_VOID_RETURN;
 }

=== modified file 'vio/vio_priv.h'
--- a/vio/vio_priv.h	2010-06-07 14:01:39 +0000
+++ b/vio/vio_priv.h	2011-05-11 23:46:04 +0000
@@ -65,5 +65,7 @@ int vio_ssl_blocking(Vio *vio, my_bool s
 
 my_bool vio_ssl_has_data(Vio *vio);
 
+unsigned long ssl_report_errors();
+
 #endif /* HAVE_OPENSSL */
 #endif /* VIO_PRIV_INCLUDED */

=== modified file 'vio/viossl.c'
--- a/vio/viossl.c	2010-08-16 12:50:27 +0000
+++ b/vio/viossl.c	2011-05-11 23:46:04 +0000
@@ -24,31 +24,92 @@
 
 #ifdef HAVE_OPENSSL
 
-static void
-report_errors(SSL* ssl)
+#include <openssl/err.h>
+
+/**
+  Clears SSL error queue. In debug builds, also reports its contents.
+  OpenSSL doc requires we empty the error Q before doing SSL I/O (at
+  least in those cases where we wish to use SSL_get_error()).
+
+SYNOPSIS
+    ssl_report_errors()
+
+  SIDE EFFECTS
+      DBUG_PRINT()s and clears error queue
+
+  RETURN VALUES
+      last error code in queue
+ */
+
+unsigned long
+ssl_report_errors(void)
 {
-  unsigned long	l;
+  unsigned long	e, l= 0;
+#ifndef DBUG_OFF
   const char *file;
   const char *data;
   int line, flags;
-#ifndef DBUG_OFF
   char buf[512];
 #endif
 
-  DBUG_ENTER("report_errors");
+  DBUG_ENTER("ssl_report_errors");
 
-  while ((l= ERR_get_error_line_data(&file,&line,&data,&flags)))
+#ifndef DBUG_OFF
+  while ((e= ERR_get_error_line_data(&file, &line, &data, &flags)))
   {
-    DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
-			 file,line,(flags&ERR_TXT_STRING)?data:"")) ;
+    DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(e, buf),
+			 file, line, (flags&ERR_TXT_STRING)?data:""));
+    l= e;
   }
+#else
+  while ((e= ERR_get_error()))
+    l= e;
+#endif
+
+  DBUG_PRINT("info", ("socket_errno: %d", socket_errno));
+  DBUG_RETURN(l);
+}
+
+
+/**
+  report SSL errors.
+  We call this because one of the TLS/SSL I/O routines -- SSL_connect(),
+  SSL_accept(), SSL_do_handshake(), SSL_read(), SSL_peek(), or SSL_write() --
+  failed.
+
+  SYNOPSIS
+    ssl_report_io_errors()
+      ssl     Current SSL (non-NULL) connection
+      r       return value from last ssl_*() call
+
+  SIDE EFFECTS
+      DBUG_PRINT()s
+
+  RETURN VALUES
+      an error code
+ */
+
+unsigned long
+ssl_report_io_errors(SSL *ssl, int r)
+{
+  unsigned long	io= 0;
+#ifndef DBUG_OFF
+  char buf[512];
+#endif
+
+  DBUG_ENTER("ssl_report_io_errors");
+
+  DBUG_ASSERT(ssl);
 
   if (ssl)
-    DBUG_PRINT("error", ("error: %s",
-                         ERR_error_string(SSL_get_error(ssl, l), buf)));
+  {
+    io= SSL_get_error(ssl, r);
+    DBUG_PRINT("error", ("SSL I/O error: %lu - %s",
+                         io, ERR_error_string(io, buf)));
+  }
 
   DBUG_PRINT("info", ("socket_errno: %d", socket_errno));
-  DBUG_VOID_RETURN;
+  DBUG_RETURN(io);
 }
 
 
@@ -59,10 +120,14 @@ size_t vio_ssl_read(Vio *vio, uchar* buf
   DBUG_PRINT("enter", ("sd: %d  buf: 0x%lx  size: %u  ssl: 0x%lx",
 		       vio->sd, (long) buf, (uint) size, (long) vio->ssl_arg));
 
+#ifndef DBUG_OFF
+  ssl_report_errors();
+#endif
+
   r= SSL_read((SSL*) vio->ssl_arg, buf, size);
 #ifndef DBUG_OFF
   if (r == (size_t) -1)
-    report_errors((SSL*) vio->ssl_arg);
+    ssl_report_io_errors((SSL*) vio->ssl_arg, r);
 #endif
   DBUG_PRINT("exit", ("%u", (uint) r));
   DBUG_RETURN(r);
@@ -75,11 +140,15 @@ size_t vio_ssl_write(Vio *vio, const uch
   DBUG_ENTER("vio_ssl_write");
   DBUG_PRINT("enter", ("sd: %d  buf: 0x%lx  size: %u", vio->sd,
                        (long) buf, (uint) size));
+ 
+#ifndef DBUG_OFF
+ ssl_report_errors();
+#endif
 
   r= SSL_write((SSL*) vio->ssl_arg, buf, size);
 #ifndef DBUG_OFF
   if (r == (size_t) -1)
-    report_errors((SSL*) vio->ssl_arg);
+    ssl_report_io_errors((SSL*) vio->ssl_arg, r);
 #endif
   DBUG_PRINT("exit", ("%u", (uint) r));
   DBUG_RETURN(r);
@@ -144,11 +213,12 @@ void vio_ssl_delete(Vio *vio)
 
 
 static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
-                  int (*connect_accept_func)(SSL*))
+                  int (*connect_accept_func)(SSL*), unsigned long *errptr)
 {
   SSL *ssl;
   my_bool unused;
   my_bool was_blocking;
+  int     r;
 
   DBUG_ENTER("ssl_do");
   DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d  ctx: 0x%lx",
@@ -160,7 +230,7 @@ static int ssl_do(struct st_VioSSLFd *pt
   if (!(ssl= SSL_new(ptr->ssl_context)))
   {
     DBUG_PRINT("error", ("SSL_new failure"));
-    report_errors(ssl);
+    *errptr= ssl_report_errors();
     vio_blocking(vio, was_blocking, &unused);
     DBUG_RETURN(1);
   }
@@ -169,10 +239,16 @@ static int ssl_do(struct st_VioSSLFd *pt
   SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
   SSL_set_fd(ssl, vio->sd);
 
-  if (connect_accept_func(ssl) < 1)
+  ssl_report_errors();
+
+  if ((r= connect_accept_func(ssl)) < 1)
   {
     DBUG_PRINT("error", ("SSL_connect/accept failure"));
-    report_errors(ssl);
+#ifndef DBUG_OFF
+    *errptr= ssl_report_io_errors(ssl, r);
+#else
+    *errptr= SSL_get_error(ssl, r);
+#endif
     SSL_free(ssl);
     vio_blocking(vio, was_blocking, &unused);
     DBUG_RETURN(1);
@@ -220,17 +296,17 @@ static int ssl_do(struct st_VioSSLFd *pt
 }
 
 
-int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
+int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr)
 {
   DBUG_ENTER("sslaccept");
-  DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept));
+  DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept, errptr));
 }
 
 
-int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
+int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr)
 {
   DBUG_ENTER("sslconnect");
-  DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect));
+  DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect, errptr));
 }
 
 

=== modified file 'vio/viosslfactories.c'
--- a/vio/viosslfactories.c	2010-07-15 11:13:30 +0000
+++ b/vio/viosslfactories.c	2011-05-11 23:46:04 +0000
@@ -50,28 +50,6 @@ static DH *get_dh512(void)
   return(dh);
 }
 
-
-static void
-report_errors()
-{
-  unsigned long	l;
-  const char*	file;
-  const char*	data;
-  int		line,flags;
-
-  DBUG_ENTER("report_errors");
-
-  while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
-  {
-#ifndef DBUG_OFF				/* Avoid warning */
-    char buf[200];
-    DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
-			 file,line,(flags & ERR_TXT_STRING) ? data : "")) ;
-#endif
-  }
-  DBUG_VOID_RETURN;
-}
-
 static const char*
 ssl_error_string[] = 
 {
@@ -165,7 +143,7 @@ static struct st_VioSSLFd *
 new_VioSSLFd(const char *key_file, const char *cert_file,
              const char *ca_file, const char *ca_path,
              const char *cipher, SSL_METHOD *method, 
-             enum enum_ssl_init_error* error)
+             enum enum_ssl_init_error *error)
 {
   DH *dh;
   struct st_VioSSLFd *ssl_fd;
@@ -189,7 +167,7 @@ new_VioSSLFd(const char *key_file, const
   {
     *error= SSL_INITERR_MEMFAIL;
     DBUG_PRINT("error", ("%s", sslGetErrString(*error)));
-    report_errors();
+    ssl_report_errors();
     my_free(ssl_fd);
     DBUG_RETURN(0);
   }
@@ -204,7 +182,7 @@ new_VioSSLFd(const char *key_file, const
   {
     *error= SSL_INITERR_CIPHERS;
     DBUG_PRINT("error", ("%s", sslGetErrString(*error)));
-    report_errors();
+    ssl_report_errors();
     SSL_CTX_free(ssl_fd->ssl_context);
     my_free(ssl_fd);
     DBUG_RETURN(0);
@@ -218,7 +196,7 @@ new_VioSSLFd(const char *key_file, const
     {
       *error= SSL_INITERR_BAD_PATHS;
       DBUG_PRINT("error", ("%s", sslGetErrString(*error)));
-      report_errors();
+      ssl_report_errors();
       SSL_CTX_free(ssl_fd->ssl_context);
       my_free(ssl_fd);
       DBUG_RETURN(0);
@@ -228,7 +206,7 @@ new_VioSSLFd(const char *key_file, const
   if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file, error))
   {
     DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
-    report_errors();
+    ssl_report_errors();
     SSL_CTX_free(ssl_fd->ssl_context);
     my_free(ssl_fd);
     DBUG_RETURN(0);
@@ -249,11 +227,10 @@ new_VioSSLFd(const char *key_file, const
 struct st_VioSSLFd *
 new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
                       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;
   int verify= SSL_VERIFY_PEER;
-  enum enum_ssl_init_error dummy;
 
   /*
     Turn off verification of servers certificate if both
@@ -263,7 +240,7 @@ new_VioSSLConnectorFd(const char *key_fi
     verify= SSL_VERIFY_NONE;
 
   if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
-                             ca_path, cipher, TLSv1_client_method(), &dummy)))
+                             ca_path, cipher, TLSv1_client_method(), error)))
   {
     return 0;
   }

=== modified file 'vio/viotest-ssl.c'
--- a/vio/viotest-ssl.c	2010-07-08 21:20:08 +0000
+++ b/vio/viotest-ssl.c	2011-05-11 23:46:04 +0000
@@ -60,6 +60,9 @@ int main(int argc, char **argv)
   struct st_VioSSLConnectorFd* ssl_connector=0; 
   Vio* client_vio=0;
   Vio* server_vio=0;
+  enum enum_ssl_init_error ssl_init_error;
+  unsigned long ssl_error;
+
   MY_INIT(argv[0]);
   DBUG_PROCESS(argv[0]);
   DBUG_PUSH(default_dbug_option);
@@ -92,14 +95,14 @@ int main(int argc, char **argv)
   ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file,
 				      ca_path);
   ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file,
-					ca_path);
+					ca_path, &ssl_init_error);
 
   client_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0));
   client_vio->sd = sv[0];
-  sslconnect(ssl_connector,client_vio);
+  sslconnect(ssl_connector,client_vio,&ssl_error);
   server_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0));
   server_vio->sd = sv[1];
-  sslaccept(ssl_acceptor,server_vio);
+  sslaccept(ssl_acceptor,server_vio,&ssl_error);
 
   printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);
 


Attachment: [text/bzr-bundle] bzr/tatjana.nuernberg@oracle.com-20110511234604-461n5ne1nnvpefgc.bundle
Thread
bzr commit into mysql-5.5-bugteam branch (tatjana.nuernberg:3229) Bug#21287Bug#11745920Tatjana Azundris Nuernberg12 May
  • Re: bzr commit into mysql-5.5-bugteam branch (tatjana.nuernberg:3229)Bug#21287 Bug#11745920Davi Arnaut13 May