diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2018-12-13 05:44:21 -0500 |
---|---|---|
committer | Jason R. Coombs <jaraco@jaraco.com> | 2018-12-13 05:44:34 -0500 |
commit | 7fa18bf507f1e11bbbe04297dee4088e587e1ae9 (patch) | |
tree | e307f30b21a7deab600ffb913274867bb882d464 | |
parent | 1c1c9152abcb8b1b6a13f1cfb4744f8d73016876 (diff) | |
download | python-setuptools-git-feature/pyopenssl-fallback.tar.gz |
Initial attempt to fall back to PyOpenSSL when built-in SSL is inadequate. Ref #1320feature/pyopenssl-fallback
-rw-r--r-- | setuptools/ssl_support.py | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/setuptools/ssl_support.py b/setuptools/ssl_support.py index 6362f1f4..77e67d8f 100644 --- a/setuptools/ssl_support.py +++ b/setuptools/ssl_support.py @@ -3,6 +3,7 @@ import socket import atexit import re import functools +import sys from setuptools.extern.six.moves import urllib, http_client, map, filter @@ -48,6 +49,12 @@ except ImportError: CertificateError = None match_hostname = None +try: + import OpenSSL +except ImportError: + pass + + if not CertificateError: class CertificateError(ValueError): @@ -158,7 +165,7 @@ class VerifyingHTTPSHandler(HTTPSHandler): def https_open(self, req): return self.do_open( - lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), req + lambda host, **kw: pick_ssl()(host, self.ca_bundle, **kw), req ) @@ -202,6 +209,29 @@ class VerifyingHTTPSConn(HTTPSConnection): raise +class OpenSSLHTTPSConnection(HTTPSConnection): + def __init__(self, host, ca_bundle, **kw): + HTTPSConnection.__init__(self, host, **kw) + self.ca_bundle = ca_bundle + + def connect(self): + context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD) + context.use_certificate_file(self.ca_bundle) + + raw_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock = OpenSSL.SSL.Connection(context, raw_sock) + self.sock.connect((self.host, self.port)) + + +def pick_ssl(): + use_openssl = ( + sys.platform == "darwin" + and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f + and 'OpenSSL' in globals() + ) + return OpenSSLHTTPSConnection if use_openssl else VerifyingHTTPSConn + + def opener_for(ca_bundle=None): """Get a urlopen() replacement that uses ca_bundle for verification""" return urllib.request.build_opener( |