]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream: Change ssl_server_request_client_cert to enum
authorAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 31 Dec 2024 10:40:39 +0000 (12:40 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 26 May 2025 05:39:13 +0000 (05:39 +0000)
If set to no, client certificates are not asked or verified.
If set to yes, client certificates are asked and verified.
If set to any-cert, client certificates are asked but verified with
fingerprinting

src/lib-ssl-iostream/ssl-settings.c
src/lib-ssl-iostream/ssl-settings.h

index 9572f978ef769094db42034d34530f8a62c6473f..9a70badf0d478744a12e4c94c32f8d7b41e1ee17 100644 (file)
@@ -89,7 +89,7 @@ static const struct setting_define ssl_server_setting_defines[] = {
        DEF(ENUM, ssl_server_prefer_ciphers),
 
        DEF(BOOL, ssl_server_require_crl),
-       DEF(BOOL, ssl_server_request_client_cert),
+       DEF(ENUM, ssl_server_request_client_cert),
 
        SETTING_DEFINE_LIST_END
 };
@@ -107,7 +107,7 @@ static const struct ssl_server_settings ssl_server_default_settings = {
        .ssl_server_prefer_ciphers = "client:server",
 
        .ssl_server_require_crl = TRUE,
-       .ssl_server_request_client_cert = FALSE,
+       .ssl_server_request_client_cert = "no:yes:any-cert",
 };
 
 const struct setting_parser_info ssl_server_setting_parser_info = {
@@ -184,9 +184,21 @@ ssl_server_settings_check(void *_set, pool_t pool ATTR_UNUSED,
                return TRUE;
        }
 
-       if (set->ssl_server_request_client_cert &&
+       if (strcmp(set->ssl_server_request_client_cert, "no") == 0) {
+               set->parsed_opts.request_client_cert = FALSE;
+               set->parsed_opts.verify_client_cert = FALSE;
+       } else if (strcmp(set->ssl_server_request_client_cert, "yes") == 0) {
+               set->parsed_opts.request_client_cert = TRUE;
+               set->parsed_opts.verify_client_cert = TRUE;
+       } else if (strcmp(set->ssl_server_request_client_cert, "any-cert") == 0) {
+               set->parsed_opts.request_client_cert = TRUE;
+               set->parsed_opts.verify_client_cert = FALSE;
+       }
+
+       if (set->parsed_opts.request_client_cert &&
+           set->parsed_opts.verify_client_cert &&
            *set->ssl_server_ca_file == '\0') {
-               *error_r = "ssl_server_request_client_cert set, but ssl_server_ca_file not";
+               *error_r = "ssl_server_request_client_cert=yes, but ssl_server_ca_file not provided";
                return FALSE;
        }
        return TRUE;
@@ -297,8 +309,10 @@ void ssl_server_settings_to_iostream_set(
                ssl_server_set->ssl_server_cert_username_field;
        set->prefer_server_ciphers =
                strcmp(ssl_server_set->ssl_server_prefer_ciphers, "server") == 0;
-       set->verify_remote_cert = ssl_server_set->ssl_server_request_client_cert;
-       set->allow_invalid_cert = !set->verify_remote_cert;
+
+       set->verify_remote_cert = ssl_server_set->parsed_opts.request_client_cert;
+       set->allow_invalid_cert = !ssl_server_set->parsed_opts.verify_client_cert ||
+                                 !set->verify_remote_cert;
        /* ssl_server_require_crl is used only for checking client-provided SSL
           certificate's CRL. */
        set->skip_crl_check = !ssl_server_set->ssl_server_require_crl;
index 83b08155254fbbf927280501b761951a6977dd34..544fc6be5b9fa20087f40a44278d80cd4daffc93 100644 (file)
@@ -42,9 +42,15 @@ struct ssl_server_settings {
        const char *ssl_server_dh_file;
        const char *ssl_server_cert_username_field;
        const char *ssl_server_prefer_ciphers;
+       const char *ssl_server_request_client_cert;
 
        bool ssl_server_require_crl;
-       bool ssl_server_request_client_cert;
+
+       /* parsed: */
+       struct {
+               bool request_client_cert;
+               bool verify_client_cert;
+       } parsed_opts;
 };
 
 extern const struct setting_parser_info ssl_setting_parser_info;