Show More
@@ -33,9 +33,8 from .utils import ( | |||||
33 | # support for TLS 1.1, TLS 1.2, SNI, system CA stores, etc. These features are |
|
33 | # support for TLS 1.1, TLS 1.2, SNI, system CA stores, etc. These features are | |
34 | # all exposed via the "ssl" module. |
|
34 | # all exposed via the "ssl" module. | |
35 | # |
|
35 | # | |
36 | # Depending on the version of Python being used, SSL/TLS support is either |
|
36 | # We require in setup.py the presence of ssl.SSLContext, which indicates modern | |
37 | # modern/secure or legacy/insecure. Many operations in this module have |
|
37 | # SSL/TLS support. | |
38 | # separate code paths depending on support in Python. |
|
|||
39 |
|
38 | |||
40 | configprotocols = { |
|
39 | configprotocols = { | |
41 | b'tls1.0', |
|
40 | b'tls1.0', | |
@@ -53,67 +52,8 if util.safehasattr(ssl, b'PROTOCOL_TLSv | |||||
53 | if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'): |
|
52 | if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'): | |
54 | supportedprotocols.add(b'tls1.2') |
|
53 | supportedprotocols.add(b'tls1.2') | |
55 |
|
54 | |||
56 | try: |
|
|||
57 | # ssl.SSLContext was added in 2.7.9 and presence indicates modern |
|
|||
58 | # SSL/TLS features are available. |
|
|||
59 | SSLContext = ssl.SSLContext |
|
|||
60 |
|
|
55 | modernssl = True | |
61 |
|
|
56 | _canloaddefaultcerts = True | |
62 | except AttributeError: |
|
|||
63 | modernssl = False |
|
|||
64 | _canloaddefaultcerts = False |
|
|||
65 |
|
||||
66 | # We implement SSLContext using the interface from the standard library. |
|
|||
67 | class SSLContext(object): |
|
|||
68 | def __init__(self, protocol): |
|
|||
69 | # From the public interface of SSLContext |
|
|||
70 | self.protocol = protocol |
|
|||
71 | self.check_hostname = False |
|
|||
72 | self.options = 0 |
|
|||
73 | self.verify_mode = ssl.CERT_NONE |
|
|||
74 |
|
||||
75 | # Used by our implementation. |
|
|||
76 | self._certfile = None |
|
|||
77 | self._keyfile = None |
|
|||
78 | self._certpassword = None |
|
|||
79 | self._cacerts = None |
|
|||
80 | self._ciphers = None |
|
|||
81 |
|
||||
82 | def load_cert_chain(self, certfile, keyfile=None, password=None): |
|
|||
83 | self._certfile = certfile |
|
|||
84 | self._keyfile = keyfile |
|
|||
85 | self._certpassword = password |
|
|||
86 |
|
||||
87 | def load_default_certs(self, purpose=None): |
|
|||
88 | pass |
|
|||
89 |
|
||||
90 | def load_verify_locations(self, cafile=None, capath=None, cadata=None): |
|
|||
91 | if capath: |
|
|||
92 | raise error.Abort(_(b'capath not supported')) |
|
|||
93 | if cadata: |
|
|||
94 | raise error.Abort(_(b'cadata not supported')) |
|
|||
95 |
|
||||
96 | self._cacerts = cafile |
|
|||
97 |
|
||||
98 | def set_ciphers(self, ciphers): |
|
|||
99 | self._ciphers = ciphers |
|
|||
100 |
|
||||
101 | def wrap_socket(self, socket, server_hostname=None, server_side=False): |
|
|||
102 | # server_hostname is unique to SSLContext.wrap_socket and is used |
|
|||
103 | # for SNI in that context. So there's nothing for us to do with it |
|
|||
104 | # in this legacy code since we don't support SNI. |
|
|||
105 |
|
||||
106 | args = { |
|
|||
107 | 'keyfile': self._keyfile, |
|
|||
108 | 'certfile': self._certfile, |
|
|||
109 | 'server_side': server_side, |
|
|||
110 | 'cert_reqs': self.verify_mode, |
|
|||
111 | 'ssl_version': self.protocol, |
|
|||
112 | 'ca_certs': self._cacerts, |
|
|||
113 | 'ciphers': self._ciphers, |
|
|||
114 | } |
|
|||
115 |
|
||||
116 | return ssl.wrap_socket(socket, **args) |
|
|||
117 |
|
57 | |||
118 |
|
58 | |||
119 | def _hostsettings(ui, hostname): |
|
59 | def _hostsettings(ui, hostname): | |
@@ -414,7 +354,7 def wrapsocket(sock, keyfile, certfile, | |||||
414 | # bundle with a specific CA cert removed. If the system/default CA bundle |
|
354 | # bundle with a specific CA cert removed. If the system/default CA bundle | |
415 | # is loaded and contains that removed CA, you've just undone the user's |
|
355 | # is loaded and contains that removed CA, you've just undone the user's | |
416 | # choice. |
|
356 | # choice. | |
417 | sslcontext = SSLContext(settings[b'protocol']) |
|
357 | sslcontext = ssl.SSLContext(settings[b'protocol']) | |
418 |
|
358 | |||
419 | # This is a no-op unless using modern ssl. |
|
359 | # This is a no-op unless using modern ssl. | |
420 | sslcontext.options |= settings[b'ctxoptions'] |
|
360 | sslcontext.options |= settings[b'ctxoptions'] | |
@@ -642,7 +582,7 def wrapserversocket( | |||||
642 | # We /could/ use create_default_context() here since it doesn't load |
|
582 | # We /could/ use create_default_context() here since it doesn't load | |
643 | # CAs when configured for client auth. However, it is hard-coded to |
|
583 | # CAs when configured for client auth. However, it is hard-coded to | |
644 | # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. |
|
584 | # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. | |
645 | sslcontext = SSLContext(protocol) |
|
585 | sslcontext = ssl.SSLContext(protocol) | |
646 | sslcontext.options |= options |
|
586 | sslcontext.options |= options | |
647 |
|
587 | |||
648 | # Improve forward secrecy. |
|
588 | # Improve forward secrecy. | |
@@ -654,7 +594,7 def wrapserversocket( | |||||
654 | sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) |
|
594 | sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) | |
655 | sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) |
|
595 | sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) | |
656 | else: |
|
596 | else: | |
657 | sslcontext = SSLContext(ssl.PROTOCOL_TLSv1) |
|
597 | sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1) | |
658 |
|
598 | |||
659 | if requireclientcert: |
|
599 | if requireclientcert: | |
660 | sslcontext.verify_mode = ssl.CERT_REQUIRED |
|
600 | sslcontext.verify_mode = ssl.CERT_REQUIRED |
General Comments 0
You need to be logged in to leave comments.
Login now