[PATCH] Throw errors on connection refused and on non-standard SSL ports

Sebastian Spaeth Sebastian at SSpaeth.de
Mon Jun 6 10:04:55 BST 2011


We were "crashing" with tracebacks when we could not connect to a host,
(e.g. because no service was on the port) and we were getting mysterious
SSL tracebacks when someone tried to connect via SSL to a non-ssl port.

In these cases, we will now throw an nice error message. On python<2.6
where no ssl module exists, we simply won't throw those errors.

Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
 offlineimap/imapserver.py |   38 +++++++++++++++++++++++++++++++++-----
 1 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/offlineimap/imapserver.py b/offlineimap/imapserver.py
index 37fc553..e7892cc 100644
--- a/offlineimap/imapserver.py
+++ b/offlineimap/imapserver.py
@@ -24,9 +24,14 @@ import offlineimap.accounts
 import hmac
 import socket
 import base64
+import errno
 
 from socket import gaierror
-
+try:
+    from ssl import SSLError
+except ImportError:
+    # Protect against python<2.6, use dummy and won't get SSL errors.
+    SSLError = None
 try:
     # do we have a recent pykerberos?
     have_gss = False
@@ -280,14 +285,37 @@ class IMAPServer:
             if(self.connectionlock.locked()):
                 self.connectionlock.release()
 
-            if type(e) == gaierror:
+            # now, check for known errors and throw OfflineImapErrors
+            severity = OfflineImapError.ERROR.REPO
+            if isinstance(e, gaierror):
                 #DNS related errors. Abort Repo sync
-                severity = OfflineImapError.ERROR.REPO
                 #TODO: special error msg for e.errno == 2 "Name or service not known"?
                 reason = "Could not resolve name '%s' for repository "\
                          "'%s'. Make sure you have configured the ser"\
-                         "ver name correctly and that you are online."\
-                         % (self.hostname, self.reposname)
+                         "ver name correctly and that you are online."%\
+                         (self.hostname, self.reposname)
+                raise OfflineImapError(reason, severity)
+
+            elif isinstance(e, SSLError) and e.errno == 1:
+                # SSL unknown protocol error
+                # happens e.g. when connecting via SSL to a non-SSL service
+                if self.port != 443:
+                    reason = "Could not connect via SSL to host '%s' and non-s"\
+                        "tandard ssl port %d configured. Make sure you connect"\
+                        " to the correct port." % (self.hostname, self.port)
+                else:
+                    reason = "Unknown SSL protocol connecting to host '%s' for"\
+                         "repository '%s'. OpenSSL responded:\n%s"\
+                         % (self.hostname, self.reposname, e)
+                raise OfflineImapError(reason, severity)
+
+            elif isinstance(e, socket.error) and e.args[0] == errno.ECONNREFUSED:
+                # "Connection refused", can be a non-existing port, or an unauthorized
+                # webproxy (open WLAN?)
+                reason = "Connection to host '%s:%d' for repository '%s' was "\
+                    "refused. Make sure you have the right host and port "\
+                    "configured and that you are actually able to access the "\
+                    "network." % (self.hostname, self.port, self.reposname)
                 raise OfflineImapError(reason, severity)
             # Could not acquire connection to the remote;
             # socket.error(last_error) raised
-- 
1.7.4.1





More information about the OfflineIMAP-project mailing list