[PATCH] https: support tls sni (server name indication) for https urls (issue3090)
Augie Fackler
raf at durin42.com
Tue Jan 13 19:57:29 CST 2015
On Jan 13, 2015, at 2:05 PM, Augie Fackler <raf at durin42.com> wrote:
> On Mon, Jan 12, 2015 at 06:11:05PM -0700, Alex Orange wrote:
>> # HG changeset patch
>> # User Alex Orange <crazycasta at gmail.com>
>> # Date 1421110880 25200
>> # Mon Jan 12 18:01:20 2015 -0700
>> # Node ID b683de04cfd910f8f9c1c9400c748a11ef853c35
>> # Parent 678f53865c6860a950392691814766957ee89316
>> https: support tls sni (server name indication) for https urls (issue3090)
>
> This looks like a good start. I'll do Antoine's proposal as a
> followup, as well as a couple of other tweaks I see that'll make doing
> that less of a headache.
I’ve encountered some test failures with this patch now that we actually run test-https.t on 2.7.9 - can you rebase this over mpm’s latest and see if you see them?
(I’d have posted a link, but I’m hunting an unrelated slowness problem in obsolete markers on my FreeBSD server where I push things.)
>
> Many thanks! This has been on my todo list since the backport was announced.
>
>>
>> SNI is a common way of sharing servers across multiple domains using separate
>> SSL certificates. As of Python 2.7.9 SSLContext has been backported from
>> Python 3. This patch changes sslutil's ssl_wrap_socket to use SSLContext and
>> take a server hostname as and argument. It also changes the url module to make
>> use of this argument.
>>
>> diff -r 678f53865c68 -r b683de04cfd9 mercurial/sslutil.py
>> --- a/mercurial/sslutil.py Thu Jan 08 00:01:03 2015 +0100
>> +++ b/mercurial/sslutil.py Mon Jan 12 18:01:20 2015 -0700
>> @@ -15,16 +15,39 @@
>> import ssl
>> CERT_REQUIRED = ssl.CERT_REQUIRED
>> PROTOCOL_TLSv1 = ssl.PROTOCOL_TLSv1
>> - def ssl_wrap_socket(sock, keyfile, certfile, ssl_version=PROTOCOL_TLSv1,
>> - cert_reqs=ssl.CERT_NONE, ca_certs=None):
>> - sslsocket = ssl.wrap_socket(sock, keyfile, certfile,
>> - cert_reqs=cert_reqs, ca_certs=ca_certs,
>> - ssl_version=ssl_version)
>> - # check if wrap_socket failed silently because socket had been closed
>> - # - see http://bugs.python.org/issue13721
>> - if not sslsocket.cipher():
>> - raise util.Abort(_('ssl connection failed'))
>> - return sslsocket
>> + try:
>> + ssl_context = ssl.SSLContext
>> +
>> + def ssl_wrap_socket(sock, keyfile, certfile, ssl_version=PROTOCOL_TLSv1,
>> + cert_reqs=ssl.CERT_NONE, ca_certs=None,
>> + server_hostname=None):
>> + sslcontext = ssl.SSLContext(ssl_version)
>> + if keyfile is not None:
>> + sslcontext.load_cert_chain(certfile, keyfile)
>> + sslcontext.verify_mode = cert_reqs
>> + sslcontext.load_verify_locations(cafile=ca_certs)
>> +
>> + sslsocket = sslcontext.wrap_socket(sock,
>> + server_hostname=server_hostname)
>> + # check if wrap_socket failed silently because socket had been
>> + # closed
>> + # - see http://bugs.python.org/issue13721
>> + if not sslsocket.cipher():
>> + raise util.Abort(_('ssl connection failed'))
>> + return sslsocket
>> + except AttributeError:
>> + def ssl_wrap_socket(sock, keyfile, certfile, ssl_version=PROTOCOL_TLSv1,
>> + cert_reqs=ssl.CERT_NONE, ca_certs=None,
>> + server_hostname=None):
>> + sslsocket = ssl.wrap_socket(sock, keyfile, certfile,
>> + cert_reqs=cert_reqs, ca_certs=ca_certs,
>> + ssl_version=ssl_version)
>> + # check if wrap_socket failed silently because socket had been
>> + # closed
>> + # - see http://bugs.python.org/issue13721
>> + if not sslsocket.cipher():
>> + raise util.Abort(_('ssl connection failed'))
>> + return sslsocket
>> except ImportError:
>> CERT_REQUIRED = 2
>>
>> @@ -33,7 +56,8 @@
>> import socket, httplib
>>
>> def ssl_wrap_socket(sock, keyfile, certfile, ssl_version=PROTOCOL_TLSv1,
>> - cert_reqs=CERT_REQUIRED, ca_certs=None):
>> + cert_reqs=CERT_REQUIRED, ca_certs=None,
>> + server_hostname=None):
>> if not util.safehasattr(socket, 'ssl'):
>> raise util.Abort(_('Python SSL support not found'))
>> if ca_certs:
>> diff -r 678f53865c68 -r b683de04cfd9 mercurial/url.py
>> --- a/mercurial/url.py Thu Jan 08 00:01:03 2015 +0100
>> +++ b/mercurial/url.py Mon Jan 12 18:01:20 2015 -0700
>> @@ -185,7 +185,8 @@
>> self.sock.connect((self.host, self.port))
>> if _generic_proxytunnel(self):
>> # we do not support client X.509 certificates
>> - self.sock = sslutil.ssl_wrap_socket(self.sock, None, None)
>> + self.sock = sslutil.ssl_wrap_socket(self.sock, None, None,
>> + server_hostname=self.host)
>> else:
>> keepalive.HTTPConnection.connect(self)
>>
>> @@ -341,7 +342,7 @@
>> _generic_proxytunnel(self)
>> host = self.realhostport.rsplit(':', 1)[0]
>> self.sock = sslutil.ssl_wrap_socket(
>> - self.sock, self.key_file, self.cert_file,
>> + self.sock, self.key_file, self.cert_file, server_hostname=host,
>> **sslutil.sslkwargs(self.ui, host))
>> sslutil.validator(self.ui, host)(self.sock)
>>
>> _______________________________________________
>> Mercurial-devel mailing list
>> Mercurial-devel at selenic.com
>> http://selenic.com/mailman/listinfo/mercurial-devel
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20150113/752d84a3/attachment.pgp>
More information about the Mercurial-devel
mailing list