50 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_1'): |
50 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_1'): |
51 supportedprotocols.add(b'tls1.1') |
51 supportedprotocols.add(b'tls1.1') |
52 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'): |
52 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'): |
53 supportedprotocols.add(b'tls1.2') |
53 supportedprotocols.add(b'tls1.2') |
54 |
54 |
55 modernssl = True |
|
56 _canloaddefaultcerts = True |
55 _canloaddefaultcerts = True |
57 |
56 |
58 |
57 |
59 def _hostsettings(ui, hostname): |
58 def _hostsettings(ui, hostname): |
60 """Obtain security settings for a hostname. |
59 """Obtain security settings for a hostname. |
397 sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) |
396 sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) |
398 except ssl.SSLError as e: |
397 except ssl.SSLError as e: |
399 # If we're doing certificate verification and no CA certs are loaded, |
398 # If we're doing certificate verification and no CA certs are loaded, |
400 # that is almost certainly the reason why verification failed. Provide |
399 # that is almost certainly the reason why verification failed. Provide |
401 # a hint to the user. |
400 # a hint to the user. |
402 # Only modern ssl module exposes SSLContext.get_ca_certs() so we can |
|
403 # only show this warning if modern ssl is available. |
|
404 # The exception handler is here to handle bugs around cert attributes: |
401 # The exception handler is here to handle bugs around cert attributes: |
405 # https://bugs.python.org/issue20916#msg213479. (See issues5313.) |
402 # https://bugs.python.org/issue20916#msg213479. (See issues5313.) |
406 # When the main 20916 bug occurs, 'sslcontext.get_ca_certs()' is a |
403 # When the main 20916 bug occurs, 'sslcontext.get_ca_certs()' is a |
407 # non-empty list, but the following conditional is otherwise True. |
404 # non-empty list, but the following conditional is otherwise True. |
408 try: |
405 try: |
409 if ( |
406 if ( |
410 caloaded |
407 caloaded |
411 and settings[b'verifymode'] == ssl.CERT_REQUIRED |
408 and settings[b'verifymode'] == ssl.CERT_REQUIRED |
412 and modernssl |
|
413 and not sslcontext.get_ca_certs() |
409 and not sslcontext.get_ca_certs() |
414 ): |
410 ): |
415 ui.warn( |
411 ui.warn( |
416 _( |
412 _( |
417 b'(an attempt was made to load CA certificates but ' |
413 b'(an attempt was made to load CA certificates but ' |
567 elif exactprotocol: |
563 elif exactprotocol: |
568 raise error.Abort( |
564 raise error.Abort( |
569 _(b'invalid value for serverexactprotocol: %s') % exactprotocol |
565 _(b'invalid value for serverexactprotocol: %s') % exactprotocol |
570 ) |
566 ) |
571 |
567 |
572 if modernssl: |
568 # We /could/ use create_default_context() here since it doesn't load |
573 # We /could/ use create_default_context() here since it doesn't load |
569 # CAs when configured for client auth. However, it is hard-coded to |
574 # CAs when configured for client auth. However, it is hard-coded to |
570 # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. |
575 # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. |
571 sslcontext = ssl.SSLContext(protocol) |
576 sslcontext = ssl.SSLContext(protocol) |
572 sslcontext.options |= options |
577 sslcontext.options |= options |
573 |
578 |
574 # Improve forward secrecy. |
579 # Improve forward secrecy. |
575 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) |
580 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) |
576 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0) |
581 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0) |
577 |
582 |
578 # Use the list of more secure ciphers if found in the ssl module. |
583 # Use the list of more secure ciphers if found in the ssl module. |
579 if util.safehasattr(ssl, b'_RESTRICTED_SERVER_CIPHERS'): |
584 if util.safehasattr(ssl, b'_RESTRICTED_SERVER_CIPHERS'): |
580 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) |
585 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) |
581 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) |
586 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) |
|
587 else: |
|
588 sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1) |
|
589 |
582 |
590 if requireclientcert: |
583 if requireclientcert: |
591 sslcontext.verify_mode = ssl.CERT_REQUIRED |
584 sslcontext.verify_mode = ssl.CERT_REQUIRED |
592 else: |
585 else: |
593 sslcontext.verify_mode = ssl.CERT_NONE |
586 sslcontext.verify_mode = ssl.CERT_NONE |