[PATCH STABLE] sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)

Gregory Szorc gregory.szorc at gmail.com
Mon Jul 25 19:01:08 UTC 2016


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1469473255 25200
#      Mon Jul 25 12:00:55 2016 -0700
# Branch stable
# Node ID 94abd7d9e7a1b8f689da7758927700a2e28959a6
# Parent  9c2cc107547fd701a7604349632f2f590366f17c
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)

SSLContext.get_ca_certs() can raise
"ssl.SSLError: unknown error (_ssl.c:636)" on Windows. See
https://bugs.python.org/issue20916 for more info.

We add a try..except that swallows the exception to work around
this bug. If we encounter the bug, we won't print a warning
message about attempting to load CA certificates. This is
unfortunate. But there appears to be little we can do :/

diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
--- a/mercurial/sslutil.py
+++ b/mercurial/sslutil.py
@@ -404,22 +404,28 @@ def wrapsocket(sock, keyfile, certfile, 
     try:
         sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname)
     except ssl.SSLError as e:
         # If we're doing certificate verification and no CA certs are loaded,
         # that is almost certainly the reason why verification failed. Provide
         # a hint to the user.
         # Only modern ssl module exposes SSLContext.get_ca_certs() so we can
         # only show this warning if modern ssl is available.
-        if (caloaded and settings['verifymode'] == ssl.CERT_REQUIRED and
-            modernssl and not sslcontext.get_ca_certs()):
-            ui.warn(_('(an attempt was made to load CA certificates but none '
-                      'were loaded; see '
-                      'https://mercurial-scm.org/wiki/SecureConnections for '
-                      'how to configure Mercurial to avoid this error)\n'))
+        # The exception handler is here because of
+        # https://bugs.python.org/issue20916.
+        try:
+            if (caloaded and settings['verifymode'] == ssl.CERT_REQUIRED and
+                modernssl and not sslcontext.get_ca_certs()):
+                ui.warn(_('(an attempt was made to load CA certificates but '
+                          'none were loaded; see '
+                          'https://mercurial-scm.org/wiki/SecureConnections '
+                          'for how to configure Mercurial to avoid this '
+                          'error)\n'))
+        except ssl.SSLError:
+            pass
         # Try to print more helpful error messages for known failures.
         if util.safehasattr(e, 'reason'):
             # This error occurs when the client and server don't share a
             # common/supported SSL/TLS protocol. We've disabled SSLv2 and SSLv3
             # outright. Hopefully the reason for this error is that we require
             # TLS 1.1+ and the server only supports TLS 1.0. Whatever the
             # reason, try to emit an actionable warning.
             if e.reason == 'UNSUPPORTED_PROTOCOL':


More information about the Mercurial-devel mailing list