bpo-35925: Skip SSL tests that fail due to weak external certs. (GH-13124)
Modern Linux distros such as Debian Buster have default OpenSSL system
configurations that reject connections to servers with weak certificates
by default. This causes our test suite run with external networking
resources enabled to skip these tests when they encounter such a failure.
Fixing the network servers is a separate issue.
(cherry picked from commit 2cc0223f43
)
Co-authored-by: Gregory P. Smith <greg@krypto.org>
This commit is contained in:
parent
b2d29bfa5b
commit
ffa29b5aca
|
@ -4,6 +4,7 @@ import io
|
|||
import itertools
|
||||
import os
|
||||
import array
|
||||
import re
|
||||
import socket
|
||||
import threading
|
||||
|
||||
|
@ -1622,14 +1623,30 @@ class HTTPSTest(TestCase):
|
|||
# We feed the server's cert as a validating cert
|
||||
import ssl
|
||||
support.requires('network')
|
||||
with support.transient_internet('self-signed.pythontest.net'):
|
||||
selfsigned_pythontestdotnet = 'self-signed.pythontest.net'
|
||||
with support.transient_internet(selfsigned_pythontestdotnet):
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
self.assertEqual(context.verify_mode, ssl.CERT_REQUIRED)
|
||||
self.assertEqual(context.check_hostname, True)
|
||||
context.load_verify_locations(CERT_selfsigned_pythontestdotnet)
|
||||
h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context)
|
||||
h.request('GET', '/')
|
||||
resp = h.getresponse()
|
||||
try:
|
||||
h = client.HTTPSConnection(selfsigned_pythontestdotnet, 443,
|
||||
context=context)
|
||||
h.request('GET', '/')
|
||||
resp = h.getresponse()
|
||||
except ssl.SSLError as ssl_err:
|
||||
ssl_err_str = str(ssl_err)
|
||||
# In the error message of [SSL: CERTIFICATE_VERIFY_FAILED] on
|
||||
# modern Linux distros (Debian Buster, etc) default OpenSSL
|
||||
# configurations it'll fail saying "key too weak" until we
|
||||
# address https://bugs.python.org/issue36816 to use a proper
|
||||
# key size on self-signed.pythontest.net.
|
||||
if re.search(r'(?i)key.too.weak', ssl_err_str):
|
||||
raise unittest.SkipTest(
|
||||
f'Got {ssl_err_str} trying to connect '
|
||||
f'to {selfsigned_pythontestdotnet}. '
|
||||
'See https://bugs.python.org/issue36816.')
|
||||
raise
|
||||
server_string = resp.getheader('server')
|
||||
resp.close()
|
||||
h.close()
|
||||
|
|
|
@ -6,6 +6,7 @@ import unittest
|
|||
import functools
|
||||
import contextlib
|
||||
import os.path
|
||||
import re
|
||||
import threading
|
||||
|
||||
from test import support
|
||||
|
@ -21,6 +22,13 @@ except ImportError:
|
|||
TIMEOUT = 30
|
||||
certfile = os.path.join(os.path.dirname(__file__), 'keycert3.pem')
|
||||
|
||||
if ssl is not None:
|
||||
SSLError = ssl.SSLError
|
||||
else:
|
||||
class SSLError(Exception):
|
||||
"""Non-existent exception class when we lack SSL support."""
|
||||
reason = "This will never be raised."
|
||||
|
||||
# TODO:
|
||||
# - test the `file` arg to more commands
|
||||
# - test error conditions
|
||||
|
@ -261,14 +269,21 @@ class NetworkedNNTPTestsMixin:
|
|||
return False
|
||||
return True
|
||||
|
||||
with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server:
|
||||
self.assertTrue(is_connected())
|
||||
self.assertTrue(server.help())
|
||||
self.assertFalse(is_connected())
|
||||
try:
|
||||
with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server:
|
||||
self.assertTrue(is_connected())
|
||||
self.assertTrue(server.help())
|
||||
self.assertFalse(is_connected())
|
||||
|
||||
with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server:
|
||||
server.quit()
|
||||
self.assertFalse(is_connected())
|
||||
with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server:
|
||||
server.quit()
|
||||
self.assertFalse(is_connected())
|
||||
except SSLError as ssl_err:
|
||||
# matches "[SSL: DH_KEY_TOO_SMALL] dh key too small"
|
||||
if re.search(r'(?i)KEY.TOO.SMALL', ssl_err.reason):
|
||||
raise unittest.SkipTest(f"Got {ssl_err} connecting "
|
||||
f"to {self.NNTP_HOST!r}")
|
||||
raise
|
||||
|
||||
|
||||
NetworkedNNTPTestsMixin.wrap_methods()
|
||||
|
@ -294,6 +309,12 @@ class NetworkedNNTPTests(NetworkedNNTPTestsMixin, unittest.TestCase):
|
|||
try:
|
||||
cls.server = cls.NNTP_CLASS(cls.NNTP_HOST, timeout=TIMEOUT,
|
||||
usenetrc=False)
|
||||
except SSLError as ssl_err:
|
||||
# matches "[SSL: DH_KEY_TOO_SMALL] dh key too small"
|
||||
if re.search(r'(?i)KEY.TOO.SMALL', ssl_err.reason):
|
||||
raise unittest.SkipTest(f"{cls} got {ssl_err} connecting "
|
||||
f"to {cls.NNTP_HOST!r}")
|
||||
raise
|
||||
except EOF_ERRORS:
|
||||
raise unittest.SkipTest(f"{cls} got EOF error on connecting "
|
||||
f"to {cls.NNTP_HOST!r}")
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Skip httplib and nntplib networking tests when they would otherwise fail due to a modern OS or distro with a default OpenSSL policy of rejecting connections to servers with weak certificates.
|
Loading…
Reference in New Issue