diff options
author | Toshio Kuratomi <toshio@fedoraproject.org> | 2015-07-15 13:17:00 -0700 |
---|---|---|
committer | Toshio Kuratomi <toshio@fedoraproject.org> | 2015-07-20 09:47:04 -0700 |
commit | 990350a0fd63f70e7f57474bf53752c38b41ef00 (patch) | |
tree | 539ed0c271066858c447cf26aba686df58985650 | |
parent | a4691991ad83bccf6fb42bdb06a5da820e8a766e (diff) | |
download | ansible-990350a0fd63f70e7f57474bf53752c38b41ef00.tar.gz |
Have openssl autonegotiate tls protocol on python < 2.7.9
This allows usage of tls-1.1 and tls-1.2 if the underlying openssl
library supports it. Unfortunately it also allows sslv2 and sslv3 if
the server is only configured to support those. In this day and age,
that's probably something that the server administrator should fix
anyhow.
-rw-r--r-- | lib/ansible/module_utils/urls.py | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/lib/ansible/module_utils/urls.py b/lib/ansible/module_utils/urls.py index cb2bb20675..a7d58fdf38 100644 --- a/lib/ansible/module_utils/urls.py +++ b/lib/ansible/module_utils/urls.py @@ -106,6 +106,33 @@ try: except ImportError: HAS_SSLCONTEXT = False +# Select a protocol that includes all secure tls protocols +# Exclude insecure ssl protocols if possible + +# If we can't find extra tls methods, ssl.PROTOCOL_TLSv1 is sufficient +PROTOCOL = ssl.PROTOCOL_TLSv1 +if not HAS_SSLCONTEXT and HAS_SSL: + try: + import ctypes, ctypes.util + except ImportError: + # python 2.4 (likely rhel5 which doesn't have tls1.1 support in its openssl) + pass + else: + libssl_name = ctypes.util.find_library('ssl') + libssl = ctypes.CDLL(libssl_name) + for method in ('TLSv1_1_method', 'TLSv1_2_method'): + try: + libssl[method] + # Found something - we'll let openssl autonegotiate and hope + # the server has disabled sslv2 and 3. best we can do. + PROTOCOL = ssl.PROTOCOL_SSLv23 + break + except AttributeError: + pass + del libssl + + + HAS_MATCH_HOSTNAME = True try: from ssl import match_hostname, CertificateError @@ -303,7 +330,7 @@ class CustomHTTPSConnection(httplib.HTTPSConnection): if HAS_SSLCONTEXT: self.sock = self.context.wrap_socket(sock, server_hostname=self.host) else: - self.sock = ssl.wrap_socket(sock, keyfile=self.key_file, certfile=self.cert_file, ssl_version=ssl.PROTOCOL_TLSv1) + self.sock = ssl.wrap_socket(sock, keyfile=self.key_file, certfile=self.cert_file, ssl_version=PROTOCOL) class CustomHTTPSHandler(urllib2.HTTPSHandler): @@ -513,7 +540,7 @@ class SSLValidationHandler(urllib2.BaseHandler): if context: ssl_s = context.wrap_socket(s, server_hostname=proxy_parts.get('hostname')) else: - ssl_s = ssl.wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLSv1) + 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) else: raise ProxyError('Unsupported proxy scheme: %s. Currently ansible only supports HTTP proxies.' % proxy_parts.get('scheme')) @@ -522,7 +549,7 @@ class SSLValidationHandler(urllib2.BaseHandler): if context: ssl_s = context.wrap_socket(s, server_hostname=self.hostname) else: - ssl_s = ssl.wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLSv1) + 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) # close the ssl connection #ssl_s.unwrap() |