17 from . import ( |
17 from . import ( |
18 error, |
18 error, |
19 util, |
19 util, |
20 ) |
20 ) |
21 |
21 |
|
22 # Python 2.7.9+ overhauled the built-in SSL/TLS features of Python. It added |
|
23 # support for TLS 1.1, TLS 1.2, SNI, system CA stores, etc. These features are |
|
24 # all exposed via the "ssl" module. |
|
25 # |
|
26 # Depending on the version of Python being used, SSL/TLS support is either |
|
27 # modern/secure or legacy/insecure. Many operations in this module have |
|
28 # separate code paths depending on support in Python. |
|
29 |
22 hassni = getattr(ssl, 'HAS_SNI', False) |
30 hassni = getattr(ssl, 'HAS_SNI', False) |
23 |
31 |
24 _canloaddefaultcerts = False |
32 _canloaddefaultcerts = False |
25 try: |
33 try: |
|
34 # ssl.SSLContext was added in 2.7.9 and presence indicates modern |
|
35 # SSL/TLS features are available. |
26 ssl_context = ssl.SSLContext |
36 ssl_context = ssl.SSLContext |
27 _canloaddefaultcerts = util.safehasattr(ssl_context, 'load_default_certs') |
37 _canloaddefaultcerts = util.safehasattr(ssl_context, 'load_default_certs') |
28 |
38 |
29 def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
39 def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
30 ca_certs=None, serverhostname=None): |
40 ca_certs=None, serverhostname=None): |
56 # - see http://bugs.python.org/issue13721 |
66 # - see http://bugs.python.org/issue13721 |
57 if not sslsocket.cipher(): |
67 if not sslsocket.cipher(): |
58 raise error.Abort(_('ssl connection failed')) |
68 raise error.Abort(_('ssl connection failed')) |
59 return sslsocket |
69 return sslsocket |
60 except AttributeError: |
70 except AttributeError: |
|
71 # We don't have a modern version of the "ssl" module and are running |
|
72 # Python <2.7.9. |
61 def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
73 def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
62 ca_certs=None, serverhostname=None): |
74 ca_certs=None, serverhostname=None): |
63 sslsocket = ssl.wrap_socket(sock, keyfile, certfile, |
75 sslsocket = ssl.wrap_socket(sock, keyfile, certfile, |
64 cert_reqs=cert_reqs, ca_certs=ca_certs, |
76 cert_reqs=cert_reqs, ca_certs=ca_certs, |
65 ssl_version=ssl.PROTOCOL_TLSv1) |
77 ssl_version=ssl.PROTOCOL_TLSv1) |