Show More
@@ -107,23 +107,32 b' except AttributeError:' | |||
|
107 | 107 | return ssl.wrap_socket(socket, **args) |
|
108 | 108 | |
|
109 | 109 | try: |
|
110 | # ssl.SSLContext was added in 2.7.9 and presence indicates modern | |
|
111 | # SSL/TLS features are available. | |
|
112 | ssl_context = ssl.SSLContext | |
|
113 | ||
|
114 | 110 | def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
|
115 | 111 | ca_certs=None, serverhostname=None): |
|
116 | # Allow any version of SSL starting with TLSv1 and | |
|
117 | # up. Note that specifying TLSv1 here prohibits use of | |
|
118 | # newer standards (like TLSv1_2), so this is the right way | |
|
119 | # to do this. Note that in the future it'd be better to | |
|
120 | # support using ssl.create_default_context(), which sets | |
|
121 | # up a bunch of things in smart ways (strong ciphers, | |
|
122 | # protocol versions, etc) and is upgraded by Python | |
|
123 | # maintainers for us, but that breaks too many things to | |
|
124 | # do it in a hurry. | |
|
125 | sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) | |
|
112 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol | |
|
113 | # that both ends support, including TLS protocols. On legacy stacks, | |
|
114 | # the highest it likely goes in TLS 1.0. On modern stacks, it can | |
|
115 | # support TLS 1.2. | |
|
116 | # | |
|
117 | # The PROTOCOL_TLSv* constants select a specific TLS version | |
|
118 | # only (as opposed to multiple versions). So the method for | |
|
119 | # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and | |
|
120 | # disable protocols via SSLContext.options and OP_NO_* constants. | |
|
121 | # However, SSLContext.options doesn't work unless we have the | |
|
122 | # full/real SSLContext available to us. | |
|
123 | # | |
|
124 | # SSLv2 and SSLv3 are broken. We ban them outright. | |
|
125 | if modernssl: | |
|
126 | protocol = ssl.PROTOCOL_SSLv23 | |
|
127 | else: | |
|
128 | protocol = ssl.PROTOCOL_TLSv1 | |
|
129 | ||
|
130 | # TODO use ssl.create_default_context() on modernssl. | |
|
131 | sslcontext = SSLContext(protocol) | |
|
132 | ||
|
133 | # This is a no-op on old Python. | |
|
126 | 134 | sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 |
|
135 | ||
|
127 | 136 | if certfile is not None: |
|
128 | 137 | def password(): |
|
129 | 138 | f = keyfile or certfile |
@@ -132,7 +141,8 b' try:' | |||
|
132 | 141 | sslcontext.verify_mode = cert_reqs |
|
133 | 142 | if ca_certs is not None: |
|
134 | 143 | sslcontext.load_verify_locations(cafile=ca_certs) |
|
135 | elif _canloaddefaultcerts: | |
|
144 | else: | |
|
145 | # This is a no-op on old Python. | |
|
136 | 146 | sslcontext.load_default_certs() |
|
137 | 147 | |
|
138 | 148 | sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) |
@@ -143,19 +153,7 b' try:' | |||
|
143 | 153 | raise error.Abort(_('ssl connection failed')) |
|
144 | 154 | return sslsocket |
|
145 | 155 | except AttributeError: |
|
146 | # We don't have a modern version of the "ssl" module and are running | |
|
147 | # Python <2.7.9. | |
|
148 | def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, | |
|
149 | ca_certs=None, serverhostname=None): | |
|
150 | sslsocket = ssl.wrap_socket(sock, keyfile, certfile, | |
|
151 | cert_reqs=cert_reqs, ca_certs=ca_certs, | |
|
152 | ssl_version=ssl.PROTOCOL_TLSv1) | |
|
153 | # check if wrap_socket failed silently because socket had been | |
|
154 | # closed | |
|
155 | # - see http://bugs.python.org/issue13721 | |
|
156 | if not sslsocket.cipher(): | |
|
157 | raise error.Abort(_('ssl connection failed')) | |
|
158 | return sslsocket | |
|
156 | raise util.Abort('this should not happen') | |
|
159 | 157 | |
|
160 | 158 | def _verifycert(cert, hostname): |
|
161 | 159 | '''Verify that cert (in socket.getpeercert() format) matches hostname. |
General Comments 0
You need to be logged in to leave comments.
Login now