mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-03 23:20:19 -07:00
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:
|
except ImportError:
|
||||||
HAS_SSLCONTEXT = False
|
HAS_SSLCONTEXT = False
|
||||||
|
|
||||||
|
# SNI Handling for python < 2.7.9 with urllib3 support
|
||||||
try:
|
try:
|
||||||
|
# urllib3>=1.15
|
||||||
|
HAS_URLLIB3_SSL_WRAP_SOCKET = False
|
||||||
try:
|
try:
|
||||||
from urllib3.contrib.pyopenssl import PyOpenSSLContext
|
from urllib3.contrib.pyopenssl import PyOpenSSLContext
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from requests.packages.urllib3.contrib.pyopenssl import PyOpenSSLContext
|
from requests.packages.urllib3.contrib.pyopenssl import PyOpenSSLContext
|
||||||
HAS_PYOPENSSL_CONTEXT = True
|
HAS_URLLIB3_PYOPENSSLCONTEXT = True
|
||||||
except ImportError:
|
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
|
# Select a protocol that includes all secure tls protocols
|
||||||
# Exclude insecure ssl protocols if possible
|
# Exclude insecure ssl protocols if possible
|
||||||
|
@ -362,7 +374,7 @@ if hasattr(httplib, 'HTTPSConnection') and hasattr(urllib_request, 'HTTPSHandler
|
||||||
self.context = None
|
self.context = None
|
||||||
if HAS_SSLCONTEXT:
|
if HAS_SSLCONTEXT:
|
||||||
self.context = create_default_context()
|
self.context = create_default_context()
|
||||||
elif HAS_PYOPENSSL_CONTEXT:
|
elif HAS_URLLIB3_PYOPENSSLCONTEXT:
|
||||||
self.context = PyOpenSSLContext(PROTOCOL)
|
self.context = PyOpenSSLContext(PROTOCOL)
|
||||||
if self.context and self.cert_file:
|
if self.context and self.cert_file:
|
||||||
self.context.load_cert_chain(self.cert_file, self.key_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()
|
self._tunnel()
|
||||||
server_hostname = self._tunnel_host
|
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)
|
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:
|
else:
|
||||||
self.sock = ssl.wrap_socket(sock, keyfile=self.key_file, certfile=self.cert_file, ssl_version=PROTOCOL)
|
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:
|
if not HAS_SSLCONTEXT:
|
||||||
msg.append('If the website serving the url uses SNI you need'
|
msg.append('If the website serving the url uses SNI you need'
|
||||||
' python >= 2.7.9 on your managed machine')
|
' 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`,'
|
msg.append('or you can install the `urllib3`, `pyOpenSSL`,'
|
||||||
' `ndg-httpsclient`, and `pyasn1` python modules')
|
' `ndg-httpsclient`, and `pyasn1` python modules')
|
||||||
|
|
||||||
|
@ -665,7 +680,7 @@ class SSLValidationHandler(urllib_request.BaseHandler):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _make_context(self, to_add_ca_cert_path):
|
def _make_context(self, to_add_ca_cert_path):
|
||||||
if HAS_PYOPENSSL_CONTEXT:
|
if HAS_URLLIB3_PYOPENSSLCONTEXT:
|
||||||
context = PyOpenSSLContext(PROTOCOL)
|
context = PyOpenSSLContext(PROTOCOL)
|
||||||
else:
|
else:
|
||||||
context = create_default_context()
|
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()
|
tmp_ca_cert_path, to_add_ca_cert_path, paths_checked = self.get_ca_certs()
|
||||||
https_proxy = os.environ.get('https_proxy')
|
https_proxy = os.environ.get('https_proxy')
|
||||||
context = None
|
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)
|
context = self._make_context(to_add_ca_cert_path)
|
||||||
|
|
||||||
# Detect if 'no_proxy' environment variable is set and if our URL is included
|
# 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)
|
self.validate_proxy_response(connect_result)
|
||||||
if context:
|
if context:
|
||||||
ssl_s = context.wrap_socket(s, server_hostname=self.hostname)
|
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:
|
else:
|
||||||
ssl_s = ssl.wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=PROTOCOL)
|
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)
|
match_hostname(ssl_s.getpeercert(), self.hostname)
|
||||||
|
@ -717,6 +734,8 @@ class SSLValidationHandler(urllib_request.BaseHandler):
|
||||||
s.connect((self.hostname, self.port))
|
s.connect((self.hostname, self.port))
|
||||||
if context:
|
if context:
|
||||||
ssl_s = context.wrap_socket(s, server_hostname=self.hostname)
|
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:
|
else:
|
||||||
ssl_s = ssl.wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=PROTOCOL)
|
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)
|
match_hostname(ssl_s.getpeercert(), self.hostname)
|
||||||
|
|
|
@ -236,15 +236,13 @@
|
||||||
- name: install OS packages that are needed for SNI on old python
|
- name: install OS packages that are needed for SNI on old python
|
||||||
package:
|
package:
|
||||||
name: "{{ item }}"
|
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
|
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||||
|
|
||||||
- name: install python modules for Older Python SNI verification
|
- name: install python modules for Older Python SNI verification
|
||||||
pip:
|
pip:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
with_items:
|
with_items:
|
||||||
- urllib3
|
|
||||||
- PyOpenSSL
|
|
||||||
- ndg-httpsclient
|
- ndg-httpsclient
|
||||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||||
|
|
||||||
|
@ -262,7 +260,7 @@
|
||||||
- 'sni_host in result.content'
|
- 'sni_host in result.content'
|
||||||
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||||
|
|
||||||
- name: Uninstall ndg-httpsclient and urllib3
|
- name: Uninstall ndg-httpsclient
|
||||||
pip:
|
pip:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
|
@ -274,7 +272,45 @@
|
||||||
package:
|
package:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: absent
|
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
|
when: not ansible_python.has_sslcontext and not is_ubuntu_precise|bool
|
||||||
|
|
||||||
- name: validate the status_codes are correct
|
- name: validate the status_codes are correct
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
uri_os_packages:
|
uri_os_packages:
|
||||||
RedHat:
|
RedHat:
|
||||||
- python-pyasn1
|
step1:
|
||||||
- libffi-devel
|
- python-pyasn1
|
||||||
- openssl-devel
|
- pyOpenSSL
|
||||||
|
- python-urllib3
|
||||||
|
step2:
|
||||||
|
- libffi-devel
|
||||||
|
- openssl-devel
|
||||||
Debian:
|
Debian:
|
||||||
- python-pyasn1
|
step1:
|
||||||
- libffi-dev
|
- python-pyasn1
|
||||||
- libssl-dev
|
- python-openssl
|
||||||
|
- python-urllib3
|
||||||
|
step2:
|
||||||
|
- libffi-dev
|
||||||
|
- libssl-dev
|
Loading…
Add table
Add a link
Reference in a new issue