]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream, global: ssl_iostream_check_cert_validity() - Change return value...
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 8 Aug 2025 11:27:20 +0000 (14:27 +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.c
src/lib-ssl-iostream/iostream-ssl.h
src/lib-ssl-iostream/test-iostream-ssl.c
src/lib-storage/index/pop3c/pop3c-client.c

index c71a8290e9a080b174846df19cfd79e2f35829b8..fa286209bee8588148e32500f0cb129e51737078 100644 (file)
@@ -1392,7 +1392,7 @@ http_client_connection_ssl_handshaked(const char **error_r, void *context)
        const char *error, *host = pshared->addr.a.tcp.https_name;
 
        if (ssl_iostream_check_cert_validity(conn->ssl_iostream,
-                                            host, &error) == 0)
+                                            host, &error) == 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, "
index b88b00395ca855d34b78db47051e4515a37011ac..7a51c754b12011808cd58026cd180414879ae37f 100644 (file)
@@ -1717,7 +1717,8 @@ static int imapc_connection_ssl_handshaked(const char **error_r, void *context)
        const char *error;
 
        if (ssl_iostream_check_cert_validity(conn->ssl_iostream,
-                                            conn->client->set->imapc_host, &error) == 0) {
+                                            conn->client->set->imapc_host,
+                                            &error) == 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)) {
index 87694357562024255d40375674e800bdcfad744f..451c71f7c95562059b5f1e6a92666d36d1c21073 100644 (file)
@@ -1534,7 +1534,7 @@ smtp_client_connection_ssl_handshaked(const char **error_r, void *context)
        const char *error, *host = conn->host;
 
        if (ssl_iostream_check_cert_validity(conn->ssl_iostream,
-                                            host, &error) == 0) {
+                                            host, &error) == 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, "
index b0e7e7baa9662fa0e60848d1cf8722e18a10aee7..e7030581e972500e30d99f8da5c6677e6c34baab 100644 (file)
@@ -625,7 +625,8 @@ static int openssl_iostream_handshake(struct ssl_iostream *ssl_io)
                }
        } else if (ssl_io->connected_host != NULL && !ssl_io->handshake_failed &&
                  !ssl_io->allow_invalid_cert) {
-               if (ssl_iostream_check_cert_validity(ssl_io, ssl_io->connected_host, &reason) < 0) {
+               if (ssl_iostream_check_cert_validity(ssl_io, ssl_io->connected_host,
+                                                    &reason) != SSL_IOSTREAM_CERT_VALIDITY_OK) {
                        openssl_iostream_set_error(ssl_io, reason);
                        ssl_io->handshake_failed = TRUE;
                }
index e3651e809c66052f2fdbf29a2b16edaa3b84ba90..58f9de3011b6a4b882ca35a291044da6a5ee2f9f 100644 (file)
@@ -284,27 +284,29 @@ bool ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io, const char *name,
        return ssl_vfuncs->cert_match_name(ssl_io, name, reason_r);
 }
 
-int ssl_iostream_check_cert_validity(struct ssl_iostream *ssl_io,
-                                    const char *host, const char **error_r)
+enum ssl_iostream_cert_validity
+ssl_iostream_check_cert_validity(struct ssl_iostream *ssl_io,
+                                const char *host, const char **error_r)
 {
        const char *reason;
 
        if (!ssl_iostream_has_valid_client_cert(ssl_io)) {
-               if (!ssl_iostream_has_client_cert(ssl_io))
+               if (!ssl_iostream_has_client_cert(ssl_io)) {
                        *error_r = "SSL certificate not received";
-               else {
+                       return SSL_IOSTREAM_CERT_VALIDITY_NO_CERT;
+               } else {
                        *error_r = t_strdup(ssl_iostream_get_last_error(ssl_io));
                        if (*error_r == NULL)
                                *error_r = "Received invalid SSL certificate";
+                       return SSL_IOSTREAM_CERT_VALIDITY_INVALID;
                }
-               return -1;
        } else if (!ssl_iostream_cert_match_name(ssl_io, host, &reason)) {
                *error_r = t_strdup_printf(
                        "SSL certificate doesn't match expected host name %s: %s",
                        host, reason);
-               return -1;
+               return SSL_IOSTREAM_CERT_VALIDITY_NAME_MISMATCH;
        }
-       return 0;
+       return SSL_IOSTREAM_CERT_VALIDITY_OK;
 }
 
 bool ssl_iostream_get_allow_invalid_cert(struct ssl_iostream *ssl_io)
index 5c964d6f6a13d0e3387939254fdb04207fd667d0..5b2648ddb0d1e12b6aa62ba429403c5deb1891d7 100644 (file)
@@ -38,6 +38,17 @@ enum ssl_iostream_flags {
        SSL_IOSTREAM_FLAG_DISABLE_CA_FILES = BIT(1),
 };
 
+enum ssl_iostream_cert_validity {
+       /* SSL certificate is valid. */
+       SSL_IOSTREAM_CERT_VALIDITY_OK,
+       /* SSL certificate has not been received. */
+       SSL_IOSTREAM_CERT_VALIDITY_NO_CERT,
+       /* SSL certificate is invalid/untrusted. */
+       SSL_IOSTREAM_CERT_VALIDITY_INVALID,
+       /* SSL certificate is valid, but it doesn't match the name. */
+       SSL_IOSTREAM_CERT_VALIDITY_NAME_MISMATCH,
+};
+
 struct ssl_iostream_cert {
        struct settings_file cert;
        struct settings_file key;
@@ -189,8 +200,9 @@ bool ssl_iostream_has_client_cert(struct ssl_iostream *ssl_io);
    This function is same as calling ssl_iostream_has_valid_client_cert()
    and ssl_iostream_cert_match_name().
  */
-int ssl_iostream_check_cert_validity(struct ssl_iostream *ssl_io,
-                                    const char *host, const char **error_r);
+enum ssl_iostream_cert_validity
+ssl_iostream_check_cert_validity(struct ssl_iostream *ssl_io,
+                                const char *host, const char **error_r);
 /* Returns TRUE if the given name matches the SSL stream's certificate.
    The returned reason is a human-readable string explaining what exactly
    matched the name, or why nothing matched. Note that this function works
index a9cf6d469749de3e796081a427cdb6a6c76af335..e2e20d092279443e9492e6d99972099c2fb31f7d 100644 (file)
@@ -249,12 +249,13 @@ static int test_iostream_ssl_handshake_real(struct ssl_iostream_settings *server
        } else if (client->hostname != NULL &&
            !client->set->allow_invalid_cert &&
            ssl_iostream_check_cert_validity(client->iostream, client->hostname,
-                                            &error) != 0) {
+                                            &error) != SSL_IOSTREAM_CERT_VALIDITY_OK) {
                i_error("client(%s): %s", client->hostname, error);
                ret = -1;
        /* client cert */
        } else if (server->set->verify_remote_cert &&
-           ssl_iostream_check_cert_validity(server->iostream, NULL, &error) != 0) {
+                  ssl_iostream_check_cert_validity(server->iostream, NULL,
+                                                   &error) != SSL_IOSTREAM_CERT_VALIDITY_OK) {
                i_error("server: %s", error);
                ret = -1;
        }
index be75dea3035caaf7b44fdde6e3eb065d00872d72..67188ebe3190013bdf6ede1b721338271b3b94a5 100644 (file)
@@ -515,7 +515,7 @@ static int pop3c_client_ssl_handshaked(const char **error_r, void *context)
        const char *error;
 
        if (ssl_iostream_check_cert_validity(client->ssl_iostream,
-                                            client->set.host, &error) == 0) {
+                                            client->set.host, &error) == 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)) {