From f47dea745297d56d3c9143e4343b6a31929137d7 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 +++++------------------------------------- 1 file changed, 6 insertions(+), 54 deletions(-) diff --git a/cheroot/ssl/builtin.py b/cheroot/ssl/builtin.py index 29864cabbc..2501f2e3db 100644 --- a/cheroot/ssl/builtin.py +++ b/cheroot/ssl/builtin.py @@ -272,68 +272,20 @@ def bind(self, sock): def wrap(self, sock): """Wrap and return the given socket, plus WSGI environ entries.""" - EMPTY_RESULT = None, {} try: 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 + return s, self.get_environ(s) 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, ssl.SSLZeroReturnError): + pass + # empty result + return None, {} def get_environ(self, sock): """Create WSGI environ entries to be merged into each request."""