[Python-checkins] bpo-41561: Add workaround for Ubuntu's custom security level (GH-24915)

miss-islington webhook-mailer at python.org
Thu Mar 18 18:41:21 EDT 2021


https://github.com/python/cpython/commit/50511677f59464e612cfef0cd0e139fe07e87737
commit: 50511677f59464e612cfef0cd0e139fe07e87737
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2021-03-18T15:41:11-07:00
summary:

bpo-41561: Add workaround for Ubuntu's custom security level (GH-24915)


Ubuntu 20.04 comes with a patched OpenSSL 1.1.1. Default security level
2 blocks TLS 1.0 and 1.1 connections. Regular OpenSSL 1.1.1 builds allow
TLS 1.0 and 1.1 on security level 2.

See:
See: https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1899878
See: https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1917625
Signed-off-by: Christian Heimes <christian at python.org>
(cherry picked from commit f6c6b5821bff815bdc810de53992fd1fbdb2edd4)

Co-authored-by: Christian Heimes <christian at python.org>

files:
A Misc/NEWS.d/next/Tests/2021-03-18-10-34-42.bpo-41561.pDg4w-.rst
M .github/workflows/build.yml
M Lib/test/test_ssl.py

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 5822428e34a86..20d3040770f6d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -114,7 +114,7 @@ jobs:
 
   build_ubuntu:
     name: 'Ubuntu'
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     needs: check_source
     if: needs.check_source.outputs.run_tests == 'true'
     env:
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 850d174272ec9..9a886c73dee87 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -143,6 +143,27 @@ def data_file(*name):
 OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
 OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0)
 
+# Ubuntu has patched OpenSSL and changed behavior of security level 2
+# see https://bugs.python.org/issue41561#msg389003
+def is_ubuntu():
+    try:
+        # Assume that any references of "ubuntu" implies Ubuntu-like distro
+        # The workaround is not required for 18.04, but doesn't hurt either.
+        with open("/etc/os-release", encoding="utf-8") as f:
+            return "ubuntu" in f.read()
+    except FileNotFoundError:
+        return False
+
+if is_ubuntu():
+    def seclevel_workaround(*ctxs):
+        """"Lower security level to '1' and allow all ciphers for TLS 1.0/1"""
+        for ctx in ctxs:
+            if ctx.minimum_version <= ssl.TLSVersion.TLSv1_1:
+                ctx.set_ciphers("@SECLEVEL=1:ALL")
+else:
+    def seclevel_workaround(*ctxs):
+        pass
+
 
 def has_tls_protocol(protocol):
     """Check if a TLS protocol is available and enabled
@@ -2772,6 +2793,8 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success,
     if client_context.protocol == ssl.PROTOCOL_TLS:
         client_context.set_ciphers("ALL")
 
+    seclevel_workaround(server_context, client_context)
+
     for ctx in (client_context, server_context):
         ctx.verify_mode = certsreqs
         ctx.load_cert_chain(SIGNED_CERTFILE)
@@ -2813,6 +2836,7 @@ def test_echo(self):
             with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
                 context = ssl.SSLContext(protocol)
                 context.load_cert_chain(CERTFILE)
+                seclevel_workaround(context)
                 server_params_test(context, context,
                                    chatty=True, connectionchatty=True)
 
@@ -3817,6 +3841,7 @@ def test_min_max_version_tlsv1_1(self):
         client_context.maximum_version = ssl.TLSVersion.TLSv1_2
         server_context.minimum_version = ssl.TLSVersion.TLSv1
         server_context.maximum_version = ssl.TLSVersion.TLSv1_1
+        seclevel_workaround(client_context, server_context)
 
         with ThreadedEchoServer(context=server_context) as server:
             with client_context.wrap_socket(socket.socket(),
@@ -3834,6 +3859,8 @@ def test_min_max_version_mismatch(self):
         server_context.minimum_version = ssl.TLSVersion.TLSv1_2
         client_context.maximum_version = ssl.TLSVersion.TLSv1
         client_context.minimum_version = ssl.TLSVersion.TLSv1
+        seclevel_workaround(client_context, server_context)
+
         with ThreadedEchoServer(context=server_context) as server:
             with client_context.wrap_socket(socket.socket(),
                                             server_hostname=hostname) as s:
@@ -3848,6 +3875,8 @@ def test_min_max_version_sslv3(self):
         server_context.minimum_version = ssl.TLSVersion.SSLv3
         client_context.minimum_version = ssl.TLSVersion.SSLv3
         client_context.maximum_version = ssl.TLSVersion.SSLv3
+        seclevel_workaround(client_context, server_context)
+
         with ThreadedEchoServer(context=server_context) as server:
             with client_context.wrap_socket(socket.socket(),
                                             server_hostname=hostname) as s:
diff --git a/Misc/NEWS.d/next/Tests/2021-03-18-10-34-42.bpo-41561.pDg4w-.rst b/Misc/NEWS.d/next/Tests/2021-03-18-10-34-42.bpo-41561.pDg4w-.rst
new file mode 100644
index 0000000000000..214350729bff6
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2021-03-18-10-34-42.bpo-41561.pDg4w-.rst
@@ -0,0 +1 @@
+Add workaround for Ubuntu's custom OpenSSL security level policy.



More information about the Python-checkins mailing list