Blob Blame History Raw
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