diff mercurial/sslutil.py @ 29288:7dee15dee53c

sslutil: add devel.disableloaddefaultcerts to disable CA loading There are various tests for behavior when CA certs aren't loaded. Previously, we would pass --insecure to disable loading of CA certs. This has worked up to this point because the error message for --insecure and no CAs loaded is the same. Upcoming commits will change the error message for --insecure and will change behavior when CAs aren't loaded. This commit introduces the ability to disable loading of CA certs by setting devel.disableloaddefaultcerts. This allows a testing backdoor to disable loading of CA certs even if system/default CA certs are available. The flag is purposefully not exposed to end-users because there should not be a need for this in the wild: certificate pinning and --insecure provide workarounds to disable cert loading/validation. Tests have been updated to use the new method. The variable used to disable CA certs has been renamed because the method is not OS X specific.
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 01 Jun 2016 19:57:20 -0700
parents fbccb334efe7
children 3536673a25ae
line wrap: on
line diff
--- a/mercurial/sslutil.py	Mon May 30 11:20:31 2016 -0700
+++ b/mercurial/sslutil.py	Wed Jun 01 19:57:20 2016 -0700
@@ -112,6 +112,9 @@
     Returns a dict of settings relevant to that hostname.
     """
     s = {
+        # Whether we should attempt to load default/available CA certs
+        # if an explicit ``cafile`` is not defined.
+        'allowloaddefaultcerts': True,
         # List of 2-tuple of (hash algorithm, hash).
         'certfingerprints': [],
         # Path to file containing concatenated CA certs. Used by
@@ -156,6 +159,9 @@
         s['disablecertverification'] = True
         s['verifymode'] = ssl.CERT_NONE
 
+    if ui.configbool('devel', 'disableloaddefaultcerts'):
+        s['allowloaddefaultcerts'] = False
+
     # Try to hook up CA certificate validation unless something above
     # makes it not necessary.
     if s['verifymode'] is None:
@@ -176,7 +182,7 @@
 
         # Require certificate validation if CA certs are being loaded and
         # verification hasn't been disabled above.
-        if cafile or _canloaddefaultcerts:
+        if cafile or (_canloaddefaultcerts and s['allowloaddefaultcerts']):
             s['verifymode'] = ssl.CERT_REQUIRED
         else:
             # At this point we don't have a fingerprint, aren't being
@@ -243,10 +249,12 @@
     if settings['cafile'] is not None:
         sslcontext.load_verify_locations(cafile=settings['cafile'])
         caloaded = True
-    else:
+    elif settings['allowloaddefaultcerts']:
         # This is a no-op on old Python.
         sslcontext.load_default_certs()
-        caloaded = _canloaddefaultcerts
+        caloaded = True
+    else:
+        caloaded = False
 
     sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname)
     # check if wrap_socket failed silently because socket had been