[PATCH] Retry SSL connections with different SSL options



The following patch against balsa 1.2.0 makes it so that balsa will
retry SSL connections that have failed due to a protocol error (able to
be identified by SSL_ERROR_SYSCALL with err == 0 according to
SSL_get_error(3)) with protocols disabled.  This provides similar
functionality to the options for enabling and disabling specific
protocols as found in mutt itself without requiring the user to know as
much.  It would be better if the successful option set made its way into
the configuration, but that would require me learning way more about
balsa internals than I really want to know and waiting on a couple of
connection attempts is better for me at the moment than not being able
to use balsa at all with the IMAP server at NCSU. :-)

Jeremy

--- balsa-1.2.0/libmutt/mutt_ssl.c	Sat Aug 18 21:41:24 2001
+++ balsa/libmutt/mutt_ssl.c	Tue Oct 16 02:10:13 2001
@@ -256,6 +256,8 @@
 
 int ssl_socket_open (CONNECTION * conn)
 {
+/* BALSA: we want to retry with different SSL options in libmutt */
+#ifndef LIBMUTT
   sslsockdata *data;
   int maxbits;
 
@@ -267,8 +269,6 @@
 
   data->ctx = SSL_CTX_new (SSLv23_client_method ());
 
-#ifndef LIBMUTT
-  /* how will we configure this in balsa ? */
   /* disable SSL protocols as needed */
   if (!option(OPTTLSV1)) 
   {
@@ -282,7 +282,6 @@
   {
     SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv3);
   }
-#endif
 
   data->ssl = SSL_new (data->ctx);
   SSL_set_fd (data->ssl, conn->fd);
@@ -297,6 +296,49 @@
     &maxbits);
 
   return 0;
+#else
+  sslsockdata *data;
+  int maxbits;
+  int ret;
+  int tries = 0;
+  /* XXX we should save the options successful here */
+  long options[4] = { 0, SSL_OP_NO_TLSv1, SSL_OP_NO_SSLv3, SSL_OP_NO_SSLv2 };
+
+  while (tries < 4) {
+    if (raw_socket_open (conn) < 0)
+      return -1;
+  
+    data = (sslsockdata *) safe_calloc (1, sizeof (sslsockdata));
+    conn->sockdata = data;
+  
+    data->ctx = SSL_CTX_new (SSLv23_client_method ());
+    
+    SSL_CTX_set_options(data->ctx, SSL_OP_ALL);
+    SSL_CTX_set_options(data->ctx, options[tries]);
+    
+    data->ssl = SSL_new (data->ctx);
+    SSL_set_fd (data->ssl, conn->fd);
+    
+    /* if we hit a protocol violation, try another variation */
+    ret = ssl_negotiate(data);
+    if (ret == -2)
+    {
+      ssl_socket_close (conn);
+      tries++;
+      continue;
+    } else if (ret) {
+      ssl_socket_close (conn);
+      return -1;
+    }
+  
+    conn->ssf = SSL_CIPHER_get_bits (SSL_get_current_cipher (data->ssl),
+				     &maxbits);
+
+    return 0;
+  }
+  mutt_error("SSL failed: Unable to negotiate protocol");
+  return -1;
+#endif
 }
 
 /* ssl_negotiate: After SSL state has been initialised, attempt to negotiate
@@ -318,6 +360,12 @@
     switch (SSL_get_error (ssldata->ssl, err))
     {
     case SSL_ERROR_SYSCALL:
+#ifdef LIBMUTT
+      /* BALSA: if err 0, protocol violation, not IO error; retry with opts */
+      if (err == 0) {
+	return -2;
+      }
+#endif
       errmsg = "I/O error";
       break;
     case SSL_ERROR_SSL:




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]