[PATCH] Don't allow SSLv2 connections

Sebastian Spaeth Sebastian at SSpaeth.de
Thu Jan 27 15:29:05 UTC 2011


Currently we connect with SSLv2 by default if the client and the server
negotiate that protocol. However, SSLv2 is inherently insecure and
should not be used.

Starting with python 3.2 there are nice ways to allow SSLv3 and TLSv1
connections, but in earlier versions we have to use brute force:
 1) Try a TLSv1 connection and if that fails
 2) try a SSLv3 connection. If that fails, bail out.

An alternative implementation would be to specify the connection
protocol with a configuration option, but this fails so quickly, that
trying both ways all the time doesn't seem to hurt performance.

Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
 offlineimap/imaplibutil.py |   32 +++++++++++++++++++++++++++++---
 1 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/offlineimap/imaplibutil.py b/offlineimap/imaplibutil.py
index cf82996..dd30ff4 100644
--- a/offlineimap/imaplibutil.py
+++ b/offlineimap/imaplibutil.py
@@ -15,7 +15,11 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
-import re, socket, time, subprocess
+import re
+import socket
+import time
+import subprocess
+import traceback
 from offlineimap.ui import getglobalui
 from imaplib import *
 
@@ -118,10 +122,32 @@ class WrappedIMAP4_SSL(IMAP4_SSL):
             else:
                 requirecert = ssl.CERT_NONE
 
-            self.sslobj = ssl.wrap_socket(self.sock, self.keyfile,
+            #first try TLSv1 and fall back to SSLv3 if that fails.
+            #Starting from python 3.2 we can use: 
+            # context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+            # context.options |= ssl.OP_NO_SSLv2
+            #to allow TLSv1 and SSLv3 but not SSLv2 in one call
+            try:
+                self.sslobj = ssl.wrap_socket(self.sock, self.keyfile,
                                           self.certfile,
                                           ca_certs = self._cacertfile,
-                                          cert_reqs = requirecert)
+                                          cert_reqs = requirecert,
+                                          ssl_version = ssl.PROTOCOL_TLSv1)
+
+            
+            except ssl.SSLError as e:
+                # assume: "Invalid SSL protocol variant specified, try SSLv3
+                try:
+                    self.sslobj = ssl.wrap_socket(self.sock, self.keyfile,
+                                          self.certfile,
+                                          ca_certs = self._cacertfile,
+                                          cert_reqs = requirecert,
+                                          ssl_version = ssl.PROTOCOL_SSLv3)
+                except ssl.SSLError as e:
+                    # SSLv3 also did not work out. Outch
+                    raise Exception("SSL: Could not connect to server using " 
+                                    "TLSv1 or SSLv3.\n%s" \
+                                        % traceback.format_exc())
         except NameError:
             #Python 2.4/2.5 don't have the ssl module, we need to
             #socket.ssl() here but that doesn't allow cert
-- 
1.7.1




More information about the OfflineIMAP-project mailing list