]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login-common: Add ssl_client_cert_fp and ssl_client_cert_pubkey_fp if configured
authorAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 31 Dec 2024 10:21:59 +0000 (12:21 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 26 May 2025 05:39:13 +0000 (05:39 +0000)
src/login-common/client-common.c
src/login-common/sasl-server.c

index fd11cb27b58183972172f94e028fd6075f86c337..20b79cc59ec1f3d3b87bcbef75c39d0712487a86 100644 (file)
@@ -1029,6 +1029,36 @@ const char *client_get_session_id(struct client *client)
        return client->session_id;
 }
 
+static int client_get_ssl_client_cert_fp(const char *key, const char **value_r,
+                                        void *context, const char **error_r)
+{
+       struct client *client = context;
+
+       if (!client->connection_tls_secured) {
+               *value_r = "";
+               return 0;
+       }
+
+       const char *client_cert_fp, *pubkey_fp;
+       int ret = ssl_iostream_get_peer_cert_fingerprint(client->ssl_iostream,
+                                                        &client_cert_fp, &pubkey_fp,
+                                                        error_r);
+       if (ret < 0)
+               return -1;
+       else if (ret == 0) {
+               *value_r = "";
+               return 0;
+       }
+
+       if (strcmp(key, "ssl_client_cert_fp") == 0)
+               *value_r = client_cert_fp;
+       else if (strcmp(key, "ssl_client_cert_pubkey_fp") == 0)
+               *value_r = pubkey_fp;
+       else
+               i_unreached();
+       return 0;
+}
+
 static struct var_expand_table login_var_expand_empty_tab[] = {
        { .key = "user", .value = NULL },
 
@@ -1053,6 +1083,8 @@ static struct var_expand_table login_var_expand_empty_tab[] = {
        { .key = "local_name", .value = NULL },
        { .key = "ssl_ja3", .value = NULL },
        { .key = "ssl_ja3_hash", .value = NULL },
+       { .key = "ssl_client_cert_fp", .func = client_get_ssl_client_cert_fp },
+       { .key = "ssl_client_cert_pubkey_fp", .func = client_get_ssl_client_cert_fp },
 
        VAR_EXPAND_TABLE_END
 };
index 08f198752e9b225673fef48c8cbf840fab6cd568..9d4bb024e394645f1015afa6e189ed4c481b3d68 100644 (file)
@@ -529,6 +529,20 @@ int sasl_server_auth_request_info_fill(struct client *client,
                        md5_get_digest(ja3, strlen(ja3), hash);
                        info_r->ssl_ja3_hash = binary_to_hex(hash, sizeof(hash));
                }
+
+               if (*client->ssl_set->ssl_peer_certificate_fingerprint_hash != '\0') {
+                       int ret = ssl_iostream_get_peer_cert_fingerprint(
+                               client->ssl_iostream, &info_r->ssl_client_cert_fp,
+                               &info_r->ssl_client_cert_pubkey_fp,
+                               &error);
+                       if (ret < 0) {
+                               e_error(client->event,
+                                       "Cannot get client certificate fingerprints: %s",
+                                       error);
+                               *client_error_r = "Unable to validate certificate";
+                               return -1;
+                       }
+               }
        }
        info_r->flags = client_get_auth_flags(client);
        info_r->local_ip = client->local_ip;