From 931ebd60b9fc111152970fd67c6e8548227302e4 Mon Sep 17 00:00:00 2001 From: kenneth topp Date: Sat, 24 Sep 2022 17:03:44 -0400 Subject: [PATCH] Simplify SSL socket exceptions in builtin Currently, sockets with SSL exceptions are discarded, except for http-over-https where we send back an http error response. For a subset of those exceptions we silient discard them, and for others we will print out the stack trace. This patch updates the code to silient discard all exceptions unless it is the http-over-https case. --- cheroot/ssl/builtin.py | 60 +++++------------------------------------- stubtest_allowlist.txt | 1 - 2 files changed, 6 insertions(+), 55 deletions(-) diff --git a/cheroot/ssl/builtin.py b/cheroot/ssl/builtin.py index 0e1d4424f6..3e15e02d99 100644 --- a/cheroot/ssl/builtin.py +++ b/cheroot/ssl/builtin.py @@ -27,7 +27,6 @@ from . import Adapter from .. import errors -from .._compat import IS_ABOVE_OPENSSL10 from ..makefile import StreamReader, StreamWriter from ..server import HTTPServer @@ -270,63 +269,16 @@ def wrap(self, sock): s = self.context.wrap_socket( sock, do_handshake_on_connect=True, server_side=True, ) - except ssl.SSLZeroReturnError: - # This is almost certainly due to the cherrypy engine - # 'pinging' the socket to assert it's connectable; - # the 'ping' isn't SSL. - return EMPTY_RESULT except ssl.SSLError as ex: - if ex.errno == ssl.SSL_ERROR_EOF: - # This is almost certainly due to the cherrypy engine - # 'pinging' the socket to assert it's connectable; - # the 'ping' isn't SSL. - return EMPTY_RESULT - elif ex.errno == ssl.SSL_ERROR_SSL: + if ex.errno == ssl.SSL_ERROR_SSL: if _assert_ssl_exc_contains(ex, 'http request'): # The client is speaking HTTP to an HTTPS server. raise errors.NoSSLError - - # Check if it's one of the known errors - # Errors that are caught by PyOpenSSL, but thrown by - # built-in ssl - _block_errors = ( - 'unknown protocol', 'unknown ca', 'unknown_ca', - 'unknown error', - 'https proxy request', 'inappropriate fallback', - 'wrong version number', - 'no shared cipher', 'certificate unknown', - 'ccs received early', - 'certificate verify failed', # client cert w/o trusted CA - 'version too low', # caused by SSL3 connections - 'unsupported protocol', # caused by TLS1 connections - ) - if _assert_ssl_exc_contains(ex, *_block_errors): - # Accepted error, let's pass - return EMPTY_RESULT - elif _assert_ssl_exc_contains(ex, 'handshake operation timed out'): - # This error is thrown by builtin SSL after a timeout - # when client is speaking HTTP to an HTTPS server. - # The connection can safely be dropped. - return EMPTY_RESULT - raise - except generic_socket_error as exc: - """It is unclear why exactly this happens. - - It's reproducible only with openssl>1.0 and stdlib - :py:mod:`ssl` wrapper. - In CherryPy it's triggered by Checker plugin, which connects - to the app listening to the socket port in TLS mode via plain - HTTP during startup (from the same process). - - - Ref: https://github.com/cherrypy/cherrypy/issues/1618 - """ - is_error0 = exc.args == (0, 'Error') - - if is_error0 and IS_ABOVE_OPENSSL10: - return EMPTY_RESULT - raise - return s, self.get_environ(s) + except generic_socket_error: + pass + else: + return s, self.get_environ(s) + return EMPTY_RESULT def get_environ(self, sock): """Create WSGI environ entries to be merged into each request.""" diff --git a/stubtest_allowlist.txt b/stubtest_allowlist.txt index ddc832bf44..89ca49bde0 100644 --- a/stubtest_allowlist.txt +++ b/stubtest_allowlist.txt @@ -37,7 +37,6 @@ cheroot.ssl.pyopenssl.SSLConnection.write # false positives (https://github.com/python/mypy/issues/11843) cheroot.connections.IS_WINDOWS -cheroot.ssl.builtin.IS_ABOVE_OPENSSL10 # suppress is both a function and class cheroot._compat.suppress