From: Aki Tuomi Date: Tue, 31 Dec 2024 10:40:39 +0000 (+0200) Subject: lib-ssl-iostream: Change ssl_server_request_client_cert to enum X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f37433ad0a85b62efd64d7632fa37c42a2f510bf;p=thirdparty%2Fdovecot%2Fcore.git lib-ssl-iostream: Change ssl_server_request_client_cert to enum 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 --- diff --git a/src/lib-ssl-iostream/ssl-settings.c b/src/lib-ssl-iostream/ssl-settings.c index 9572f978ef..9a70badf0d 100644 --- a/src/lib-ssl-iostream/ssl-settings.c +++ b/src/lib-ssl-iostream/ssl-settings.c @@ -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; diff --git a/src/lib-ssl-iostream/ssl-settings.h b/src/lib-ssl-iostream/ssl-settings.h index 83b0815525..544fc6be5b 100644 --- a/src/lib-ssl-iostream/ssl-settings.h +++ b/src/lib-ssl-iostream/ssl-settings.h @@ -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;