Commits

Marc Abramowitz  committed 92513ef

Make sure that match_hostname and CertificateError are available in Python 3.1

  • Participants
  • Parent commits 0033e59
  • Branches py31_1

Comments (0)

Files changed (1)

File distlib/compat.py

 import re
 import sys
 
+try:
+    from ssl import match_hostname
+except ImportError:
+    def match_hostname(cert, hostname):
+        """Verify that *cert* (in decoded format as returned by
+        SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 rules
+        are mostly followed, but IP addresses are not accepted for *hostname*.
+
+        CertificateError is raised on failure. On success, the function
+        returns nothing.
+        """
+        if not cert:
+            raise ValueError("empty or no certificate")
+        dnsnames = []
+        san = cert.get('subjectAltName', ())
+        for key, value in san:
+            if key == 'DNS':
+                if _dnsname_to_pat(value).match(hostname):
+                    return
+                dnsnames.append(value)
+        if not dnsnames:
+            # The subject is only checked when there is no dNSName entry
+            # in subjectAltName
+            for sub in cert.get('subject', ()):
+                for key, value in sub:
+                    # XXX according to RFC 2818, the most specific Common Name
+                    # must be used.
+                    if key == 'commonName':
+                        if _dnsname_to_pat(value).match(hostname):
+                            return
+                        dnsnames.append(value)
+        if len(dnsnames) > 1:
+            raise CertificateError("hostname %r "
+                "doesn't match either of %s"
+                % (hostname, ', '.join(map(repr, dnsnames))))
+        elif len(dnsnames) == 1:
+            raise CertificateError("hostname %r "
+                "doesn't match %r"
+                % (hostname, dnsnames[0]))
+        else:
+            raise CertificateError("no appropriate commonName or "
+                "subjectAltName fields were found")
+
+
+try:
+    from ssl import CertificateError
+except ImportError:
+    class CertificateError(ValueError):
+        pass
+
+
 if sys.version_info[0] < 3:
     from StringIO import StringIO
     string_types = basestring,
         if match: return match.group(1, 2)
         return None, host
 
-    class CertificateError(ValueError):
-        pass
-
 
     def _dnsname_to_pat(dn):
         pats = []
                 pats.append(frag.replace(r'\*', '[^.]*'))
         return re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
 
-
-    def match_hostname(cert, hostname):
-        """Verify that *cert* (in decoded format as returned by
-        SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 rules
-        are mostly followed, but IP addresses are not accepted for *hostname*.
-
-        CertificateError is raised on failure. On success, the function
-        returns nothing.
-        """
-        if not cert:
-            raise ValueError("empty or no certificate")
-        dnsnames = []
-        san = cert.get('subjectAltName', ())
-        for key, value in san:
-            if key == 'DNS':
-                if _dnsname_to_pat(value).match(hostname):
-                    return
-                dnsnames.append(value)
-        if not dnsnames:
-            # The subject is only checked when there is no dNSName entry
-            # in subjectAltName
-            for sub in cert.get('subject', ()):
-                for key, value in sub:
-                    # XXX according to RFC 2818, the most specific Common Name
-                    # must be used.
-                    if key == 'commonName':
-                        if _dnsname_to_pat(value).match(hostname):
-                            return
-                        dnsnames.append(value)
-        if len(dnsnames) > 1:
-            raise CertificateError("hostname %r "
-                "doesn't match either of %s"
-                % (hostname, ', '.join(map(repr, dnsnames))))
-        elif len(dnsnames) == 1:
-            raise CertificateError("hostname %r "
-                "doesn't match %r"
-                % (hostname, dnsnames[0]))
-        else:
-            raise CertificateError("no appropriate commonName or "
-                "subjectAltName fields were found")
-
 else:
     from io import StringIO
     string_types = str,
     from itertools import filterfalse
     filter = filter
 
-    from ssl import match_hostname, CertificateError
-
 
 try:
     from types import SimpleNamespace as Container