Patchwork [2,of,2,v3] setup: require that Python has TLS 1.1 or TLS 1.2

login
register
mail settings
Submitter Manuel Jacob
Date May 31, 2020, 3:58 a.m.
Message ID <9590fdc527eb7c96c252.1590897531@tmp>
Download mbox | patch
Permalink /patch/46431/
State New
Headers show

Comments

Manuel Jacob - May 31, 2020, 3:58 a.m.
# HG changeset patch
# User Manuel Jacob <me@manueljacob.de>
# Date 1590874939 -7200
#      Sat May 30 23:42:19 2020 +0200
# Node ID 9590fdc527eb7c96c252af5b471da6f33bb1295f
# Parent  d5441892eb22aa451bb479919e95f671e99857eb
# EXP-Topic require_modern_ssl
setup: require that Python has TLS 1.1 or TLS 1.2

This increases the minimum security baseline of Mercurial (up from TLS 1.0)
and enables us to remove compatibility code that downgrades security if these
features are not available.

It is reasonable to expect that distributions having Python 2.7.9+ or having
backported modern features to the ssl module (which we require) have a OpenSSL
version supporting TLS 1.1 or TLS 1.2, as this is the main reason why
distributions would want to backport these features.

In practice, TLS 1.1 and TLS 1.2 are either both enabled or both not enabled.
However, it is imaginable that only one of them is enabled.

ssl.HAS_TLSv1_1 / ssl.HAS_TLSv1_2 are preferred to check support but they were
added in Python 3.7. ssl.PROTOCOL_TLSv1_1 / ssl.PROTOCOL_TLSv1_2 were
deprecated in Python 3.6, but checking their presence is good enough for older
Python versions.
Yuya Nishihara - May 31, 2020, 6:01 a.m.
On Sun, 31 May 2020 05:58:51 +0200, Manuel Jacob wrote:
> # HG changeset patch
> # User Manuel Jacob <me@manueljacob.de>
> # Date 1590874939 -7200
> #      Sat May 30 23:42:19 2020 +0200
> # Node ID 9590fdc527eb7c96c252af5b471da6f33bb1295f
> # Parent  d5441892eb22aa451bb479919e95f671e99857eb
> # EXP-Topic require_modern_ssl
> setup: require that Python has TLS 1.1 or TLS 1.2
> 
> This increases the minimum security baseline of Mercurial (up from TLS 1.0)
> and enables us to remove compatibility code that downgrades security if these
> features are not available.
> 
> It is reasonable to expect that distributions having Python 2.7.9+ or having
> backported modern features to the ssl module (which we require) have a OpenSSL
> version supporting TLS 1.1 or TLS 1.2, as this is the main reason why
> distributions would want to backport these features.
> 
> In practice, TLS 1.1 and TLS 1.2 are either both enabled or both not enabled.
> However, it is imaginable that only one of them is enabled.
> 
> ssl.HAS_TLSv1_1 / ssl.HAS_TLSv1_2 are preferred to check support but they were
> added in Python 3.7. ssl.PROTOCOL_TLSv1_1 / ssl.PROTOCOL_TLSv1_2 were
> deprecated in Python 3.6, but checking their presence is good enough for older
> Python versions.
> 
> diff --git a/relnotes/next b/relnotes/next
> --- a/relnotes/next
> +++ b/relnotes/next
> @@ -7,7 +7,9 @@
>  == Backwards Compatibility Changes ==
>  
>  * Mercurial now requires at least Python 2.7.9 or a Python version that
> -  backported modern SSL/TLS features (as defined in PEP 466).
> +  backported modern SSL/TLS features (as defined in PEP 466), and that Python
> +  was compiled against a OpenSSL version supporting TLS 1.1 or TLS 1.2
> +  (likely this requires the OpenSSL version to be at least 1.0.1).
>  
>  
>  == Internal API Changes ==
> diff --git a/setup.py b/setup.py
> --- a/setup.py
> +++ b/setup.py
> @@ -98,6 +98,21 @@ features.
>      printf(error, file=sys.stderr)
>      sys.exit(1)
>  
> +if not any(
> +    [
> +        getattr(ssl, 'HAS_TLSv1_1', hasattr(ssl, 'PROTOCOL_TLSv1_1')),
> +        getattr(ssl, 'HAS_TLSv1_2', hasattr(ssl, 'PROTOCOL_TLSv1_2')),

Can you rewrite hasattr() with getattr()? check-code complains about it.

+  setup.py:103:
+   >         getattr(ssl, 'HAS_TLSv1_1', hasattr(ssl, 'PROTOCOL_TLSv1_1')),
+   hasattr(foo, bar) is broken on py2, use util.safehasattr(foo, bar) instead
+  setup.py:104:
+   >         getattr(ssl, 'HAS_TLSv1_2', hasattr(ssl, 'PROTOCOL_TLSv1_2')),
+   hasattr(foo, bar) is broken on py2, use util.safehasattr(foo, bar) instead

Patch

diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -7,7 +7,9 @@ 
 == Backwards Compatibility Changes ==
 
 * Mercurial now requires at least Python 2.7.9 or a Python version that
-  backported modern SSL/TLS features (as defined in PEP 466).
+  backported modern SSL/TLS features (as defined in PEP 466), and that Python
+  was compiled against a OpenSSL version supporting TLS 1.1 or TLS 1.2
+  (likely this requires the OpenSSL version to be at least 1.0.1).
 
 
 == Internal API Changes ==
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -98,6 +98,21 @@  features.
     printf(error, file=sys.stderr)
     sys.exit(1)
 
+if not any(
+    [
+        getattr(ssl, 'HAS_TLSv1_1', hasattr(ssl, 'PROTOCOL_TLSv1_1')),
+        getattr(ssl, 'HAS_TLSv1_2', hasattr(ssl, 'PROTOCOL_TLSv1_2')),
+    ]
+):
+    error = """
+The `ssl` module does not advertise support for TLS 1.1 or TLS 1.2.
+Please make sure that your Python installation was compiled against an OpenSSL
+version enabling these features (likely this requires the OpenSSL version to
+be at least 1.0.1).
+"""
+    printf(error, file=sys.stderr)
+    sys.exit(1)
+
 if sys.version_info[0] >= 3:
     DYLIB_SUFFIX = sysconfig.get_config_vars()['EXT_SUFFIX']
 else: