cert_fingerprint option is ignored: fingerprints aren't verified!

James Cook james.cook at utoronto.ca
Wed Feb 29 08:20:54 GMT 2012


Hi all,

I've found a bug in the code that checks fingerprints: namely,  
fingerprints are never actually checked.

To reproduce (I'm at git commit 464342e1) add

   ssl = True
   cert_fingerprint = BANANAS

to an IMAP repository configuration where the server supports SSL.   
Run offlineimap, and notice that it happily connects to the server,  
even though the server's fingerprint is not "BANANAS".

The cause: imaplibutil.py checks for ssl support by checking if 'ssl'  
is in locals(),
but it should check globals(), since ssl is not a local variable.

A quick fix: (but see below for a change that improves security, in my  
opinion)

diff --git a/offlineimap/imaplibutil.py b/offlineimap/imaplibutil.py
index c9a7715..005a864 100644
--- a/offlineimap/imaplibutil.py
+++ b/offlineimap/imaplibutil.py
@@ -148,7 +148,7 @@ class WrappedIMAP4_SSL(UsefulIMAPMixIn, IMAP4_SSL):
      def open(self, host=None, port=None):
          super(WrappedIMAP4_SSL, self).open(host, port)
          if (self._fingerprint or not self.ca_certs) and\
-                'ssl' in locals(): # <--disable for python 2.5
+                'ssl' in globals(): # <--disable for python 2.5
              # compare fingerprints
              fingerprint = sha1(self.sock.getpeercert(True)).hexdigest()
              if fingerprint != self._fingerprint:


In my opinion, it's a bad thing to silently accept fingerprints that
can't be verified, so I prefer the following:

diff --git a/offlineimap/imaplibutil.py b/offlineimap/imaplibutil.py
index c9a7715..a18127f 100644
--- a/offlineimap/imaplibutil.py
+++ b/offlineimap/imaplibutil.py
@@ -147,8 +147,12 @@ class WrappedIMAP4_SSL(UsefulIMAPMixIn, IMAP4_SSL):

      def open(self, host=None, port=None):
          super(WrappedIMAP4_SSL, self).open(host, port)
-        if (self._fingerprint or not self.ca_certs) and\
-                'ssl' in locals(): # <--disable for python 2.5
+        if self._fingerprint or not self.ca_certs:
+            if 'ssl' not in globals():
+                raise OfflineImapError("SSL fingerprint verification  
requested, but "
+                      "python's ssl module isn't available.  Use  
python version 2.6 "
+                      "or later, or disable fingerprint verification  
by removing cer"
+                      "t_fingerprint from the configuration file.")
              # compare fingerprints
              fingerprint = sha1(self.sock.getpeercert(True)).hexdigest()
              if fingerprint != self._fingerprint:

Thanks,
   James






More information about the OfflineIMAP-project mailing list