mercurial/sslutil.py
changeset 25415 21b536f01eda
parent 24614 241d98d84aed
child 25429 9d1c61715939
equal deleted inserted replaced
25414:f7ccbc2776b7 25415:21b536f01eda
    19     try:
    19     try:
    20         ssl_context = ssl.SSLContext
    20         ssl_context = ssl.SSLContext
    21         _canloaddefaultcerts = util.safehasattr(ssl_context,
    21         _canloaddefaultcerts = util.safehasattr(ssl_context,
    22                                                 'load_default_certs')
    22                                                 'load_default_certs')
    23 
    23 
    24         def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=ssl.CERT_NONE,
    24         def ssl_wrap_socket(sock, keyfile, certfile, ui,
       
    25                             cert_reqs=ssl.CERT_NONE,
    25                             ca_certs=None, serverhostname=None):
    26                             ca_certs=None, serverhostname=None):
    26             # Allow any version of SSL starting with TLSv1 and
    27             # Allow any version of SSL starting with TLSv1 and
    27             # up. Note that specifying TLSv1 here prohibits use of
    28             # up. Note that specifying TLSv1 here prohibits use of
    28             # newer standards (like TLSv1_2), so this is the right way
    29             # newer standards (like TLSv1_2), so this is the right way
    29             # to do this. Note that in the future it'd be better to
    30             # to do this. Note that in the future it'd be better to
    33             # maintainers for us, but that breaks too many things to
    34             # maintainers for us, but that breaks too many things to
    34             # do it in a hurry.
    35             # do it in a hurry.
    35             sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    36             sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    36             sslcontext.options &= ssl.OP_NO_SSLv2 & ssl.OP_NO_SSLv3
    37             sslcontext.options &= ssl.OP_NO_SSLv2 & ssl.OP_NO_SSLv3
    37             if certfile is not None:
    38             if certfile is not None:
    38                 sslcontext.load_cert_chain(certfile, keyfile)
    39                 def password():
       
    40                     f = keyfile or certfile
       
    41                     return ui.getpass(_('passphrase for %s: ') % f, '')
       
    42                 sslcontext.load_cert_chain(certfile, keyfile, password)
    39             sslcontext.verify_mode = cert_reqs
    43             sslcontext.verify_mode = cert_reqs
    40             if ca_certs is not None:
    44             if ca_certs is not None:
    41                 sslcontext.load_verify_locations(cafile=ca_certs)
    45                 sslcontext.load_verify_locations(cafile=ca_certs)
    42             elif _canloaddefaultcerts:
    46             elif _canloaddefaultcerts:
    43                 sslcontext.load_default_certs()
    47                 sslcontext.load_default_certs()
    49             # - see http://bugs.python.org/issue13721
    53             # - see http://bugs.python.org/issue13721
    50             if not sslsocket.cipher():
    54             if not sslsocket.cipher():
    51                 raise util.Abort(_('ssl connection failed'))
    55                 raise util.Abort(_('ssl connection failed'))
    52             return sslsocket
    56             return sslsocket
    53     except AttributeError:
    57     except AttributeError:
    54         def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=ssl.CERT_NONE,
    58         def ssl_wrap_socket(sock, keyfile, certfile, ui,
       
    59                             cert_reqs=ssl.CERT_NONE,
    55                             ca_certs=None, serverhostname=None):
    60                             ca_certs=None, serverhostname=None):
    56             sslsocket = ssl.wrap_socket(sock, keyfile, certfile,
    61             sslsocket = ssl.wrap_socket(sock, keyfile, certfile,
    57                                         cert_reqs=cert_reqs, ca_certs=ca_certs,
    62                                         cert_reqs=cert_reqs, ca_certs=ca_certs,
    58                                         ssl_version=ssl.PROTOCOL_TLSv1)
    63                                         ssl_version=ssl.PROTOCOL_TLSv1)
    59             # check if wrap_socket failed silently because socket had been
    64             # check if wrap_socket failed silently because socket had been
    65 except ImportError:
    70 except ImportError:
    66     CERT_REQUIRED = 2
    71     CERT_REQUIRED = 2
    67 
    72 
    68     import socket, httplib
    73     import socket, httplib
    69 
    74 
    70     def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=CERT_REQUIRED,
    75     def ssl_wrap_socket(sock, keyfile, certfile, ui,
       
    76                         cert_reqs=CERT_REQUIRED,
    71                         ca_certs=None, serverhostname=None):
    77                         ca_certs=None, serverhostname=None):
    72         if not util.safehasattr(socket, 'ssl'):
    78         if not util.safehasattr(socket, 'ssl'):
    73             raise util.Abort(_('Python SSL support not found'))
    79             raise util.Abort(_('Python SSL support not found'))
    74         if ca_certs:
    80         if ca_certs:
    75             raise util.Abort(_(
    81             raise util.Abort(_(
   144     if _canloaddefaultcerts:
   150     if _canloaddefaultcerts:
   145         return None
   151         return None
   146     return '!'
   152     return '!'
   147 
   153 
   148 def sslkwargs(ui, host):
   154 def sslkwargs(ui, host):
   149     kws = {}
   155     kws = {'ui': ui}
   150     hostfingerprint = ui.config('hostfingerprints', host)
   156     hostfingerprint = ui.config('hostfingerprints', host)
   151     if hostfingerprint:
   157     if hostfingerprint:
   152         return kws
   158         return kws
   153     cacerts = ui.config('web', 'cacerts')
   159     cacerts = ui.config('web', 'cacerts')
   154     if cacerts == '!':
   160     if cacerts == '!':