Fallback to old ssl_wrap_socket
This commit is contained in:
parent
b4b76bab14
commit
13ac993d25
3 changed files with 81 additions and 18 deletions
|
@ -145,14 +145,26 @@ try:
|
|||
except ImportError:
|
||||
HAS_SSLCONTEXT = False
|
||||
|
||||
# SNI Handling for python < 2.7.9 with urllib3 support
|
||||
try:
|
||||
# urllib3>=1.15
|
||||
HAS_URLLIB3_SSL_WRAP_SOCKET = False
|
||||
try:
|
||||
from urllib3.contrib.pyopenssl import PyOpenSSLContext
|
||||
except ImportError:
|
||||
from requests.packages.urllib3.contrib.pyopenssl import PyOpenSSLContext
|
||||
HAS_PYOPENSSL_CONTEXT = True
|
||||
HAS_URLLIB3_PYOPENSSLCONTEXT = True
|
||||
except ImportError:
|
||||
HAS_PYOPENSSL_CONTEXT = False
|
||||
# urllib3<1.15,>=1.6
|
||||
HAS_URLLIB3_PYOPENSSLCONTEXT = False
|
||||
try:
|
||||
try:
|
||||
from urllib3.contrib.pyopenssl import ssl_wrap_socket
|
||||
except ImportError:
|
||||
from requests.packages.urllib3.contrib.pyopenssl import ssl_wrap_socket
|
||||
HAS_URLLIB3_SSL_WRAP_SOCKET = True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Select a protocol that includes all secure tls protocols
|
||||
# Exclude insecure ssl protocols if possible
|
||||
|
@ -362,7 +374,7 @@ if hasattr(httplib, 'HTTPSConnection') and hasattr(urllib_request, 'HTTPSHandler
|
|||
self.context = None
|
||||
if HAS_SSLCONTEXT:
|
||||
self.context = create_default_context()
|
||||
elif HAS_PYOPENSSL_CONTEXT:
|
||||
elif HAS_URLLIB3_PYOPENSSLCONTEXT:
|
||||
self.context = PyOpenSSLContext(PROTOCOL)
|
||||
if self.context and self.cert_file:
|
||||
self.context.load_cert_chain(self.cert_file, self.key_file)
|
||||
|
@ -383,8 +395,11 @@ if hasattr(httplib, 'HTTPSConnection') and hasattr(urllib_request, 'HTTPSHandler
|
|||
self._tunnel()
|
||||
server_hostname = self._tunnel_host
|
||||
|
||||
if HAS_SSLCONTEXT or HAS_PYOPENSSL_CONTEXT:
|
||||
if HAS_SSLCONTEXT or HAS_URLLIB3_PYOPENSSLCONTEXT:
|
||||
self.sock = self.context.wrap_socket(sock, server_hostname=server_hostname)
|
||||
elif HAS_URLLIB3_SSL_WRAP_SOCKET:
|
||||
self.sock = ssl_wrap_socket(sock, keyfile=self.key_file, cert_reqs=ssl.CERT_NONE, certfile=self.cert_file, ssl_version=PROTOCOL,
|
||||
server_hostname=server_hostname)
|
||||
else:
|
||||
self.sock = ssl.wrap_socket(sock, keyfile=self.key_file, certfile=self.cert_file, ssl_version=PROTOCOL)
|
||||
|
||||
|
@ -541,7 +556,7 @@ def build_ssl_validation_error(hostname, port, paths, exc=None):
|
|||
if not HAS_SSLCONTEXT:
|
||||
msg.append('If the website serving the url uses SNI you need'
|
||||
' python >= 2.7.9 on your managed machine')
|
||||
if not HAS_PYOPENSSL_CONTEXT:
|
||||
if not HAS_URLLIB3_PYOPENSSLCONTEXT or not HAS_URLLIB3_SSL_WRAP_SOCKET:
|
||||
msg.append('or you can install the `urllib3`, `pyOpenSSL`,'
|
||||
' `ndg-httpsclient`, and `pyasn1` python modules')
|
||||
|
||||
|
@ -665,7 +680,7 @@ class SSLValidationHandler(urllib_request.BaseHandler):
|
|||
return True
|
||||
|
||||
def _make_context(self, to_add_ca_cert_path):
|
||||
if HAS_PYOPENSSL_CONTEXT:
|
||||
if HAS_URLLIB3_PYOPENSSLCONTEXT:
|
||||
context = PyOpenSSLContext(PROTOCOL)
|
||||
else:
|
||||
context = create_default_context()
|
||||
|
@ -677,7 +692,7 @@ class SSLValidationHandler(urllib_request.BaseHandler):
|
|||
tmp_ca_cert_path, to_add_ca_cert_path, paths_checked = self.get_ca_certs()
|
||||
https_proxy = os.environ.get('https_proxy')
|
||||
context = None
|
||||
if HAS_SSLCONTEXT or HAS_PYOPENSSL_CONTEXT:
|
||||
if HAS_SSLCONTEXT or HAS_URLLIB3_PYOPENSSLCONTEXT:
|
||||
context = self._make_context(to_add_ca_cert_path)
|
||||
|
||||
# Detect if 'no_proxy' environment variable is set and if our URL is included
|
||||
|
@ -708,6 +723,8 @@ class SSLValidationHandler(urllib_request.BaseHandler):
|
|||
self.validate_proxy_response(connect_result)
|
||||
if context:
|
||||
ssl_s = context.wrap_socket(s, server_hostname=self.hostname)
|
||||
elif HAS_URLLIB3_SSL_WRAP_SOCKET:
|
||||
ssl_s = ssl_wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=PROTOCOL, server_hostname=self.hostname)
|
||||
else:
|
||||
ssl_s = ssl.wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=PROTOCOL)
|
||||
match_hostname(ssl_s.getpeercert(), self.hostname)
|
||||
|
@ -717,6 +734,8 @@ class SSLValidationHandler(urllib_request.BaseHandler):
|
|||
s.connect((self.hostname, self.port))
|
||||
if context:
|
||||
ssl_s = context.wrap_socket(s, server_hostname=self.hostname)
|
||||
elif HAS_URLLIB3_SSL_WRAP_SOCKET:
|
||||
ssl_s = ssl_wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=PROTOCOL, server_hostname=self.hostname)
|
||||
else:
|
||||
ssl_s = ssl.wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=PROTOCOL)
|
||||
match_hostname(ssl_s.getpeercert(), self.hostname)
|
||||
|
|
|
@ -236,15 +236,13 @@
|
|||
- name: install OS packages that are needed for SNI on old python
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
with_items: "{{ uri_os_packages[ansible_os_family] | default([]) }}"
|
||||
with_items: "{{ uri_os_packages[ansible_os_family].step1 | default([]) }}"
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
|
||||
- name: install python modules for Older Python SNI verification
|
||||
pip:
|
||||
name: "{{ item }}"
|
||||
with_items:
|
||||
- urllib3
|
||||
- PyOpenSSL
|
||||
- ndg-httpsclient
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
|
||||
|
@ -262,7 +260,7 @@
|
|||
- 'sni_host in result.content'
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
|
||||
- name: Uninstall ndg-httpsclient and urllib3
|
||||
- name: Uninstall ndg-httpsclient
|
||||
pip:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
|
@ -274,7 +272,45 @@
|
|||
package:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
with_items: "{{ uri_os_packages[ansible_os_family] | default([]) }}"
|
||||
with_items: "{{ uri_os_packages[ansible_os_family].step1 | default([]) }}"
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
|
||||
- name: install OS packages that are needed for building cryptography
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
with_items: "{{ uri_os_packages[ansible_os_family].step2 | default([]) }}"
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
|
||||
- name: install urllib3 and pyopenssl via pip
|
||||
pip:
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
with_items:
|
||||
- urllib3
|
||||
- PyOpenSSL
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
|
||||
- name: Verify SNI verification succeeds on old python with pip urllib3 contrib
|
||||
uri:
|
||||
url: 'https://{{ sni_host }}'
|
||||
return_content: true
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
register: result
|
||||
|
||||
- name: Assert SNI verification succeeds on old python with pip urllib3 contrib
|
||||
assert:
|
||||
that:
|
||||
- result|success
|
||||
- 'sni_host in result.content'
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
|
||||
- name: Uninstall urllib3 and PyOpenSSL
|
||||
pip:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
with_items:
|
||||
- urllib3
|
||||
- PyOpenSSL
|
||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||
|
||||
- name: validate the status_codes are correct
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
uri_os_packages:
|
||||
RedHat:
|
||||
- python-pyasn1
|
||||
- libffi-devel
|
||||
- openssl-devel
|
||||
step1:
|
||||
- python-pyasn1
|
||||
- pyOpenSSL
|
||||
- python-urllib3
|
||||
step2:
|
||||
- libffi-devel
|
||||
- openssl-devel
|
||||
Debian:
|
||||
- python-pyasn1
|
||||
- libffi-dev
|
||||
- libssl-dev
|
||||
step1:
|
||||
- python-pyasn1
|
||||
- python-openssl
|
||||
- python-urllib3
|
||||
step2:
|
||||
- libffi-dev
|
||||
- libssl-dev
|
Loading…
Reference in a new issue