|
|
5fca41 |
From a5e15f1e5af7d7c41717c18566ea0f2a01c086ec Mon Sep 17 00:00:00 2001
|
|
|
5fca41 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
5fca41 |
Date: Wed, 27 Mar 2019 09:02:27 +0100
|
|
|
5fca41 |
Subject: [PATCH 16/21] pam: introduce prompt_config struct
|
|
|
5fca41 |
|
|
|
5fca41 |
prompt_config is the internal struct to control the prompting of
|
|
|
5fca41 |
pam_sss. To make it easy to change internal details when more options
|
|
|
5fca41 |
are added it should be opaque and only accessed by getters and setter.
|
|
|
5fca41 |
|
|
|
5fca41 |
Related to https://pagure.io/SSSD/sssd/issue/3264
|
|
|
5fca41 |
|
|
|
5fca41 |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
5fca41 |
(cherry picked from commit fa8ef7c6db19a160d807f05b08bbc66c0c25ebfe)
|
|
|
5fca41 |
---
|
|
|
5fca41 |
Makefile.am | 17 +
|
|
|
5fca41 |
src/sss_client/pam_sss_prompt_config.c | 547 +++++++++++++++++++++++++
|
|
|
5fca41 |
src/sss_client/sss_cli.h | 29 ++
|
|
|
5fca41 |
src/tests/cmocka/test_prompt_config.c | 215 ++++++++++
|
|
|
5fca41 |
4 files changed, 808 insertions(+)
|
|
|
5fca41 |
create mode 100644 src/sss_client/pam_sss_prompt_config.c
|
|
|
5fca41 |
create mode 100644 src/tests/cmocka/test_prompt_config.c
|
|
|
5fca41 |
|
|
|
5fca41 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
5fca41 |
index d09f50aa2..f7f55e96a 100644
|
|
|
5fca41 |
--- a/Makefile.am
|
|
|
5fca41 |
+++ b/Makefile.am
|
|
|
5fca41 |
@@ -241,6 +241,7 @@ if HAVE_CMOCKA
|
|
|
5fca41 |
test-negcache \
|
|
|
5fca41 |
negcache_2-tests \
|
|
|
5fca41 |
test-authtok \
|
|
|
5fca41 |
+ test_prompt_config \
|
|
|
5fca41 |
sss_nss_idmap-tests \
|
|
|
5fca41 |
deskprofile_utils-tests \
|
|
|
5fca41 |
dyndns-tests \
|
|
|
5fca41 |
@@ -2644,6 +2645,21 @@ test_authtok_LDADD = \
|
|
|
5fca41 |
libsss_debug.la \
|
|
|
5fca41 |
$(NULL)
|
|
|
5fca41 |
|
|
|
5fca41 |
+test_prompt_config_SOURCES = \
|
|
|
5fca41 |
+ src/tests/cmocka/test_prompt_config.c \
|
|
|
5fca41 |
+ src/sss_client/pam_sss_prompt_config.c \
|
|
|
5fca41 |
+ $(NULL)
|
|
|
5fca41 |
+test_prompt_config_CFLAGS = \
|
|
|
5fca41 |
+ $(AM_CFLAGS) \
|
|
|
5fca41 |
+ $(POPT_CFLAGS) \
|
|
|
5fca41 |
+ $(NULL)
|
|
|
5fca41 |
+test_prompt_config_LDADD = \
|
|
|
5fca41 |
+ $(CMOCKA_LIBS) \
|
|
|
5fca41 |
+ $(POPT_LIBS) \
|
|
|
5fca41 |
+ libsss_debug.la \
|
|
|
5fca41 |
+ $(TALLOC_LIBS) \
|
|
|
5fca41 |
+ $(NULL)
|
|
|
5fca41 |
+
|
|
|
5fca41 |
sss_nss_idmap_tests_SOURCES = \
|
|
|
5fca41 |
src/tests/cmocka/sss_nss_idmap-tests.c
|
|
|
5fca41 |
sss_nss_idmap_tests_CFLAGS = \
|
|
|
5fca41 |
@@ -3820,6 +3836,7 @@ endif
|
|
|
5fca41 |
pamlib_LTLIBRARIES = pam_sss.la
|
|
|
5fca41 |
pam_sss_la_SOURCES = \
|
|
|
5fca41 |
src/sss_client/pam_sss.c \
|
|
|
5fca41 |
+ src/sss_client/pam_sss_prompt_config.c \
|
|
|
5fca41 |
src/sss_client/pam_message.c \
|
|
|
5fca41 |
src/sss_client/common.c \
|
|
|
5fca41 |
src/sss_client/sss_cli.h \
|
|
|
5fca41 |
diff --git a/src/sss_client/pam_sss_prompt_config.c b/src/sss_client/pam_sss_prompt_config.c
|
|
|
5fca41 |
new file mode 100644
|
|
|
5fca41 |
index 000000000..35094b406
|
|
|
5fca41 |
--- /dev/null
|
|
|
5fca41 |
+++ b/src/sss_client/pam_sss_prompt_config.c
|
|
|
5fca41 |
@@ -0,0 +1,547 @@
|
|
|
5fca41 |
+/*
|
|
|
5fca41 |
+ Authors:
|
|
|
5fca41 |
+ Sumit Bose <sbose@redhat.com>
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ Copyright (C) 2019 Red Hat
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
5fca41 |
+ it under the terms of the GNU Lesser General Public License as published by
|
|
|
5fca41 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
5fca41 |
+ (at your option) any later version.
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ This program is distributed in the hope that it will be useful,
|
|
|
5fca41 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
5fca41 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
5fca41 |
+ GNU Lesser General Public License for more details.
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ You should have received a copy of the GNU Lesser General Public License
|
|
|
5fca41 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
5fca41 |
+*/
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+#include "config.h"
|
|
|
5fca41 |
+#include <stdlib.h>
|
|
|
5fca41 |
+#include <errno.h>
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+#include "sss_cli.h"
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+#include <libintl.h>
|
|
|
5fca41 |
+#define _(STRING) dgettext (PACKAGE, STRING)
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+struct prompt_config_password {
|
|
|
5fca41 |
+ char *prompt;
|
|
|
5fca41 |
+};
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+struct prompt_config_2fa {
|
|
|
5fca41 |
+ char *prompt_1st;
|
|
|
5fca41 |
+ char *prompt_2nd;
|
|
|
5fca41 |
+};
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+struct prompt_config_2fa_single {
|
|
|
5fca41 |
+ char *prompt;
|
|
|
5fca41 |
+};
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+struct prompt_config_sc_pin {
|
|
|
5fca41 |
+ char *prompt; /* Currently not used */
|
|
|
5fca41 |
+};
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+struct prompt_config {
|
|
|
5fca41 |
+ enum prompt_config_type type;
|
|
|
5fca41 |
+ union {
|
|
|
5fca41 |
+ struct prompt_config_password password;
|
|
|
5fca41 |
+ struct prompt_config_2fa two_fa;
|
|
|
5fca41 |
+ struct prompt_config_2fa_single two_fa_single;
|
|
|
5fca41 |
+ struct prompt_config_sc_pin sc_pin;
|
|
|
5fca41 |
+ } data;
|
|
|
5fca41 |
+};
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+enum prompt_config_type pc_get_type(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc->type > PC_TYPE_INVALID && pc->type < PC_TYPE_LAST) {
|
|
|
5fca41 |
+ return pc->type;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return PC_TYPE_INVALID;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+const char *pc_get_password_prompt(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_PASSWORD) {
|
|
|
5fca41 |
+ return pc->data.password.prompt;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return NULL;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+const char *pc_get_2fa_1st_prompt(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_2FA) {
|
|
|
5fca41 |
+ return pc->data.two_fa.prompt_1st;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return NULL;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+const char *pc_get_2fa_2nd_prompt(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_2FA) {
|
|
|
5fca41 |
+ return pc->data.two_fa.prompt_2nd;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return NULL;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+const char *pc_get_2fa_single_prompt(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_2FA_SINGLE) {
|
|
|
5fca41 |
+ return pc->data.two_fa_single.prompt;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return NULL;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+static void pc_free_password(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_PASSWORD) {
|
|
|
5fca41 |
+ free(pc->data.password.prompt);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+static void pc_free_2fa(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_2FA) {
|
|
|
5fca41 |
+ free(pc->data.two_fa.prompt_1st);
|
|
|
5fca41 |
+ free(pc->data.two_fa.prompt_2nd);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+static void pc_free_2fa_single(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_2FA_SINGLE) {
|
|
|
5fca41 |
+ free(pc->data.two_fa_single.prompt);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+static void pc_free_sc_pin(struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_SC_PIN) {
|
|
|
5fca41 |
+ free(pc->data.sc_pin.prompt);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ return;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+void pc_list_free(struct prompt_config **pc_list)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ size_t c;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (pc_list == NULL) {
|
|
|
5fca41 |
+ return;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ for (c = 0; pc_list[c] != NULL; c++) {
|
|
|
5fca41 |
+ switch (pc_list[c]->type) {
|
|
|
5fca41 |
+ case PC_TYPE_PASSWORD:
|
|
|
5fca41 |
+ pc_free_password(pc_list[c]);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_2FA:
|
|
|
5fca41 |
+ pc_free_2fa(pc_list[c]);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_2FA_SINGLE:
|
|
|
5fca41 |
+ pc_free_2fa_single(pc_list[c]);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_SC_PIN:
|
|
|
5fca41 |
+ pc_free_sc_pin(pc_list[c]);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ default:
|
|
|
5fca41 |
+ return;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ free(pc_list[c]);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ free(pc_list);
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+static errno_t pc_list_add_pc(struct prompt_config ***pc_list,
|
|
|
5fca41 |
+ struct prompt_config *pc)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ size_t c = 0;
|
|
|
5fca41 |
+ struct prompt_config **pcl;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ for (c = 0; *pc_list != NULL && (*pc_list)[c] != NULL; c++); /* just counting */
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pcl = realloc(*pc_list, (c + 2) * sizeof(struct prompt_config *));
|
|
|
5fca41 |
+ if (pcl == NULL) {
|
|
|
5fca41 |
+ return ENOMEM;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ pcl[c] = pc;
|
|
|
5fca41 |
+ pcl[c + 1] = NULL;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ *pc_list = pcl;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ return EOK;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+#define DEFAULT_PASSWORD_PROMPT _("Password: ")
|
|
|
5fca41 |
+#define DEFAULT_2FA_SINGLE_PROMPT _("Password + Token value: ")
|
|
|
5fca41 |
+#define DEFAULT_2FA_PROMPT_1ST _("First Factor: ")
|
|
|
5fca41 |
+#define DEFAULT_2FA_PROMPT_2ND _("Second Factor: ")
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+errno_t pc_list_add_password(struct prompt_config ***pc_list,
|
|
|
5fca41 |
+ const char *prompt)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ struct prompt_config *pc;
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (pc_list == NULL) {
|
|
|
5fca41 |
+ return EINVAL;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc = calloc(1, sizeof(struct prompt_config));
|
|
|
5fca41 |
+ if (pc == NULL) {
|
|
|
5fca41 |
+ return ENOMEM;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc->type = PC_TYPE_PASSWORD;
|
|
|
5fca41 |
+ pc->data.password.prompt = strdup(prompt != NULL ? prompt
|
|
|
5fca41 |
+ : DEFAULT_PASSWORD_PROMPT);
|
|
|
5fca41 |
+ if (pc->data.password.prompt == NULL) {
|
|
|
5fca41 |
+ ret = ENOMEM;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_pc(pc_list, pc);
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = EOK;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+done:
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ free(pc->data.password.prompt);
|
|
|
5fca41 |
+ free(pc);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ return ret;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+errno_t pc_list_add_2fa(struct prompt_config ***pc_list,
|
|
|
5fca41 |
+ const char *prompt_1st, const char *prompt_2nd)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ struct prompt_config *pc;
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (pc_list == NULL) {
|
|
|
5fca41 |
+ return EINVAL;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc = calloc(1, sizeof(struct prompt_config));
|
|
|
5fca41 |
+ if (pc == NULL) {
|
|
|
5fca41 |
+ return ENOMEM;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc->type = PC_TYPE_2FA;
|
|
|
5fca41 |
+ pc->data.two_fa.prompt_1st = strdup(prompt_1st != NULL ? prompt_1st
|
|
|
5fca41 |
+ : DEFAULT_2FA_PROMPT_1ST);
|
|
|
5fca41 |
+ if (pc->data.two_fa.prompt_1st == NULL) {
|
|
|
5fca41 |
+ ret = ENOMEM;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ pc->data.two_fa.prompt_2nd = strdup(prompt_2nd != NULL ? prompt_2nd
|
|
|
5fca41 |
+ : DEFAULT_2FA_PROMPT_2ND);
|
|
|
5fca41 |
+ if (pc->data.two_fa.prompt_2nd == NULL) {
|
|
|
5fca41 |
+ ret = ENOMEM;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_pc(pc_list, pc);
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = EOK;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+done:
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ free(pc->data.two_fa.prompt_1st);
|
|
|
5fca41 |
+ free(pc->data.two_fa.prompt_2nd);
|
|
|
5fca41 |
+ free(pc);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ return ret;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+errno_t pc_list_add_2fa_single(struct prompt_config ***pc_list,
|
|
|
5fca41 |
+ const char *prompt)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ struct prompt_config *pc;
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (pc_list == NULL) {
|
|
|
5fca41 |
+ return EINVAL;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc = calloc(1, sizeof(struct prompt_config));
|
|
|
5fca41 |
+ if (pc == NULL) {
|
|
|
5fca41 |
+ return ENOMEM;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc->type = PC_TYPE_2FA_SINGLE;
|
|
|
5fca41 |
+ pc->data.two_fa_single.prompt = strdup(prompt != NULL ? prompt
|
|
|
5fca41 |
+ : DEFAULT_2FA_SINGLE_PROMPT);
|
|
|
5fca41 |
+ if (pc->data.two_fa_single.prompt == NULL) {
|
|
|
5fca41 |
+ ret = ENOMEM;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_pc(pc_list, pc);
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = EOK;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+done:
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ free(pc->data.two_fa_single.prompt);
|
|
|
5fca41 |
+ free(pc);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ return ret;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+errno_t pam_get_response_prompt_config(struct prompt_config **pc_list, int *len,
|
|
|
5fca41 |
+ uint8_t **data)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ size_t c;
|
|
|
5fca41 |
+ size_t l = 0;
|
|
|
5fca41 |
+ uint8_t *d = NULL;
|
|
|
5fca41 |
+ uint32_t uint32_val;
|
|
|
5fca41 |
+ size_t rp;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (pc_list == NULL || *pc_list == NULL) {
|
|
|
5fca41 |
+ return ENOENT;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ l += sizeof(uint32_t);
|
|
|
5fca41 |
+ for (c = 0; pc_list[c] != NULL; c++) {
|
|
|
5fca41 |
+ l += sizeof(uint32_t);
|
|
|
5fca41 |
+ switch (pc_list[c]->type) {
|
|
|
5fca41 |
+ case PC_TYPE_PASSWORD:
|
|
|
5fca41 |
+ l += sizeof(uint32_t);
|
|
|
5fca41 |
+ l += strlen(pc_list[c]->data.password.prompt);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_2FA:
|
|
|
5fca41 |
+ l += sizeof(uint32_t);
|
|
|
5fca41 |
+ l += strlen(pc_list[c]->data.two_fa.prompt_1st);
|
|
|
5fca41 |
+ l += sizeof(uint32_t);
|
|
|
5fca41 |
+ l += strlen(pc_list[c]->data.two_fa.prompt_2nd);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_2FA_SINGLE:
|
|
|
5fca41 |
+ l += sizeof(uint32_t);
|
|
|
5fca41 |
+ l += strlen(pc_list[c]->data.two_fa_single.prompt);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_SC_PIN:
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ default:
|
|
|
5fca41 |
+ return EINVAL;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ d = malloc(l * sizeof(uint8_t));
|
|
|
5fca41 |
+ if (d == NULL) {
|
|
|
5fca41 |
+ return ENOMEM;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ rp = 0;
|
|
|
5fca41 |
+ uint32_val = c;
|
|
|
5fca41 |
+ SAFEALIGN_COPY_UINT32(&d[rp], &uint32_val, &rp);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ for (c = 0; pc_list[c] != NULL; c++) {
|
|
|
5fca41 |
+ uint32_val = pc_list[c]->type;
|
|
|
5fca41 |
+ SAFEALIGN_COPY_UINT32(&d[rp], &uint32_val, &rp);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ switch (pc_list[c]->type) {
|
|
|
5fca41 |
+ case PC_TYPE_PASSWORD:
|
|
|
5fca41 |
+ SAFEALIGN_SET_UINT32(&d[rp],
|
|
|
5fca41 |
+ strlen(pc_list[c]->data.password.prompt), &rp);
|
|
|
5fca41 |
+ safealign_memcpy(&d[rp], pc_list[c]->data.password.prompt,
|
|
|
5fca41 |
+ strlen(pc_list[c]->data.password.prompt), &rp);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_2FA:
|
|
|
5fca41 |
+ SAFEALIGN_SET_UINT32(&d[rp],
|
|
|
5fca41 |
+ strlen(pc_list[c]->data.two_fa.prompt_1st),
|
|
|
5fca41 |
+ &rp);
|
|
|
5fca41 |
+ safealign_memcpy(&d[rp], pc_list[c]->data.two_fa.prompt_1st,
|
|
|
5fca41 |
+ strlen(pc_list[c]->data.two_fa.prompt_1st), &rp);
|
|
|
5fca41 |
+ SAFEALIGN_SET_UINT32(&d[rp],
|
|
|
5fca41 |
+ strlen(pc_list[c]->data.two_fa.prompt_2nd),
|
|
|
5fca41 |
+ &rp);
|
|
|
5fca41 |
+ safealign_memcpy(&d[rp], pc_list[c]->data.two_fa.prompt_2nd,
|
|
|
5fca41 |
+ strlen(pc_list[c]->data.two_fa.prompt_2nd), &rp);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_2FA_SINGLE:
|
|
|
5fca41 |
+ SAFEALIGN_SET_UINT32(&d[rp],
|
|
|
5fca41 |
+ strlen(pc_list[c]->data.two_fa_single.prompt),
|
|
|
5fca41 |
+ &rp);
|
|
|
5fca41 |
+ safealign_memcpy(&d[rp], pc_list[c]->data.two_fa_single.prompt,
|
|
|
5fca41 |
+ strlen(pc_list[c]->data.two_fa_single.prompt),
|
|
|
5fca41 |
+ &rp);
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_SC_PIN:
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ default:
|
|
|
5fca41 |
+ free(d);
|
|
|
5fca41 |
+ return EINVAL;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (rp != l) {
|
|
|
5fca41 |
+ free(d);
|
|
|
5fca41 |
+ return EFAULT;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ *data = d;
|
|
|
5fca41 |
+ *len = l;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ return EOK;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+errno_t pc_list_from_response(int size, uint8_t *buf,
|
|
|
5fca41 |
+ struct prompt_config ***pc_list)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+ uint32_t count;
|
|
|
5fca41 |
+ uint32_t type;
|
|
|
5fca41 |
+ uint32_t l;
|
|
|
5fca41 |
+ size_t rp;
|
|
|
5fca41 |
+ size_t c;
|
|
|
5fca41 |
+ struct prompt_config **pl = NULL;
|
|
|
5fca41 |
+ char *str;
|
|
|
5fca41 |
+ char *str2;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (buf == NULL || size < 3 * sizeof(uint32_t)) {
|
|
|
5fca41 |
+ return EINVAL;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ rp = 0;
|
|
|
5fca41 |
+ SAFEALIGN_COPY_UINT32_CHECK(&count, buf + rp, size, &rp);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ for (c = 0; c < count; c++) {
|
|
|
5fca41 |
+ /* Since we already know size < 3 * sizeof(uint32_t) this check should
|
|
|
5fca41 |
+ * be safe and without over- or underflow. */
|
|
|
5fca41 |
+ if (rp > size - sizeof(uint32_t)) {
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ SAFEALIGN_COPY_UINT32(&type, buf + rp, &rp);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ switch (type) {
|
|
|
5fca41 |
+ case PC_TYPE_PASSWORD:
|
|
|
5fca41 |
+ if (rp > size - sizeof(uint32_t)) {
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (l > size || rp > size - l) {
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ str = strndup((char *) buf + rp, l);
|
|
|
5fca41 |
+ if (str == NULL) {
|
|
|
5fca41 |
+ ret = ENOMEM;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ rp += l;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_password(&pl, str);
|
|
|
5fca41 |
+ free(str);
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_2FA:
|
|
|
5fca41 |
+ if (rp > size - sizeof(uint32_t)) {
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (l > size || rp > size - l) {
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ str = strndup((char *) buf + rp, l);
|
|
|
5fca41 |
+ if (str == NULL) {
|
|
|
5fca41 |
+ ret = ENOMEM;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ rp += l;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (rp > size - sizeof(uint32_t)) {
|
|
|
5fca41 |
+ free(str);
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (l > size || rp > size - l) {
|
|
|
5fca41 |
+ free(str);
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ str2 = strndup((char *) buf + rp, l);
|
|
|
5fca41 |
+ if (str2 == NULL) {
|
|
|
5fca41 |
+ free(str);
|
|
|
5fca41 |
+ ret = ENOMEM;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ rp += l;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa(&pl, str, str2);
|
|
|
5fca41 |
+ free(str);
|
|
|
5fca41 |
+ free(str2);
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_2FA_SINGLE:
|
|
|
5fca41 |
+ if (rp > size - sizeof(uint32_t)) {
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ if (l > size || rp > size - l) {
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ str = strndup((char *) buf + rp, l);
|
|
|
5fca41 |
+ if (str == NULL) {
|
|
|
5fca41 |
+ ret = ENOMEM;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ rp += l;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa_single(&pl, str);
|
|
|
5fca41 |
+ free(str);
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ case PC_TYPE_SC_PIN:
|
|
|
5fca41 |
+ break;
|
|
|
5fca41 |
+ default:
|
|
|
5fca41 |
+ ret = EINVAL;
|
|
|
5fca41 |
+ goto done;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ *pc_list = pl;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = EOK;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+done:
|
|
|
5fca41 |
+ if (ret != EOK) {
|
|
|
5fca41 |
+ pc_list_free(pl);
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ return ret;
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
|
|
|
5fca41 |
index 24d28ed4b..7e748c281 100644
|
|
|
5fca41 |
--- a/src/sss_client/sss_cli.h
|
|
|
5fca41 |
+++ b/src/sss_client/sss_cli.h
|
|
|
5fca41 |
@@ -561,6 +561,35 @@ enum user_info_type {
|
|
|
5fca41 |
* @}
|
|
|
5fca41 |
*/ /* end of group sss_pam_cli */
|
|
|
5fca41 |
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+enum prompt_config_type {
|
|
|
5fca41 |
+ PC_TYPE_INVALID = 0,
|
|
|
5fca41 |
+ PC_TYPE_PASSWORD,
|
|
|
5fca41 |
+ PC_TYPE_2FA,
|
|
|
5fca41 |
+ PC_TYPE_2FA_SINGLE,
|
|
|
5fca41 |
+ PC_TYPE_SC_PIN,
|
|
|
5fca41 |
+ PC_TYPE_LAST
|
|
|
5fca41 |
+};
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+struct prompt_config;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+enum prompt_config_type pc_get_type(struct prompt_config *pc);
|
|
|
5fca41 |
+const char *pc_get_password_prompt(struct prompt_config *pc);
|
|
|
5fca41 |
+const char *pc_get_2fa_1st_prompt(struct prompt_config *pc);
|
|
|
5fca41 |
+const char *pc_get_2fa_2nd_prompt(struct prompt_config *pc);
|
|
|
5fca41 |
+const char *pc_get_2fa_single_prompt(struct prompt_config *pc);
|
|
|
5fca41 |
+void pc_list_free(struct prompt_config **pc_list);
|
|
|
5fca41 |
+errno_t pc_list_add_password(struct prompt_config ***pc_list,
|
|
|
5fca41 |
+ const char *prompt);
|
|
|
5fca41 |
+errno_t pc_list_add_2fa(struct prompt_config ***pc_list,
|
|
|
5fca41 |
+ const char *prompt_1st, const char *prompt_2nd);
|
|
|
5fca41 |
+errno_t pc_list_add_2fa_single(struct prompt_config ***pc_list,
|
|
|
5fca41 |
+ const char *prompt);
|
|
|
5fca41 |
+errno_t pam_get_response_prompt_config(struct prompt_config **pc_list, int *len,
|
|
|
5fca41 |
+ uint8_t **data);
|
|
|
5fca41 |
+errno_t pc_list_from_response(int size, uint8_t *buf,
|
|
|
5fca41 |
+ struct prompt_config ***pc_list);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
enum sss_netgr_rep_type {
|
|
|
5fca41 |
SSS_NETGR_REP_TRIPLE = 1,
|
|
|
5fca41 |
SSS_NETGR_REP_GROUP
|
|
|
5fca41 |
diff --git a/src/tests/cmocka/test_prompt_config.c b/src/tests/cmocka/test_prompt_config.c
|
|
|
5fca41 |
new file mode 100644
|
|
|
5fca41 |
index 000000000..0b761ae4c
|
|
|
5fca41 |
--- /dev/null
|
|
|
5fca41 |
+++ b/src/tests/cmocka/test_prompt_config.c
|
|
|
5fca41 |
@@ -0,0 +1,215 @@
|
|
|
5fca41 |
+/*
|
|
|
5fca41 |
+ SSSD
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ prompt config - Utilities tests
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ Authors:
|
|
|
5fca41 |
+ Sumit bose <sbose@redhat.com>
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ Copyright (C) 2019 Red Hat
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
5fca41 |
+ it under the terms of the GNU General Public License as published by
|
|
|
5fca41 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
5fca41 |
+ (at your option) any later version.
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ This program is distributed in the hope that it will be useful,
|
|
|
5fca41 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
5fca41 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
5fca41 |
+ GNU General Public License for more details.
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ You should have received a copy of the GNU General Public License
|
|
|
5fca41 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
5fca41 |
+*/
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+#include <string.h>
|
|
|
5fca41 |
+#include <popt.h>
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+#include "tests/cmocka/common_mock.h"
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+#include "sss_client/sss_cli.h"
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+void test_pc_list_add_password(void **state)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+ struct prompt_config **pc_list = NULL;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_password(&pc_list, "Hello");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+ assert_non_null(pc_list);
|
|
|
5fca41 |
+ assert_non_null(pc_list[0]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_PASSWORD, pc_get_type(pc_list[0]));
|
|
|
5fca41 |
+ assert_string_equal("Hello", pc_get_password_prompt(pc_list[0]));
|
|
|
5fca41 |
+ assert_null(pc_list[1]);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_password(&pc_list, "Hello2");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+ assert_non_null(pc_list);
|
|
|
5fca41 |
+ assert_non_null(pc_list[0]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_PASSWORD, pc_get_type(pc_list[0]));
|
|
|
5fca41 |
+ assert_string_equal("Hello", pc_get_password_prompt(pc_list[0]));
|
|
|
5fca41 |
+ assert_non_null(pc_list[1]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_PASSWORD, pc_get_type(pc_list[1]));
|
|
|
5fca41 |
+ assert_string_equal("Hello2", pc_get_password_prompt(pc_list[1]));
|
|
|
5fca41 |
+ assert_null(pc_list[2]);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc_list_free(pc_list);
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+void test_pc_list_add_2fa_single(void **state)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+ struct prompt_config **pc_list = NULL;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa_single(&pc_list, "Hello");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+ assert_non_null(pc_list);
|
|
|
5fca41 |
+ assert_non_null(pc_list[0]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_2FA_SINGLE, pc_get_type(pc_list[0]));
|
|
|
5fca41 |
+ assert_string_equal("Hello", pc_get_2fa_single_prompt(pc_list[0]));
|
|
|
5fca41 |
+ assert_null(pc_list[1]);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa_single(&pc_list, "Hello2");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+ assert_non_null(pc_list);
|
|
|
5fca41 |
+ assert_non_null(pc_list[0]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_2FA_SINGLE, pc_get_type(pc_list[0]));
|
|
|
5fca41 |
+ assert_string_equal("Hello", pc_get_2fa_single_prompt(pc_list[0]));
|
|
|
5fca41 |
+ assert_non_null(pc_list[1]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_2FA_SINGLE, pc_get_type(pc_list[1]));
|
|
|
5fca41 |
+ assert_string_equal("Hello2", pc_get_2fa_single_prompt(pc_list[1]));
|
|
|
5fca41 |
+ assert_null(pc_list[2]);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc_list_free(pc_list);
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+void test_pc_list_add_2fa(void **state)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+ struct prompt_config **pc_list = NULL;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa(&pc_list, "Hello", "Good Bye");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+ assert_non_null(pc_list);
|
|
|
5fca41 |
+ assert_non_null(pc_list[0]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_2FA, pc_get_type(pc_list[0]));
|
|
|
5fca41 |
+ assert_string_equal("Hello", pc_get_2fa_1st_prompt(pc_list[0]));
|
|
|
5fca41 |
+ assert_string_equal("Good Bye", pc_get_2fa_2nd_prompt(pc_list[0]));
|
|
|
5fca41 |
+ assert_null(pc_list[1]);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc_list_free(pc_list);
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+void test_pam_get_response_prompt_config(void **state)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+ struct prompt_config **pc_list = NULL;
|
|
|
5fca41 |
+ int len;
|
|
|
5fca41 |
+ uint8_t *data;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_password(&pc_list, "password");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa(&pc_list, "first", "second");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa_single(&pc_list, "single");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pam_get_response_prompt_config(pc_list, &len, &data);
|
|
|
5fca41 |
+ pc_list_free(pc_list);
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+ assert_int_equal(len, 57);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
5fca41 |
+ assert_memory_equal(data, "\3\0\0\0\1\0\0\0\10\0\0\0" "password\2\0\0\0\5\0\0\0" "first\6\0\0\0" "second\3\0\0\0\6\0\0\0" "single", len);
|
|
|
5fca41 |
+#else
|
|
|
5fca41 |
+ assert_memory_equal(data, "\0\0\0\3\0\0\0\1\0\0\0\10" "password\0\0\0\2\0\0\0\5" "first\0\0\0\6" "second\0\0\0\3\0\0\0\6" "single", len);
|
|
|
5fca41 |
+#endif
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ free(data);
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+void test_pc_list_from_response(void **state)
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ int ret;
|
|
|
5fca41 |
+ struct prompt_config **pc_list = NULL;
|
|
|
5fca41 |
+ int len;
|
|
|
5fca41 |
+ uint8_t *data;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_password(&pc_list, "password");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa(&pc_list, "first", "second");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_add_2fa_single(&pc_list, "single");
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pam_get_response_prompt_config(pc_list, &len, &data);
|
|
|
5fca41 |
+ pc_list_free(pc_list);
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+ assert_int_equal(len, 57);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc_list = NULL;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ ret = pc_list_from_response(len, data, &pc_list);
|
|
|
5fca41 |
+ free(data);
|
|
|
5fca41 |
+ assert_int_equal(ret, EOK);
|
|
|
5fca41 |
+ assert_non_null(pc_list);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ assert_non_null(pc_list[0]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_PASSWORD, pc_get_type(pc_list[0]));
|
|
|
5fca41 |
+ assert_string_equal("password", pc_get_password_prompt(pc_list[0]));
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ assert_non_null(pc_list[1]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_2FA, pc_get_type(pc_list[1]));
|
|
|
5fca41 |
+ assert_string_equal("first", pc_get_2fa_1st_prompt(pc_list[1]));
|
|
|
5fca41 |
+ assert_string_equal("second", pc_get_2fa_2nd_prompt(pc_list[1]));
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ assert_non_null(pc_list[2]);
|
|
|
5fca41 |
+ assert_int_equal(PC_TYPE_2FA_SINGLE, pc_get_type(pc_list[2]));
|
|
|
5fca41 |
+ assert_string_equal("single", pc_get_2fa_single_prompt(pc_list[2]));
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ assert_null(pc_list[3]);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc_list_free(pc_list);
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+int main(int argc, const char *argv[])
|
|
|
5fca41 |
+{
|
|
|
5fca41 |
+ poptContext pc;
|
|
|
5fca41 |
+ int opt;
|
|
|
5fca41 |
+ struct poptOption long_options[] = {
|
|
|
5fca41 |
+ POPT_AUTOHELP
|
|
|
5fca41 |
+ SSSD_DEBUG_OPTS
|
|
|
5fca41 |
+ POPT_TABLEEND
|
|
|
5fca41 |
+ };
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ const struct CMUnitTest tests[] = {
|
|
|
5fca41 |
+ cmocka_unit_test(test_pc_list_add_password),
|
|
|
5fca41 |
+ cmocka_unit_test(test_pc_list_add_2fa_single),
|
|
|
5fca41 |
+ cmocka_unit_test(test_pc_list_add_2fa),
|
|
|
5fca41 |
+ cmocka_unit_test(test_pam_get_response_prompt_config),
|
|
|
5fca41 |
+ cmocka_unit_test(test_pc_list_from_response),
|
|
|
5fca41 |
+ };
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ /* Set debug level to invalid value so we can decide if -d 0 was used. */
|
|
|
5fca41 |
+ debug_level = SSSDBG_INVALID;
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
|
|
|
5fca41 |
+ while((opt = poptGetNextOpt(pc)) != -1) {
|
|
|
5fca41 |
+ switch(opt) {
|
|
|
5fca41 |
+ default:
|
|
|
5fca41 |
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
|
|
|
5fca41 |
+ poptBadOption(pc, 0), poptStrerror(opt));
|
|
|
5fca41 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
5fca41 |
+ return 1;
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ }
|
|
|
5fca41 |
+ poptFreeContext(pc);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ DEBUG_CLI_INIT(debug_level);
|
|
|
5fca41 |
+
|
|
|
5fca41 |
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
|
|
5fca41 |
+}
|
|
|
5fca41 |
--
|
|
|
5fca41 |
2.19.1
|
|
|
5fca41 |
|