]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[2.7] bpo-38338, test.pythoninfo: add more ssl infos (GH-16543)
authorVictor Stinner <vstinner@redhat.com>
Wed, 2 Oct 2019 16:36:32 +0000 (18:36 +0200)
committerGitHub <noreply@github.com>
Wed, 2 Oct 2019 16:36:32 +0000 (18:36 +0200)
test.pythoninfo now logs environment variables used by OpenSSL and
Python ssl modules, and logs attributes of 3 SSL contexts
(SSLContext, default HTTPS context, stdlib context).

(cherry picked from commit 1df1c2f8df53d005ff47af81aa02c58752b84e20)

Lib/test/pythoninfo.py

index a6983ba021c678c8132f0ba5529bbc5d3db610b0..12de99b09d5e2404838e7820274af071df86949e 100644 (file)
@@ -439,10 +439,15 @@ def collect_sysconfig(info_add):
 
 
 def collect_ssl(info_add):
+    import os
     try:
         import ssl
     except ImportError:
         return
+    try:
+        import _ssl
+    except ImportError:
+        _ssl = None
 
     def format_attr(attr, value):
         if attr.startswith('OP_'):
@@ -459,6 +464,61 @@ def collect_ssl(info_add):
     )
     copy_attributes(info_add, ssl, 'ssl.%s', attributes, formatter=format_attr)
 
+    options_names = []
+    protocol_names = {}
+    verify_modes = {}
+    for name in dir(ssl):
+        if name.startswith('OP_'):
+            options_names.append((name, getattr(ssl, name)))
+        elif name.startswith('PROTOCOL_'):
+            protocol_names[getattr(ssl, name)] = name
+        elif name.startswith('CERT_'):
+            verify_modes[getattr(ssl, name)] = name
+    options_names.sort(key=lambda item: item[1], reverse=True)
+
+    def formatter(attr_name, value):
+        if attr_name == 'options':
+            options_text = []
+            for opt_name, opt_value in options_names:
+                if value & opt_value:
+                    options_text.append(opt_name)
+                    value &= ~opt_value
+            if value:
+                options_text.append(str(value))
+            return '|' .join(options_text)
+        elif attr_name == 'verify_mode':
+            return verify_modes.get(value, value)
+        elif attr_name == 'protocol':
+            return protocol_names.get(value, value)
+        else:
+            return value
+
+    for name, ctx in (
+        ('SSLContext(PROTOCOL_TLS)', ssl.SSLContext(ssl.PROTOCOL_TLS)),
+        ('default_https_context', ssl._create_default_https_context()),
+        ('stdlib_context', ssl._create_stdlib_context()),
+    ):
+        attributes = (
+            'minimum_version',
+            'maximum_version',
+            'protocol',
+            'options',
+            'verify_mode',
+        )
+        copy_attributes(info_add, ctx, 'ssl.%s.%%s' % name, attributes, formatter=formatter)
+
+    env_names = ["OPENSSL_CONF", "SSLKEYLOGFILE"]
+    if _ssl is not None and hasattr(_ssl, 'get_default_verify_paths'):
+        parts = _ssl.get_default_verify_paths()
+        env_names.extend((parts[0], parts[2]))
+
+    for name in env_names:
+        try:
+            value = os.environ[name]
+        except KeyError:
+            continue
+        info_add('ssl.environ[%s]' % name, value)
+
 
 def collect_socket(info_add):
     import socket