diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2017-02-19 21:00:46 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2017-02-19 21:00:46 +0000 |
commit | 04e30652172d69d399641893e6a801503a0a1f8f (patch) | |
tree | 13dc6a841647bee3f58db67dea6c46970b923e12 /t/t_openpam_dispatch.c | |
parent | d2afd010d41e1acf0fe4e164246c8055368bf503 (diff) |
Diffstat (limited to 't/t_openpam_dispatch.c')
-rw-r--r-- | t/t_openpam_dispatch.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/t/t_openpam_dispatch.c b/t/t_openpam_dispatch.c new file mode 100644 index 000000000000..f198a994e63e --- /dev/null +++ b/t/t_openpam_dispatch.c @@ -0,0 +1,220 @@ +/*- + * Copyright (c) 2015 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: t_openpam_dispatch.c 922 2017-02-19 19:28:30Z des $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <err.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <cryb/test.h> + +#include <security/pam_appl.h> +#include <security/openpam.h> + +#include "openpam_impl.h" +#include "t_pam_conv.h" + +#define T_FUNC(n, d) \ + static const char *t_ ## n ## _desc = d; \ + static int t_ ## n ## _func(OPENPAM_UNUSED(char **desc), \ + OPENPAM_UNUSED(void *arg)) + +#define T(n) \ + t_add_test(&t_ ## n ## _func, NULL, t_ ## n ## _desc) + +const char *pam_return_so; + +T_FUNC(empty_policy, "empty policy") +{ + struct t_pam_conv_script script; + struct pam_conv pamc; + struct t_file *tf; + pam_handle_t *pamh; + int pam_err, ret; + + memset(&script, 0, sizeof script); + pamc.conv = &t_pam_conv; + pamc.appdata_ptr = &script; + tf = t_fopen(NULL); + t_fprintf(tf, "# empty policy\n"); + pam_err = pam_start(tf->name, "test", &pamc, &pamh); + if (pam_err != PAM_SUCCESS) { + t_verbose("pam_start() returned %d\n", pam_err); + return (0); + } + /* + * Note: openpam_dispatch() currently returns PAM_SYSTEM_ERR when + * the chain is empty, it should possibly return PAM_SERVICE_ERR + * instead. + */ + pam_err = pam_authenticate(pamh, 0); + t_verbose("pam_authenticate() returned %d\n", pam_err); + ret = (pam_err == PAM_SYSTEM_ERR); + pam_err = pam_setcred(pamh, 0); + t_verbose("pam_setcred() returned %d\n", pam_err); + ret &= (pam_err == PAM_SYSTEM_ERR); + pam_err = pam_acct_mgmt(pamh, 0); + t_verbose("pam_acct_mgmt() returned %d\n", pam_err); + ret &= (pam_err == PAM_SYSTEM_ERR); + pam_err = pam_chauthtok(pamh, 0); + t_verbose("pam_chauthtok() returned %d\n", pam_err); + ret &= (pam_err == PAM_SYSTEM_ERR); + pam_err = pam_open_session(pamh, 0); + t_verbose("pam_open_session() returned %d\n", pam_err); + ret &= (pam_err == PAM_SYSTEM_ERR); + pam_err = pam_close_session(pamh, 0); + t_verbose("pam_close_session() returned %d\n", pam_err); + ret &= (pam_err == PAM_SYSTEM_ERR); + pam_end(pamh, pam_err); + t_fclose(tf); + return (ret); +} + +static struct t_pam_return_case { + int facility; + int primitive; + int flags; + struct { + int ctlflag; + int modret; + } mod[2]; + int result; +} t_pam_return_cases[] = { + { + PAM_AUTH, PAM_SM_AUTHENTICATE, 0, + { + { PAM_REQUIRED, PAM_SUCCESS }, + { PAM_REQUIRED, PAM_SUCCESS }, + }, + PAM_SUCCESS, + }, +}; + +T_FUNC(mod_return, "module return value") +{ + struct t_pam_return_case *tc; + struct t_pam_conv_script script; + struct pam_conv pamc; + struct t_file *tf; + pam_handle_t *pamh; + unsigned int i, j, n; + int pam_err; + + memset(&script, 0, sizeof script); + pamc.conv = &t_pam_conv; + pamc.appdata_ptr = &script; + n = sizeof t_pam_return_cases / sizeof t_pam_return_cases[0]; + for (i = 0; i < n; ++i) { + tc = &t_pam_return_cases[i]; + tf = t_fopen(NULL); + for (j = 0; j < 2; ++j) { + t_fprintf(tf, "%s %s %s error=%s\n", + pam_facility_name[tc->facility], + pam_control_flag_name[tc->mod[j].ctlflag], + pam_return_so, + pam_err_name[tc->mod[j].modret]); + } + pam_err = pam_start(tf->name, "test", &pamc, &pamh); + if (pam_err != PAM_SUCCESS) { + t_verbose("pam_start() returned %d\n", pam_err); + t_fclose(tf); + continue; + } + switch (tc->primitive) { + case PAM_SM_AUTHENTICATE: + pam_err = pam_authenticate(pamh, tc->flags); + break; + case PAM_SM_SETCRED: + pam_err = pam_setcred(pamh, tc->flags); + break; + case PAM_SM_ACCT_MGMT: + pam_err = pam_acct_mgmt(pamh, tc->flags); + break; + case PAM_SM_OPEN_SESSION: + pam_err = pam_open_session(pamh, tc->flags); + break; + case PAM_SM_CLOSE_SESSION: + pam_err = pam_close_session(pamh, tc->flags); + break; + case PAM_SM_CHAUTHTOK: + pam_err = pam_chauthtok(pamh, tc->flags); + break; + } + t_verbose("%s returned %d\n", + pam_func_name[tc->primitive], pam_err); + pam_end(pamh, pam_err); + t_verbose("here\n"); + t_fclose(tf); + } + return (1); +} + + +/*************************************************************************** + * Boilerplate + */ + +static int +t_prepare(int argc, char *argv[]) +{ + + (void)argc; + (void)argv; + + if ((pam_return_so = getenv("PAM_RETURN_SO")) == NULL) { + t_verbose("define PAM_RETURN_SO before running these tests\n"); + return (0); + } + + openpam_set_feature(OPENPAM_RESTRICT_MODULE_NAME, 0); + openpam_set_feature(OPENPAM_VERIFY_MODULE_FILE, 0); + openpam_set_feature(OPENPAM_RESTRICT_SERVICE_NAME, 0); + openpam_set_feature(OPENPAM_VERIFY_POLICY_FILE, 0); + openpam_set_feature(OPENPAM_FALLBACK_TO_OTHER, 0); + + T(empty_policy); + T(mod_return); + + return (0); +} + +int +main(int argc, char *argv[]) +{ + + t_main(t_prepare, NULL, argc, argv); +} |