]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream, global: Convert ssl_[alt_]cert setting to ssl_[alt_]cert_file
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 1 Feb 2024 12:19:12 +0000 (14:19 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:11 +0000 (12:34 +0200)
14 files changed:
src/config/old-set-parser.c
src/lib-doveadm/Makefile.am
src/lib-ldap/ldap-connection.c
src/lib-smtp/test-smtp-payload.c
src/lib-ssl-iostream/iostream-openssl-common.c
src/lib-ssl-iostream/iostream-openssl-context.c
src/lib-ssl-iostream/iostream-openssl.h
src/lib-ssl-iostream/iostream-ssl-context-cache.c
src/lib-ssl-iostream/iostream-ssl-test.c
src/lib-ssl-iostream/iostream-ssl.c
src/lib-ssl-iostream/iostream-ssl.h
src/lib-ssl-iostream/ssl-settings.c
src/lib-ssl-iostream/ssl-settings.h
src/lib-ssl-iostream/test-iostream-ssl.c

index 45bb50a9dde4a1e1d7b1616f3390c9f844d6854d..45c856f0c392217967b1aace4635eccea1481d3c 100644 (file)
@@ -211,8 +211,7 @@ old_settings_handle_root(struct config_parser_context *ctx,
                old_set_parser_apply(ctx, CONFIG_LINE_TYPE_KEYVALUE, key, value);
                return TRUE;
        }
-       if (strcmp(key, "ssl_cert_file") == 0 ||
-           strcmp(key, "ssl_key_file") == 0 ||
+       if (strcmp(key, "ssl_key_file") == 0 ||
            strcmp(key, "ssl_ca_file") == 0) {
                if (*value == '\0')
                        return TRUE;
index 91b0c166452aa89721a868337b12dfe5cbe7a8b9..4dd4e43d15d014a1427cdb3cb1146273b64893aa 100644 (file)
@@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libdoveadm.la
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
+       -I$(top_srcdir)/src/lib-settings \
        -I$(top_srcdir)/src/lib-auth-client \
        -I$(top_srcdir)/src/lib-dns \
        -I$(top_srcdir)/src/lib-mail \
index 9decdac638d8aadff11cb03b0087d6ba2f124ef3..a4b81b3ca15e0f02baee406a7822358c7e95c796 100644 (file)
@@ -76,8 +76,8 @@ int ldap_connection_setup(struct ldap_connection *conn, const char **error_r)
                ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CACERTDIR, conn->ssl_set.ca_dir);
 
 #ifdef LDAP_OPT_X_TLS_CERT
-       if (conn->ssl_set.cert.cert != NULL)
-               ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CERT, conn->ssl_set.cert.cert);
+       if (conn->ssl_set.cert.cert.content != NULL)
+               ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CERT, conn->ssl_set.cert.cert.content);
        if (conn->ssl_set.cert.key != NULL)
                ldap_set_option(conn->conn, LDAP_OPT_X_TLS_KEYFILE, conn->ssl_set.cert.key);
 #endif
@@ -137,7 +137,8 @@ bool ldap_connection_have_settings(struct ldap_connection *conn,
                return FALSE;
        if (null_strcmp(conn->ssl_set.ca_file, set->ssl_set->ca_file) != 0)
                return FALSE;
-       if (null_strcmp(conn->ssl_set.cert.cert, set->ssl_set->cert.cert) != 0)
+       if (null_strcmp(conn->ssl_set.cert.cert.content,
+                       set->ssl_set->cert.cert.content) != 0)
                return FALSE;
        if (null_strcmp(conn->ssl_set.cert.key, set->ssl_set->cert.key) != 0)
                return FALSE;
@@ -184,7 +185,10 @@ int ldap_connection_init(struct ldap_client *client,
                conn->ssl_set.min_protocol = p_strdup(pool, set->ssl_set->min_protocol);
                conn->ssl_set.cipher_list = p_strdup(pool, set->ssl_set->cipher_list);
                conn->ssl_set.ca_file = p_strdup(pool, set->ssl_set->ca_file);
-               conn->ssl_set.cert.cert = p_strdup(pool, set->ssl_set->cert.cert);
+               conn->ssl_set.cert.cert.path =
+                       p_strdup(pool, set->ssl_set->cert.cert.path);
+               conn->ssl_set.cert.cert.content =
+                       p_strdup(pool, set->ssl_set->cert.cert.content);
                conn->ssl_set.cert.key = p_strdup(pool, set->ssl_set->cert.key);
        }
        i_assert(ldap_connection_have_settings(conn, set));
index 23d7d6710ce1730f649fbbed73e8b54573259d6f..3a1d489f9ec0cb361ba3acd6d4ba3cb4cd45f804 100644 (file)
@@ -936,7 +936,8 @@ test_run_client_server(
           relevant settings. */
        const char *const settings[] = {
                "ssl_ca", server_set->ssl->ca,
-               "ssl_cert", server_set->ssl->cert.cert,
+               "ssl_cert_file", settings_file_get_value(unsafe_data_stack_pool,
+                                                        &server_set->ssl->cert.cert),
                "ssl_key", server_set->ssl->cert.key,
                NULL,
        };
index edf58d1bae5991229ef480c60461a3a97003f517..98474af8c3ebf129d2be57285541acaa15bbcb69 100644 (file)
@@ -161,7 +161,7 @@ const char *openssl_iostream_key_load_error(void)
 
        if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
            ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH)
-               return "Key is for a different cert than ssl_cert";
+               return "Key is for a different cert than ssl_cert_file";
        else
                return openssl_iostream_error();
 }
@@ -171,8 +171,7 @@ static bool is_pem_key(const char *cert)
        return strstr(cert, "PRIVATE KEY---") != NULL;
 }
 
-const char *
-openssl_iostream_use_certificate_error(const char *cert, const char *set_name)
+const char *openssl_iostream_use_certificate_error(const char *cert)
 {
        unsigned long err;
 
@@ -185,10 +184,7 @@ openssl_iostream_use_certificate_error(const char *cert, const char *set_name)
                return openssl_iostream_error();
        else if (is_pem_key(cert)) {
                return "The file contains a private key "
-                       "(you've mixed ssl_cert and ssl_key settings)";
-       } else if (set_name != NULL && strchr(cert, '\n') == NULL) {
-               return t_strdup_printf("There is no valid PEM certificate. "
-                       "(You probably forgot '<' from %s=<%s)", set_name, cert);
+                       "(you've mixed ssl_cert_file and ssl_key settings)";
        } else {
                return "There is no valid PEM certificate.";
        }
index d1c28748a8798e3e92800b3bad3b8db1bb396aad..4ffac088f57790009f2727dc799a1b112a86b373 100644 (file)
@@ -594,25 +594,26 @@ ssl_iostream_context_set(struct ssl_iostream_context *ctx,
        }
 
        /* Client can ignore an empty ssl_client_cert, but server will fail
-          if ssl_cert is empty. */
-       if (set->cert.cert != NULL &&
-           (set->cert.cert[0] != '\0' || !ctx->client_ctx) &&
-           ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert.cert) == 0) {
+          if ssl_cert_file is empty. */
+       if (set->cert.cert.content != NULL &&
+           (set->cert.cert.content[0] != '\0' || !ctx->client_ctx) &&
+           ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert.cert.content) == 0) {
                *error_r = t_strdup_printf(
-                       "Can't load SSL certificate (ssl_cert setting): %s",
-                       openssl_iostream_use_certificate_error(set->cert.cert, NULL));
+                       "Can't load SSL certificate (ssl_cert_file setting): %s",
+                       openssl_iostream_use_certificate_error(set->cert.cert.content));
                return -1;
        }
        if (set->cert.key != NULL && set->cert.key[0] != '\0') {
                if (ssl_iostream_ctx_use_key(ctx, "ssl_key", &set->cert, error_r) < 0)
                        return -1;
        }
-       if (set->alt_cert.cert != NULL && set->alt_cert.cert[0] != '\0' &&
-           ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->alt_cert.cert) == 0) {
+       if (set->alt_cert.cert.content != NULL &&
+           set->alt_cert.cert.content[0] != '\0' &&
+           ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->alt_cert.cert.content) == 0) {
                *error_r = t_strdup_printf(
                        "Can't load alternative SSL certificate "
-                       "(ssl_alt_cert setting): %s",
-                       openssl_iostream_use_certificate_error(set->alt_cert.cert, NULL));
+                       "(ssl_alt_cert_file setting): %s",
+                       openssl_iostream_use_certificate_error(set->alt_cert.cert.content));
                return -1;
        }
        if (set->alt_cert.key != NULL && set->alt_cert.key[0] != '\0') {
index 5eb9eb7bdc8954baacefffb3a0f9d99e4aaf6206..4dbc51a71cfa5a5947d41fd357ac3c1a0db2a6c4 100644 (file)
@@ -120,7 +120,7 @@ void openssl_iostream_set_error(struct ssl_iostream *ssl_io, const char *str);
 const char *openssl_iostream_error(void);
 const char *openssl_iostream_key_load_error(void);
 const char *
-openssl_iostream_use_certificate_error(const char *cert, const char *set_name);
+openssl_iostream_use_certificate_error(const char *cert);
 void openssl_iostream_clear_errors(void);
 
 void ssl_iostream_openssl_init(void);
index bcb666ec0d0485550a07ff6a08fae38c301aa0e7..033cc769726494ddebd8e073289000a2c5444380 100644 (file)
@@ -18,7 +18,10 @@ static unsigned int
 ssl_iostream_context_cache_hash(const struct ssl_iostream_context_cache *cache)
 {
        unsigned int n, i, g, h = 0;
-       const char *const cert[] = { cache->set->cert.cert, cache->set->alt_cert.cert };
+       const char *const cert[] = {
+               cache->set->cert.cert.content,
+               cache->set->alt_cert.cert.content
+       };
 
        /* checking for different certs is typically good enough,
           and it should be enough to check only the first few bytes (after the
index 87b2b5890689d3f503af17571b6780e50cfdf54d..2e697be1949b490300be3f39125499b639fb23c1 100644 (file)
@@ -156,7 +156,7 @@ void ssl_iostream_test_settings_server(struct ssl_iostream_settings *test_set)
        i_zero(test_set);
        test_set->pool = null_pool;
        test_set->ca = test_ca_cert;
-       test_set->cert.cert = test_server_cert;
+       test_set->cert.cert.content = test_server_cert;
        test_set->cert.key = test_server_key;
        test_set->dh = test_server_dh;
        test_set->skip_crl_check = TRUE;
index 96e4ec32b49d0b07923477531850d57b16d77f65..0ad9facf59317688625c2af8a457cef7154888bc 100644 (file)
@@ -347,12 +347,13 @@ bool ssl_iostream_settings_equals(const struct ssl_iostream_settings *set1,
        if (set1 == set2)
                return TRUE;
 
-       if (!quick_strcmp(set1->cert.cert, set2->cert.cert) ||
+       if (!quick_strcmp(set1->cert.cert.content, set2->cert.cert.content) ||
            !quick_strcmp(set1->cert.key, set2->cert.key) ||
            !quick_strcmp(set1->cert.key_password, set2->cert.key_password))
                return FALSE;
 
-       if (!quick_strcmp(set1->alt_cert.cert, set2->alt_cert.cert) ||
+       if (!quick_strcmp(set1->alt_cert.cert.content,
+                         set2->alt_cert.cert.content) ||
            !quick_strcmp(set1->alt_cert.key, set2->alt_cert.key) ||
            !quick_strcmp(set1->alt_cert.key_password,
                          set2->alt_cert.key_password))
index 065d47319207ef0b75050fc13c9757054225fa13..1e7115e13f7ed3fab6c3f858ec1bf045c0f1b997 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef IOSTREAM_SSL_H
 #define IOSTREAM_SSL_H
 
+#include "settings-parser.h"
 #include "ssl-settings.h"
 
 struct ssl_iostream;
@@ -18,7 +19,7 @@ enum ssl_iostream_flags {
 };
 
 struct ssl_iostream_cert {
-       const char *cert;
+       struct settings_file cert;
        const char *key;
        const char *key_password;
 };
index 5e21eb1c38f3f29b5006d946c4d8e515b79864f5..9405804f8aadf872ca08193a2e5b1b1a88d9d33f 100644 (file)
@@ -66,9 +66,9 @@ const struct setting_parser_info ssl_setting_parser_info = {
 static const struct setting_define ssl_server_setting_defines[] = {
        DEF(ENUM, ssl),
        DEF(STR, ssl_ca),
-       DEF(STR, ssl_cert),
+       DEF(FILE, ssl_cert_file),
        DEF(STR, ssl_key),
-       DEF(STR, ssl_alt_cert),
+       DEF(FILE, ssl_alt_cert_file),
        DEF(STR, ssl_alt_key),
        DEF(STR, ssl_key_password),
        DEF(STR, ssl_dh),
@@ -84,9 +84,9 @@ static const struct setting_define ssl_server_setting_defines[] = {
 static const struct ssl_server_settings ssl_server_default_settings = {
        .ssl = "yes:no:required",
        .ssl_ca = "",
-       .ssl_cert = "",
+       .ssl_cert_file = "",
        .ssl_key = "",
-       .ssl_alt_cert = "",
+       .ssl_alt_cert_file = "",
        .ssl_alt_key = "",
        .ssl_key_password = "",
        .ssl_dh = "",
@@ -193,7 +193,7 @@ void ssl_client_settings_to_iostream_set(
        set->ca = ssl_set->ssl_client_ca;
        set->ca_file = ssl_set->ssl_client_ca_file;
        set->ca_dir = ssl_set->ssl_client_ca_dir;
-       set->cert.cert = ssl_set->ssl_client_cert;
+       set->cert.cert.content = ssl_set->ssl_client_cert;
        set->cert.key = ssl_set->ssl_client_key;
        set->verify_remote_cert = ssl_set->ssl_client_require_valid_cert;
        set->allow_invalid_cert = !set->verify_remote_cert;
@@ -212,12 +212,14 @@ void ssl_server_settings_to_iostream_set(
        pool_add_external_ref(set->pool, ssl_server_set->pool);
 
        set->ca = ssl_server_set->ssl_ca;
-       set->cert.cert = ssl_server_set->ssl_cert;
+       settings_file_get(ssl_server_set->ssl_cert_file,
+                         set->pool, &set->cert.cert);
        set->cert.key = ssl_server_set->ssl_key;
        set->cert.key_password = ssl_server_set->ssl_key_password;
-       if (ssl_server_set->ssl_alt_cert != NULL &&
-           *ssl_server_set->ssl_alt_cert != '\0') {
-               set->alt_cert.cert = ssl_server_set->ssl_alt_cert;
+       if (ssl_server_set->ssl_alt_cert_file != NULL &&
+           *ssl_server_set->ssl_alt_cert_file != '\0') {
+               settings_file_get(ssl_server_set->ssl_alt_cert_file,
+                                 set->pool, &set->alt_cert.cert);
                set->alt_cert.key = ssl_server_set->ssl_alt_key;
                set->alt_cert.key_password = ssl_server_set->ssl_key_password;
        }
index 2e123b25a69300a35d4620188dfe4bd815dd4e17..ba08db79ed9b53416c68eaccf1363331a5221130 100644 (file)
@@ -33,8 +33,8 @@ struct ssl_server_settings {
 
        const char *ssl;
        const char *ssl_ca;
-       const char *ssl_cert;
-       const char *ssl_alt_cert;
+       const char *ssl_cert_file;
+       const char *ssl_alt_cert_file;
        const char *ssl_key;
        const char *ssl_alt_key;
        const char *ssl_key_password;
index a11a3ad3846b6c4c70b35a1c0a1b83a751f53853..6265698d20386f1f463b1daa35f6c8bfde37527e 100644 (file)
@@ -344,7 +344,7 @@ static void test_iostream_ssl_handshake(void)
                                                         "failhost") != 0, idx);
        idx++;
        ssl_iostream_test_settings_server(&server_set);
-       server_set.cert.cert = NULL;
+       i_zero(&server_set.cert.cert);
        ssl_iostream_test_settings_client(&client_set);
        client_set.verify_remote_cert = TRUE;
        test_expect_error_string("client(failhost): SSL certificate not received");