224 assert s[b'verifymode'] is not None |
224 assert s[b'verifymode'] is not None |
225 |
225 |
226 return s |
226 return s |
227 |
227 |
228 |
228 |
229 def protocolsettings(minimumprotocol): |
229 def commonssloptions(minimumprotocol): |
230 """Resolve the protocol for a config value. |
230 """Return SSLContext options common to servers and clients. |
231 |
|
232 Returns a tuple of (protocol, options) which are values used by SSLContext. |
|
233 """ |
231 """ |
234 if minimumprotocol not in configprotocols: |
232 if minimumprotocol not in configprotocols: |
235 raise ValueError(b'protocol value not supported: %s' % minimumprotocol) |
233 raise ValueError(b'protocol value not supported: %s' % minimumprotocol) |
236 |
|
237 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol |
|
238 # that both ends support, including TLS protocols. |
|
239 # |
|
240 # The PROTOCOL_TLSv* constants select a specific TLS version |
|
241 # only (as opposed to multiple versions). So the method for |
|
242 # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and |
|
243 # disable protocols via SSLContext.options and OP_NO_* constants. |
|
244 |
234 |
245 # SSLv2 and SSLv3 are broken. We ban them outright. |
235 # SSLv2 and SSLv3 are broken. We ban them outright. |
246 options = ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 |
236 options = ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 |
247 |
237 |
248 if minimumprotocol == b'tls1.0': |
238 if minimumprotocol == b'tls1.0': |
257 |
247 |
258 # Prevent CRIME. |
248 # Prevent CRIME. |
259 # There is no guarantee this attribute is defined on the module. |
249 # There is no guarantee this attribute is defined on the module. |
260 options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) |
250 options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) |
261 |
251 |
262 return ssl.PROTOCOL_SSLv23, options |
252 return options |
263 |
253 |
264 |
254 |
265 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): |
255 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): |
266 """Add SSL/TLS to a socket. |
256 """Add SSL/TLS to a socket. |
267 |
257 |
312 # have explicit control over CA loading because implicitly loading |
302 # have explicit control over CA loading because implicitly loading |
313 # CAs may undermine the user's intent. For example, a user may define a CA |
303 # CAs may undermine the user's intent. For example, a user may define a CA |
314 # bundle with a specific CA cert removed. If the system/default CA bundle |
304 # bundle with a specific CA cert removed. If the system/default CA bundle |
315 # is loaded and contains that removed CA, you've just undone the user's |
305 # is loaded and contains that removed CA, you've just undone the user's |
316 # choice. |
306 # choice. |
317 protocol, options = protocolsettings(settings[b'minimumprotocol']) |
307 # |
318 sslcontext = ssl.SSLContext(protocol) |
308 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol that both |
319 sslcontext.options |= options |
309 # ends support, including TLS protocols. commonssloptions() restricts the |
|
310 # set of allowed protocols. |
|
311 sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) |
|
312 sslcontext.options |= commonssloptions(settings[b'minimumprotocol']) |
320 sslcontext.verify_mode = settings[b'verifymode'] |
313 sslcontext.verify_mode = settings[b'verifymode'] |
321 |
314 |
322 if settings[b'ciphers']: |
315 if settings[b'ciphers']: |
323 try: |
316 try: |
324 sslcontext.set_ciphers(pycompat.sysstr(settings[b'ciphers'])) |
317 sslcontext.set_ciphers(pycompat.sysstr(settings[b'ciphers'])) |
510 if f and not os.path.exists(f): |
503 if f and not os.path.exists(f): |
511 raise error.Abort( |
504 raise error.Abort( |
512 _(b'referenced certificate file (%s) does not exist') % f |
505 _(b'referenced certificate file (%s) does not exist') % f |
513 ) |
506 ) |
514 |
507 |
515 protocol, options = protocolsettings(b'tls1.0') |
508 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol that both |
|
509 # ends support, including TLS protocols. commonssloptions() restricts the |
|
510 # set of allowed protocols. |
|
511 protocol = ssl.PROTOCOL_SSLv23 |
|
512 options = commonssloptions(b'tls1.0') |
516 |
513 |
517 # This config option is intended for use in tests only. It is a giant |
514 # This config option is intended for use in tests only. It is a giant |
518 # footgun to kill security. Don't define it. |
515 # footgun to kill security. Don't define it. |
519 exactprotocol = ui.config(b'devel', b'serverexactprotocol') |
516 exactprotocol = ui.config(b'devel', b'serverexactprotocol') |
520 if exactprotocol == b'tls1.0': |
517 if exactprotocol == b'tls1.0': |