]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master, login-common: Split off master_service_ssl_server_settings
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 29 Jul 2021 18:45:18 +0000 (21:45 +0300)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Mon, 9 Aug 2021 15:51:22 +0000 (15:51 +0000)
src/config/settings-get.pl
src/lib-master/master-service-settings.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/login-common/client-common.c
src/login-common/client-common.h
src/login-common/login-settings.c
src/login-common/login-settings.h
src/login-common/main.c

index e900baaf7d17d96def838007c8ce41d3855f9417..ca124eb4ae94248f747cc50e56d26c66f9077144 100755 (executable)
@@ -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};
index 4f81c89b9e6cbb945367e67b8d573c90cc734d4a..b3b1bbeb6b24d16baea966c3692f1d1991fd8316 100644 (file)
@@ -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 *
index 9d1f5dda477b3dd9742886a665688a42c46edb83..a7f52161142fb36a4a5ef25af3551534368bcf04 100644 (file)
@@ -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,
+};
+
 /* <settings checks> */
 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;
 }
index 523f7b6b584251d296110c41b4062c61bca18877..cda3de89a121cf6f3cc00a810eaf3cc09902865d 100644 (file)
@@ -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
index 906ad072ed58afe582599a6f1ba1392c58042398..5d1b5156cfa40274c4929ee3184da1273de98c0b 100644 (file)
@@ -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;
index df11479431d1e5101e472552b5b0039958aeb7b9..1314efa69be532d6951e0251bc72c6f0cd6c70f1 100644 (file)
@@ -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;
index c8b5a6ef95d97a6ecbe5d4623a181191d4e9f63b..84e116dbb8e6c66f6ae6cd712fb55944c4faf6ce 100644 (file)
@@ -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);
index ccbbb00682a669892f59f92f2bb02f09e5e5a4dc..bc8020e3c540417ef4c1ce234a6bd377efcae8d9 100644 (file)
@@ -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];
 }
index adf078f4c126ca1e7c4decc74dc107fb31431958..5bff8377bdd4bf5f2a30b4315454693f6f6c3c73 100644 (file)
@@ -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);
 
index e75f7cd6180353fc41cd7840e447c83a4acc6089..006166d0b428af4181664931e03bb3ccb5e4ba9f 100644 (file)
@@ -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();