mercurial/sslutil.py
changeset 29554 4a7b0c696fbc
parent 29537 5f8b36d5a6ec
child 29557 53de8255ec4e
equal deleted inserted replaced
29553:cd3e58862cab 29554:4a7b0c696fbc
   323         'ui': ui,
   323         'ui': ui,
   324     }
   324     }
   325 
   325 
   326     return sslsocket
   326     return sslsocket
   327 
   327 
       
   328 def wrapserversocket(sock, ui, certfile=None, keyfile=None, cafile=None,
       
   329                      requireclientcert=False):
       
   330     """Wrap a socket for use by servers.
       
   331 
       
   332     ``certfile`` and ``keyfile`` specify the files containing the certificate's
       
   333     public and private keys, respectively. Both keys can be defined in the same
       
   334     file via ``certfile`` (the private key must come first in the file).
       
   335 
       
   336     ``cafile`` defines the path to certificate authorities.
       
   337 
       
   338     ``requireclientcert`` specifies whether to require client certificates.
       
   339 
       
   340     Typically ``cafile`` is only defined if ``requireclientcert`` is true.
       
   341     """
       
   342     if modernssl:
       
   343         # We /could/ use create_default_context() here since it doesn't load
       
   344         # CAs when configured for client auth.
       
   345         sslcontext = SSLContext(ssl.PROTOCOL_SSLv23)
       
   346         # SSLv2 and SSLv3 are broken. Ban them outright.
       
   347         sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3
       
   348         # Prevent CRIME
       
   349         sslcontext.options |= getattr(ssl, 'OP_NO_COMPRESSION', 0)
       
   350         # Improve forward secrecy.
       
   351         sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0)
       
   352         sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0)
       
   353 
       
   354         # Use the list of more secure ciphers if found in the ssl module.
       
   355         if util.safehasattr(ssl, '_RESTRICTED_SERVER_CIPHERS'):
       
   356             sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0)
       
   357             sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS)
       
   358     else:
       
   359         sslcontext = SSLContext(ssl.PROTOCOL_TLSv1)
       
   360 
       
   361     if requireclientcert:
       
   362         sslcontext.verify_mode = ssl.CERT_REQUIRED
       
   363     else:
       
   364         sslcontext.verify_mode = ssl.CERT_NONE
       
   365 
       
   366     if certfile or keyfile:
       
   367         sslcontext.load_cert_chain(certfile=certfile, keyfile=keyfile)
       
   368 
       
   369     if cafile:
       
   370         sslcontext.load_verify_locations(cafile=cafile)
       
   371 
       
   372     return sslcontext.wrap_socket(sock, server_side=True)
       
   373 
   328 class wildcarderror(Exception):
   374 class wildcarderror(Exception):
   329     """Represents an error parsing wildcards in DNS name."""
   375     """Represents an error parsing wildcards in DNS name."""
   330 
   376 
   331 def _dnsnamematch(dn, hostname, maxwildcards=1):
   377 def _dnsnamematch(dn, hostname, maxwildcards=1):
   332     """Match DNS names according RFC 6125 section 6.4.3.
   378     """Match DNS names according RFC 6125 section 6.4.3.