From: Timo Sirainen Date: Fri, 8 Aug 2025 11:35:21 +0000 (+0300) Subject: lib-ssl-iostream, global: Change ssl_iostream_handshake_callback_t to return enum X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0ce17a00dd1efca518d78a67f1214c794bcfed8f;p=thirdparty%2Fdovecot%2Fcore.git lib-ssl-iostream, global: Change ssl_iostream_handshake_callback_t to return enum The enum gives more details what failed. --- diff --git a/src/lib-http/http-client-connection.c b/src/lib-http/http-client-connection.c index fa286209be..9dbd569399 100644 --- a/src/lib-http/http-client-connection.c +++ b/src/lib-http/http-client-connection.c @@ -1384,24 +1384,27 @@ static void http_client_connection_ready(struct http_client_connection *conn) http_client_connection_output, conn); } -static int +static enum ssl_iostream_state http_client_connection_ssl_handshaked(const char **error_r, void *context) { struct http_client_connection *conn = context; struct http_client_peer_shared *pshared = conn->ppool->peer; const char *error, *host = pshared->addr.a.tcp.https_name; + enum ssl_iostream_cert_validity validity = + ssl_iostream_check_cert_validity(conn->ssl_iostream, host, &error); - if (ssl_iostream_check_cert_validity(conn->ssl_iostream, - host, &error) == SSL_IOSTREAM_CERT_VALIDITY_OK) + if (validity == SSL_IOSTREAM_CERT_VALIDITY_OK) e_debug(conn->event, "SSL handshake successful"); else if (ssl_iostream_get_allow_invalid_cert(conn->ssl_iostream)) { e_debug(conn->event, "SSL handshake successful, " "ignoring invalid certificate: %s", error); } else { *error_r = error; - return -1; + return validity == SSL_IOSTREAM_CERT_VALIDITY_NAME_MISMATCH ? + SSL_IOSTREAM_STATE_NAME_MISMATCH : + SSL_IOSTREAM_STATE_INVALID_CERT; } - return 0; + return SSL_IOSTREAM_STATE_OK; } static int diff --git a/src/lib-imap-client/imapc-connection.c b/src/lib-imap-client/imapc-connection.c index 7a51c754b1..590e4c5fac 100644 --- a/src/lib-imap-client/imapc-connection.c +++ b/src/lib-imap-client/imapc-connection.c @@ -1711,24 +1711,27 @@ static void imapc_connection_input(struct imapc_connection *conn) imapc_connection_unref(&conn); } -static int imapc_connection_ssl_handshaked(const char **error_r, void *context) +static enum ssl_iostream_state +imapc_connection_ssl_handshaked(const char **error_r, void *context) { struct imapc_connection *conn = context; const char *error; + enum ssl_iostream_cert_validity validity = + ssl_iostream_check_cert_validity(conn->ssl_iostream, + conn->client->set->imapc_host, &error); - if (ssl_iostream_check_cert_validity(conn->ssl_iostream, - conn->client->set->imapc_host, - &error) == SSL_IOSTREAM_CERT_VALIDITY_OK) { + if (validity == SSL_IOSTREAM_CERT_VALIDITY_OK) e_debug(conn->event, "SSL handshake successful"); - return 0; - } else if (ssl_iostream_get_allow_invalid_cert(conn->ssl_iostream)) { + else if (ssl_iostream_get_allow_invalid_cert(conn->ssl_iostream)) { e_debug(conn->event, "SSL handshake successful, " "ignoring invalid certificate: %s", error); - return 0; } else { *error_r = error; - return -1; + return validity == SSL_IOSTREAM_CERT_VALIDITY_NAME_MISMATCH ? + SSL_IOSTREAM_STATE_NAME_MISMATCH : + SSL_IOSTREAM_STATE_INVALID_CERT; } + return SSL_IOSTREAM_STATE_OK; } static int imapc_connection_ssl_init(struct imapc_connection *conn) diff --git a/src/lib-smtp/smtp-client-connection.c b/src/lib-smtp/smtp-client-connection.c index 451c71f7c9..7451dfff8a 100644 --- a/src/lib-smtp/smtp-client-connection.c +++ b/src/lib-smtp/smtp-client-connection.c @@ -1527,23 +1527,26 @@ smtp_client_connection_established(struct smtp_client_connection *conn) smtp_client_connection_output, conn); } -static int +static enum ssl_iostream_state smtp_client_connection_ssl_handshaked(const char **error_r, void *context) { struct smtp_client_connection *conn = context; const char *error, *host = conn->host; + enum ssl_iostream_cert_validity validity = + ssl_iostream_check_cert_validity(conn->ssl_iostream, host, &error); - if (ssl_iostream_check_cert_validity(conn->ssl_iostream, - host, &error) == SSL_IOSTREAM_CERT_VALIDITY_OK) { + if (validity == SSL_IOSTREAM_CERT_VALIDITY_OK) { e_debug(conn->event, "SSL handshake successful"); } else if (ssl_iostream_get_allow_invalid_cert(conn->ssl_iostream)) { e_debug(conn->event, "SSL handshake successful, " "ignoring invalid certificate: %s", error); } else { *error_r = error; - return -1; + return validity == SSL_IOSTREAM_CERT_VALIDITY_NAME_MISMATCH ? + SSL_IOSTREAM_STATE_NAME_MISMATCH : + SSL_IOSTREAM_STATE_INVALID_CERT; } - return 0; + return SSL_IOSTREAM_STATE_OK; } static void diff --git a/src/lib-ssl-iostream/iostream-openssl.c b/src/lib-ssl-iostream/iostream-openssl.c index e7030581e9..8e04006c74 100644 --- a/src/lib-ssl-iostream/iostream-openssl.c +++ b/src/lib-ssl-iostream/iostream-openssl.c @@ -618,7 +618,7 @@ static int openssl_iostream_handshake(struct ssl_iostream *ssl_io) (void)openssl_iostream_bio_sync(ssl_io, OPENSSL_IOSTREAM_SYNC_TYPE_HANDSHAKE); if (ssl_io->handshake_callback != NULL) { - if (ssl_io->handshake_callback(&error, ssl_io->handshake_context) < 0) { + if (ssl_io->handshake_callback(&error, ssl_io->handshake_context) != SSL_IOSTREAM_STATE_OK) { i_assert(error != NULL); openssl_iostream_set_error(ssl_io, error); ssl_io->handshake_failed = TRUE; diff --git a/src/lib-ssl-iostream/iostream-ssl.h b/src/lib-ssl-iostream/iostream-ssl.h index 5b2648ddb0..c9d9357416 100644 --- a/src/lib-ssl-iostream/iostream-ssl.h +++ b/src/lib-ssl-iostream/iostream-ssl.h @@ -49,6 +49,15 @@ enum ssl_iostream_cert_validity { SSL_IOSTREAM_CERT_VALIDITY_NAME_MISMATCH, }; +enum ssl_iostream_state { + /* Handshake is finished and successful. */ + SSL_IOSTREAM_STATE_OK, + /* SSL certificate is missing/invalid/untrusted. */ + SSL_IOSTREAM_STATE_INVALID_CERT, + /* SSL certificate is valid, but it doesn't match the name. */ + SSL_IOSTREAM_STATE_NAME_MISMATCH, +}; + struct ssl_iostream_cert { struct settings_file cert; struct settings_file key; @@ -100,10 +109,11 @@ struct ssl_iostream_settings { /* Load SSL module */ int ssl_module_load(const char **error_r); -/* Returns 0 if ok, -1 and sets error_r if failed. The returned error string - becomes available via ssl_iostream_get_last_error(). The callback most - likely should be calling ssl_iostream_check_cert_validity(). */ -typedef int +/* If returned state is not SSL_IOSTREAM_STATE_OK, error_r is also returned. + The returned error string becomes available via + ssl_iostream_get_last_error(). The callback most likely should be calling + ssl_iostream_check_cert_validity(). */ +typedef enum ssl_iostream_state ssl_iostream_handshake_callback_t(const char **error_r, void *context); /* Called when TLS SNI becomes available. */ typedef int ssl_iostream_sni_callback_t(const char *name, const char **error_r, diff --git a/src/lib-storage/index/pop3c/pop3c-client.c b/src/lib-storage/index/pop3c/pop3c-client.c index 67188ebe31..244ba19b70 100644 --- a/src/lib-storage/index/pop3c/pop3c-client.c +++ b/src/lib-storage/index/pop3c/pop3c-client.c @@ -509,25 +509,29 @@ static void pop3c_client_prelogin_input(struct pop3c_client *client) } } -static int pop3c_client_ssl_handshaked(const char **error_r, void *context) +static enum ssl_iostream_state +pop3c_client_ssl_handshaked(const char **error_r, void *context) { struct pop3c_client *client = context; const char *error; + enum ssl_iostream_cert_validity validity = + ssl_iostream_check_cert_validity(client->ssl_iostream, + client->set.host, &error); - if (ssl_iostream_check_cert_validity(client->ssl_iostream, - client->set.host, &error) == SSL_IOSTREAM_CERT_VALIDITY_OK) { + if (validity == SSL_IOSTREAM_CERT_VALIDITY_OK) e_debug(client->event, "SSL handshake successful"); - return 0; - } else if (ssl_iostream_get_allow_invalid_cert(client->ssl_iostream)) { + else if (ssl_iostream_get_allow_invalid_cert(client->ssl_iostream)) { e_debug(client->event, "SSL handshake successful, " "ignoring invalid certificate: %s", error); - return 0; } else { *error_r = error; - return -1; + return validity == SSL_IOSTREAM_CERT_VALIDITY_NAME_MISMATCH ? + SSL_IOSTREAM_STATE_NAME_MISMATCH : + SSL_IOSTREAM_STATE_INVALID_CERT; } + return SSL_IOSTREAM_STATE_OK; } static int pop3c_client_ssl_init(struct pop3c_client *client)