Blob Blame History Raw
From b8800d3e1b43f2eb28b2df7adb2bcb323bf2d1f1 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Sat, 14 Nov 2020 17:52:35 +0100
Subject: [PATCH 15/16] pam_sss: add certificate label to reply to pam_sss

Add the certificate label to the data send back and forth to the pam
module to avoid the ambiguity if two certificates use the same key.

Resolves: https://github.com/SSSD/sssd/issues/5400

Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
 src/responder/pam/pamsrv_p11.c  | 13 ++++++++++---
 src/sss_client/pam_sss.c        | 15 +++++++++++++++
 src/tests/cmocka/test_pam_srv.c | 20 ++++++++++++++++----
 3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 23f94927a..e1fd72e64 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -1086,11 +1086,13 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
     const char *token_name;
     const char *module_name;
     const char *key_id;
+    const char *label;
     char *prompt;
     size_t user_len;
     size_t token_len;
     size_t module_len;
     size_t key_id_len;
+    size_t label_len;
     size_t prompt_len;
     size_t nss_name_len;
     const char *username = "";
@@ -1113,16 +1115,18 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
     token_name = sss_cai_get_token_name(cert_info);
     module_name = sss_cai_get_module_name(cert_info);
     key_id = sss_cai_get_key_id(cert_info);
+    label = sss_cai_get_label(cert_info);
 
     user_len = strlen(username) + 1;
     token_len = strlen(token_name) + 1;
     module_len = strlen(module_name) + 1;
     key_id_len = strlen(key_id) + 1;
+    label_len = strlen(label) + 1;
     prompt_len = strlen(prompt) + 1;
     nss_name_len = strlen(nss_username) +1;
 
-    msg_len = user_len + token_len + module_len + key_id_len + prompt_len
-                       + nss_name_len;
+    msg_len = user_len + token_len + module_len + key_id_len + label_len
+                       + prompt_len + nss_name_len;
 
     msg = talloc_zero_size(mem_ctx, msg_len);
     if (msg == NULL) {
@@ -1136,8 +1140,11 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
     memcpy(msg + user_len + token_len, module_name, module_len);
     memcpy(msg + user_len + token_len + module_len, key_id, key_id_len);
     memcpy(msg + user_len + token_len + module_len + key_id_len,
+           label, label_len);
+    memcpy(msg + user_len + token_len + module_len + key_id_len + label_len,
            prompt, prompt_len);
-    memcpy(msg + user_len + token_len + module_len + key_id_len + prompt_len,
+    memcpy(msg + user_len + token_len + module_len + key_id_len + label_len
+               + prompt_len,
            nss_username, nss_name_len);
     talloc_free(prompt);
 
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index cffbfa770..c539d6de6 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -142,6 +142,7 @@ static void free_cai(struct cert_auth_info *cai)
         free(cai->token_name);
         free(cai->module_name);
         free(cai->key_id);
+        free(cai->label);
         free(cai->prompt_str);
         free(cai->choice_list_id);
         free(cai);
@@ -936,6 +937,20 @@ static int parse_cert_info(struct pam_items *pi, uint8_t *buf, size_t len,
         goto done;
     }
 
+    cai->label = strdup((char *) &buf[*p + offset]);
+    if (cai->label == NULL) {
+        D(("strdup failed"));
+        ret = ENOMEM;
+        goto done;
+    }
+
+    offset += strlen(cai->label) + 1;
+    if (offset >= len) {
+        D(("Cert message size mismatch"));
+        ret = EINVAL;
+        goto done;
+    }
+
     cai->prompt_str = strdup((char *) &buf[*p + offset]);
     if (cai->prompt_str == NULL) {
         D(("strdup failed"));
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index cb05042de..5506fbf34 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -62,13 +62,16 @@
 #define TEST_TOKEN_NAME "SSSD Test Token"
 #define TEST_TOKEN2_NAME "SSSD Test Token Number 2"
 #define TEST_KEY_ID "C554C9F82C2A9D58B70921C143304153A8A42F17"
+#define TEST_LABEL "SSSD test cert 0001"
 #define TEST_MODULE_NAME SOFTHSM2_PATH
 #define TEST_PROMPT "SSSD test cert 0001\nCN=SSSD test cert 0001,OU=SSSD test,O=SSSD"
 #define TEST2_PROMPT "SSSD test cert 0002\nCN=SSSD test cert 0002,OU=SSSD test,O=SSSD"
 #define TEST5_PROMPT "SSSD test cert 0005\nCN=SSSD test cert 0005,OU=SSSD test,O=SSSD"
 
 #define TEST2_KEY_ID "5405842D56CF31F0BB025A695C5F3E907051C5B9"
+#define TEST2_LABEL "SSSD test cert 0002"
 #define TEST5_KEY_ID "1195833C424AB00297F582FC43FFFFAB47A64CC9"
+#define TEST5_LABEL "SSSD test cert 0005"
 
 static char CACHED_AUTH_TIMEOUT_STR[] = "4";
 static const int CACHED_AUTH_TIMEOUT = 4;
@@ -673,6 +676,7 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
                                 + sizeof(TEST_TOKEN_NAME)
                                 + sizeof(TEST_MODULE_NAME)
                                 + sizeof(TEST_KEY_ID)
+                                + sizeof(TEST_LABEL)
                                 + sizeof(TEST_PROMPT)
                                 + sizeof("pamuser")));
 
@@ -692,6 +696,10 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
     assert_string_equal(body + rp, TEST_KEY_ID);
     rp += sizeof(TEST_KEY_ID);
 
+    assert_int_equal(*(body + rp + sizeof(TEST_LABEL) - 1), 0);
+    assert_string_equal(body + rp, TEST_LABEL);
+    rp += sizeof(TEST_LABEL);
+
     assert_int_equal(*(body + rp + sizeof(TEST_PROMPT) - 1), 0);
     assert_string_equal(body + rp, TEST_PROMPT);
     rp += sizeof(TEST_PROMPT);
@@ -740,6 +748,7 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
                                     TEST_TOKEN_NAME,
                                     TEST_MODULE_NAME,
                                     TEST_KEY_ID,
+                                    TEST_LABEL,
                                     TEST_PROMPT,
                                     NULL,
                                     NULL };
@@ -749,6 +758,7 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
                                      TEST_TOKEN_NAME,
                                      TEST_MODULE_NAME,
                                      TEST2_KEY_ID,
+                                     TEST2_LABEL,
                                      TEST2_PROMPT,
                                      NULL,
                                      NULL };
@@ -756,10 +766,10 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
     assert_int_equal(status, 0);
 
     check_strings[0] = name;
-    check_strings[5] = nss_name;
+    check_strings[6] = nss_name;
     check_len = check_string_array_len(check_strings);
     check2_strings[0] = name;
-    check2_strings[5] = nss_name;
+    check2_strings[6] = nss_name;
     check2_len = check_string_array_len(check2_strings);
 
 
@@ -843,6 +853,7 @@ static int test_pam_cert2_token2_check_ex(uint32_t status, uint8_t *body,
                                      TEST_TOKEN2_NAME,
                                      TEST_MODULE_NAME,
                                      TEST2_KEY_ID,
+                                     TEST2_LABEL,
                                      TEST2_PROMPT,
                                      NULL,
                                      NULL };
@@ -850,7 +861,7 @@ static int test_pam_cert2_token2_check_ex(uint32_t status, uint8_t *body,
     assert_int_equal(status, 0);
 
     check2_strings[0] = name;
-    check2_strings[5] = nss_name;
+    check2_strings[6] = nss_name;
     check2_len = check_string_array_len(check2_strings);
 
     SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
@@ -895,7 +906,7 @@ static int test_pam_cert_X_token_X_check_ex(uint32_t status, uint8_t *body,
     assert_int_equal(status, 0);
 
     check_strings[0] = name;
-    check_strings[5] = nss_name;
+    check_strings[6] = nss_name;
     check_len = check_string_array_len(check_strings);
 
     SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
@@ -946,6 +957,7 @@ static int test_pam_cert5_check(uint32_t status, uint8_t *body, size_t blen)
                                      TEST_TOKEN_NAME,
                                      TEST_MODULE_NAME,
                                      TEST5_KEY_ID,
+                                     TEST5_LABEL,
                                      TEST5_PROMPT,
                                      NULL,
                                      NULL };
-- 
2.21.3