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