[PATCH 4 of 4 V2] ssl: load CA certificates from system's store by default on Python 2.7.9

Yuya Nishihara yuya at tcha.org
Thu Mar 12 10:41:57 CDT 2015


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1424958853 -32400
#      Thu Feb 26 22:54:13 2015 +0900
# Node ID 4a831146e17df61f30573d852bba9062883791d6
# Parent  aa314d9b7beae9d6bdc9f939615edf5a18c17144
ssl: load CA certificates from system's store by default on Python 2.7.9

This will make it easy to manage in-house CA certificates, which are often
used in corporate environment and installed into the Windows' certs store.

Unlike Apple python, the dummycert trick isn't necessary on Python 2.7.9.
The default web.cacerts will be set as follows:

  environment    web.cacerts  behavior
  -------------  -----------  -----------------------------------------
  Apple Python   dummycert    fall back to system's store
  Python 2.7.8   '!'          never use CA certs (show warning instead)
  Python 2.7.9+  None         load CA certs from system's store

diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
--- a/mercurial/sslutil.py
+++ b/mercurial/sslutil.py
@@ -10,12 +10,16 @@ import os, sys
 
 from mercurial import util
 from mercurial.i18n import _
+
+_canloaddefaultcerts = False
 try:
     # avoid using deprecated/broken FakeSocket in python 2.6
     import ssl
     CERT_REQUIRED = ssl.CERT_REQUIRED
     try:
         ssl_context = ssl.SSLContext
+        _canloaddefaultcerts = util.safehasattr(ssl_context,
+                                                'load_default_certs')
 
         def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=ssl.CERT_NONE,
                             ca_certs=None, serverhostname=None):
@@ -35,6 +39,8 @@ try:
             sslcontext.verify_mode = cert_reqs
             if ca_certs is not None:
                 sslcontext.load_verify_locations(cafile=ca_certs)
+            elif _canloaddefaultcerts:
+                sslcontext.load_default_certs()
 
             sslsocket = sslcontext.wrap_socket(sock,
                                                server_hostname=serverhostname)
@@ -130,10 +136,13 @@ def _plainapplepython():
             exe.startswith('/system/library/frameworks/python.framework/'))
 
 def _defaultcacerts():
+    """return path to CA certificates; None for system's store; ! to disable"""
     if _plainapplepython():
         dummycert = os.path.join(os.path.dirname(__file__), 'dummycert.pem')
         if os.path.exists(dummycert):
             return dummycert
+    if _canloaddefaultcerts:
+        return None
     return '!'
 
 def sslkwargs(ui, host):


More information about the Mercurial-devel mailing list