]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream, global: Change ssl_iostream_handshake_callback_t to return enum
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 8 Aug 2025 11:35:21 +0000 (14:35 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 11 Aug 2025 07:47:35 +0000 (07:47 +0000)
The enum gives more details what failed.

src/lib-http/http-client-connection.c
src/lib-imap-client/imapc-connection.c
src/lib-smtp/smtp-client-connection.c
src/lib-ssl-iostream/iostream-openssl.c
src/lib-ssl-iostream/iostream-ssl.h
src/lib-storage/index/pop3c/pop3c-client.c

index fa286209bee8588148e32500f0cb129e51737078..9dbd569399d41e6a2b77841a695a81492cec8b52 100644 (file)
@@ -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
index 7a51c754b12011808cd58026cd180414879ae37f..590e4c5fac8e6cb5c4e4d14294512425fda1accd 100644 (file)
@@ -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)
index 451c71f7c95562059b5f1e6a92666d36d1c21073..7451dfff8a2e699c3d6dacfd77325d6bfdcf26f1 100644 (file)
@@ -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
index e7030581e972500e30d99f8da5c6677e6c34baab..8e04006c743d2ddac5d1c91afd20c707c31ba7f1 100644 (file)
@@ -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;
index 5b2648ddb0d1e12b6aa62ba429403c5deb1891d7..c9d9357416730b88ab8fe62643354cd5ff04f924 100644 (file)
@@ -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,
index 67188ebe3190013bdf6ede1b721338271b3b94a5..244ba19b704a7eb9cd8ede471ac1c430b31a747b 100644 (file)
@@ -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)