]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream, global: Add ssl_iostream_settings.pool
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 16 Jun 2023 00:00:41 +0000 (03:00 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:09 +0000 (12:34 +0200)
Change all callers to set and use the pool properly.

39 files changed:
src/auth/auth-policy.c
src/auth/db-oauth2.c
src/doveadm/doveadm-dsync.c
src/doveadm/doveadm-fs.c
src/doveadm/doveadm-mail-server.c
src/doveadm/doveadm-settings.c
src/doveadm/doveadm-settings.h
src/lib-doveadm/doveadm-client.c
src/lib-doveadm/doveadm-client.h
src/lib-http/Makefile.am
src/lib-http/http-client.c
src/lib-http/http-server.c
src/lib-http/test-http-client.c
src/lib-imap-client/Makefile.am
src/lib-imap-client/imapc-client.c
src/lib-lua/dlua-dovecot-http.c
src/lib-master/master-service-ssl-settings.c
src/lib-master/master-service-ssl-settings.h
src/lib-master/master-service-ssl.c
src/lib-smtp/smtp-client-connection.c
src/lib-smtp/smtp-client.c
src/lib-smtp/smtp-server-connection.c
src/lib-smtp/smtp-server.c
src/lib-smtp/smtp-submit.c
src/lib-ssl-iostream/iostream-ssl-test.c
src/lib-ssl-iostream/iostream-ssl.h
src/lib-storage/index/pop3c/pop3c-client.c
src/lib-storage/mail-storage-service.c
src/lib-storage/mail-storage-service.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-user.c
src/lib-storage/mail-user.h
src/lib-storage/mailbox-list.c
src/lmtp/lmtp-proxy.c
src/login-common/client-common.c
src/login-common/login-proxy.c
src/login-common/main.c
src/stats/event-exporter-transport-http-post.c
src/submission/submission-backend-relay.c

index a459d8a668e2bb33d816dd3d1e74c1d6d0c2049b..fe0fe9e38fb78a19ba4c662e86a6cd04dce747f3 100644 (file)
@@ -158,20 +158,19 @@ void auth_policy_init(void)
        const struct master_service_ssl_settings *master_ssl_set =
                settings_get_or_fatal(master_service_get_event(master_service),
                        &master_service_ssl_setting_parser_info);
-       struct ssl_iostream_settings ssl_set;
-       i_zero(&ssl_set);
+       const struct ssl_iostream_settings *ssl_set;
 
        http_client_set.request_absolute_timeout_msecs =
                global_auth_settings->policy_server_timeout_msecs;
        if (global_auth_settings->debug)
                http_client_set.debug = 1;
 
-       master_service_ssl_client_settings_to_iostream_set(
-               master_ssl_set, pool_datastack_create(), &ssl_set);
-       http_client_set.ssl = &ssl_set;
+       master_service_ssl_client_settings_to_iostream_set(master_ssl_set, &ssl_set);
+       http_client_set.ssl = ssl_set;
        http_client_set.event_parent = auth_event;
        http_client = http_client_init(&http_client_set);
        settings_free(master_ssl_set);
+       settings_free(ssl_set);
 
        /* prepare template */
 
index 2789d97485f82b693beb623cf698d24f7444e621..e0e0570050f79d18440bda33512f1070711fb4ac 100644 (file)
@@ -194,7 +194,7 @@ struct db_oauth2 *db_oauth2_init(const char *config_path)
 {
        struct db_oauth2 *db;
        const char *error;
-       struct ssl_iostream_settings ssl_set;
+       struct ssl_iostream_settings *ssl_set;
        struct http_client_settings http_set;
 
        for(db = db_oauth2_head; db != NULL; db = db->next) {
@@ -216,19 +216,23 @@ struct db_oauth2 *db_oauth2_init(const char *config_path)
 
        db->tmpl = passdb_template_build(pool, db->set.pass_attrs);
 
-       i_zero(&ssl_set);
-       i_zero(&http_set);
+       pool_t ssl_pool = pool_alloconly_create("oauth2 ssl settings",
+                                               sizeof(*ssl_set));
+       ssl_set = p_new(ssl_pool, struct ssl_iostream_settings, 1);
+       ssl_set->pool = ssl_pool;
 
-       ssl_set.cipher_list = db->set.tls_cipher_suite;
-       ssl_set.ca_file = db->set.tls_ca_cert_file;
-       ssl_set.ca_dir = db->set.tls_ca_cert_dir;
+       ssl_set->cipher_list = db->set.tls_cipher_suite;
+       ssl_set->ca_file = db->set.tls_ca_cert_file;
+       ssl_set->ca_dir = db->set.tls_ca_cert_dir;
        if (db->set.tls_cert_file != NULL && *db->set.tls_cert_file != '\0') {
-               ssl_set.cert.cert = db->set.tls_cert_file;
-               ssl_set.cert.key = db->set.tls_key_file;
+               ssl_set->cert.cert = db->set.tls_cert_file;
+               ssl_set->cert.key = db->set.tls_key_file;
        }
-       ssl_set.prefer_server_ciphers = TRUE;
-       ssl_set.allow_invalid_cert = db->set.tls_allow_invalid_cert;
-       http_set.ssl = &ssl_set;
+       ssl_set->prefer_server_ciphers = TRUE;
+       ssl_set->allow_invalid_cert = db->set.tls_allow_invalid_cert;
+
+       i_zero(&http_set);
+       http_set.ssl = ssl_set;
 
        http_set.dns_client_socket_path = "dns-client";
        http_set.user_agent = "dovecot-oauth2-passdb/" DOVECOT_VERSION;
@@ -252,6 +256,7 @@ struct db_oauth2 *db_oauth2_init(const char *config_path)
        http_set.event_parent = auth_event;
 
        db->client = http_client_init(&http_set);
+       pool_unref(&ssl_pool);
 
        i_zero(&db->oauth2_set);
        db->oauth2_set.client = db->client;
index f06ae3ff2175dcbe9ddc187ec8475b177ebd2d0e..342fb8c56e821515247d46b84c6fa4d0a01826c2 100644 (file)
@@ -926,11 +926,10 @@ dsync_connect_tcp(struct dsync_cmd_context *ctx,
 
        if (ssl) {
                if (mail_storage_service_user_init_ssl_client_settings(
-                               service_user, pool_datastack_create(),
-                               &conn_set.ssl_set, error_r) < 0)
+                               service_user, &conn_set.ssl_set, error_r) < 0)
                        return -1;
                if (ctx->ssl_ctx == NULL &&
-                   ssl_iostream_client_context_cache_get(&conn_set.ssl_set,
+                   ssl_iostream_client_context_cache_get(conn_set.ssl_set,
                                                          &ctx->ssl_ctx,
                                                          &error) < 0) {
                        *error_r = t_strdup_printf(
index fdd2b62e4a253aa6adba668608b037ff29450ccc..a7861f64485aaf25af69fcbf16ec5ed7323290d1 100644 (file)
@@ -9,6 +9,7 @@
 #include "istream.h"
 #include "ostream.h"
 #include "iostream-ssl.h"
+#include "settings.h"
 #include "fs-api.h"
 #include "doveadm.h"
 #include "doveadm-print.h"
@@ -22,7 +23,7 @@ static void cmd_fs_delete(struct doveadm_cmd_context *cctx);
 static struct fs *
 cmd_fs_init(struct doveadm_cmd_context *cctx)
 {
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        struct fs_settings fs_set;
        struct fs *fs;
        const char *fs_driver, *fs_args, *error;
@@ -31,15 +32,16 @@ cmd_fs_init(struct doveadm_cmd_context *cctx)
            !doveadm_cmd_param_str(cctx, "fs-args", &fs_args))
                fs_cmd_help(cctx);
 
-       doveadm_get_ssl_settings(&ssl_set, pool_datastack_create());
+       doveadm_get_ssl_settings(&ssl_set);
        i_zero(&fs_set);
-       fs_set.ssl_client_set = &ssl_set;
+       fs_set.ssl_client_set = ssl_set;
        fs_set.temp_dir = doveadm_settings->mail_temp_dir;
        fs_set.base_dir = doveadm_settings->base_dir;
        fs_set.debug = doveadm_debug;
 
        if (fs_init(fs_driver, fs_args, &fs_set, &fs, &error) < 0)
                i_fatal("fs_init() failed: %s", error);
+       settings_free(ssl_set);
        return fs;
 }
 
index 4fce499d547f11b49a26218e02564ba8e1157ac6..51a50313355d5ef382b2a89e6bc6413382240764 100644 (file)
@@ -8,6 +8,7 @@
 #include "connection.h"
 #include "ioloop.h"
 #include "istream.h"
+#include "settings.h"
 #include "master-service.h"
 #include "iostream-ssl.h"
 #include "auth-proxy.h"
@@ -624,12 +625,13 @@ doveadm_mail_server_request_queue_handle_next(struct doveadm_mail_cmd_context *c
        request_copy = *request;
        array_pop_front(&doveadm_server_request_queue);
 
-       doveadm_get_ssl_settings(&request_copy.set.ssl_set,
-                                pool_datastack_create());
+       doveadm_get_ssl_settings(&request_copy.set.ssl_set);
        if (doveadm_client_create(&request_copy.set, &conn, error_r) < 0) {
+               settings_free(request_copy.set.ssl_set);
                internal_failure = TRUE;
                return -1;
        }
+       settings_free(request_copy.set.ssl_set);
        doveadm_mail_server_handle(request_copy.server, conn, cmd_ctx,
                                   request_copy.username,
                                   request_copy.print_username);
@@ -823,12 +825,13 @@ int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx,
        }
 
        if (doveadm_clients_count() <= limit) {
-               doveadm_get_ssl_settings(&conn_set.ssl_set,
-                                        pool_datastack_create());
+               doveadm_get_ssl_settings(&conn_set.ssl_set);
                if (doveadm_client_create(&conn_set, &conn, error_r) < 0) {
+                       settings_free(conn_set.ssl_set);
                        internal_failure = TRUE;
                        return -1;
                } else {
+                       settings_free(conn_set.ssl_set);
                        doveadm_mail_server_handle(server, conn, ctx,
                                                   proxy_set.username,
                                                   print_username);
index 17b2695ea30a80aafeb9dd15b9ffa0600aa0d7af..b09f42b25a819fa9779ac8c1df307345a0de943c 100644 (file)
@@ -194,10 +194,9 @@ static bool doveadm_settings_check(void *_set, pool_t pool ATTR_UNUSED,
 
 const struct master_service_ssl_settings *doveadm_ssl_set = NULL;
 
-void doveadm_get_ssl_settings(struct ssl_iostream_settings *set_r, pool_t pool)
+void doveadm_get_ssl_settings(const struct ssl_iostream_settings **set_r)
 {
-       master_service_ssl_client_settings_to_iostream_set(doveadm_ssl_set,
-                                                          pool, set_r);
+       master_service_ssl_client_settings_to_iostream_set(doveadm_ssl_set, set_r);
 }
 
 void doveadm_read_settings(void)
index e54023cff19234b2abe2680c8f54f3ecc65d47a9..69903542259245b43f09675639137dd31e3fc758 100644 (file)
@@ -45,7 +45,7 @@ extern const struct doveadm_settings *doveadm_settings;
 extern const struct master_service_ssl_settings *doveadm_ssl_set;
 extern bool doveadm_verbose_proctitle;
 
-void doveadm_get_ssl_settings(struct ssl_iostream_settings *set_r, pool_t pool);
+void doveadm_get_ssl_settings(const struct ssl_iostream_settings **set_r);
 
 void doveadm_read_settings(void);
 /* Returns the global binary config fd. Note that it may be -1 if doveadm was
index 41dfcb9961157ce1997e9f01db8eda7cc6fb536f..a85bd7cb663f227563a97888e72a0d18e66583ff 100644 (file)
@@ -94,7 +94,8 @@ void doveadm_client_settings_dup(const struct doveadm_client_settings *src,
        dest_r->password = p_strdup(pool, src->password);
 
        dest_r->ssl_flags = src->ssl_flags;
-       dest_r->ssl_set = *ssl_iostream_settings_dup(pool, &src->ssl_set);
+       dest_r->ssl_set = src->ssl_set;
+       pool_add_external_ref(pool, src->ssl_set->pool);
        if (src->ssl_ctx != NULL) {
                dest_r->ssl_ctx = src->ssl_ctx;
                ssl_iostream_context_ref(dest_r->ssl_ctx);
@@ -559,7 +560,7 @@ static bool doveadm_client_input_one(struct doveadm_client *conn)
 static int doveadm_client_init_ssl(struct doveadm_client *conn,
                                   const char **error_r)
 {
-       struct ssl_iostream_settings ssl_set = conn->set.ssl_set;
+       struct ssl_iostream_settings ssl_set = *conn->set.ssl_set;
        const char *error;
 
        if (conn->set.ssl_flags == 0)
index 23ade6cd84c83438ffbd37920e78c6be343869c2..fd2e4f518600744430a4f5f5c4585bf68e2f47e2 100644 (file)
@@ -47,7 +47,7 @@ struct doveadm_client_settings {
        /* SSL flags. */
        enum auth_proxy_ssl_flags ssl_flags;
        /* SSL settings. */
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        /* SSL context, or NULL to create a new one. */
        struct ssl_iostream_context *ssl_ctx;
 
index 7e912861ec465e6689f74a44d239669a5084c4e1..09bf2bcecb5a24f1cf34782ca1be02988656a217 100644 (file)
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libhttp.la
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
        -I$(top_srcdir)/src/lib-test \
+       -I$(top_srcdir)/src/lib-settings \
        -I$(top_srcdir)/src/lib-dns \
        -I$(top_srcdir)/src/lib-ssl-iostream \
        -I$(top_srcdir)/src/lib-master \
index 9eacd23d9cb57fa2079c1aef099cd26930dee888..03f3625dc764c10be79274e4797cb3dce96318b3 100644 (file)
@@ -13,6 +13,7 @@
 #include "dns-lookup.h"
 #include "iostream-rawlog.h"
 #include "iostream-ssl.h"
+#include "settings.h"
 #include "http-url.h"
 
 #include "http-client-private.h"
@@ -161,8 +162,10 @@ http_client_init_shared(struct http_client_context *cctx,
                if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
                        client->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
 
-               if (set->ssl != NULL)
-                       client->set.ssl = ssl_iostream_settings_dup(pool, set->ssl);
+               if (set->ssl != NULL) {
+                       client->set.ssl = set->ssl;
+                       pool_ref(client->set.ssl->pool);
+               }
 
                if (set->proxy_socket_path != NULL && *set->proxy_socket_path != '\0') {
                        client->set.proxy_socket_path = p_strdup(pool, set->proxy_socket_path);
@@ -278,6 +281,7 @@ void http_client_deinit(struct http_client **_client)
        array_free(&client->delayed_failing_requests);
        timeout_remove(&client->to_failing_requests);
 
+       settings_free(client->set.ssl);
        if (client->ssl_ctx != NULL)
                ssl_iostream_context_unref(&client->ssl_ctx);
        http_client_context_remove_client(client->cctx, client);
@@ -460,8 +464,10 @@ http_client_context_create(const struct http_client_settings *set)
        cctx->set.user_agent = p_strdup_empty(pool, set->user_agent);
        cctx->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
 
-       if (set->ssl != NULL)
-               cctx->set.ssl = ssl_iostream_settings_dup(pool, set->ssl);
+       if (set->ssl != NULL) {
+               cctx->set.ssl = set->ssl;
+               pool_ref(cctx->set.ssl->pool);
+       }
 
        if (set->proxy_socket_path != NULL &&
            *set->proxy_socket_path != '\0') {
index dd89a168c9fb4ef9ec8ed11099f8895cf5541b7e..3827ed937e844d1921118dfbac7d58d5c8a2cc7e 100644 (file)
@@ -12,6 +12,7 @@
 #include "dns-lookup.h"
 #include "iostream-rawlog.h"
 #include "iostream-ssl.h"
+#include "settings.h"
 #include "http-url.h"
 
 #include "http-server-private.h"
@@ -40,8 +41,8 @@ struct http_server *http_server_init(const struct http_server_settings *set)
        if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
                server->set.rawlog_dir = p_strdup(pool, set->rawlog_dir);
        if (set->ssl != NULL) {
-               server->set.ssl =
-                       ssl_iostream_settings_dup(server->pool, set->ssl);
+               server->set.ssl = set->ssl;
+               pool_ref(server->set.ssl->pool);
        }
        server->set.max_client_idle_time_msecs = set->max_client_idle_time_msecs;
        server->set.max_pipelined_requests =
@@ -77,6 +78,7 @@ void http_server_deinit(struct http_server **_server)
                http_server_resource_free(&res);
        i_assert(array_count(&server->locations) == 0);
 
+       settings_free(server->set.ssl);
        if (server->ssl_ctx != NULL)
                ssl_iostream_context_unref(&server->ssl_ctx);
        event_unref(&server->event);
index 18a834dcb355d431b785e62491c3492e6e2b2535..6a7ea6f711755db6b13fcd055580de6b46c9eb8c 100644 (file)
@@ -381,6 +381,7 @@ int main(int argc, char *argv[])
                dns_client = NULL;
        }
        i_zero(&ssl_set);
+       ssl_set.pool = null_pool;
        ssl_set.allow_invalid_cert = TRUE;
        if (stat("/etc/ssl/certs", &st) == 0 && S_ISDIR(st.st_mode))
                ssl_set.ca_dir = "/etc/ssl/certs"; /* debian */
index f5721e12066b65d98ac1eb4c6f07e18cf94b9a04..4b6597781f0a7be25c6ce4b74bd363173f0247ef 100644 (file)
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libimap_client.la
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
        -I$(top_srcdir)/src/lib-test \
+       -I$(top_srcdir)/src/lib-settings \
        -I$(top_srcdir)/src/lib-dns \
        -I$(top_srcdir)/src/lib-sasl \
        -I$(top_srcdir)/src/lib-ssl-iostream \
index 10ca1a5bcbcd21459b03f65b953af4597207fefa..5ca8b66a337672ab93c2e2ac0a8f5689cc726bc1 100644 (file)
@@ -6,6 +6,7 @@
 #include "ioloop.h"
 #include "safe-mkstemp.h"
 #include "iostream-ssl.h"
+#include "settings.h"
 #include "imapc-msgmap.h"
 #include "imapc-connection.h"
 #include "imapc-client-private.h"
@@ -103,8 +104,7 @@ imapc_client_init(const struct imapc_client_settings *set,
 
        if (set->ssl_mode != IMAPC_CLIENT_SSL_MODE_NONE) {
                client->set.ssl_mode = set->ssl_mode;
-               ssl_iostream_settings_init_from(pool, &client->set.ssl_set, &set->ssl_set);
-               if (ssl_iostream_client_context_cache_get(&client->set.ssl_set,
+               if (ssl_iostream_client_context_cache_get(&set->ssl_set,
                                                          &client->ssl_ctx,
                                                          &error) < 0) {
                        e_error(client->event, "Couldn't initialize SSL context: %s", error);
index ebab5212c08083a6e1626e38357a61f5ac64f5fb..70a3d39dbd3c1be4586472bdc537bc2d7e7ef192 100644 (file)
@@ -527,7 +527,7 @@ static int dlua_http_client_new(lua_State *L)
 
        struct http_client *client;
        struct http_client_settings http_set;
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        const char *error;
 
        i_zero(&http_set);
@@ -541,12 +541,12 @@ static int dlua_http_client_new(lua_State *L)
                         &master_service_ssl_setting_parser_info,
                         0, &master_ssl_set, &error) < 0)
                luaL_error(L, "%s", error);
-       master_service_ssl_client_settings_to_iostream_set(master_ssl_set,
-               pool_datastack_create(), &ssl_set);
-       http_set.ssl = &ssl_set;
+       master_service_ssl_client_settings_to_iostream_set(master_ssl_set, &ssl_set);
+       http_set.ssl = ssl_set;
        settings_free(master_ssl_set);
 
        client = http_client_init(&http_set);
+       settings_free(ssl_set);
        dlua_push_http_client(L, client);
        return 1;
 }
index 614f273ee4a1a4cbb81b8763a53ecdce2245af9e..6e838387020b2a046af7f4397bab28413bc4ff6c 100644 (file)
@@ -166,64 +166,74 @@ master_service_ssl_server_settings_check(void *_set, pool_t pool ATTR_UNUSED,
 }
 /* </settings checks> */
 
-static void master_service_ssl_common_settings_to_iostream_set(
-       const struct master_service_ssl_settings *ssl_set, pool_t pool,
-       struct ssl_iostream_settings *set_r)
+static struct ssl_iostream_settings *
+master_service_ssl_common_settings_to_iostream_set(
+       const struct master_service_ssl_settings *ssl_set)
 {
-       i_zero(set_r);
-       set_r->min_protocol = p_strdup(pool, ssl_set->ssl_min_protocol);
-       set_r->cipher_list = p_strdup(pool, ssl_set->ssl_cipher_list);
+       struct ssl_iostream_settings *set;
+       pool_t pool = pool_alloconly_create("ssl iostream settings", 256);
+       set = p_new(pool, struct ssl_iostream_settings, 1);
+       set->pool = pool;
+       set->min_protocol = p_strdup(pool, ssl_set->ssl_min_protocol);
+       set->cipher_list = p_strdup(pool, ssl_set->ssl_cipher_list);
        /* leave NULL if empty - let library decide */
-       set_r->ciphersuites = p_strdup_empty(pool, ssl_set->ssl_cipher_suites);
+       set->ciphersuites = p_strdup_empty(pool, ssl_set->ssl_cipher_suites);
 
-       set_r->crypto_device = p_strdup(pool, ssl_set->ssl_crypto_device);
+       set->crypto_device = p_strdup(pool, ssl_set->ssl_crypto_device);
 
-       set_r->compression = ssl_set->parsed_opts.compression;
-       set_r->tickets = ssl_set->parsed_opts.tickets;
-       set_r->curve_list = p_strdup(pool, ssl_set->ssl_curve_list);
+       set->compression = ssl_set->parsed_opts.compression;
+       set->tickets = ssl_set->parsed_opts.tickets;
+       set->curve_list = p_strdup(pool, ssl_set->ssl_curve_list);
+       return set;
 }
 
 void master_service_ssl_client_settings_to_iostream_set(
-       const struct master_service_ssl_settings *ssl_set, pool_t pool,
-       struct ssl_iostream_settings *set_r)
+       const struct master_service_ssl_settings *ssl_set,
+       const struct ssl_iostream_settings **set_r)
 {
-       master_service_ssl_common_settings_to_iostream_set(ssl_set, pool, set_r);
-
-       set_r->ca = p_strdup_empty(pool, ssl_set->ssl_client_ca);
-       set_r->ca_file = p_strdup_empty(pool, ssl_set->ssl_client_ca_file);
-       set_r->ca_dir = p_strdup_empty(pool, ssl_set->ssl_client_ca_dir);
-       set_r->cert.cert = p_strdup_empty(pool, ssl_set->ssl_client_cert);
-       set_r->cert.key = p_strdup_empty(pool, ssl_set->ssl_client_key);
-       set_r->verify_remote_cert = ssl_set->ssl_client_require_valid_cert;
-       set_r->allow_invalid_cert = !set_r->verify_remote_cert;
+       struct ssl_iostream_settings *set =
+               master_service_ssl_common_settings_to_iostream_set(ssl_set);
+       pool_t pool = set->pool;
+
+       set->ca = p_strdup_empty(pool, ssl_set->ssl_client_ca);
+       set->ca_file = p_strdup_empty(pool, ssl_set->ssl_client_ca_file);
+       set->ca_dir = p_strdup_empty(pool, ssl_set->ssl_client_ca_dir);
+       set->cert.cert = p_strdup_empty(pool, ssl_set->ssl_client_cert);
+       set->cert.key = p_strdup_empty(pool, ssl_set->ssl_client_key);
+       set->verify_remote_cert = ssl_set->ssl_client_require_valid_cert;
+       set->allow_invalid_cert = !set->verify_remote_cert;
        /* client-side CRL checking not supported currently */
-       set_r->skip_crl_check = TRUE;
+       set->skip_crl_check = TRUE;
+       *set_r = set;
 }
 
 void master_service_ssl_server_settings_to_iostream_set(
        const struct master_service_ssl_settings *ssl_set,
        const struct master_service_ssl_server_settings *ssl_server_set,
-       pool_t pool, struct ssl_iostream_settings *set_r)
+       const struct ssl_iostream_settings **set_r)
 {
-       master_service_ssl_common_settings_to_iostream_set(ssl_set, pool, set_r);
-
-       set_r->ca = p_strdup_empty(pool, ssl_server_set->ssl_ca);
-       set_r->cert.cert = p_strdup(pool, ssl_server_set->ssl_cert);
-       set_r->cert.key = p_strdup(pool, ssl_server_set->ssl_key);
-       set_r->cert.key_password = p_strdup(pool, ssl_server_set->ssl_key_password);
+       struct ssl_iostream_settings *set =
+               master_service_ssl_common_settings_to_iostream_set(ssl_set);
+       pool_t pool = set->pool;
+
+       set->ca = p_strdup_empty(pool, ssl_server_set->ssl_ca);
+       set->cert.cert = p_strdup(pool, ssl_server_set->ssl_cert);
+       set->cert.key = p_strdup(pool, ssl_server_set->ssl_key);
+       set->cert.key_password = p_strdup(pool, ssl_server_set->ssl_key_password);
        if (ssl_server_set->ssl_alt_cert != NULL &&
            *ssl_server_set->ssl_alt_cert != '\0') {
-               set_r->alt_cert.cert = p_strdup(pool, ssl_server_set->ssl_alt_cert);
-               set_r->alt_cert.key = p_strdup(pool, ssl_server_set->ssl_alt_key);
-               set_r->alt_cert.key_password = p_strdup(pool, ssl_server_set->ssl_key_password);
+               set->alt_cert.cert = p_strdup(pool, ssl_server_set->ssl_alt_cert);
+               set->alt_cert.key = p_strdup(pool, ssl_server_set->ssl_alt_key);
+               set->alt_cert.key_password = p_strdup(pool, ssl_server_set->ssl_key_password);
        }
-       set_r->dh = p_strdup(pool, ssl_server_set->ssl_dh);
-       set_r->cert_username_field =
+       set->dh = p_strdup(pool, ssl_server_set->ssl_dh);
+       set->cert_username_field =
                p_strdup(pool, ssl_server_set->ssl_cert_username_field);
-       set_r->prefer_server_ciphers = ssl_server_set->ssl_prefer_server_ciphers;
-       set_r->verify_remote_cert = ssl_server_set->ssl_request_client_cert;
-       set_r->allow_invalid_cert = !set_r->verify_remote_cert;
+       set->prefer_server_ciphers = ssl_server_set->ssl_prefer_server_ciphers;
+       set->verify_remote_cert = ssl_server_set->ssl_request_client_cert;
+       set->allow_invalid_cert = !set->verify_remote_cert;
        /* ssl_require_crl is used only for checking client-provided SSL
           certificate's CRL. */
-       set_r->skip_crl_check = !ssl_server_set->ssl_require_crl;
+       set->skip_crl_check = !ssl_server_set->ssl_require_crl;
+       *set_r = set;
 }
index d1b2b23a904a42d475e81ed4beb98164d9183edd..6b2cc490b6e20b9e287ac2012cefb81b1e104284 100644 (file)
@@ -53,11 +53,11 @@ extern const struct setting_parser_info master_service_ssl_server_setting_parser
 
 /* Provides master service ssl settings to iostream settings */
 void master_service_ssl_client_settings_to_iostream_set(
-       const struct master_service_ssl_settings *ssl_set, pool_t pool,
-       struct ssl_iostream_settings *set_r);
+       const struct master_service_ssl_settings *ssl_set,
+       const struct ssl_iostream_settings **set_r);
 void master_service_ssl_server_settings_to_iostream_set(
        const struct master_service_ssl_settings *ssl_set,
        const struct master_service_ssl_server_settings *ssl_server_set,
-       pool_t pool, struct ssl_iostream_settings *set_r);
+       const struct ssl_iostream_settings **set_r);
 
 #endif
index f4a3022ec36d02967a9052c3693bb8f41d33304d..cb8181a3273ebb38f906a442729b3d72aaeca2dd 100644 (file)
@@ -79,6 +79,8 @@ void master_service_ssl_ctx_init(struct master_service *service)
        }
 
        i_zero(&ssl_set);
+       ssl_set.pool = set->pool;
+       pool_add_external_ref(ssl_set.pool, server_set->pool);
        ssl_set.min_protocol = set->ssl_min_protocol;
        ssl_set.cipher_list = set->ssl_cipher_list;
        ssl_set.curve_list = set->ssl_curve_list;
index 376ca3b64dcaa1cea5f0a25657beaf551104ccee..629318db65225f35b54164f3537510f527e44dce 100644 (file)
@@ -13,6 +13,7 @@
 #include "iostream-rawlog.h"
 #include "iostream-ssl.h"
 #include "str.h"
+#include "settings.h"
 #include "dsasl-client.h"
 #include "dns-lookup.h"
 #include "smtp-syntax.h"
@@ -2056,6 +2057,7 @@ void smtp_client_connection_disconnect(struct smtp_client_connection *conn)
        timeout_remove(&conn->to_cmd_fail);
 
        ssl_iostream_destroy(&conn->ssl_iostream);
+       settings_free(conn->set.ssl);
        if (conn->ssl_ctx != NULL)
                ssl_iostream_context_unref(&conn->ssl_ctx);
        smtp_client_connection_auth_deinit(conn);
@@ -2119,8 +2121,8 @@ smtp_client_connection_do_create(struct smtp_client *client, const char *name,
                }
 
                if (set->ssl != NULL) {
-                       conn->set.ssl =
-                               ssl_iostream_settings_dup(pool, set->ssl);
+                       conn->set.ssl = set->ssl;
+                       pool_ref(conn->set.ssl->pool);
                }
 
                if (set->master_user != NULL && *set->master_user != '\0') {
index 86c8bb1d541ca46016f3e3af62a0c2e47854a22b..e0dbc6fd926cb51a3a74d9a26c53e47ac607e5fd 100644 (file)
@@ -9,6 +9,7 @@
 #include "istream.h"
 #include "ostream.h"
 #include "connection.h"
+#include "settings.h"
 #include "dns-lookup.h"
 #include "iostream-rawlog.h"
 #include "iostream-ssl.h"
@@ -47,8 +48,8 @@ struct smtp_client *smtp_client_init(const struct smtp_client_settings *set)
        client->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
 
        if (set->ssl != NULL) {
-               client->set.ssl =
-                       ssl_iostream_settings_dup(client->pool, set->ssl);
+               client->set.ssl = set->ssl;
+               pool_ref(client->set.ssl->pool);
        }
 
        client->set.master_user = p_strdup_empty(pool, set->master_user);
@@ -96,6 +97,7 @@ void smtp_client_deinit(struct smtp_client **_client)
 
        connection_list_deinit(&client->conn_list);
 
+       settings_free(client->set.ssl);
        if (client->ssl_ctx != NULL)
                ssl_iostream_context_unref(&client->ssl_ctx);
        event_unref(&client->event);
index 0bc4360060c6fe599b9f63e1ced13268a4117977..909043565514ab721868d4ab7529444669272bf6 100644 (file)
@@ -13,6 +13,7 @@
 #include "connection.h"
 #include "iostream-rawlog.h"
 #include "iostream-ssl.h"
+#include "settings.h"
 #include "master-service.h"
 #include "master-service-ssl.h"
 
@@ -808,8 +809,10 @@ smtp_server_connection_alloc(struct smtp_server *server,
                if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
                        conn->set.rawlog_dir = p_strdup(pool, set->rawlog_dir);
 
-               if (set->ssl != NULL)
-                       conn->set.ssl = ssl_iostream_settings_dup(pool, set->ssl);
+               if (set->ssl != NULL) {
+                       conn->set.ssl = set->ssl;
+                       pool_ref(conn->set.ssl->pool);
+               }
 
                if (set->hostname != NULL && *set->hostname != '\0')
                        conn->set.hostname = p_strdup(pool, set->hostname);
@@ -1086,6 +1089,7 @@ smtp_server_connection_disconnect(struct smtp_server_connection *conn,
        if (conn->smtp_parser != NULL)
                smtp_command_parser_deinit(&conn->smtp_parser);
        ssl_iostream_destroy(&conn->ssl_iostream);
+       settings_free(conn->set.ssl);
        if (conn->ssl_ctx != NULL)
                ssl_iostream_context_unref(&conn->ssl_ctx);
 
index e0afde3116365cdfdbbf23a22080561d5c9b3a72..9a7028dbaafa8b21891b07a84273ff51fa87eb17 100644 (file)
@@ -10,6 +10,7 @@
 #include "istream.h"
 #include "ostream.h"
 #include "connection.h"
+#include "settings.h"
 #include "dns-lookup.h"
 #include "iostream-rawlog.h"
 #include "iostream-ssl.h"
@@ -38,8 +39,8 @@ struct smtp_server *smtp_server_init(const struct smtp_server_settings *set)
        server->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
 
        if (set->ssl != NULL) {
-               server->set.ssl =
-                       ssl_iostream_settings_dup(server->pool, set->ssl);
+               server->set.ssl = set->ssl;
+               pool_ref(server->set.ssl->pool);
        }
 
        if (set->hostname != NULL && *set->hostname != '\0')
@@ -113,6 +114,7 @@ void smtp_server_deinit(struct smtp_server **_server)
 
        connection_list_deinit(&server->conn_list);
 
+       settings_free(server->set.ssl);
        if (server->ssl_ctx != NULL)
                ssl_iostream_context_unref(&server->ssl_ctx);
        event_unref(&server->event);
index 0328b95488c0602795144fe5960c52865dc928b4..e645bacc46e7b3cee18304949b0909ba0c669fc8 100644 (file)
@@ -8,6 +8,7 @@
 #include "ostream.h"
 #include "iostream-temp.h"
 #include "iostream-ssl.h"
+#include "settings.h"
 #include "master-service.h"
 #include "program-client.h"
 #include "smtp-client.h"
@@ -29,7 +30,7 @@ static struct event_category event_category_smtp_submit = {
 struct smtp_submit_session {
        pool_t pool;
        struct smtp_submit_settings set;
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        struct event *event;
        bool allow_root:1;
 };
@@ -82,8 +83,8 @@ smtp_submit_session_init(const struct smtp_submit_input *input,
                p_strdup_empty(pool, set->submission_ssl);
 
        if (input->ssl != NULL) {
-               ssl_iostream_settings_init_from(pool, &session->ssl_set,
-                                               input->ssl);
+               session->ssl_set = input->ssl;
+               pool_ref(session->ssl_set->pool);
        }
        session->allow_root = input->allow_root;
 
@@ -99,6 +100,7 @@ void smtp_submit_session_deinit(struct smtp_submit_session **_session)
 
        *_session = NULL;
 
+       settings_free(session->ssl_set);
        event_unref(&session->event);
        pool_unref(&session->pool);
 }
@@ -332,7 +334,7 @@ smtp_submit_send_host(struct smtp_submit *subm)
        smtp_set.connect_timeout_msecs = set->submission_timeout*1000;
        smtp_set.command_timeout_msecs = set->submission_timeout*1000;
        smtp_set.debug = set->mail_debug;
-       smtp_set.ssl = &subm->session->ssl_set;
+       smtp_set.ssl = subm->session->ssl_set;
        smtp_set.event_parent = subm->event;
 
        ssl_mode = SMTP_CLIENT_SSL_MODE_NONE;
index 43a302278d975f50fe1ed15fd629b589edba8850..87b2b5890689d3f503af17571b6780e50cfdf54d 100644 (file)
@@ -154,6 +154,7 @@ static const char *test_server_dh =
 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.key = test_server_key;
@@ -164,6 +165,7 @@ void ssl_iostream_test_settings_server(struct ssl_iostream_settings *test_set)
 void ssl_iostream_test_settings_client(struct ssl_iostream_settings *test_set)
 {
        i_zero(test_set);
+       test_set->pool = null_pool;
        test_set->ca = test_ca_cert;
        test_set->skip_crl_check = TRUE;
 }
index 40e41349dfde9c713d27ad9e5fa363e133ca0fbf..274517fb1ca01e3fafda00633f0dbea329054788 100644 (file)
@@ -11,6 +11,7 @@ struct ssl_iostream_cert {
 };
 
 struct ssl_iostream_settings {
+       pool_t pool;
        /* NOTE: when updating, remember to update:
           ssl_iostream_settings_string_offsets[] */
        const char *min_protocol;
index bb31d6182502fdac15d1a008ce90e937899b4038..a5be16eece95e81c98b97f026be76240aa4ff3eb 100644 (file)
@@ -14,6 +14,7 @@
 #include "safe-mkstemp.h"
 #include "base64.h"
 #include "str.h"
+#include "settings.h"
 #include "dns-lookup.h"
 #include "pop3c-client.h"
 
@@ -120,7 +121,8 @@ pop3c_client_init(const struct pop3c_client_settings *set,
        client->set.ssl_mode = set->ssl_mode;
 
        if (set->ssl_mode != POP3C_CLIENT_SSL_MODE_NONE) {
-               ssl_iostream_settings_init_from(client->pool, &client->set.ssl_set, &set->ssl_set);
+               client->set.ssl_set = set->ssl_set;
+               pool_ref(client->set.ssl_set.pool);
                if (ssl_iostream_client_context_cache_get(&set->ssl_set,
                                                          &client->ssl_ctx,
                                                          &error) < 0) {
@@ -210,8 +212,10 @@ static void pop3c_client_disconnect(struct pop3c_client *client)
 void pop3c_client_deinit(struct pop3c_client **_client)
 {
        struct pop3c_client *client = *_client;
+       const struct ssl_iostream_settings *ssl_set = &client->set.ssl_set;
 
        pop3c_client_disconnect(client);
+       settings_free(ssl_set);
        if (client->ssl_ctx != NULL)
                ssl_iostream_context_unref(&client->ssl_ctx);
        event_unref(&client->event);
index 804983b52467f7d289cc8374fff2507ca8be0107..f91400f72b7a777789da79ac0834d4743b7382e9 100644 (file)
@@ -1590,16 +1590,15 @@ mail_storage_service_user_get_settings_instance(struct mail_storage_service_user
 }
 
 int mail_storage_service_user_init_ssl_client_settings(
-       struct mail_storage_service_user *user, pool_t pool,
-       struct ssl_iostream_settings *ssl_set_r, const char **error_r)
+       struct mail_storage_service_user *user,
+       const struct ssl_iostream_settings **ssl_set_r, const char **error_r)
 {
        const struct master_service_ssl_settings *ssl_set;
 
        if (settings_get(user->event, &master_service_ssl_setting_parser_info,
                         0, &ssl_set, error_r) < 0)
                return -1;
-       master_service_ssl_client_settings_to_iostream_set(ssl_set, pool,
-                                                          ssl_set_r);
+       master_service_ssl_client_settings_to_iostream_set(ssl_set, ssl_set_r);
        settings_free(ssl_set);
        return 0;
 }
index 11e877fada795e5a26ccc4e0c412f5167b41d001..f913ade4619b50c88eecf8010e0b58e72b44655a 100644 (file)
@@ -155,8 +155,8 @@ mail_storage_service_user_get_input(struct mail_storage_service_user *user);
 struct settings_instance *
 mail_storage_service_user_get_settings_instance(struct mail_storage_service_user *user);
 int mail_storage_service_user_init_ssl_client_settings(
-       struct mail_storage_service_user *user, pool_t pool,
-       struct ssl_iostream_settings *ssl_set_r, const char **error_r);
+       struct mail_storage_service_user *user,
+       const struct ssl_iostream_settings **ssl_set_r, const char **error_r);
 struct mail_storage_service_ctx *
 mail_storage_service_user_get_service_ctx(struct mail_storage_service_user *user);
 pool_t mail_storage_service_user_get_pool(struct mail_storage_service_user *user);
index 90f392ad225baccde6e8f7ff9ccaf91decd5c26e..6eb7449fdeabf2df2c7ed8d0f4417ab6abc8eec1 100644 (file)
@@ -454,7 +454,7 @@ mail_storage_create_full_real(struct mail_namespace *ns, const char *driver,
        if (storage->v.list_index_rebuild != NULL &&
            storage->mailboxes_fs == NULL) {
                struct fs_settings fs_set;
-               struct ssl_iostream_settings ssl_set;
+               const struct ssl_iostream_settings *ssl_set;
                const char *error;
                i_zero(&fs_set);
 
index b608bc524c6bf06b4cd71378d83564e7db19c31f..d083ef83863514447577aa8721334fb5f186b0df 100644 (file)
@@ -153,11 +153,9 @@ int mail_user_init(struct mail_user *user, const char **error_r)
        else
                mail_user_expand_plugins_envs(user, user->_mail_set);
 
-       user->ssl_set = p_new(user->pool, struct ssl_iostream_settings, 1);
        if (user->error == NULL &&
            mail_storage_service_user_init_ssl_client_settings(
-                       user->service_user, user->pool,
-                       user->ssl_set, &error) < 0)
+                       user->service_user, &user->ssl_set, &error) < 0)
                user->error = p_strdup(user->pool, error);
 
        /* autocreated users for shared mailboxes need to be fully initialized
@@ -752,7 +750,7 @@ struct mail_user *mail_user_dup(struct mail_user *user)
 
 void mail_user_init_fs_settings(struct mail_user *user,
                                struct fs_settings *fs_set,
-                               struct ssl_iostream_settings *ssl_set_r)
+                               const struct ssl_iostream_settings **ssl_set_r)
 {
        fs_set->event_parent = user->event;
        fs_set->username = user->username;
@@ -762,8 +760,8 @@ void mail_user_init_fs_settings(struct mail_user *user,
        fs_set->debug = event_want_debug(user->event);
        fs_set->enable_timing = user->stats_enabled;
 
-       fs_set->ssl_client_set = ssl_set_r;
-       *ssl_set_r = *user->ssl_set;
+       fs_set->ssl_client_set = user->ssl_set;
+       *ssl_set_r = user->ssl_set;
 }
 
 static int
index 30b3a2998484d47acb810684b9732dbbb622b236..6a191e6b8f76c215dd29bd1da8e8f2b7f0136753 100644 (file)
@@ -61,7 +61,7 @@ struct mail_user {
 
        const struct mail_user_settings *set;
        struct mail_storage_settings *_mail_set;
-       struct ssl_iostream_settings *ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        struct mail_namespace *namespaces;
        struct mail_storage *storages;
        struct dict_op_settings *dict_op_set;
@@ -205,7 +205,7 @@ void mail_user_add_event_fields(struct mail_user *user);
 /* Initialize fs_settings from mail_user settings. */
 void mail_user_init_fs_settings(struct mail_user *user,
                                struct fs_settings *fs_set,
-                               struct ssl_iostream_settings *ssl_set_r);
+                               const struct ssl_iostream_settings **ssl_set_r);
 
 /* Try to mkdir() user's home directory. Ideally this should be called only
    after the caller tries to create a file to the home directory, but it fails
index fc9ef670b3466dd99492b806174030ef52ac9c42..950702b18a4fa83f34d031ab92998aa5a1a7e203 100644 (file)
@@ -2087,7 +2087,7 @@ int mailbox_list_init_fs(struct mailbox_list *list, struct event *event_parent,
                         struct fs **fs_r, const char **error_r)
 {
        struct fs_settings fs_set;
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        struct mailbox_list_fs_context *ctx;
        struct fs *parent_fs;
 
index 64250288c7c89694f162a3182b6867c0c6d8e5ab..bb86e96cf77acc414a0e8fe9d09fed33a492e13f 100644 (file)
@@ -196,7 +196,7 @@ static void lmtp_proxy_connection_finish(struct lmtp_proxy_connection *conn)
 
 static int
 lmtp_proxy_connection_init_ssl(struct lmtp_proxy_connection *conn,
-                              struct ssl_iostream_settings *ssl_set_r,
+                              const struct ssl_iostream_settings **ssl_set_r,
                               enum smtp_client_connection_ssl_mode *ssl_mode_r,
                               const char **error_r)
 {
@@ -205,7 +205,7 @@ lmtp_proxy_connection_init_ssl(struct lmtp_proxy_connection *conn,
        *ssl_mode_r = SMTP_CLIENT_SSL_MODE_NONE;
 
        if ((conn->set.set.ssl_flags & AUTH_PROXY_SSL_FLAG_YES) == 0) {
-               i_zero(ssl_set_r);
+               *ssl_set_r = NULL;
                return 0;
        }
 
@@ -214,9 +214,17 @@ lmtp_proxy_connection_init_ssl(struct lmtp_proxy_connection *conn,
                         &master_ssl_set, error_r) < 0)
                return -1;
        master_service_ssl_client_settings_to_iostream_set(
-               master_ssl_set, pool_datastack_create(), ssl_set_r);
-       if ((conn->set.set.ssl_flags & AUTH_PROXY_SSL_FLAG_ANY_CERT) != 0)
-               ssl_set_r->allow_invalid_cert = TRUE;
+               master_ssl_set, ssl_set_r);
+       if ((conn->set.set.ssl_flags & AUTH_PROXY_SSL_FLAG_ANY_CERT) != 0) {
+               pool_t pool = pool_alloconly_create("ssl iostream settings",
+                                                   sizeof(**ssl_set_r));
+               struct ssl_iostream_settings *ssl_set_copy =
+                       p_memdup(pool, *ssl_set_r, sizeof(**ssl_set_r));
+               ssl_set_copy->pool = pool;
+               pool_add_external_ref(pool, (*ssl_set_r)->pool);
+               ssl_set_copy->allow_invalid_cert = TRUE;
+               *ssl_set_r = ssl_set_copy;
+       }
 
        if ((conn->set.set.ssl_flags & AUTH_PROXY_SSL_FLAG_STARTTLS) == 0)
                *ssl_mode_r = SMTP_CLIENT_SSL_MODE_IMMEDIATE;
@@ -253,7 +261,7 @@ lmtp_proxy_get_connection(struct lmtp_proxy *proxy,
        struct client *client = proxy->client;
        struct lmtp_proxy_connection *conn;
        enum smtp_client_connection_ssl_mode ssl_mode;
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
 
        i_assert(set->set.timeout_msecs > 0);
 
@@ -287,7 +295,7 @@ lmtp_proxy_get_connection(struct lmtp_proxy *proxy,
 
        i_zero(&lmtp_set);
        lmtp_set.my_ip = conn->set.set.source_ip;
-       lmtp_set.ssl = &ssl_set;
+       lmtp_set.ssl = ssl_set;
        lmtp_set.peer_trusted = !conn->set.set.remote_not_trusted;
        lmtp_set.forced_capabilities = SMTP_CAPABILITY__ORCPT;
        lmtp_set.mail_send_broken_path = TRUE;
@@ -304,6 +312,7 @@ lmtp_proxy_get_connection(struct lmtp_proxy *proxy,
                        conn->set.set.host, conn->set.set.port,
                        ssl_mode, &lmtp_set);
        }
+       settings_free(ssl_set);
        struct smtp_proxy_data proxy_data = {
                .session = t_strdup_printf("%s:P%u", proxy->trans->id,
                                           ++proxy->proxy_session_seq),
index 731fcd368f2220094f70230fb5bf4d822d6d8995..fc36dbae2e64b32cd732105102a535cef97606e0 100644 (file)
@@ -654,7 +654,7 @@ static int client_sni_callback(const char *name, const char **error_r,
 {
        struct client *client = context;
        struct ssl_iostream_context *ssl_ctx;
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        const char *error;
 
        if (client->ssl_servername_settings_read)
@@ -687,12 +687,14 @@ static int client_sni_callback(const char *name, const char **error_r,
        settings_free(old_ssl_server_set);
 
        master_service_ssl_server_settings_to_iostream_set(client->ssl_set,
-               client->ssl_server_set, pool_datastack_create(), &ssl_set);
-       if (ssl_iostream_server_context_cache_get(&ssl_set, &ssl_ctx, &error) < 0) {
+               client->ssl_server_set, &ssl_set);
+       if (ssl_iostream_server_context_cache_get(ssl_set, &ssl_ctx, &error) < 0) {
                *error_r = t_strdup_printf(
                        "Failed to initialize SSL server context: %s", error);
+               settings_free(ssl_set);
                return -1;
        }
+       settings_free(ssl_set);
        ssl_iostream_change_context(client->ssl_iostream, ssl_ctx);
        ssl_iostream_context_unref(&ssl_ctx);
        return 0;
@@ -701,7 +703,7 @@ static int client_sni_callback(const char *name, const char **error_r,
 int client_init_ssl(struct client *client)
 {
        struct ssl_iostream_context *ssl_ctx;
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        const char *error;
 
        i_assert(client->fd != -1);
@@ -712,12 +714,15 @@ int client_init_ssl(struct client *client)
        }
 
        master_service_ssl_server_settings_to_iostream_set(client->ssl_set,
-               client->ssl_server_set, pool_datastack_create(), &ssl_set);
-       if (ssl_iostream_server_context_cache_get(&ssl_set, &ssl_ctx, &error) < 0) {
+               client->ssl_server_set, &ssl_set);
+       if (ssl_iostream_server_context_cache_get(ssl_set, &ssl_ctx, &error) < 0) {
                e_error(client->event,
                        "Failed to initialize SSL server context: %s", error);
+               settings_free(ssl_set);
                return -1;
        }
+       settings_free(ssl_set);
+
        if (client->v.iostream_change_pre != NULL)
                client->v.iostream_change_pre(client);
        int ret = io_stream_create_ssl_server(ssl_ctx, client->event,
index fc7c6b2d19d4f2a0280a8a1161c7dbe5043efc56..79f0b35e8fc5f33f60f0c81cb526905dc4b34cc0 100644 (file)
@@ -16,6 +16,7 @@
 #include "str.h"
 #include "strescape.h"
 #include "time-util.h"
+#include "settings.h"
 #include "master-service.h"
 #include "master-service-ssl-settings.h"
 #include "client-common.h"
@@ -1198,24 +1199,30 @@ void login_proxy_detach(struct login_proxy *proxy)
 int login_proxy_starttls(struct login_proxy *proxy)
 {
        struct ssl_iostream_context *ssl_ctx;
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
+       struct ssl_iostream_settings *ssl_set_copy;
        const char *error;
        bool add_multiplex_istream = FALSE;
 
        master_service_ssl_client_settings_to_iostream_set(
-               proxy->client->ssl_set, pool_datastack_create(), &ssl_set);
+               proxy->client->ssl_set, &ssl_set);
+       pool_t pool = pool_alloconly_create("ssl iostream settings",
+                                           sizeof(*ssl_set));
+       ssl_set_copy = p_memdup(pool, ssl_set, sizeof(*ssl_set));
+       ssl_set_copy->pool = pool;
+       pool_add_external_ref(pool, ssl_set->pool);
        if ((proxy->ssl_flags & AUTH_PROXY_SSL_FLAG_ANY_CERT) != 0)
-               ssl_set.allow_invalid_cert = TRUE;
+               ssl_set_copy->allow_invalid_cert = TRUE;
        /* NOTE: We're explicitly disabling ssl_client_ca_* settings for now
           at least. The main problem is that we're chrooted, so we can't read
           them at this point anyway. The second problem is that especially
           ssl_client_ca_dir does blocking disk I/O, which could cause
           unexpected hangs when login process handles multiple clients. */
-       ssl_set.ca_file = ssl_set.ca_dir = NULL;
+       ssl_set_copy->ca_file = ssl_set_copy->ca_dir = NULL;
 
        io_remove(&proxy->side_channel_io);
        io_remove(&proxy->server_io);
-       if (ssl_iostream_client_context_cache_get(&ssl_set, &ssl_ctx, &error) < 0) {
+       if (ssl_iostream_client_context_cache_get(ssl_set_copy, &ssl_ctx, &error) < 0) {
                const char *reason = t_strdup_printf(
                        "Failed to create SSL client context: %s", error);
                login_proxy_failed(proxy, proxy->event,
@@ -1245,9 +1252,12 @@ int login_proxy_starttls(struct login_proxy *proxy)
                login_proxy_failed(proxy, proxy->event,
                                   LOGIN_PROXY_FAILURE_TYPE_INTERNAL, reason);
                ssl_iostream_context_unref(&ssl_ctx);
+               settings_free(ssl_set_copy);
                return -1;
        }
        ssl_iostream_context_unref(&ssl_ctx);
+       settings_free(ssl_set_copy);
+
        if (ssl_iostream_handshake(proxy->server_ssl_iostream) < 0) {
                error = ssl_iostream_get_last_error(proxy->server_ssl_iostream);
                const char *reason = t_strdup_printf(
index b594e4bae1cac48078ddf1320c0975559b2559ac..708e78392ea211f4f81920883db8cfe10d77aa17 100644 (file)
@@ -342,16 +342,17 @@ static void login_load_modules(void)
 
 static void login_ssl_init(void)
 {
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
        const char *error;
 
        if (strcmp(global_ssl_server_settings->ssl, "no") == 0)
                return;
 
        master_service_ssl_server_settings_to_iostream_set(global_ssl_settings,
-               global_ssl_server_settings, pool_datastack_create(), &ssl_set);
-       if (io_stream_ssl_global_init(&ssl_set, &error) < 0)
+               global_ssl_server_settings, &ssl_set);
+       if (io_stream_ssl_global_init(ssl_set, &error) < 0)
                i_fatal("Failed to initialize SSL library: %s", error);
+       settings_free(ssl_set);
        login_ssl_initialized = TRUE;
 }
 
index 3e00cb0c466901f234e036612a5b35f60c26312f..e40138cbf94760e7f8e0bc1cf103b28b257e26f2 100644 (file)
@@ -4,6 +4,7 @@
 #include "ioloop.h"
 #include "str.h"
 #include "event-exporter.h"
+#include "settings.h"
 #include "http-client.h"
 #include "iostream-ssl.h"
 #include "master-service.h"
@@ -51,18 +52,18 @@ void event_export_transport_http_post(const struct exporter *exporter,
        struct http_client_request *req;
 
        if (exporter_http_client == NULL) {
-               struct ssl_iostream_settings ssl_set;
+               const struct ssl_iostream_settings *ssl_set = NULL;
 
                struct http_client_settings set = {
                        .dns_client_socket_path = "dns-client",
                };
                if (master_ssl_set != NULL) {
                        master_service_ssl_client_settings_to_iostream_set(
-                               master_ssl_set, pool_datastack_create(),
-                               &ssl_set);
-                       set.ssl = &ssl_set;
+                               master_ssl_set, &ssl_set);
+                       set.ssl = ssl_set;
                }
                exporter_http_client = http_client_init(&set);
+               settings_free(ssl_set);
        }
 
        req = http_client_request_url_str(exporter_http_client, "POST",
index 76ffdfb429193d6836a40a7ec9d5a643e43da8bd..7398cb7cdd2053f360f19ed65c5d76db19e46a14 100644 (file)
@@ -3,6 +3,7 @@
 #include "submission-common.h"
 #include "str.h"
 #include "str-sanitize.h"
+#include "settings.h"
 #include "mail-user.h"
 #include "iostream-ssl.h"
 #include "smtp-client.h"
@@ -1077,7 +1078,8 @@ submission_backend_relay_create(
 {
        struct submission_backend_relay *rbackend;
        struct mail_user *user = client->user;
-       struct ssl_iostream_settings ssl_set;
+       const struct ssl_iostream_settings *ssl_set;
+       struct ssl_iostream_settings *ssl_set_copy = NULL;
        struct smtp_client_settings smtp_set;
        pool_t pool;
 
@@ -1088,15 +1090,22 @@ submission_backend_relay_create(
 
        event_set_append_log_prefix(rbackend->backend.event, "relay: ");
 
-       ssl_set = *user->ssl_set;
-       if (!set->ssl_verify)
-               ssl_set.allow_invalid_cert = TRUE;
+       ssl_set = user->ssl_set;
+       if (!set->ssl_verify) {
+               pool_t pool = pool_alloconly_create("ssl iostream settings",
+                                                   sizeof(*ssl_set));
+               ssl_set_copy = p_memdup(pool, ssl_set, sizeof(*ssl_set));
+               ssl_set_copy->pool = pool;
+               pool_add_external_ref(pool, ssl_set->pool);
+               ssl_set_copy->allow_invalid_cert = TRUE;
+               ssl_set = ssl_set_copy;
+       }
 
        /* make relay connection */
        i_zero(&smtp_set);
        smtp_set.my_hostname = set->my_hostname;
        smtp_set.extra_capabilities = set->extra_capabilities;
-       smtp_set.ssl = &ssl_set;
+       smtp_set.ssl = ssl_set;
        smtp_set.debug = event_want_debug(rbackend->backend.event);
        smtp_set.event_parent = rbackend->backend.event;
 
@@ -1141,6 +1150,7 @@ submission_backend_relay_create(
                        smtp_client, set->protocol, &set->ip, set->port,
                        set->host, set->ssl_mode, &smtp_set);
        }
+       settings_free(ssl_set_copy);
 
        return rbackend;
 }