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

Nicolas Sebrecht nicolas.s-dev at laposte.net
Thu Jun 16 22:51:27 BST 2011


On Mon, Jun 06, 2011 at 11:04:55AM +0200, Sebastian Spaeth wrote:
> 
> 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.

I've reverted this patch due to this regression:

Traceback (most recent call last):
  File "/usr/lib64/python2.5/site-packages/offlineimap/accounts.py", line 177, in syncrunner
    self.sync()
  File "/usr/lib64/python2.5/site-packages/offlineimap/accounts.py", line 235, in sync
    remoterepos.syncfoldersto(localrepos, [statusrepos])
  File "/usr/lib64/python2.5/site-packages/offlineimap/repository/Base.py", line 124, in syncfoldersto
    srcfolders = src.getfolders()
  File "/usr/lib64/python2.5/site-packages/offlineimap/repository/IMAP.py", line 276, in getfolders
    imapobj = self.imapserver.acquireconnection()
  File "/usr/lib64/python2.5/site-packages/offlineimap/imapserver.py", line 304, in acquireconnection
    elif isinstance(e, SSLError) and e.errno == 1:
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

I'm afraid I don't have time to look more deeply, for now.

> 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
-- 
Nicolas Sebrecht




More information about the OfflineIMAP-project mailing list