From b5a092b4b0e4f072f0f402146a83addb97cf2977 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 16 Sep 2016 11:48:18 +0200 Subject: [PATCH 143/143] pam_sss: check PKCS11_LOGIN_TOKEN_NAME Check if PKCS11_LOGIN_TOKEN_NAME is set and prompt the user if the matching Smartcard is not inserted. Related to https://fedorahosted.org/sssd/ticket/3165 Reviewed-by: Jakub Hrozek (cherry picked from commit 35ba922bc51416f02877b53a6f25c04104ae5f03) --- src/sss_client/pam_sss.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c index fdb9c907644f1317b6f8e58619f01ad2753deafc..2049d5fb0c6092aaaa914385c79d02d8f44b447e 100644 --- a/src/sss_client/pam_sss.c +++ b/src/sss_client/pam_sss.c @@ -1410,6 +1410,7 @@ done: } #define SC_PROMPT_FMT "PIN for %s for user %s" + static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi) { int ret; @@ -1691,6 +1692,62 @@ static int get_authtok_for_password_change(pam_handle_t *pamh, return PAM_SUCCESS; } +#define SC_ENTER_FMT "Please enter smart card labeled\n %s\nand press enter" + +static int check_login_token_name(pam_handle_t *pamh, struct pam_items *pi, + bool quiet_mode) +{ + int ret; + int pam_status; + char *login_token_name; + char *prompt = NULL; + size_t size; + char *answer = NULL; + + login_token_name = getenv("PKCS11_LOGIN_TOKEN_NAME"); + if (login_token_name == NULL) { + return PAM_SUCCESS; + } + + while (pi->token_name == NULL + || strcmp(login_token_name, pi->token_name) != 0) { + size = sizeof(SC_ENTER_FMT) + strlen(login_token_name); + prompt = malloc(size); + if (prompt == NULL) { + D(("malloc failed.")); + return ENOMEM; + } + + ret = snprintf(prompt, size, SC_ENTER_FMT, + login_token_name); + if (ret < 0 || ret >= size) { + D(("snprintf failed.")); + free(prompt); + return EFAULT; + } + + ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_OFF, prompt, + NULL, &answer); + free(prompt); + free(answer); + if (ret != PAM_SUCCESS) { + D(("do_pam_conversation failed.")); + return ret; + } + + pam_status = send_and_receive(pamh, pi, SSS_PAM_PREAUTH, quiet_mode); + if (pam_status != PAM_SUCCESS) { + D(("send_and_receive returned [%d] during pre-auth", pam_status)); + /* + * Since we are waiting for the right Smartcard to be inserted errors + * can be ignored here. + */ + } + } + + return PAM_SUCCESS; +} + static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, int pam_flags, int argc, const char **argv) { @@ -1758,6 +1815,14 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, } } + if (strcmp(pi.pam_service, "gdm-smartcard") == 0) { + ret = check_login_token_name(pamh, &pi, quiet_mode); + if (ret != PAM_SUCCESS) { + D(("check_login_token_name failed.\n")); + return ret; + } + } + ret = get_authtok_for_authentication(pamh, &pi, flags); if (ret != PAM_SUCCESS) { D(("failed to get authentication token: %s", -- 2.7.4