From b8800d3e1b43f2eb28b2df7adb2bcb323bf2d1f1 Mon Sep 17 00:00:00 2001 From: Sumit Bose 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 --- 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