Catch SSL errors
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 3 Aug 2015 19:00:57 +0000 (20:00 +0100)
committerStefan Schantl <stefan.schantl@ipfire.org>
Sat, 8 Aug 2015 16:22:04 +0000 (18:22 +0200)
Properly catch SSL errors. When a connection could not be
established, the ddns client will try again. If an invalid
certificate is presented future updates are held back for
the usual time.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
src/ddns/errors.py
src/ddns/system.py

index 26bc18e..58a5ba9 100644 (file)
@@ -64,6 +64,13 @@ class DDNSBlockedError(DDNSError):
        reason = N_("The server denies any updates from this client")
 
 
+class DDNSCertificateError(DDNSError):
+       """
+               Thrown when a server presented an invalid certificate.
+       """
+       reason = N_("Invalid certificate")
+
+
 class DDNSConfigurationError(DDNSError):
        """
                Thrown when invalid or insufficient
@@ -139,6 +146,14 @@ class DDNSResolveError(DDNSNetworkError):
        reason = N_("Could not resolve DNS entry")
 
 
+class DDNSSSLError(DDNSNetworkError):
+       """
+               Raised when a SSL connection could not be
+               negotiated.
+       """
+       reason = N_("SSL negotiation error")
+
+
 class DDNSServiceUnavailableError(DDNSNetworkError):
        """
                Equivalent to HTTP error code 503.
index 6a21af8..0d90ce6 100644 (file)
@@ -21,6 +21,7 @@
 
 import base64
 import re
+import ssl
 import socket
 import urllib
 import urllib2
@@ -199,6 +200,16 @@ class DDNSSystem(object):
 
                except urllib2.URLError, e:
                        if e.reason:
+                               # Handle SSL errors
+                               if isinstance(e.reason, ssl.SSLError):
+                                       e = e.reason
+
+                                       if e.reason == "CERTIFICATE_VERIFY_FAILED":
+                                               raise DDNSCertificateError
+
+                                       # Raise all other SSL errors
+                                       raise DDNSSSLError(e.reason)
+
                                # Name or service not known
                                if e.reason.errno == -2:
                                        raise DDNSResolveError