Skip to content

Commit e08a8bb

Browse files
committed
[3.9] bpo-37322: Fix ResourceWarning and exception handling in test (GH-25553)
Revert 73ea546, increase logging, and improve stability of test. Handle all OSErrors in a single block. OSError also takes care of SSLError and socket's connection errors. Partly reverts commit fb7e750. The threaded connection handler must not raise an unhandled exception.. (cherry picked from commit c8666cf) Co-authored-by: Christian Heimes <[email protected]>
1 parent 5374fbc commit e08a8bb

File tree

3 files changed

+40
-40
lines changed

3 files changed

+40
-40
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ jobs:
191191
strategy:
192192
fail-fast: false
193193
matrix:
194-
openssl_ver: [1.0.2u, 1.1.0l, 1.1.1k, 3.0.0-alpha14]
194+
openssl_ver: [1.0.2u, 1.1.0l, 1.1.1k, 3.0.0-alpha15]
195195
env:
196196
OPENSSL_VER: ${{ matrix.openssl_ver }}
197197
MULTISSL_DIR: ${{ github.workspace }}/multissl

Lib/test/test_ssl.py

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,7 +2397,10 @@ def wrap_conn(self):
23972397
sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
23982398
cert_binary = self.sslconn.getpeercert(True)
23992399
if support.verbose and self.server.chatty:
2400-
sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
2400+
if cert_binary is None:
2401+
sys.stdout.write(" client did not provide a cert\n")
2402+
else:
2403+
sys.stdout.write(f" cert binary is {len(cert_binary)}b\n")
24012404
cipher = self.sslconn.cipher()
24022405
if support.verbose and self.server.chatty:
24032406
sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
@@ -2495,31 +2498,22 @@ def run(self):
24952498
sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
24962499
% (msg, ctype, msg.lower(), ctype))
24972500
self.write(msg.lower())
2498-
except (ConnectionResetError, ConnectionAbortedError):
2499-
# XXX: OpenSSL 1.1.1 sometimes raises ConnectionResetError
2500-
# when connection is not shut down gracefully.
2501+
except OSError as e:
2502+
# handles SSLError and socket errors
25012503
if self.server.chatty and support.verbose:
2502-
sys.stdout.write(
2503-
" Connection reset by peer: {}\n".format(
2504-
self.addr)
2505-
)
2506-
self.close()
2507-
self.running = False
2508-
except ssl.SSLError as err:
2509-
# On Windows sometimes test_pha_required_nocert receives the
2510-
# PEER_DID_NOT_RETURN_A_CERTIFICATE exception
2511-
# before the 'tlsv13 alert certificate required' exception.
2512-
# If the server is stopped when PEER_DID_NOT_RETURN_A_CERTIFICATE
2513-
# is received test_pha_required_nocert fails with ConnectionResetError
2514-
# because the underlying socket is closed
2515-
if 'PEER_DID_NOT_RETURN_A_CERTIFICATE' == err.reason:
2516-
if self.server.chatty and support.verbose:
2517-
sys.stdout.write(err.args[1])
2518-
# test_pha_required_nocert is expecting this exception
2519-
raise ssl.SSLError('tlsv13 alert certificate required')
2520-
except OSError:
2521-
if self.server.chatty:
2522-
handle_error("Test server failure:\n")
2504+
if isinstance(e, ConnectionError):
2505+
# OpenSSL 1.1.1 sometimes raises
2506+
# ConnectionResetError when connection is not
2507+
# shut down gracefully.
2508+
print(
2509+
f" Connection reset by peer: {self.addr}"
2510+
)
2511+
else:
2512+
handle_error("Test server failure:\n")
2513+
try:
2514+
self.write(b"ERROR\n")
2515+
except OSError:
2516+
pass
25232517
self.close()
25242518
self.running = False
25252519

@@ -4502,24 +4496,30 @@ def test_pha_required_nocert(self):
45024496
server_context.verify_mode = ssl.CERT_REQUIRED
45034497
client_context.post_handshake_auth = True
45044498

4505-
# Ignore expected SSLError in ConnectionHandler of ThreadedEchoServer
4506-
# (it is only raised sometimes on Windows)
4507-
with support.catch_threading_exception() as cm:
4508-
server = ThreadedEchoServer(context=server_context, chatty=False)
4509-
with server:
4510-
with client_context.wrap_socket(socket.socket(),
4511-
server_hostname=hostname) as s:
4512-
s.connect((HOST, server.port))
4513-
s.write(b'PHA')
4499+
def msg_cb(conn, direction, version, content_type, msg_type, data):
4500+
if support.verbose and content_type == _TLSContentType.ALERT:
4501+
info = (conn, direction, version, content_type, msg_type, data)
4502+
sys.stdout.write(f"TLS: {info!r}\n")
4503+
4504+
server_context._msg_callback = msg_cb
4505+
client_context._msg_callback = msg_cb
4506+
4507+
server = ThreadedEchoServer(context=server_context, chatty=True)
4508+
with server:
4509+
with client_context.wrap_socket(socket.socket(),
4510+
server_hostname=hostname) as s:
4511+
s.connect((HOST, server.port))
4512+
s.write(b'PHA')
4513+
with self.assertRaisesRegex(
4514+
ssl.SSLError,
4515+
'tlsv13 alert certificate required'
4516+
):
45144517
# receive CertificateRequest
45154518
self.assertEqual(s.recv(1024), b'OK\n')
45164519
# send empty Certificate + Finish
45174520
s.write(b'HASCERT')
45184521
# receive alert
4519-
with self.assertRaisesRegex(
4520-
ssl.SSLError,
4521-
'tlsv13 alert certificate required'):
4522-
s.recv(1024)
4522+
s.recv(1024)
45234523

45244524
def test_pha_optional(self):
45254525
if support.verbose:

Tools/ssl/multissltests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050

5151
OPENSSL_RECENT_VERSIONS = [
5252
"1.1.1k",
53-
# "3.0.0-alpha14"
53+
# "3.0.0-alpha15"
5454
]
5555

5656
LIBRESSL_OLD_VERSIONS = [

0 commit comments

Comments
 (0)