From f9a027877ecdd697a052f6135963fb3726692310 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 26 Jun 2015 17:55:23 +0200
Subject: [PATCH 33/37] authok: add support for Smart Card related authtokens
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/sss_client/sss_cli.h | 7 ++++
src/tests/cmocka/test_authtok.c | 75 +++++++++++++++++++++++++++++++++++++++++
src/util/authtok.c | 64 +++++++++++++++++++++++++++++++++++
src/util/authtok.h | 41 ++++++++++++++++++++++
4 files changed, 187 insertions(+)
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
index 0dfb525bacba5f6928e8ece76e05f60d7f2eebd5..3c4e938ae37c042879b1ae26fe389fa37cef682c 100644
--- a/src/sss_client/sss_cli.h
+++ b/src/sss_client/sss_cli.h
@@ -308,6 +308,13 @@ enum sss_authtok_type {
SSS_AUTHTOK_TYPE_2FA = 0x0003, /**< Authentication token has two
* factors, they may or may no contain
* a trailing \\0 */
+ SSS_AUTHTOK_TYPE_SC_PIN = 0x0004, /**< Authentication token is a Smart
+ * Card pin, it may or may no contain
+ * a trailing \\0 */
+ SSS_AUTHTOK_TYPE_SC_KEYPAD = 0x0005, /**< Authentication token indicates
+ * Smart Card authentication is used
+ * and that the pin will be entered
+ * at the card reader. */
};
/**
diff --git a/src/tests/cmocka/test_authtok.c b/src/tests/cmocka/test_authtok.c
index 5aa47c7b6b8c955666a9c73d5f9627d6378d13e0..30dcc9c8401103a275bd592fe8afd2c2f396ffb1 100644
--- a/src/tests/cmocka/test_authtok.c
+++ b/src/tests/cmocka/test_authtok.c
@@ -488,6 +488,77 @@ void test_sss_authtok_2fa_blobs_missing_null(void **state)
MISSING_NULL_CHECK;
}
+void test_sss_authtok_sc_keypad(void **state)
+{
+ struct test_state *ts;
+
+ ts = talloc_get_type_abort(*state, struct test_state);
+
+ sss_authtok_set_sc_keypad(NULL);
+
+ sss_authtok_set_sc_keypad(ts->authtoken);
+ assert_int_equal(sss_authtok_get_type(ts->authtoken),
+ SSS_AUTHTOK_TYPE_SC_KEYPAD);
+ assert_int_equal(sss_authtok_get_size(ts->authtoken), 0);
+ assert_null(sss_authtok_get_data(ts->authtoken));
+}
+
+void test_sss_authtok_sc_pin(void **state)
+{
+ struct test_state *ts;
+ int ret;
+ size_t size;
+ const char *pin;
+ size_t len;
+
+ ts = talloc_get_type_abort(*state, struct test_state);
+
+ ret = sss_authtok_set_sc_pin(NULL, NULL, 0);
+ assert_int_equal(ret, EFAULT);
+
+ ret = sss_authtok_set_sc_pin(ts->authtoken, NULL, 0);
+ assert_int_equal(ret, EINVAL);
+
+ ret = sss_authtok_set_sc_pin(ts->authtoken, "12345678", 0);
+ assert_int_equal(ret, EOK);
+ assert_int_equal(sss_authtok_get_type(ts->authtoken),
+ SSS_AUTHTOK_TYPE_SC_PIN);
+ size = sss_authtok_get_size(ts->authtoken);
+ assert_int_equal(size, 9);
+ assert_memory_equal(sss_authtok_get_data(ts->authtoken), "12345678\0",
+ size);
+
+ ret = sss_authtok_set_sc_pin(ts->authtoken, "12345678", 5);
+ assert_int_equal(ret, EOK);
+ assert_int_equal(sss_authtok_get_type(ts->authtoken),
+ SSS_AUTHTOK_TYPE_SC_PIN);
+ size = sss_authtok_get_size(ts->authtoken);
+ assert_int_equal(size, 6);
+ assert_memory_equal(sss_authtok_get_data(ts->authtoken), "12345\0",
+ size);
+
+ ret = sss_authtok_get_sc_pin(ts->authtoken, &pin, &len);
+ assert_int_equal(ret, EOK);
+ assert_int_equal(len, 5);
+ assert_string_equal(pin, "12345");
+
+ sss_authtok_set_empty(ts->authtoken);
+
+ ret = sss_authtok_get_sc_pin(ts->authtoken, &pin, &len);
+ assert_int_equal(ret, ENOENT);
+
+ ret = sss_authtok_set_password(ts->authtoken, "12345", 0);
+ assert_int_equal(ret, EOK);
+
+ ret = sss_authtok_get_sc_pin(ts->authtoken, &pin, &len);
+ assert_int_equal(ret, EACCES);
+
+ sss_authtok_set_empty(ts->authtoken);
+
+ ret = sss_authtok_get_sc_pin(NULL, &pin, &len);
+ assert_int_equal(ret, EFAULT);
+}
+
int main(int argc, const char *argv[])
{
poptContext pc;
@@ -517,6 +588,10 @@ int main(int argc, const char *argv[])
setup, teardown),
cmocka_unit_test_setup_teardown(test_sss_authtok_2fa_blobs_missing_null,
setup, teardown),
+ cmocka_unit_test_setup_teardown(test_sss_authtok_sc_keypad,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(test_sss_authtok_sc_pin,
+ setup, teardown),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
diff --git a/src/util/authtok.c b/src/util/authtok.c
index 45761df80175fded8a6c6e5dac8a90180b11d225..6062cd875ce2c6b541ef237e7f7bdddac80366c5 100644
--- a/src/util/authtok.c
+++ b/src/util/authtok.c
@@ -39,6 +39,8 @@ size_t sss_authtok_get_size(struct sss_auth_token *tok)
case SSS_AUTHTOK_TYPE_PASSWORD:
case SSS_AUTHTOK_TYPE_CCFILE:
case SSS_AUTHTOK_TYPE_2FA:
+ case SSS_AUTHTOK_TYPE_SC_PIN:
+ case SSS_AUTHTOK_TYPE_SC_KEYPAD:
return tok->length;
case SSS_AUTHTOK_TYPE_EMPTY:
return 0;
@@ -72,6 +74,8 @@ errno_t sss_authtok_get_password(struct sss_auth_token *tok,
return EOK;
case SSS_AUTHTOK_TYPE_CCFILE:
case SSS_AUTHTOK_TYPE_2FA:
+ case SSS_AUTHTOK_TYPE_SC_PIN:
+ case SSS_AUTHTOK_TYPE_SC_KEYPAD:
return EACCES;
}
@@ -95,6 +99,8 @@ errno_t sss_authtok_get_ccfile(struct sss_auth_token *tok,
return EOK;
case SSS_AUTHTOK_TYPE_PASSWORD:
case SSS_AUTHTOK_TYPE_2FA:
+ case SSS_AUTHTOK_TYPE_SC_PIN:
+ case SSS_AUTHTOK_TYPE_SC_KEYPAD:
return EACCES;
}
@@ -144,9 +150,11 @@ void sss_authtok_set_empty(struct sss_auth_token *tok)
return;
case SSS_AUTHTOK_TYPE_PASSWORD:
case SSS_AUTHTOK_TYPE_2FA:
+ case SSS_AUTHTOK_TYPE_SC_PIN:
safezero(tok->data, tok->length);
break;
case SSS_AUTHTOK_TYPE_CCFILE:
+ case SSS_AUTHTOK_TYPE_SC_KEYPAD:
break;
}
@@ -187,6 +195,11 @@ errno_t sss_authtok_set(struct sss_auth_token *tok,
return sss_authtok_set_ccfile(tok, (const char *)data, len);
case SSS_AUTHTOK_TYPE_2FA:
return sss_authtok_set_2fa_from_blob(tok, data, len);
+ case SSS_AUTHTOK_TYPE_SC_PIN:
+ return sss_authtok_set_sc_pin(tok, (const char*)data, len);
+ case SSS_AUTHTOK_TYPE_SC_KEYPAD:
+ sss_authtok_set_sc_keypad(tok);
+ return EOK;
case SSS_AUTHTOK_TYPE_EMPTY:
sss_authtok_set_empty(tok);
return EOK;
@@ -411,3 +424,54 @@ errno_t sss_authtok_set_2fa(struct sss_auth_token *tok,
return EOK;
}
+
+errno_t sss_authtok_set_sc_pin(struct sss_auth_token *tok, const char *pin,
+ size_t len)
+{
+ if (tok == NULL) {
+ return EFAULT;
+ }
+ if (pin == NULL) {
+ return EINVAL;
+ }
+
+ sss_authtok_set_empty(tok);
+
+ return sss_authtok_set_string(tok, SSS_AUTHTOK_TYPE_SC_PIN,
+ "sc_pin", pin, len);
+}
+
+errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **pin,
+ size_t *len)
+{
+ if (!tok) {
+ return EFAULT;
+ }
+ switch (tok->type) {
+ case SSS_AUTHTOK_TYPE_EMPTY:
+ return ENOENT;
+ case SSS_AUTHTOK_TYPE_SC_PIN:
+ *pin = (const char *)tok->data;
+ if (len) {
+ *len = tok->length - 1;
+ }
+ return EOK;
+ case SSS_AUTHTOK_TYPE_PASSWORD:
+ case SSS_AUTHTOK_TYPE_CCFILE:
+ case SSS_AUTHTOK_TYPE_2FA:
+ case SSS_AUTHTOK_TYPE_SC_KEYPAD:
+ return EACCES;
+ }
+
+ return EINVAL;
+}
+
+void sss_authtok_set_sc_keypad(struct sss_auth_token *tok)
+{
+ if (!tok) {
+ return;
+ }
+ sss_authtok_set_empty(tok);
+
+ tok->type = SSS_AUTHTOK_TYPE_SC_KEYPAD;
+}
diff --git a/src/util/authtok.h b/src/util/authtok.h
index cb366270832852281a222018f8e27feb1500ff01..f1a01a42306a720fc39e701078550a071835e980 100644
--- a/src/util/authtok.h
+++ b/src/util/authtok.h
@@ -223,4 +223,45 @@ errno_t sss_authtok_set_2fa(struct sss_auth_token *tok,
errno_t sss_authtok_get_2fa(struct sss_auth_token *tok,
const char **fa1, size_t *fa1_len,
const char **fa2, size_t *fa2_len);
+
+/**
+ * @brief Set a Smart Card pin into a an auth token, replacing any previous data
+ *
+ * @param tok A pointer to a sss_auth_token structure to change, also
+ * used as a memory context to allocate the internal data.
+ * @param pin A string
+ * @param len The length of the string or, if 0 is passed,
+ * then strlen(password) will be used internally.
+ *
+ * @return EOK on success
+ * ENOMEM on error
+ */
+errno_t sss_authtok_set_sc_pin(struct sss_auth_token *tok, const char *pin,
+ size_t len);
+
+/**
+ * @brief Returns a Smart Card pin as const string if the auth token is of
+ * type SSS_AUTHTOK_TYPE_SC_PIN, otherwise it returns an error
+ *
+ * @param tok A pointer to an sss_auth_token
+ * @param pin A pointer to a const char *, that will point to a null
+ * terminated string
+ * @param len The length of the pin string
+ *
+ * @return EOK on success
+ * ENOENT if the token is empty
+ * EACCESS if the token is not a Smart Card pin token
+ */
+errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **pin,
+ size_t *len);
+
+/**
+ * @brief Sets an auth token to type SSS_AUTHTOK_TYPE_SC_KEYPAD, replacing any
+ * previous data
+ *
+ * @param tok A pointer to a sss_auth_token structure to change, also
+ * used as a memory context to allocate the internal data.
+ */
+void sss_authtok_set_sc_keypad(struct sss_auth_token *tok);
+
#endif /* __AUTHTOK_H__ */
--
2.4.3