From: Timo Sirainen Date: Fri, 16 Jun 2023 00:00:41 +0000 (+0300) Subject: lib-ssl-iostream, global: Add ssl_iostream_settings.pool X-Git-Tag: 2.4.1~1501 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcaeb3d0100e47a78c0076f18aa2c82db7d7ed4a;p=thirdparty%2Fdovecot%2Fcore.git lib-ssl-iostream, global: Add ssl_iostream_settings.pool Change all callers to set and use the pool properly. --- diff --git a/src/auth/auth-policy.c b/src/auth/auth-policy.c index a459d8a668..fe0fe9e38f 100644 --- a/src/auth/auth-policy.c +++ b/src/auth/auth-policy.c @@ -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 */ diff --git a/src/auth/db-oauth2.c b/src/auth/db-oauth2.c index 2789d97485..e0e0570050 100644 --- a/src/auth/db-oauth2.c +++ b/src/auth/db-oauth2.c @@ -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; diff --git a/src/doveadm/doveadm-dsync.c b/src/doveadm/doveadm-dsync.c index f06ae3ff21..342fb8c56e 100644 --- a/src/doveadm/doveadm-dsync.c +++ b/src/doveadm/doveadm-dsync.c @@ -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( diff --git a/src/doveadm/doveadm-fs.c b/src/doveadm/doveadm-fs.c index fdd2b62e4a..a7861f6448 100644 --- a/src/doveadm/doveadm-fs.c +++ b/src/doveadm/doveadm-fs.c @@ -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; } diff --git a/src/doveadm/doveadm-mail-server.c b/src/doveadm/doveadm-mail-server.c index 4fce499d54..51a5031335 100644 --- a/src/doveadm/doveadm-mail-server.c +++ b/src/doveadm/doveadm-mail-server.c @@ -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); diff --git a/src/doveadm/doveadm-settings.c b/src/doveadm/doveadm-settings.c index 17b2695ea3..b09f42b25a 100644 --- a/src/doveadm/doveadm-settings.c +++ b/src/doveadm/doveadm-settings.c @@ -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) diff --git a/src/doveadm/doveadm-settings.h b/src/doveadm/doveadm-settings.h index e54023cff1..6990354225 100644 --- a/src/doveadm/doveadm-settings.h +++ b/src/doveadm/doveadm-settings.h @@ -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 diff --git a/src/lib-doveadm/doveadm-client.c b/src/lib-doveadm/doveadm-client.c index 41dfcb9961..a85bd7cb66 100644 --- a/src/lib-doveadm/doveadm-client.c +++ b/src/lib-doveadm/doveadm-client.c @@ -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) diff --git a/src/lib-doveadm/doveadm-client.h b/src/lib-doveadm/doveadm-client.h index 23ade6cd84..fd2e4f5186 100644 --- a/src/lib-doveadm/doveadm-client.h +++ b/src/lib-doveadm/doveadm-client.h @@ -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; diff --git a/src/lib-http/Makefile.am b/src/lib-http/Makefile.am index 7e912861ec..09bf2bcecb 100644 --- a/src/lib-http/Makefile.am +++ b/src/lib-http/Makefile.am @@ -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 \ diff --git a/src/lib-http/http-client.c b/src/lib-http/http-client.c index 9eacd23d9c..03f3625dc7 100644 --- a/src/lib-http/http-client.c +++ b/src/lib-http/http-client.c @@ -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') { diff --git a/src/lib-http/http-server.c b/src/lib-http/http-server.c index dd89a168c9..3827ed937e 100644 --- a/src/lib-http/http-server.c +++ b/src/lib-http/http-server.c @@ -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); diff --git a/src/lib-http/test-http-client.c b/src/lib-http/test-http-client.c index 18a834dcb3..6a7ea6f711 100644 --- a/src/lib-http/test-http-client.c +++ b/src/lib-http/test-http-client.c @@ -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 */ diff --git a/src/lib-imap-client/Makefile.am b/src/lib-imap-client/Makefile.am index f5721e1206..4b6597781f 100644 --- a/src/lib-imap-client/Makefile.am +++ b/src/lib-imap-client/Makefile.am @@ -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 \ diff --git a/src/lib-imap-client/imapc-client.c b/src/lib-imap-client/imapc-client.c index 10ca1a5bcb..5ca8b66a33 100644 --- a/src/lib-imap-client/imapc-client.c +++ b/src/lib-imap-client/imapc-client.c @@ -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); diff --git a/src/lib-lua/dlua-dovecot-http.c b/src/lib-lua/dlua-dovecot-http.c index ebab5212c0..70a3d39dbd 100644 --- a/src/lib-lua/dlua-dovecot-http.c +++ b/src/lib-lua/dlua-dovecot-http.c @@ -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; } diff --git a/src/lib-master/master-service-ssl-settings.c b/src/lib-master/master-service-ssl-settings.c index 614f273ee4..6e83838702 100644 --- a/src/lib-master/master-service-ssl-settings.c +++ b/src/lib-master/master-service-ssl-settings.c @@ -166,64 +166,74 @@ master_service_ssl_server_settings_check(void *_set, pool_t pool ATTR_UNUSED, } /* */ -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; } diff --git a/src/lib-master/master-service-ssl-settings.h b/src/lib-master/master-service-ssl-settings.h index d1b2b23a90..6b2cc490b6 100644 --- a/src/lib-master/master-service-ssl-settings.h +++ b/src/lib-master/master-service-ssl-settings.h @@ -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 diff --git a/src/lib-master/master-service-ssl.c b/src/lib-master/master-service-ssl.c index f4a3022ec3..cb8181a327 100644 --- a/src/lib-master/master-service-ssl.c +++ b/src/lib-master/master-service-ssl.c @@ -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; diff --git a/src/lib-smtp/smtp-client-connection.c b/src/lib-smtp/smtp-client-connection.c index 376ca3b64d..629318db65 100644 --- a/src/lib-smtp/smtp-client-connection.c +++ b/src/lib-smtp/smtp-client-connection.c @@ -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') { diff --git a/src/lib-smtp/smtp-client.c b/src/lib-smtp/smtp-client.c index 86c8bb1d54..e0dbc6fd92 100644 --- a/src/lib-smtp/smtp-client.c +++ b/src/lib-smtp/smtp-client.c @@ -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); diff --git a/src/lib-smtp/smtp-server-connection.c b/src/lib-smtp/smtp-server-connection.c index 0bc4360060..9090435655 100644 --- a/src/lib-smtp/smtp-server-connection.c +++ b/src/lib-smtp/smtp-server-connection.c @@ -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); diff --git a/src/lib-smtp/smtp-server.c b/src/lib-smtp/smtp-server.c index e0afde3116..9a7028dbaa 100644 --- a/src/lib-smtp/smtp-server.c +++ b/src/lib-smtp/smtp-server.c @@ -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); diff --git a/src/lib-smtp/smtp-submit.c b/src/lib-smtp/smtp-submit.c index 0328b95488..e645bacc46 100644 --- a/src/lib-smtp/smtp-submit.c +++ b/src/lib-smtp/smtp-submit.c @@ -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; diff --git a/src/lib-ssl-iostream/iostream-ssl-test.c b/src/lib-ssl-iostream/iostream-ssl-test.c index 43a302278d..87b2b58906 100644 --- a/src/lib-ssl-iostream/iostream-ssl-test.c +++ b/src/lib-ssl-iostream/iostream-ssl-test.c @@ -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; } diff --git a/src/lib-ssl-iostream/iostream-ssl.h b/src/lib-ssl-iostream/iostream-ssl.h index 40e41349df..274517fb1c 100644 --- a/src/lib-ssl-iostream/iostream-ssl.h +++ b/src/lib-ssl-iostream/iostream-ssl.h @@ -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; diff --git a/src/lib-storage/index/pop3c/pop3c-client.c b/src/lib-storage/index/pop3c/pop3c-client.c index bb31d61825..a5be16eece 100644 --- a/src/lib-storage/index/pop3c/pop3c-client.c +++ b/src/lib-storage/index/pop3c/pop3c-client.c @@ -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); diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index 804983b524..f91400f72b 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -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; } diff --git a/src/lib-storage/mail-storage-service.h b/src/lib-storage/mail-storage-service.h index 11e877fada..f913ade461 100644 --- a/src/lib-storage/mail-storage-service.h +++ b/src/lib-storage/mail-storage-service.h @@ -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); diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 90f392ad22..6eb7449fde 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -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); diff --git a/src/lib-storage/mail-user.c b/src/lib-storage/mail-user.c index b608bc524c..d083ef8386 100644 --- a/src/lib-storage/mail-user.c +++ b/src/lib-storage/mail-user.c @@ -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 diff --git a/src/lib-storage/mail-user.h b/src/lib-storage/mail-user.h index 30b3a29984..6a191e6b8f 100644 --- a/src/lib-storage/mail-user.h +++ b/src/lib-storage/mail-user.h @@ -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 diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index fc9ef670b3..950702b18a 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -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; diff --git a/src/lmtp/lmtp-proxy.c b/src/lmtp/lmtp-proxy.c index 64250288c7..bb86e96cf7 100644 --- a/src/lmtp/lmtp-proxy.c +++ b/src/lmtp/lmtp-proxy.c @@ -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), diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index 731fcd368f..fc36dbae2e 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -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, diff --git a/src/login-common/login-proxy.c b/src/login-common/login-proxy.c index fc7c6b2d19..79f0b35e8f 100644 --- a/src/login-common/login-proxy.c +++ b/src/login-common/login-proxy.c @@ -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( diff --git a/src/login-common/main.c b/src/login-common/main.c index b594e4bae1..708e78392e 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -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; } diff --git a/src/stats/event-exporter-transport-http-post.c b/src/stats/event-exporter-transport-http-post.c index 3e00cb0c46..e40138cbf9 100644 --- a/src/stats/event-exporter-transport-http-post.c +++ b/src/stats/event-exporter-transport-http-post.c @@ -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", diff --git a/src/submission/submission-backend-relay.c b/src/submission/submission-backend-relay.c index 76ffdfb429..7398cb7cdd 100644 --- a/src/submission/submission-backend-relay.c +++ b/src/submission/submission-backend-relay.c @@ -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; }