df32c4
--- a/setuptools/ssl_support.py.orig	2013-09-18 08:16:26.613869055 +0200
df32c4
+++ b/setuptools/ssl_support.py	2013-09-18 08:17:44.081722399 +0200
df32c4
@@ -82,71 +82,7 @@
df32c4
             raise error("getaddrinfo returns an empty list")
df32c4
 
df32c4
 
df32c4
-try:
df32c4
-    from ssl import CertificateError, match_hostname
df32c4
-except ImportError:
df32c4
-    class CertificateError(ValueError):
df32c4
-        pass
df32c4
-
df32c4
-    def _dnsname_to_pat(dn, max_wildcards=1):
df32c4
-        pats = []
df32c4
-        for frag in dn.split(r'.'):
df32c4
-            if frag.count('*') > max_wildcards:
df32c4
-                # Issue #17980: avoid denials of service by refusing more
df32c4
-                # than one wildcard per fragment.  A survery of established
df32c4
-                # policy among SSL implementations showed it to be a
df32c4
-                # reasonable choice.
df32c4
-                raise CertificateError(
df32c4
-                    "too many wildcards in certificate DNS name: " + repr(dn))
df32c4
-            if frag == '*':
df32c4
-                # When '*' is a fragment by itself, it matches a non-empty dotless
df32c4
-                # fragment.
df32c4
-                pats.append('[^.]+')
df32c4
-            else:
df32c4
-                # Otherwise, '*' matches any dotless fragment.
df32c4
-                frag = re.escape(frag)
df32c4
-                pats.append(frag.replace(r'\*', '[^.]*'))
df32c4
-        return re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
df32c4
-
df32c4
-    def match_hostname(cert, hostname):
df32c4
-        """Verify that *cert* (in decoded format as returned by
df32c4
-        SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 rules
df32c4
-        are mostly followed, but IP addresses are not accepted for *hostname*.
df32c4
-
df32c4
-        CertificateError is raised on failure. On success, the function
df32c4
-        returns nothing.
df32c4
-        """
df32c4
-        if not cert:
df32c4
-            raise ValueError("empty or no certificate")
df32c4
-        dnsnames = []
df32c4
-        san = cert.get('subjectAltName', ())
df32c4
-        for key, value in san:
df32c4
-            if key == 'DNS':
df32c4
-                if _dnsname_to_pat(value).match(hostname):
df32c4
-                    return
df32c4
-                dnsnames.append(value)
df32c4
-        if not dnsnames:
df32c4
-            # The subject is only checked when there is no dNSName entry
df32c4
-            # in subjectAltName
df32c4
-            for sub in cert.get('subject', ()):
df32c4
-                for key, value in sub:
df32c4
-                    # XXX according to RFC 2818, the most specific Common Name
df32c4
-                    # must be used.
df32c4
-                    if key == 'commonName':
df32c4
-                        if _dnsname_to_pat(value).match(hostname):
df32c4
-                            return
df32c4
-                        dnsnames.append(value)
df32c4
-        if len(dnsnames) > 1:
df32c4
-            raise CertificateError("hostname %r "
df32c4
-                "doesn't match either of %s"
df32c4
-                % (hostname, ', '.join(map(repr, dnsnames))))
df32c4
-        elif len(dnsnames) == 1:
df32c4
-            raise CertificateError("hostname %r "
df32c4
-                "doesn't match %r"
df32c4
-                % (hostname, dnsnames[0]))
df32c4
-        else:
df32c4
-            raise CertificateError("no appropriate commonName or "
df32c4
-                "subjectAltName fields were found")
df32c4
+from backports.ssl_match_hostname import CertificateError, match_hostname
df32c4
 
df32c4
 
df32c4