From: Timo Sirainen Date: Mon, 25 Nov 2024 13:07:10 +0000 (+0200) Subject: lib-ssl-iostream: Hide useless errors when a better one is available X-Git-Tag: 2.4.1~457 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=88031644eeb4a3417381bc2d6b07c5c3be6be083;p=thirdparty%2Fdovecot%2Fcore.git lib-ssl-iostream: Hide useless errors when a better one is available For example remove "SSL_accept() syscall failed: Invalid argument+" when it happens together with a more exact reason why the handshake fails. --- diff --git a/src/lib-ssl-iostream/iostream-openssl.c b/src/lib-ssl-iostream/iostream-openssl.c index 2f67a8a7ea..55d85a1dee 100644 --- a/src/lib-ssl-iostream/iostream-openssl.c +++ b/src/lib-ssl-iostream/iostream-openssl.c @@ -24,7 +24,9 @@ static struct event_category event_category_ssl_server = { static void openssl_iostream_free(struct ssl_iostream *ssl_io); -void openssl_iostream_set_error(struct ssl_iostream *ssl_io, const char *str) +static void +openssl_iostream_set_error_full(struct ssl_iostream *ssl_io, + const char *str, bool fallback_error) { char *new_str; @@ -39,6 +41,12 @@ void openssl_iostream_set_error(struct ssl_iostream *ssl_io, const char *str) e_debug(ssl_io->event, "SSL error: %s", new_str); i_free(ssl_io->last_error); ssl_io->last_error = new_str; + ssl_io->last_error_is_fallback = fallback_error; +} + +void openssl_iostream_set_error(struct ssl_iostream *ssl_io, const char *str) +{ + openssl_iostream_set_error_full(ssl_io, str, FALSE); } static void openssl_info_callback(const SSL *ssl, int where, int ret) @@ -473,6 +481,7 @@ int openssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret, const char *func_name) { const char *errstr = NULL; + bool fallback_error = FALSE; int err; err = SSL_get_error(ssl_io->ssl, ret); @@ -514,10 +523,12 @@ int openssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret, break; } else if (errno != 0) { errstr = strerror(errno); + fallback_error = TRUE; } else { /* Seen this at least with v1.1.0l SSL_accept() */ errstr = "OpenSSL BUG: errno=0"; errno = EINVAL; + fallback_error = TRUE; } errstr = t_strdup_printf("%s syscall failed: %s", func_name, errstr); @@ -545,9 +556,15 @@ int openssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret, break; } - if (ssl_io->last_error != NULL) + if (ssl_io->last_error != NULL && !ssl_io->last_error_is_fallback) { + if (fallback_error) { + /* We already have an error, and this new one doesn't + provide anything useful over it. Ignore it. */ + return -1; + } errstr = t_strdup_printf("%s+%s", errstr, ssl_io->last_error); - openssl_iostream_set_error(ssl_io, errstr); + } + openssl_iostream_set_error_full(ssl_io, errstr, fallback_error); return -1; } diff --git a/src/lib-ssl-iostream/iostream-openssl.h b/src/lib-ssl-iostream/iostream-openssl.h index 2a7e9648c4..7ee58734e7 100644 --- a/src/lib-ssl-iostream/iostream-openssl.h +++ b/src/lib-ssl-iostream/iostream-openssl.h @@ -69,6 +69,9 @@ struct ssl_iostream { bool cert_received:1; bool cert_broken:1; bool want_read:1; + /* last_error is a "fallback error", which is used only if another + error won't show up. */ + bool last_error_is_fallback:1; bool ostream_flush_waiting_input:1; bool closed:1; bool destroyed:1;