591 lines
24 KiB
Diff
591 lines
24 KiB
Diff
|
From 4aef95ff22cb926998773330cc860879b0dea5c2 Mon Sep 17 00:00:00 2001
|
||
|
From: Sumit Bose <sbose@redhat.com>
|
||
|
Date: Fri, 27 Oct 2017 10:13:36 +0200
|
||
|
Subject: [PATCH 45/79] p11_child: use options to select certificate for
|
||
|
authentication
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
New options are added to p11_child to select a specific certificate
|
||
|
during authentication.
|
||
|
|
||
|
The related unit tests are updated by adding the needed attributes to
|
||
|
the requests. The was not necessary before because although the
|
||
|
attribute were already send by pam_sss they were not used in the PAM
|
||
|
responder but only forwarded to the back where they were used by the
|
||
|
PKINIT code to select the expected certificate.
|
||
|
|
||
|
Related to https://pagure.io/SSSD/sssd/issue/3560
|
||
|
|
||
|
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||
|
Tested-by: Scott Poore <spoore@redhat.com>
|
||
|
---
|
||
|
src/p11_child/p11_child_nss.c | 213 ++++++++++++++++++++++++++--------------
|
||
|
src/responder/pam/pamsrv_p11.c | 30 +++++-
|
||
|
src/tests/cmocka/test_pam_srv.c | 60 +++++++----
|
||
|
3 files changed, 208 insertions(+), 95 deletions(-)
|
||
|
|
||
|
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
|
||
|
index 50bde2f4f91f6c00260b0db383d0962112686ebc..c676375cf7f6677a1d7f38f09b9bb5fd820d60c5 100644
|
||
|
--- a/src/p11_child/p11_child_nss.c
|
||
|
+++ b/src/p11_child/p11_child_nss.c
|
||
|
@@ -67,12 +67,34 @@ static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg)
|
||
|
return PL_strdup((char *)arg);
|
||
|
}
|
||
|
|
||
|
+static char *get_key_id_str(PK11SlotInfo *slot, CERTCertificate *cert)
|
||
|
+{
|
||
|
+ SECItem *key_id = NULL;
|
||
|
+ char *key_id_str = NULL;
|
||
|
|
||
|
+ key_id = PK11_GetLowLevelKeyIDForCert(slot, cert, NULL);
|
||
|
+ if (key_id == NULL) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
||
|
+ "PK11_GetLowLevelKeyIDForCert failed [%d].\n",
|
||
|
+ PR_GetError());
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
|
||
|
-int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
|
||
|
+ key_id_str = CERT_Hexify(key_id, PR_FALSE);
|
||
|
+ SECITEM_FreeItem(key_id, PR_TRUE);
|
||
|
+ if (key_id_str == NULL) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", PR_GetError());
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ return key_id_str;
|
||
|
+}
|
||
|
+
|
||
|
+int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
|
||
|
enum op_mode mode, const char *pin,
|
||
|
struct cert_verify_opts *cert_verify_opts,
|
||
|
- char **_multi)
|
||
|
+ const char *module_name_in, const char *token_name_in,
|
||
|
+ const char *key_id_in, char **_multi)
|
||
|
{
|
||
|
int ret;
|
||
|
SECStatus rv;
|
||
|
@@ -153,42 +175,31 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
|
||
|
mod_list_item->module->dllName);
|
||
|
}
|
||
|
|
||
|
- if (slot_name_in != NULL) {
|
||
|
- slot = PK11_FindSlotByName(slot_name_in);
|
||
|
- if (slot == NULL) {
|
||
|
- DEBUG(SSSDBG_OP_FAILURE, "PK11_FindSlotByName failed for [%s]: [%d].\n",
|
||
|
- slot_name_in, PR_GetError());
|
||
|
- return EIO;
|
||
|
- }
|
||
|
- } else {
|
||
|
-
|
||
|
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE,
|
||
|
- NULL);
|
||
|
- if (list == NULL) {
|
||
|
- DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n");
|
||
|
- return EIO;
|
||
|
- }
|
||
|
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE,
|
||
|
+ NULL);
|
||
|
+ if (list == NULL) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n");
|
||
|
+ return EIO;
|
||
|
+ }
|
||
|
|
||
|
- for (le = list->head; le; le = le->next) {
|
||
|
- CK_SLOT_INFO slInfo;
|
||
|
+ for (le = list->head; le; le = le->next) {
|
||
|
+ CK_SLOT_INFO slInfo;
|
||
|
|
||
|
- slInfo.flags = 0;
|
||
|
- rv = PK11_GetSlotInfo(le->slot, &slInfo);
|
||
|
- DEBUG(SSSDBG_TRACE_ALL,
|
||
|
- "Description [%s] Manufacturer [%s] flags [%lu].\n",
|
||
|
- slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags);
|
||
|
- if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) {
|
||
|
- slot = PK11_ReferenceSlot(le->slot);
|
||
|
- break;
|
||
|
- }
|
||
|
- }
|
||
|
- PK11_FreeSlotList(list);
|
||
|
- if (slot == NULL) {
|
||
|
- DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n");
|
||
|
- return EIO;
|
||
|
+ slInfo.flags = 0;
|
||
|
+ rv = PK11_GetSlotInfo(le->slot, &slInfo);
|
||
|
+ DEBUG(SSSDBG_TRACE_ALL,
|
||
|
+ "Description [%s] Manufacturer [%s] flags [%lu].\n",
|
||
|
+ slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags);
|
||
|
+ if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) {
|
||
|
+ slot = PK11_ReferenceSlot(le->slot);
|
||
|
+ break;
|
||
|
}
|
||
|
}
|
||
|
-
|
||
|
+ PK11_FreeSlotList(list);
|
||
|
+ if (slot == NULL) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n");
|
||
|
+ return EIO;
|
||
|
+ }
|
||
|
|
||
|
slot_id = PK11_GetSlotID(slot);
|
||
|
module_id = PK11_GetModuleID(slot);
|
||
|
@@ -317,24 +328,60 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
|
||
|
for (cert_list_node = CERT_LIST_HEAD(cert_list);
|
||
|
!CERT_LIST_END(cert_list_node, cert_list);
|
||
|
cert_list_node = CERT_LIST_NEXT(cert_list_node)) {
|
||
|
- if (cert_list_node->cert) {
|
||
|
- DEBUG(SSSDBG_TRACE_ALL, "found cert[%s][%s]\n",
|
||
|
- cert_list_node->cert->nickname,
|
||
|
- cert_list_node->cert->subjectName);
|
||
|
+ if (cert_list_node->cert == NULL) {
|
||
|
+ DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n");
|
||
|
+ continue;
|
||
|
+ }
|
||
|
|
||
|
- if (cert_verify_opts->do_verification) {
|
||
|
- rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert,
|
||
|
- PR_TRUE,
|
||
|
- certificateUsageSSLClient,
|
||
|
- NULL, NULL);
|
||
|
- if (rv != SECSuccess) {
|
||
|
- DEBUG(SSSDBG_OP_FAILURE,
|
||
|
- "Certificate [%s][%s] not valid [%d], skipping.\n",
|
||
|
- cert_list_node->cert->nickname,
|
||
|
- cert_list_node->cert->subjectName, PR_GetError());
|
||
|
- continue;
|
||
|
- }
|
||
|
+ DEBUG(SSSDBG_TRACE_ALL,
|
||
|
+ "found cert[%s][%s]\n",
|
||
|
+ cert_list_node->cert->nickname,
|
||
|
+ cert_list_node->cert->subjectName);
|
||
|
+
|
||
|
+ if (cert_verify_opts->do_verification) {
|
||
|
+ rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert,
|
||
|
+ PR_TRUE,
|
||
|
+ certificateUsageSSLClient,
|
||
|
+ NULL, NULL);
|
||
|
+ if (rv != SECSuccess) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
||
|
+ "Certificate [%s][%s] not valid [%d], skipping.\n",
|
||
|
+ cert_list_node->cert->nickname,
|
||
|
+ cert_list_node->cert->subjectName, PR_GetError());
|
||
|
+ continue;
|
||
|
}
|
||
|
+ }
|
||
|
+
|
||
|
+ if (key_id_in != NULL) {
|
||
|
+ PORT_Free(key_id_str);
|
||
|
+ key_id_str = NULL;
|
||
|
+ key_id_str = get_key_id_str(slot, cert_list_node->cert);
|
||
|
+ }
|
||
|
+ /* Check if we found the certificates we needed for authentication or
|
||
|
+ * the requested ones for pre-auth. For authentication all attributes
|
||
|
+ * must be given and match, for pre-auth only the given ones must
|
||
|
+ * match. */
|
||
|
+ DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s %s %s.\n",
|
||
|
+ module_name_in, module_name, token_name_in, token_name,
|
||
|
+ key_id_in, key_id_str);
|
||
|
+ if ((mode == OP_AUTH
|
||
|
+ && module_name_in != NULL
|
||
|
+ && token_name_in != NULL
|
||
|
+ && key_id_in != NULL
|
||
|
+ && key_id_str != NULL
|
||
|
+ && strcmp(key_id_in, key_id_str) == 0
|
||
|
+ && strcmp(token_name_in, token_name) == 0
|
||
|
+ && strcmp(module_name_in, module_name) == 0)
|
||
|
+ || (mode == OP_PREAUTH
|
||
|
+ && (module_name_in == NULL
|
||
|
+ || (module_name_in != NULL
|
||
|
+ && strcmp(module_name_in, module_name) == 0))
|
||
|
+ && (token_name_in == NULL
|
||
|
+ || (token_name_in != NULL
|
||
|
+ && strcmp(token_name_in, token_name) == 0))
|
||
|
+ && (key_id_in == NULL
|
||
|
+ || (key_id_in != NULL && key_id_str != NULL
|
||
|
+ && strcmp(key_id_in, key_id_str) == 0)))) {
|
||
|
|
||
|
rv = CERT_AddCertToListTail(valid_certs, cert_list_node->cert);
|
||
|
if (rv != SECSuccess) {
|
||
|
@@ -343,15 +390,6 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
|
||
|
ret = EIO;
|
||
|
goto done;
|
||
|
}
|
||
|
-
|
||
|
- if (found_cert == NULL) {
|
||
|
- found_cert = cert_list_node->cert;
|
||
|
- } else {
|
||
|
- DEBUG(SSSDBG_TRACE_ALL, "More than one certificate found, " \
|
||
|
- "using just the first one.\n");
|
||
|
- }
|
||
|
- } else {
|
||
|
- DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -367,7 +405,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- if (found_cert == NULL) {
|
||
|
+ if (CERT_LIST_EMPTY(valid_certs)) {
|
||
|
DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n");
|
||
|
*_multi = NULL;
|
||
|
ret = EOK;
|
||
|
@@ -375,6 +413,23 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
|
||
|
}
|
||
|
|
||
|
if (mode == OP_AUTH) {
|
||
|
+ cert_list_node = CERT_LIST_HEAD(valid_certs);
|
||
|
+ if (!CERT_LIST_END(CERT_LIST_NEXT(cert_list_node), valid_certs)) {
|
||
|
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||
|
+ "More than one certificate found for authentication, "
|
||
|
+ "aborting!\n");
|
||
|
+ ret = EINVAL;
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
+ found_cert = cert_list_node->cert;
|
||
|
+ if (found_cert == NULL) {
|
||
|
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||
|
+ "No certificate found for authentication, aborting!\n");
|
||
|
+ ret = EINVAL;
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
rv = PK11_GenerateRandom(random_value, sizeof(random_value));
|
||
|
if (rv != SECSuccess) {
|
||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||
|
@@ -449,21 +504,10 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
|
||
|
|
||
|
found_cert = cert_list_node->cert;
|
||
|
|
||
|
- SECITEM_FreeItem(key_id, PR_TRUE);
|
||
|
PORT_Free(key_id_str);
|
||
|
- key_id = PK11_GetLowLevelKeyIDForCert(slot, found_cert, NULL);
|
||
|
- if (key_id == NULL) {
|
||
|
- DEBUG(SSSDBG_OP_FAILURE,
|
||
|
- "PK11_GetLowLevelKeyIDForCert failed [%d].\n",
|
||
|
- PR_GetError());
|
||
|
- ret = EINVAL;
|
||
|
- goto done;
|
||
|
- }
|
||
|
-
|
||
|
- key_id_str = CERT_Hexify(key_id, PR_FALSE);
|
||
|
+ key_id_str = get_key_id_str(slot, found_cert);
|
||
|
if (key_id_str == NULL) {
|
||
|
- DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n",
|
||
|
- PR_GetError());
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE, "get_key_id_str [%d].\n", PR_GetError());
|
||
|
ret = ENOMEM;
|
||
|
goto done;
|
||
|
}
|
||
|
@@ -576,11 +620,13 @@ int main(int argc, const char *argv[])
|
||
|
enum op_mode mode = OP_NONE;
|
||
|
enum pin_mode pin_mode = PIN_NONE;
|
||
|
char *pin = NULL;
|
||
|
- char *slot_name_in = NULL;
|
||
|
char *nss_db = NULL;
|
||
|
struct cert_verify_opts *cert_verify_opts;
|
||
|
char *verify_opts = NULL;
|
||
|
char *multi = NULL;
|
||
|
+ char *module_name = NULL;
|
||
|
+ char *token_name = NULL;
|
||
|
+ char *key_id = NULL;
|
||
|
|
||
|
struct poptOption long_options[] = {
|
||
|
POPT_AUTOHELP
|
||
|
@@ -605,6 +651,12 @@ int main(int argc, const char *argv[])
|
||
|
NULL},
|
||
|
{"nssdb", 0, POPT_ARG_STRING, &nss_db, 0, _("NSS DB to use"),
|
||
|
NULL},
|
||
|
+ {"module_name", 0, POPT_ARG_STRING, &module_name, 0,
|
||
|
+ _("Module name for authentication"), NULL},
|
||
|
+ {"token_name", 0, POPT_ARG_STRING, &token_name, 0,
|
||
|
+ _("Token name for authentication"), NULL},
|
||
|
+ {"key_id", 0, POPT_ARG_STRING, &key_id, 0,
|
||
|
+ _("Key ID for authentication"), NULL},
|
||
|
POPT_TABLEEND
|
||
|
};
|
||
|
|
||
|
@@ -730,6 +782,15 @@ int main(int argc, const char *argv[])
|
||
|
}
|
||
|
talloc_steal(main_ctx, debug_prg_name);
|
||
|
|
||
|
+ if (mode == OP_AUTH && (module_name == NULL || token_name == NULL
|
||
|
+ || key_id == NULL)) {
|
||
|
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||
|
+ "--module_name, --token_name and --key_id must be for "
|
||
|
+ "authentication");
|
||
|
+ ret = EINVAL;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
ret = parse_cert_verify_opts(main_ctx, verify_opts, &cert_verify_opts);
|
||
|
if (ret != EOK) {
|
||
|
DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse verifiy option.\n");
|
||
|
@@ -744,8 +805,8 @@ int main(int argc, const char *argv[])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- ret = do_work(main_ctx, nss_db, slot_name_in, mode, pin, cert_verify_opts,
|
||
|
- &multi);
|
||
|
+ ret = do_work(main_ctx, nss_db, mode, pin, cert_verify_opts, module_name,
|
||
|
+ token_name, key_id, &multi);
|
||
|
if (ret != EOK) {
|
||
|
DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n");
|
||
|
goto fail;
|
||
|
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
|
||
|
index 57c8e1e464f4262f2d78f869c52ca48bd469d90a..4d5572164763ed0b3a842019f820680a4dc2dfdc 100644
|
||
|
--- a/src/responder/pam/pamsrv_p11.c
|
||
|
+++ b/src/responder/pam/pamsrv_p11.c
|
||
|
@@ -399,10 +399,13 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
|
||
|
struct timeval tv;
|
||
|
int pipefd_to_child[2] = PIPE_INIT;
|
||
|
int pipefd_from_child[2] = PIPE_INIT;
|
||
|
- const char *extra_args[7] = { NULL };
|
||
|
+ const char *extra_args[13] = { NULL };
|
||
|
uint8_t *write_buf = NULL;
|
||
|
size_t write_buf_len = 0;
|
||
|
size_t arg_c;
|
||
|
+ const char *module_name = NULL;
|
||
|
+ const char *token_name = NULL;
|
||
|
+ const char *key_id = NULL;
|
||
|
|
||
|
req = tevent_req_create(mem_ctx, &state, struct pam_check_cert_state);
|
||
|
if (req == NULL) {
|
||
|
@@ -423,6 +426,30 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
|
||
|
extra_args[arg_c++] = verify_opts;
|
||
|
extra_args[arg_c++] = "--verify";
|
||
|
}
|
||
|
+
|
||
|
+ if (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_SC_PIN
|
||
|
+ || sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_SC_KEYPAD) {
|
||
|
+ ret = sss_authtok_get_sc(pd->authtok, NULL, NULL, &token_name, NULL,
|
||
|
+ &module_name, NULL, &key_id, NULL);
|
||
|
+ if (ret != EOK) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_sc failed.\n");
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (module_name != NULL && *module_name != '\0') {
|
||
|
+ extra_args[arg_c++] = module_name;
|
||
|
+ extra_args[arg_c++] = "--module_name";
|
||
|
+ }
|
||
|
+ if (token_name != NULL && *token_name != '\0') {
|
||
|
+ extra_args[arg_c++] = token_name;
|
||
|
+ extra_args[arg_c++] = "--token_name";
|
||
|
+ }
|
||
|
+ if (key_id != NULL && *key_id != '\0') {
|
||
|
+ extra_args[arg_c++] = key_id;
|
||
|
+ extra_args[arg_c++] = "--key_id";
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
if (pd->cmd == SSS_PAM_AUTHENTICATE) {
|
||
|
extra_args[arg_c++] = "--auth";
|
||
|
switch (sss_authtok_get_type(pd->authtok)) {
|
||
|
@@ -437,6 +464,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
|
||
|
ret = EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
+
|
||
|
} else if (pd->cmd == SSS_PAM_PREAUTH) {
|
||
|
extra_args[arg_c++] = "--pre";
|
||
|
} else {
|
||
|
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
|
||
|
index 6adbc15f580997c41a02819d0d6aa253f2d5a64b..ad5aeb6e252d989b6587525d9d2355ce9505f0e5 100644
|
||
|
--- a/src/tests/cmocka/test_pam_srv.c
|
||
|
+++ b/src/tests/cmocka/test_pam_srv.c
|
||
|
@@ -687,7 +687,9 @@ static void mock_input_pam(TALLOC_CTX *mem_ctx,
|
||
|
}
|
||
|
|
||
|
static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
|
||
|
- const char *pin, const char *service,
|
||
|
+ const char *pin, const char *token_name,
|
||
|
+ const char *module_name, const char *key_id,
|
||
|
+ const char *service,
|
||
|
acct_cb_t acct_cb, const char *cert,
|
||
|
bool only_one_provider_call)
|
||
|
{
|
||
|
@@ -697,6 +699,7 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
|
||
|
struct pam_items pi = { 0 };
|
||
|
int ret;
|
||
|
bool already_mocked = false;
|
||
|
+ size_t needed_size;
|
||
|
|
||
|
if (name != NULL) {
|
||
|
pi.pam_user = name;
|
||
|
@@ -707,9 +710,21 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
|
||
|
}
|
||
|
|
||
|
if (pin != NULL) {
|
||
|
- pi.pam_authtok = discard_const(pin);
|
||
|
- pi.pam_authtok_size = strlen(pi.pam_authtok) + 1;
|
||
|
+ ret = sss_auth_pack_sc_blob(pin, 0, token_name, 0, module_name, 0,
|
||
|
+ key_id, 0, NULL, 0, &needed_size);
|
||
|
+ assert_int_equal(ret, EAGAIN);
|
||
|
+
|
||
|
+ pi.pam_authtok = malloc(needed_size);
|
||
|
+ assert_non_null(pi.pam_authtok);
|
||
|
+
|
||
|
+ ret = sss_auth_pack_sc_blob(pin, 0, token_name, 0, module_name, 0,
|
||
|
+ key_id, 0,
|
||
|
+ (uint8_t *)pi.pam_authtok, needed_size,
|
||
|
+ &needed_size);
|
||
|
+ assert_int_equal(ret, EOK);
|
||
|
+
|
||
|
pi.pam_authtok_type = SSS_AUTHTOK_TYPE_SC_PIN;
|
||
|
+ pi.pam_authtok_size = needed_size;
|
||
|
}
|
||
|
|
||
|
pi.pam_service = service == NULL ? "login" : service;
|
||
|
@@ -724,6 +739,7 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
|
||
|
pi.cli_pid = 12345;
|
||
|
|
||
|
ret = pack_message_v3(&pi, &buf_size, &m_buf);
|
||
|
+ free(pi.pam_authtok);
|
||
|
assert_int_equal(ret, 0);
|
||
|
|
||
|
buf = talloc_memdup(mem_ctx, m_buf, buf_size);
|
||
|
@@ -1732,7 +1748,8 @@ void test_pam_preauth_no_logon_name(void **state)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, false);
|
||
|
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
+ NULL, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||
|
@@ -1824,7 +1841,8 @@ void test_pam_preauth_cert_nocert(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, "/no/path");
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, false);
|
||
|
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL,
|
||
|
+ NULL, NULL, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||
|
@@ -1962,7 +1980,7 @@ void test_pam_preauth_cert_nomatch(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL,
|
||
|
test_lookup_by_cert_cb, NULL, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
@@ -1984,7 +2002,7 @@ void test_pam_preauth_cert_match(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL,
|
||
|
test_lookup_by_cert_cb, TEST_TOKEN_CERT, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
@@ -2007,8 +2025,9 @@ void test_pam_preauth_cert_match_gdm_smartcard(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, "gdm-smartcard",
|
||
|
- test_lookup_by_cert_cb, TEST_TOKEN_CERT, false);
|
||
|
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL,
|
||
|
+ "gdm-smartcard", test_lookup_by_cert_cb,
|
||
|
+ TEST_TOKEN_CERT, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||
|
@@ -2029,7 +2048,7 @@ void test_pam_preauth_cert_match_wrong_user(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL,
|
||
|
test_lookup_by_cert_wrong_user_cb,
|
||
|
TEST_TOKEN_CERT, false);
|
||
|
|
||
|
@@ -2061,7 +2080,7 @@ void test_pam_preauth_cert_no_logon_name(void **state)
|
||
|
* Additionally sss_parse_inp_recv() must be mocked because the cache
|
||
|
* request will be done with the username found by the certificate
|
||
|
* lookup. */
|
||
|
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
test_lookup_by_cert_cb, TEST_TOKEN_CERT, false);
|
||
|
mock_account_recv_simple();
|
||
|
mock_parse_inp("pamuser", NULL, EOK);
|
||
|
@@ -2090,7 +2109,7 @@ void test_pam_preauth_cert_no_logon_name_with_hint(void **state)
|
||
|
* Since user name hint is enabled we do not have to search the user
|
||
|
* during pre-auth and there is no need for an extra mocked response as in
|
||
|
* test_pam_preauth_cert_no_logon_name. */
|
||
|
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
test_lookup_by_cert_cb, TEST_TOKEN_CERT, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
@@ -2112,7 +2131,7 @@ void test_pam_preauth_cert_no_logon_name_double_cert(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
@@ -2135,7 +2154,7 @@ void test_pam_preauth_cert_no_logon_name_double_cert_with_hint(void **state)
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
|
||
|
pam_test_ctx->rctx->domains->user_name_hint = true;
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
@@ -2157,7 +2176,8 @@ void test_pam_preauth_no_cert_no_logon_name(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, "/no/path");
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, false);
|
||
|
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
+ NULL, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||
|
@@ -2178,7 +2198,7 @@ void test_pam_preauth_cert_no_logon_name_no_match(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
test_lookup_by_cert_cb, NULL, false);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
|
||
|
@@ -2206,7 +2226,9 @@ void test_pam_cert_auth(void **state)
|
||
|
* is looked up. Since the first mocked reply already adds the certificate
|
||
|
* to the user entry the lookup by certificate will already find the user
|
||
|
* in the cache and no second request to the backend is needed. */
|
||
|
- mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", "SSSD Test Token",
|
||
|
+ "NSS-Internal",
|
||
|
+ "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7", NULL,
|
||
|
test_lookup_by_cert_cb, TEST_TOKEN_CERT, true);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
|
||
|
@@ -2232,7 +2254,9 @@ void test_pam_cert_auth_double_cert(void **state)
|
||
|
|
||
|
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
|
||
|
|
||
|
- mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", NULL,
|
||
|
+ mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", "SSSD Test Token",
|
||
|
+ "NSS-Internal",
|
||
|
+ "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7", NULL,
|
||
|
test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, true);
|
||
|
|
||
|
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
|
||
|
--
|
||
|
2.15.1
|
||
|
|