dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0039-p11_child-use-options-to-select-certificate-for-auth.patch

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