summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2015-07-03 14:05:11 +0200
committerJakub Hrozek <jhrozek@redhat.com>2015-07-31 09:52:03 +0200
commit5242964d275d0b2e96c9b0d1f8a9958c85d566fc (patch)
tree124712a30db75c26dbb720beccc943968ac116dc
parenta8d887323f83984679a7d9b827a70146656bb7b2 (diff)
downloadsssd-5242964d275d0b2e96c9b0d1f8a9958c85d566fc.tar.gz
sssd-5242964d275d0b2e96c9b0d1f8a9958c85d566fc.tar.xz
sssd-5242964d275d0b2e96c9b0d1f8a9958c85d566fc.zip
pam_sss: add sc support
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r--src/sss_client/pam_message.h3
-rw-r--r--src/sss_client/pam_sss.c94
2 files changed, 96 insertions, 1 deletions
diff --git a/src/sss_client/pam_message.h b/src/sss_client/pam_message.h
index 3b3841a2c..f0a7a076c 100644
--- a/src/sss_client/pam_message.h
+++ b/src/sss_client/pam_message.h
@@ -56,6 +56,9 @@ struct pam_items {
char *otp_token_id;
char *otp_challenge;
char *first_factor;
+
+ char *cert_user;
+ char *token_name;
};
int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer);
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index e4fa83e12..431f5dc62 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -155,6 +155,12 @@ static void overwrite_and_free_pam_items(struct pam_items *pi)
free(pi->otp_challenge);
pi->otp_challenge = NULL;
+
+ free(pi->cert_user);
+ pi->cert_user = NULL;
+
+ free(pi->token_name);
+ pi->token_name = NULL;
}
static int null_strcmp(const char *s1, const char *s2) {
@@ -922,7 +928,7 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
break;
case SSS_PAM_OTP_INFO:
if (buf[p + (len - 1)] != '\0') {
- D(("system info does not end with \\0."));
+ D(("otp info does not end with \\0."));
break;
}
@@ -959,6 +965,33 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
}
break;
+ case SSS_PAM_CERT_INFO:
+ if (buf[p + (len - 1)] != '\0') {
+ D(("cert info does not end with \\0."));
+ break;
+ }
+
+ pi->cert_user = strdup((char *) &buf[p]);
+ if (pi->cert_user == NULL) {
+ D(("strdup failed"));
+ break;
+ }
+
+ offset = strlen(pi->cert_user) + 1;
+ if (offset >= len) {
+ D(("Cert message size mismatch"));
+ free(pi->cert_user);
+ pi->cert_user = NULL;
+ break;
+ }
+ pi->token_name = strdup((char *) &buf[p + offset]);
+ if (pi->token_name == NULL) {
+ D(("strdup failed"));
+ break;
+ }
+ D(("cert user: [%s] token name: [%s]", pi->cert_user,
+ pi->token_name));
+ break;
default:
D(("Unknown response type [%d]", type));
}
@@ -1039,6 +1072,9 @@ static int get_pam_items(pam_handle_t *pamh, struct pam_items *pi)
pi->otp_token_id = NULL;
pi->otp_challenge = NULL;
+ pi->cert_user = NULL;
+ pi->token_name = NULL;
+
return PAM_SUCCESS;
}
@@ -1345,6 +1381,60 @@ done:
return ret;
}
+#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;
+ char *answer = NULL;
+ char *prompt;
+ size_t size;
+
+ if (pi->token_name == NULL || *pi->token_name == '\0'
+ || pi->cert_user == NULL || *pi->cert_user == '\0') {
+ return EINVAL;
+ }
+
+ size = sizeof(SC_PROMPT_FMT) + strlen(pi->token_name) +
+ strlen(pi->cert_user);
+ prompt = malloc(size);
+ if (prompt == NULL) {
+ D(("malloc failed."));
+ return ENOMEM;
+ }
+
+ ret = snprintf(prompt, size, SC_PROMPT_FMT, pi->token_name, pi->cert_user);
+ 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);
+ if (ret != PAM_SUCCESS) {
+ D(("do_pam_conversation failed."));
+ return ret;
+ }
+
+ if (answer == NULL) {
+ pi->pam_authtok = NULL;
+ pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY;
+ pi->pam_authtok_size=0;
+ } else {
+ pi->pam_authtok = strdup(answer);
+ _pam_overwrite((void *)answer);
+ free(answer);
+ answer=NULL;
+ if (pi->pam_authtok == NULL) {
+ return PAM_BUF_ERR;
+ }
+ pi->pam_authtok_type = SSS_AUTHTOK_TYPE_SC_PIN;
+ pi->pam_authtok_size=strlen(pi->pam_authtok);
+ }
+
+ return PAM_SUCCESS;
+}
+
static int prompt_new_password(pam_handle_t *pamh, struct pam_items *pi)
{
int ret;
@@ -1458,6 +1548,8 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
&& pi->otp_challenge != NULL)) {
ret = prompt_2fa(pamh, pi, _("First Factor: "),
_("Second Factor: "));
+ } else if (pi->cert_user != NULL) {
+ ret = prompt_sc_pin(pamh, pi);
} else {
ret = prompt_password(pamh, pi, _("Password: "));
}