From: Timo Sirainen Date: Thu, 29 Jul 2021 18:45:18 +0000 (+0300) Subject: lib-master, login-common: Split off master_service_ssl_server_settings X-Git-Tag: 2.3.17~242 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6cea575772189495a612d4e55f207a2d5009db2;p=thirdparty%2Fdovecot%2Fcore.git lib-master, login-common: Split off master_service_ssl_server_settings --- diff --git a/src/config/settings-get.pl b/src/config/settings-get.pl index e900baaf7d..ca124eb4ae 100755 --- a/src/config/settings-get.pl +++ b/src/config/settings-get.pl @@ -148,6 +148,7 @@ print "};\n"; print "const struct setting_parser_info *all_default_roots[] = {\n"; print "\t&master_service_setting_parser_info,\n"; print "\t&master_service_ssl_setting_parser_info,\n"; +print "\t&master_service_ssl_server_setting_parser_info,\n"; print "\t&smtp_submit_setting_parser_info,\n"; foreach my $name (sort(keys %parsers)) { my $module = $parsers{$name}; diff --git a/src/lib-master/master-service-settings.c b/src/lib-master/master-service-settings.c index 4f81c89b9e..b3b1bbeb6b 100644 --- a/src/lib-master/master-service-settings.c +++ b/src/lib-master/master-service-settings.c @@ -226,7 +226,7 @@ master_service_exec_config(struct master_service *service, if (service->want_ssl_settings && (input->module != NULL || input->extra_modules != NULL)) { strarr_push(&conf_argv, "-m"); - strarr_push(&conf_argv, "ssl"); + strarr_push(&conf_argv, "ssl-server"); } if (input->parse_full_config) strarr_push(&conf_argv, "-p"); @@ -359,7 +359,7 @@ config_build_request(struct master_service *service, string_t *str, } if (service->want_ssl_settings && (input->module != NULL || input->extra_modules != NULL)) - str_append(str, "\tmodule=ssl"); + str_append(str, "\tmodule=ssl-server"); if (input->service != NULL) str_printfa(str, "\tservice=%s", input->service); if (input->username != NULL) @@ -609,6 +609,8 @@ int master_service_settings_read(struct master_service *service, if (service->want_ssl_settings) { tmp_root = &master_service_ssl_setting_parser_info; array_push_back(&all_roots, &tmp_root); + tmp_root = &master_service_ssl_server_setting_parser_info; + array_push_back(&all_roots, &tmp_root); } if (input->roots != NULL) { for (i = 0; input->roots[i] != NULL; i++) @@ -757,7 +759,7 @@ void **master_service_settings_parser_get_others(struct master_service *service, const struct setting_parser_context *set_parser) { return settings_parser_get_list(set_parser) + 1 + - (service->want_ssl_settings ? 1 : 0); + (service->want_ssl_settings ? 2 : 0); } struct setting_parser_context * diff --git a/src/lib-master/master-service-ssl-settings.c b/src/lib-master/master-service-ssl-settings.c index 9d1f5dda47..a7f5216114 100644 --- a/src/lib-master/master-service-ssl-settings.c +++ b/src/lib-master/master-service-ssl-settings.c @@ -18,16 +18,10 @@ master_service_ssl_settings_check(void *_set, pool_t pool, const char **error_r) static const struct setting_define master_service_ssl_setting_defines[] = { DEF(ENUM, ssl), DEF(STR, ssl_ca), - DEF(STR, ssl_cert), - DEF(STR, ssl_key), - DEF(STR, ssl_alt_cert), - DEF(STR, ssl_alt_key), - DEF(STR, ssl_key_password), DEF(STR, ssl_client_ca_file), DEF(STR, ssl_client_ca_dir), DEF(STR, ssl_client_cert), DEF(STR, ssl_client_key), - DEF(STR, ssl_dh), DEF(STR, ssl_cipher_list), DEF(STR, ssl_cipher_suites), DEF(STR, ssl_curve_list), @@ -52,16 +46,10 @@ static const struct master_service_ssl_settings master_service_ssl_default_setti #endif /* keep synced with mail-storage-settings */ .ssl_ca = "", - .ssl_cert = "", - .ssl_key = "", - .ssl_alt_cert = "", - .ssl_alt_key = "", - .ssl_key_password = "", .ssl_client_ca_file = "", .ssl_client_ca_dir = "", .ssl_client_cert = "", .ssl_client_key = "", - .ssl_dh = "", .ssl_cipher_list = "ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH", .ssl_cipher_suites = "", /* Use TLS library provided value */ .ssl_curve_list = "", @@ -88,6 +76,47 @@ const struct setting_parser_info master_service_ssl_setting_parser_info = { .check_func = master_service_ssl_settings_check }; +#undef DEF +#define DEF(type, name) \ + SETTING_DEFINE_STRUCT_##type(#name, name, struct master_service_ssl_server_settings) + +static const struct setting_define master_service_ssl_server_setting_defines[] = { + DEF(STR, ssl_cert), + DEF(STR, ssl_key), + DEF(STR, ssl_alt_cert), + DEF(STR, ssl_alt_key), + DEF(STR, ssl_key_password), + DEF(STR, ssl_dh), + + SETTING_DEFINE_LIST_END +}; + +static const struct master_service_ssl_server_settings master_service_ssl_server_default_settings = { + .ssl_cert = "", + .ssl_key = "", + .ssl_alt_cert = "", + .ssl_alt_key = "", + .ssl_key_password = "", + .ssl_dh = "", +}; + +static const struct setting_parser_info *master_service_ssl_server_setting_dependencies[] = { + &master_service_ssl_setting_parser_info, + NULL +}; + +const struct setting_parser_info master_service_ssl_server_setting_parser_info = { + .module_name = "ssl-server", + .defines = master_service_ssl_server_setting_defines, + .defaults = &master_service_ssl_server_default_settings, + + .type_offset = SIZE_MAX, + .struct_size = sizeof(struct master_service_ssl_server_settings), + + .parent_offset = SIZE_MAX, + .dependencies = master_service_ssl_server_setting_dependencies, +}; + /* */ static bool master_service_ssl_settings_check(void *_set, pool_t pool ATTR_UNUSED, @@ -171,6 +200,16 @@ master_service_ssl_settings_get(struct master_service *service) return sets[1]; } +const struct master_service_ssl_server_settings * +master_service_ssl_server_settings_get(struct master_service *service) +{ + void **sets; + + i_assert(service->want_ssl_settings); + sets = settings_parser_get_list(service->set_parser); + return sets[2]; +} + 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) @@ -184,7 +223,6 @@ static void master_service_ssl_common_settings_to_iostream_set( clients. But at least for now it's needed for login-proxy. */ set_r->ca = p_strdup_empty(pool, ssl_set->ssl_ca); - set_r->dh = p_strdup(pool, ssl_set->ssl_dh); set_r->crypto_device = p_strdup(pool, ssl_set->ssl_crypto_device); set_r->cert_username_field = p_strdup(pool, ssl_set->ssl_cert_username_field); @@ -213,19 +251,21 @@ void master_service_ssl_client_settings_to_iostream_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) { master_service_ssl_common_settings_to_iostream_set(ssl_set, pool, set_r); - set_r->cert.cert = p_strdup(pool, ssl_set->ssl_cert); - set_r->cert.key = p_strdup(pool, ssl_set->ssl_key); - set_r->cert.key_password = p_strdup(pool, ssl_set->ssl_key_password); - if (ssl_set->ssl_alt_cert != NULL && - *ssl_set->ssl_alt_cert != '\0') { - set_r->alt_cert.cert = p_strdup(pool, ssl_set->ssl_alt_cert); - set_r->alt_cert.key = p_strdup(pool, ssl_set->ssl_alt_key); - set_r->alt_cert.key_password = p_strdup(pool, ssl_set->ssl_key_password); + 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); + 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_r->dh = p_strdup(pool, ssl_server_set->ssl_dh); set_r->verify_remote_cert = ssl_set->ssl_verify_client_cert; set_r->allow_invalid_cert = !set_r->verify_remote_cert; } diff --git a/src/lib-master/master-service-ssl-settings.h b/src/lib-master/master-service-ssl-settings.h index 523f7b6b58..cda3de89a1 100644 --- a/src/lib-master/master-service-ssl-settings.h +++ b/src/lib-master/master-service-ssl-settings.h @@ -7,16 +7,10 @@ struct ssl_iostream_settings; struct master_service_ssl_settings { const char *ssl; const char *ssl_ca; - const char *ssl_cert; - const char *ssl_alt_cert; - const char *ssl_key; - const char *ssl_alt_key; - const char *ssl_key_password; const char *ssl_client_ca_file; const char *ssl_client_ca_dir; const char *ssl_client_cert; const char *ssl_client_key; - const char *ssl_dh; const char *ssl_cipher_list; const char *ssl_cipher_suites; const char *ssl_curve_list; @@ -38,17 +32,30 @@ struct master_service_ssl_settings { } parsed_opts; }; +struct master_service_ssl_server_settings { + const char *ssl_cert; + const char *ssl_alt_cert; + const char *ssl_key; + const char *ssl_alt_key; + const char *ssl_key_password; + const char *ssl_dh; +}; + extern const struct setting_parser_info master_service_ssl_setting_parser_info; +extern const struct setting_parser_info master_service_ssl_server_setting_parser_info; const struct master_service_ssl_settings * master_service_ssl_settings_get(struct master_service *service); +const struct master_service_ssl_server_settings * +master_service_ssl_server_settings_get(struct master_service *service); /* 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); void master_service_ssl_server_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 master_service_ssl_server_settings *ssl_server_set, + pool_t pool, 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 906ad072ed..5d1b5156cf 100644 --- a/src/lib-master/master-service-ssl.c +++ b/src/lib-master/master-service-ssl.c @@ -45,6 +45,7 @@ bool master_service_ssl_is_enabled(struct master_service *service) void master_service_ssl_ctx_init(struct master_service *service) { const struct master_service_ssl_settings *set; + const struct master_service_ssl_server_settings *server_set; struct ssl_iostream_settings ssl_set; const char *error; @@ -57,6 +58,7 @@ void master_service_ssl_ctx_init(struct master_service *service) i_assert(service->listeners != NULL || service->socket_count == 0); set = master_service_ssl_settings_get(service); + server_set = master_service_ssl_server_settings_get(service); if (strcmp(set->ssl, "no") == 0) { /* SSL disabled, don't use it */ return; @@ -67,15 +69,16 @@ void master_service_ssl_ctx_init(struct master_service *service) ssl_set.cipher_list = set->ssl_cipher_list; ssl_set.curve_list = set->ssl_curve_list; ssl_set.ca = set->ssl_ca; - ssl_set.cert.cert = set->ssl_cert; - ssl_set.cert.key = set->ssl_key; - ssl_set.dh = set->ssl_dh; - ssl_set.cert.key_password = set->ssl_key_password; + ssl_set.cert.cert = server_set->ssl_cert; + ssl_set.cert.key = server_set->ssl_key; + ssl_set.dh = server_set->ssl_dh; + ssl_set.cert.key_password = server_set->ssl_key_password; ssl_set.cert_username_field = set->ssl_cert_username_field; - if (set->ssl_alt_cert != NULL && *set->ssl_alt_cert != '\0') { - ssl_set.alt_cert.cert = set->ssl_alt_cert; - ssl_set.alt_cert.key = set->ssl_alt_key; - ssl_set.alt_cert.key_password = set->ssl_key_password; + if (server_set->ssl_alt_cert != NULL && + *server_set->ssl_alt_cert != '\0') { + ssl_set.alt_cert.cert = server_set->ssl_alt_cert; + ssl_set.alt_cert.key = server_set->ssl_alt_key; + ssl_set.alt_cert.key_password = server_set->ssl_key_password; } ssl_set.crypto_device = set->ssl_crypto_device; ssl_set.skip_crl_check = !set->ssl_require_crl; diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index df11479431..1314efa69b 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -170,7 +170,8 @@ struct client * client_alloc(int fd, pool_t pool, const struct master_service_connection *conn, const struct login_settings *set, - const struct master_service_ssl_settings *ssl_set) + const struct master_service_ssl_settings *ssl_set, + const struct master_service_ssl_server_settings *ssl_server_set) { struct client *client; @@ -190,6 +191,7 @@ client_alloc(int fd, pool_t pool, client->preproxy_pool = pool_alloconly_create(MEMPOOL_GROWING"preproxy pool", 256); client->set = set; client->ssl_set = ssl_set; + client->ssl_server_set = ssl_server_set; p_array_init(&client->module_contexts, client->pool, 5); client->fd = fd; @@ -514,10 +516,11 @@ static int client_sni_callback(const char *name, const char **error_r, client->local_name = p_strdup(client->pool, name); client->set = login_settings_read(client->pool, &client->local_ip, &client->ip, name, - &client->ssl_set, &other_sets); + &client->ssl_set, + &client->ssl_server_set, &other_sets); master_service_ssl_server_settings_to_iostream_set(client->ssl_set, - pool_datastack_create(), &ssl_set); + client->ssl_server_set, pool_datastack_create(), &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); @@ -542,7 +545,7 @@ int client_init_ssl(struct client *client) } master_service_ssl_server_settings_to_iostream_set(client->ssl_set, - pool_datastack_create(), &ssl_set); + client->ssl_server_set, pool_datastack_create(), &ssl_set); /* If the client cert is invalid, we'll reply NO to the login command. */ ssl_set.allow_invalid_cert = TRUE; diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index c8b5a6ef95..84e116dbb8 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -174,6 +174,7 @@ struct client { struct ssl_iostream *ssl_iostream; const struct login_settings *set; const struct master_service_ssl_settings *ssl_set; + const struct master_service_ssl_server_settings *ssl_server_set; const char *session_id, *listener_name, *postlogin_socket_path; const char *local_name; const char *client_cert_common_name; @@ -279,7 +280,8 @@ struct client * client_alloc(int fd, pool_t pool, const struct master_service_connection *conn, const struct login_settings *set, - const struct master_service_ssl_settings *ssl_set); + const struct master_service_ssl_settings *ssl_set, + const struct master_service_ssl_server_settings *ssl_server_set); void client_init(struct client *client, void **other_sets); void client_disconnect(struct client *client, const char *reason, bool add_disconnected_prefix); diff --git a/src/login-common/login-settings.c b/src/login-common/login-settings.c index ccbbb00682..bc8020e3c5 100644 --- a/src/login-common/login-settings.c +++ b/src/login-common/login-settings.c @@ -160,6 +160,7 @@ login_settings_read(pool_t pool, const struct ip_addr *remote_ip, const char *local_name, const struct master_service_ssl_settings **ssl_set_r, + const struct master_service_ssl_server_settings **ssl_server_set_r, void ***other_settings_r) { struct master_service_settings_input input; @@ -212,6 +213,9 @@ login_settings_read(pool_t pool, *ssl_set_r = login_setting_dup(pool, &master_service_ssl_setting_parser_info, settings_parser_get_list(parser)[1]); + *ssl_server_set_r = + login_setting_dup(pool, &master_service_ssl_server_setting_parser_info, + settings_parser_get_list(parser)[2]); *other_settings_r = sets + 1; return sets[0]; } diff --git a/src/login-common/login-settings.h b/src/login-common/login-settings.h index adf078f4c1..5bff8377bd 100644 --- a/src/login-common/login-settings.h +++ b/src/login-common/login-settings.h @@ -2,6 +2,7 @@ #define LOGIN_SETTINGS_H struct master_service_ssl_settings; +struct master_service_ssl_server_settings; struct login_settings { const char *login_trusted_networks; @@ -42,6 +43,7 @@ login_settings_read(pool_t pool, const struct ip_addr *remote_ip, const char *local_name, const struct master_service_ssl_settings **ssl_set_r, + const struct master_service_ssl_server_settings **ssl_server_set_r, void ***other_settings_r) ATTR_NULL(2, 3, 4); void login_settings_deinit(void); diff --git a/src/login-common/main.c b/src/login-common/main.c index e75f7cd618..006166d0b4 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -52,6 +52,7 @@ bool login_ssl_initialized; const struct login_settings *global_login_settings; const struct master_service_ssl_settings *global_ssl_settings; +const struct master_service_ssl_server_settings *global_ssl_server_settings; void **global_other_settings; static ARRAY(struct ip_addr) login_source_ips_array; @@ -164,14 +165,17 @@ client_connected_finish(const struct master_service_connection *conn) struct client *client; const struct login_settings *set; const struct master_service_ssl_settings *ssl_set; + const struct master_service_ssl_server_settings *ssl_server_set; pool_t pool; void **other_sets; pool = pool_alloconly_create("login client", 8*1024); set = login_settings_read(pool, &conn->local_ip, - &conn->remote_ip, NULL, &ssl_set, &other_sets); + &conn->remote_ip, NULL, + &ssl_set, &ssl_server_set, &other_sets); - client = client_alloc(conn->fd, pool, conn, set, ssl_set); + client = client_alloc(conn->fd, pool, conn, set, + ssl_set, ssl_server_set); if (ssl_connections || conn->ssl) { if (client_init_ssl(client) < 0) { client_unref(&client); @@ -381,7 +385,7 @@ static void login_ssl_init(void) return; master_service_ssl_server_settings_to_iostream_set(global_ssl_settings, - pool_datastack_create(), &ssl_set); + global_ssl_server_settings, pool_datastack_create(), &ssl_set); if (io_stream_ssl_global_init(&ssl_set, &error) < 0) i_fatal("Failed to initialize SSL library: %s", error); login_ssl_initialized = TRUE; @@ -552,6 +556,7 @@ int login_binary_run(struct login_binary *binary, global_login_settings = login_settings_read(set_pool, NULL, NULL, NULL, &global_ssl_settings, + &global_ssl_server_settings, &global_other_settings); main_preinit();