[PATCH 1 of 6] sslutil: verify that wrap_socket really wrapped the socket

Mads Kiilerich mads at kiilerich.com
Mon Jan 9 08:00:45 CST 2012


# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1326116595 -3600
# Node ID 8e24d27b9049149a21539e2567634ef55cbfd119
# Parent  a814f8fcc65a445b2ad8a56cf1b0fa777305542c
sslutil: verify that wrap_socket really wrapped the socket

This works around that ssl.wrap_socket silently skips ssl negotiation on
sockets that was connected but since then has been reset by the peer but not
yet closed at the Python level. That leaves the socket in a state where
.getpeercert() fails with an AttributeError on None. See
http://bugs.python.org/issue13721 .

A call to .cipher() is now used to verify that the wrapping really did succeed.
Otherwise it aborts with "ssl connection failed".

diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
--- a/mercurial/sslutil.py
+++ b/mercurial/sslutil.py
@@ -13,8 +13,16 @@
 try:
     # avoid using deprecated/broken FakeSocket in python 2.6
     import ssl
-    ssl_wrap_socket = ssl.wrap_socket
     CERT_REQUIRED = ssl.CERT_REQUIRED
+    def ssl_wrap_socket(sock, keyfile, certfile,
+                cert_reqs=ssl.CERT_NONE, ca_certs=None):
+        sslsocket = ssl.wrap_socket(sock, keyfile, certfile,
+                cert_reqs=cert_reqs, ca_certs=ca_certs)
+        # 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
 


More information about the Mercurial-devel mailing list