Patchwork [1,of,4,V2] sslutil: use certificates provided by certifi if available

login
register
mail settings
Submitter Gregory Szorc
Date July 4, 2016, 5:04 p.m.
Message ID <21168a74003cc690f9a2.1467651877@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/15738/
State Accepted
Headers show

Comments

Gregory Szorc - July 4, 2016, 5:04 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1467651525 25200
#      Mon Jul 04 09:58:45 2016 -0700
# Node ID 21168a74003cc690f9a2ef7059e382996965247d
# Parent  e61ab83a2ee04e5446a0778b692a5f0fca925358
sslutil: use certificates provided by certifi if available

The "certifi" Python package provides a distribution of the
Mozilla trusted CA certificates as a Python package. If it is
present, we assume the user intends it to be used and we use
it to provide the default CA certificates when certificates
are otherwise not configured.

It's worth noting that this behavior roughly matches the popular
"requests" package, which also attempts to use "certifi" if
present.
Yuya Nishihara - July 5, 2016, 11:47 a.m.
On Mon, 04 Jul 2016 10:04:37 -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1467651525 25200
> #      Mon Jul 04 09:58:45 2016 -0700
> # Node ID 21168a74003cc690f9a2ef7059e382996965247d
> # Parent  e61ab83a2ee04e5446a0778b692a5f0fca925358
> sslutil: use certificates provided by certifi if available

The series LGTM, queued, thanks.

Patch

diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
--- a/mercurial/sslutil.py
+++ b/mercurial/sslutil.py
@@ -427,16 +427,26 @@  def _plainapplepython():
     if sys.platform != 'darwin' or util.mainfrozen() or not sys.executable:
         return False
     exe = os.path.realpath(sys.executable).lower()
     return (exe.startswith('/usr/bin/python') or
             exe.startswith('/system/library/frameworks/python.framework/'))
 
 def _defaultcacerts(ui):
     """return path to default CA certificates or None."""
+    # The "certifi" Python package provides certificates. If it is installed,
+    # assume the user intends it to be used and use it.
+    try:
+        import certifi
+        certs = certifi.where()
+        ui.debug('using ca certificates from certifi\n')
+        return certs
+    except ImportError:
+        pass
+
     if _plainapplepython():
         dummycert = os.path.join(os.path.dirname(__file__), 'dummycert.pem')
         if os.path.exists(dummycert):
             return dummycert
 
     return None
 
 def validatesocket(sock):