dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0035-pam_sss-add-sc-support.patch

6cf099
From 98be4f0858e7c38f18b73fda6949edf7790bcad6 Mon Sep 17 00:00:00 2001
6cf099
From: Sumit Bose <sbose@redhat.com>
6cf099
Date: Fri, 3 Jul 2015 14:05:11 +0200
6cf099
Subject: [PATCH 35/37] pam_sss: add sc support
6cf099
6cf099
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
6cf099
---
6cf099
 src/sss_client/pam_message.h |  3 ++
6cf099
 src/sss_client/pam_sss.c     | 94 +++++++++++++++++++++++++++++++++++++++++++-
6cf099
 2 files changed, 96 insertions(+), 1 deletion(-)
6cf099
6cf099
diff --git a/src/sss_client/pam_message.h b/src/sss_client/pam_message.h
6cf099
index 3b3841a2c66b46d78855164099684ef2ac98ed77..f0a7a076cf38a4efc8befcc2fb835ae26e9415a4 100644
6cf099
--- a/src/sss_client/pam_message.h
6cf099
+++ b/src/sss_client/pam_message.h
6cf099
@@ -56,6 +56,9 @@ struct pam_items {
6cf099
     char *otp_token_id;
6cf099
     char *otp_challenge;
6cf099
     char *first_factor;
6cf099
+
6cf099
+    char *cert_user;
6cf099
+    char *token_name;
6cf099
 };
6cf099
 
6cf099
 int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer);
6cf099
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
6cf099
index e4fa83e12c71bb05dd329686cf2d2df6323ff3bd..431f5dc62655dd1e6901f16f72dcad9703f037ac 100644
6cf099
--- a/src/sss_client/pam_sss.c
6cf099
+++ b/src/sss_client/pam_sss.c
6cf099
@@ -155,6 +155,12 @@ static void overwrite_and_free_pam_items(struct pam_items *pi)
6cf099
 
6cf099
     free(pi->otp_challenge);
6cf099
     pi->otp_challenge = NULL;
6cf099
+
6cf099
+    free(pi->cert_user);
6cf099
+    pi->cert_user = NULL;
6cf099
+
6cf099
+    free(pi->token_name);
6cf099
+    pi->token_name = NULL;
6cf099
 }
6cf099
 
6cf099
 static int null_strcmp(const char *s1, const char *s2) {
6cf099
@@ -922,7 +928,7 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
6cf099
                 break;
6cf099
             case SSS_PAM_OTP_INFO:
6cf099
                 if (buf[p + (len - 1)] != '\0') {
6cf099
-                    D(("system info does not end with \\0."));
6cf099
+                    D(("otp info does not end with \\0."));
6cf099
                     break;
6cf099
                 }
6cf099
 
6cf099
@@ -959,6 +965,33 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
6cf099
                 }
6cf099
 
6cf099
                 break;
6cf099
+            case SSS_PAM_CERT_INFO:
6cf099
+                if (buf[p + (len - 1)] != '\0') {
6cf099
+                    D(("cert info does not end with \\0."));
6cf099
+                    break;
6cf099
+                }
6cf099
+
6cf099
+                pi->cert_user = strdup((char *) &buf[p]);
6cf099
+                if (pi->cert_user == NULL) {
6cf099
+                    D(("strdup failed"));
6cf099
+                    break;
6cf099
+                }
6cf099
+
6cf099
+                offset = strlen(pi->cert_user) + 1;
6cf099
+                if (offset >= len) {
6cf099
+                    D(("Cert message size mismatch"));
6cf099
+                    free(pi->cert_user);
6cf099
+                    pi->cert_user = NULL;
6cf099
+                    break;
6cf099
+                }
6cf099
+                pi->token_name = strdup((char *) &buf[p + offset]);
6cf099
+                if (pi->token_name == NULL) {
6cf099
+                    D(("strdup failed"));
6cf099
+                    break;
6cf099
+                }
6cf099
+                D(("cert user: [%s] token name: [%s]", pi->cert_user,
6cf099
+                                                       pi->token_name));
6cf099
+                break;
6cf099
             default:
6cf099
                 D(("Unknown response type [%d]", type));
6cf099
         }
6cf099
@@ -1039,6 +1072,9 @@ static int get_pam_items(pam_handle_t *pamh, struct pam_items *pi)
6cf099
     pi->otp_token_id = NULL;
6cf099
     pi->otp_challenge = NULL;
6cf099
 
6cf099
+    pi->cert_user = NULL;
6cf099
+    pi->token_name = NULL;
6cf099
+
6cf099
     return PAM_SUCCESS;
6cf099
 }
6cf099
 
6cf099
@@ -1345,6 +1381,60 @@ done:
6cf099
     return ret;
6cf099
 }
6cf099
 
6cf099
+#define SC_PROMPT_FMT "PIN for %s for user %s"
6cf099
+static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi)
6cf099
+{
6cf099
+    int ret;
6cf099
+    char *answer = NULL;
6cf099
+    char *prompt;
6cf099
+    size_t size;
6cf099
+
6cf099
+    if (pi->token_name == NULL || *pi->token_name == '\0'
6cf099
+            || pi->cert_user == NULL || *pi->cert_user == '\0') {
6cf099
+        return EINVAL;
6cf099
+    }
6cf099
+
6cf099
+    size = sizeof(SC_PROMPT_FMT) + strlen(pi->token_name) +
6cf099
+           strlen(pi->cert_user);
6cf099
+    prompt = malloc(size);
6cf099
+    if (prompt == NULL) {
6cf099
+        D(("malloc failed."));
6cf099
+        return ENOMEM;
6cf099
+    }
6cf099
+
6cf099
+    ret = snprintf(prompt, size, SC_PROMPT_FMT, pi->token_name, pi->cert_user);
6cf099
+    if (ret < 0 || ret >= size) {
6cf099
+        D(("snprintf failed."));
6cf099
+        free(prompt);
6cf099
+        return EFAULT;
6cf099
+    }
6cf099
+
6cf099
+    ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_OFF, prompt, NULL, &answer);
6cf099
+    free(prompt);
6cf099
+    if (ret != PAM_SUCCESS) {
6cf099
+        D(("do_pam_conversation failed."));
6cf099
+        return ret;
6cf099
+    }
6cf099
+
6cf099
+    if (answer == NULL) {
6cf099
+        pi->pam_authtok = NULL;
6cf099
+        pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY;
6cf099
+        pi->pam_authtok_size=0;
6cf099
+    } else {
6cf099
+        pi->pam_authtok = strdup(answer);
6cf099
+        _pam_overwrite((void *)answer);
6cf099
+        free(answer);
6cf099
+        answer=NULL;
6cf099
+        if (pi->pam_authtok == NULL) {
6cf099
+            return PAM_BUF_ERR;
6cf099
+        }
6cf099
+        pi->pam_authtok_type = SSS_AUTHTOK_TYPE_SC_PIN;
6cf099
+        pi->pam_authtok_size=strlen(pi->pam_authtok);
6cf099
+    }
6cf099
+
6cf099
+    return PAM_SUCCESS;
6cf099
+}
6cf099
+
6cf099
 static int prompt_new_password(pam_handle_t *pamh, struct pam_items *pi)
6cf099
 {
6cf099
     int ret;
6cf099
@@ -1458,6 +1548,8 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
6cf099
                         && pi->otp_challenge != NULL)) {
6cf099
             ret = prompt_2fa(pamh, pi, _("First Factor: "),
6cf099
                              _("Second Factor: "));
6cf099
+        } else if (pi->cert_user != NULL) {
6cf099
+            ret = prompt_sc_pin(pamh, pi);
6cf099
         } else {
6cf099
             ret = prompt_password(pamh, pi, _("Password: "));
6cf099
         }
6cf099
-- 
6cf099
2.4.3
6cf099