Patchwork ssl: only use the dummy cert hack if using an Apply Python (issue4410)

login
register
mail settings
Submitter Mads Kiilerich
Date Oct. 17, 2014, 3:18 p.m.
Message ID <7c2c5e37f66ca6661daf.1413559114@ssl.google-analytics.com>
Download mbox | patch
Permalink /patch/6368/
State Accepted
Headers show

Comments

Mads Kiilerich - Oct. 17, 2014, 3:18 p.m.
# HG changeset patch
# User Mads Kiilerich <madski@unity3d.com>
# Date 1413559075 -7200
#      Fri Oct 17 17:17:55 2014 +0200
# Node ID 7c2c5e37f66ca6661dafc403d0d616b979b40e44
# Parent  840be5ca03e1db16ba994e55597771c418166c97
ssl: only use the dummy cert hack if using an Apply Python (issue4410)

The hack for using certificate store in addition to the provided CAs resides in
Apple's OpenSSL. Apple's own Pythons will use it, but other custom built
Pythons might use a custom built OpenSSL without that hack and will fail when
exposed to the dummy cacert introduced in d7f7f1860f00.

There do not seem to be a simple way to check from Python if we are using a
patched OpenSSL or if it is an Apple OpenSSL.

Instead, check if the Python executable resides in /usr/bin/python* or in
/System/Library/Frameworks/Python.framework/ and assume that all Pythons found
there will be native Pythons using the patched OpenSSL.

Custom built Pythons will not get the benefit of using the CAs from the
certificate store.
Augie Fackler - Oct. 17, 2014, 4:12 p.m.
On Fri, Oct 17, 2014 at 05:18:34PM +0200, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich <madski@unity3d.com>
> # Date 1413559075 -7200
> #      Fri Oct 17 17:17:55 2014 +0200
> # Node ID 7c2c5e37f66ca6661dafc403d0d616b979b40e44
> # Parent  840be5ca03e1db16ba994e55597771c418166c97
> ssl: only use the dummy cert hack if using an Apply Python (issue4410)
>
> The hack for using certificate store in addition to the provided CAs resides in
> Apple's OpenSSL. Apple's own Pythons will use it, but other custom built
> Pythons might use a custom built OpenSSL without that hack and will fail when
> exposed to the dummy cacert introduced in d7f7f1860f00.
>
> There do not seem to be a simple way to check from Python if we are using a
> patched OpenSSL or if it is an Apple OpenSSL.
>
> Instead, check if the Python executable resides in /usr/bin/python* or in
> /System/Library/Frameworks/Python.framework/ and assume that all Pythons found
> there will be native Pythons using the patched OpenSSL.
>
> Custom built Pythons will not get the benefit of using the CAs from the
> certificate store.
>
> diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
> --- a/mercurial/sslutil.py
> +++ b/mercurial/sslutil.py
> @@ -105,11 +105,14 @@ def sslkwargs(ui, host):
>          if not os.path.exists(cacerts):
>              raise util.Abort(_('could not find web.cacerts: %s') % cacerts)
>      elif cacerts is None and sys.platform == 'darwin' and not util.mainfrozen():
> -        dummycert = os.path.join(os.path.dirname(__file__), 'dummycert.pem')
> -        if os.path.exists(dummycert):
> -            ui.debug('using %s to enable OS X system CA\n' % dummycert)
> -            ui.setconfig('web', 'cacerts', dummycert, 'dummy')
> -            cacerts = dummycert
> +        exe = (sys.executable or '').lower()
> +        if (exe.startswith('/usr/bin/python') or
> +            exe.startswith('/system/library/frameworks/python.framework/')):

Nit: I'd like to see these path checks teased out into an _applepython() method or something similar to make the code more self-documenting.

> +            cert = os.path.join(os.path.dirname(__file__), 'dummycert.pem')
> +            if os.path.exists(cert):
> +                ui.debug('using %s to enable OS X system CA\n' % cert)
> +                ui.setconfig('web', 'cacerts', cert, 'dummy')
> +                cacerts = cert
>      if cacerts:
>          kws.update({'ca_certs': cacerts,
>                      'cert_reqs': CERT_REQUIRED,
> diff --git a/tests/test-https.t b/tests/test-https.t
> --- a/tests/test-https.t
> +++ b/tests/test-https.t
> @@ -115,7 +115,8 @@ Test server address cannot be reused
>  #endif
>    $ cd ..
>
> -OS X has a dummy CA cert that enables use of the system CA store
> +OS X has a dummy CA cert that enables use of the system CA store when using
> +Apple's OpenSSL. This trick do not work with plain OpenSSL.
>
>    $ DISABLEOSXDUMMYCERT=
>  #if osx
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
--- a/mercurial/sslutil.py
+++ b/mercurial/sslutil.py
@@ -105,11 +105,14 @@  def sslkwargs(ui, host):
         if not os.path.exists(cacerts):
             raise util.Abort(_('could not find web.cacerts: %s') % cacerts)
     elif cacerts is None and sys.platform == 'darwin' and not util.mainfrozen():
-        dummycert = os.path.join(os.path.dirname(__file__), 'dummycert.pem')
-        if os.path.exists(dummycert):
-            ui.debug('using %s to enable OS X system CA\n' % dummycert)
-            ui.setconfig('web', 'cacerts', dummycert, 'dummy')
-            cacerts = dummycert
+        exe = (sys.executable or '').lower()
+        if (exe.startswith('/usr/bin/python') or
+            exe.startswith('/system/library/frameworks/python.framework/')):
+            cert = os.path.join(os.path.dirname(__file__), 'dummycert.pem')
+            if os.path.exists(cert):
+                ui.debug('using %s to enable OS X system CA\n' % cert)
+                ui.setconfig('web', 'cacerts', cert, 'dummy')
+                cacerts = cert
     if cacerts:
         kws.update({'ca_certs': cacerts,
                     'cert_reqs': CERT_REQUIRED,
diff --git a/tests/test-https.t b/tests/test-https.t
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -115,7 +115,8 @@  Test server address cannot be reused
 #endif
   $ cd ..
 
-OS X has a dummy CA cert that enables use of the system CA store
+OS X has a dummy CA cert that enables use of the system CA store when using
+Apple's OpenSSL. This trick do not work with plain OpenSSL.
 
   $ DISABLEOSXDUMMYCERT=
 #if osx