URL: https://github.com/SSSD/sssd/pull/665
Author: sumit-bose
 Title: #665: p11: handle multiple certs during auth with OpenSSL
Action: opened

PR body:
"""
This patch adds missing code already available in the NSS version to
select a certificate for authentication if multiple certificates are
available on the Smartcard. A unit test to check this feature is added
as well.

Related to https://pagure.io/SSSD/sssd/issue/3489
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/665/head:pr665
git checkout pr665
From 4ff183ecbe4d8e70715eee186f1fedecc335163e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Tue, 2 Oct 2018 12:13:29 +0200
Subject: [PATCH] p11: handle multiple certs during auth with OpenSSL

This patch adds missing code already available in the NSS version to
select a certificate for authentication if multiple certificates are
available on the Smartcard. A unit test to check this feature is added
as well.

Related to https://pagure.io/SSSD/sssd/issue/3489
---
 src/p11_child/p11_child_openssl.c | 42 ++++++++++++++++++++++++++++++-
 src/tests/cmocka/test_pam_srv.c   | 36 ++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c
index be5872626..eaf9c3882 100644
--- a/src/p11_child/p11_child_openssl.c
+++ b/src/p11_child/p11_child_openssl.c
@@ -572,8 +572,10 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx,
     char *slot_name = NULL;
     char *token_name = NULL;
     CK_SESSION_HANDLE session = 0;
+    struct cert_list *all_cert_list = NULL;
     struct cert_list *cert_list = NULL;
     struct cert_list *item = NULL;
+    struct cert_list *tmp_cert = NULL;
     char *multi = NULL;
     bool pkcs11_session = false;
     bool pkcs11_login = false;
@@ -691,12 +693,50 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx,
         DEBUG(SSSDBG_TRACE_ALL, "Login NOT required.\n");
     }
 
-    ret = read_certs(mem_ctx, module, session, p11_ctx, &cert_list);
+    ret = read_certs(mem_ctx, module, session, p11_ctx, &all_cert_list);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "read_certs failed.\n");
         goto done;
     }
 
+    DLIST_FOR_EACH(item, all_cert_list) {
+        DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s %s %s.\n",
+              module_name_in, module_file_name, token_name_in, token_name,
+              key_id_in, item->id);
+
+        if ((mode == OP_AUTH
+                && module_name_in != NULL
+                && token_name_in != NULL
+                && key_id_in != NULL
+                && item->id != NULL
+                && strcmp(key_id_in, item->id) == 0
+                && strcmp(token_name_in, token_name) == 0
+                && strcmp(module_name_in, module_file_name) == 0)
+            || (mode == OP_PREAUTH
+                && (module_name_in == NULL
+                    || (module_name_in != NULL
+                        && strcmp(module_name_in, module_file_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 && item->id != NULL
+                        && strcmp(key_id_in, item->id) == 0)))) {
+
+            tmp_cert = talloc_memdup(mem_ctx, item, sizeof(struct cert_list));
+            if (tmp_cert == NULL) {
+                DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n");
+                ret = ENOMEM;
+                goto done;
+            }
+            tmp_cert->prev = NULL;
+            tmp_cert->next = NULL;
+
+            DLIST_ADD(cert_list, tmp_cert);
+
+        }
+    }
+
     /* TODO: check module_name_in, token_name_in, key_id_in */
 
     if (cert_list == NULL) {
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 446985d5d..2b02ac27b 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -2443,6 +2443,40 @@ void test_pam_cert_preauth_2certs_two_mappings(void **state)
     assert_int_equal(ret, EOK);
 }
 
+void test_pam_cert_auth_2certs_one_mapping(void **state)
+{
+    int ret;
+
+#ifdef HAVE_NSS
+    set_cert_auth_param(pam_test_ctx->pctx, NSS_DB_2CERTS);
+#else
+    set_cert_auth_param(pam_test_ctx->pctx, CA_DB);
+    putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_CA/softhsm2_two.conf"));
+#endif
+
+    mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", "SSSD Test Token",
+                        TEST_MODULE_NAME,
+                        "C554C9F82C2A9D58B70921C143304153A8A42F17", NULL,
+                        test_lookup_by_cert_double_cb, SSSD_TEST_CERT_0001,
+                        true);
+
+    will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+    /* Assume backend cannot handle Smartcard credentials */
+    pam_test_ctx->exp_pam_status = PAM_BAD_ITEM;
+
+    set_cmd_cb(test_pam_simple_check_success);
+    ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
+                          pam_test_ctx->pam_cmds);
+    assert_int_equal(ret, EOK);
+
+    /* Wait until the test finishes with EOK */
+    ret = test_ev_loop(pam_test_ctx->tctx);
+    assert_int_equal(ret, EOK);
+}
+
+
 void test_filter_response(void **state)
 {
     int ret;
@@ -2875,6 +2909,8 @@ int main(int argc, const char *argv[])
                                         pam_test_setup, pam_test_teardown),
         cmocka_unit_test_setup_teardown(test_pam_cert_preauth_2certs_two_mappings,
                                         pam_test_setup, pam_test_teardown),
+        cmocka_unit_test_setup_teardown(test_pam_cert_auth_2certs_one_mapping,
+                                        pam_test_setup, pam_test_teardown),
         cmocka_unit_test_setup_teardown(test_pam_cert_auth_no_logon_name,
                                         pam_test_setup, pam_test_teardown),
         cmocka_unit_test_setup_teardown(test_pam_cert_auth_no_logon_name_no_key_id,
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org

Reply via email to