diff -r 4827d07073e6 -r c617614aefd2 mercurial/sslutil.py --- a/mercurial/sslutil.py Sun Mar 27 14:18:32 2016 -0700 +++ b/mercurial/sslutil.py Sun Mar 27 11:39:39 2016 -0700 @@ -106,54 +106,51 @@ return ssl.wrap_socket(socket, **args) -try: - def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, - ca_certs=None, serverhostname=None): - # Despite its name, PROTOCOL_SSLv23 selects the highest protocol - # that both ends support, including TLS protocols. On legacy stacks, - # the highest it likely goes in TLS 1.0. On modern stacks, it can - # support TLS 1.2. - # - # The PROTOCOL_TLSv* constants select a specific TLS version - # only (as opposed to multiple versions). So the method for - # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and - # disable protocols via SSLContext.options and OP_NO_* constants. - # However, SSLContext.options doesn't work unless we have the - # full/real SSLContext available to us. - # - # SSLv2 and SSLv3 are broken. We ban them outright. - if modernssl: - protocol = ssl.PROTOCOL_SSLv23 - else: - protocol = ssl.PROTOCOL_TLSv1 +def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, + ca_certs=None, serverhostname=None): + # Despite its name, PROTOCOL_SSLv23 selects the highest protocol + # that both ends support, including TLS protocols. On legacy stacks, + # the highest it likely goes in TLS 1.0. On modern stacks, it can + # support TLS 1.2. + # + # The PROTOCOL_TLSv* constants select a specific TLS version + # only (as opposed to multiple versions). So the method for + # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and + # disable protocols via SSLContext.options and OP_NO_* constants. + # However, SSLContext.options doesn't work unless we have the + # full/real SSLContext available to us. + # + # SSLv2 and SSLv3 are broken. We ban them outright. + if modernssl: + protocol = ssl.PROTOCOL_SSLv23 + else: + protocol = ssl.PROTOCOL_TLSv1 - # TODO use ssl.create_default_context() on modernssl. - sslcontext = SSLContext(protocol) + # TODO use ssl.create_default_context() on modernssl. + sslcontext = SSLContext(protocol) - # This is a no-op on old Python. - sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 + # This is a no-op on old Python. + sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 - if certfile is not None: - def password(): - f = keyfile or certfile - return ui.getpass(_('passphrase for %s: ') % f, '') - sslcontext.load_cert_chain(certfile, keyfile, password) - sslcontext.verify_mode = cert_reqs - if ca_certs is not None: - sslcontext.load_verify_locations(cafile=ca_certs) - else: - # This is a no-op on old Python. - sslcontext.load_default_certs() + if certfile is not None: + def password(): + f = keyfile or certfile + return ui.getpass(_('passphrase for %s: ') % f, '') + sslcontext.load_cert_chain(certfile, keyfile, password) + sslcontext.verify_mode = cert_reqs + if ca_certs is not None: + sslcontext.load_verify_locations(cafile=ca_certs) + else: + # This is a no-op on old Python. + sslcontext.load_default_certs() - sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) - # check if wrap_socket failed silently because socket had been - # closed - # - see http://bugs.python.org/issue13721 - if not sslsocket.cipher(): - raise error.Abort(_('ssl connection failed')) - return sslsocket -except AttributeError: - raise util.Abort('this should not happen') + sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) + # check if wrap_socket failed silently because socket had been + # closed + # - see http://bugs.python.org/issue13721 + if not sslsocket.cipher(): + raise error.Abort(_('ssl connection failed')) + return sslsocket def _verifycert(cert, hostname): '''Verify that cert (in socket.getpeercert() format) matches hostname.