mercurial/sslutil.py
changeset 44878 035199ba04ee
parent 44876 dca2629f6d2e
child 44880 7dd63a8cb1ee
equal deleted inserted replaced
44877:86a7b7abf28e 44878:035199ba04ee
    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