1 /*- 2 * Copyright (c) 2015-2017 Dag-Erling Smørgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote 14 * products derived from this software without specific prior written 15 * permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #ifdef HAVE_CONFIG_H 31 # include "config.h" 32 #endif 33 34 #include <err.h> 35 #include <stdint.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <unistd.h> 40 41 #include <cryb/test.h> 42 43 #include <security/pam_appl.h> 44 #include <security/openpam.h> 45 46 #include "openpam_impl.h" 47 #include "t_pam_conv.h" 48 49 #define T_FUNC(n, d) \ 50 static const char *t_ ## n ## _desc = d; \ 51 static int t_ ## n ## _func(OPENPAM_UNUSED(char **desc), \ 52 OPENPAM_UNUSED(void *arg)) 53 54 #define T(n) \ 55 t_add_test(&t_ ## n ## _func, NULL, "%s", t_ ## n ## _desc) 56 57 const char *pam_return_so; 58 59 T_FUNC(empty_policy, "empty policy") 60 { 61 struct t_pam_conv_script script; 62 struct pam_conv pamc; 63 struct t_file *tf; 64 pam_handle_t *pamh; 65 int pam_err, ret; 66 67 memset(&script, 0, sizeof script); 68 pamc.conv = &t_pam_conv; 69 pamc.appdata_ptr = &script; 70 tf = t_fopen(NULL); 71 t_fprintf(tf, "# empty policy\n"); 72 pam_err = pam_start(tf->name, "test", &pamc, &pamh); 73 if (pam_err != PAM_SUCCESS) { 74 t_printv("pam_start() returned %d\n", pam_err); 75 return (0); 76 } 77 /* 78 * Note: openpam_dispatch() currently returns PAM_SYSTEM_ERR when 79 * the chain is empty, it should possibly return PAM_SERVICE_ERR 80 * instead. 81 */ 82 pam_err = pam_authenticate(pamh, 0); 83 t_printv("pam_authenticate() returned %d\n", pam_err); 84 ret = (pam_err == PAM_SYSTEM_ERR); 85 pam_err = pam_setcred(pamh, 0); 86 t_printv("pam_setcred() returned %d\n", pam_err); 87 ret &= (pam_err == PAM_SYSTEM_ERR); 88 pam_err = pam_acct_mgmt(pamh, 0); 89 t_printv("pam_acct_mgmt() returned %d\n", pam_err); 90 ret &= (pam_err == PAM_SYSTEM_ERR); 91 pam_err = pam_chauthtok(pamh, 0); 92 t_printv("pam_chauthtok() returned %d\n", pam_err); 93 ret &= (pam_err == PAM_SYSTEM_ERR); 94 pam_err = pam_open_session(pamh, 0); 95 t_printv("pam_open_session() returned %d\n", pam_err); 96 ret &= (pam_err == PAM_SYSTEM_ERR); 97 pam_err = pam_close_session(pamh, 0); 98 t_printv("pam_close_session() returned %d\n", pam_err); 99 ret &= (pam_err == PAM_SYSTEM_ERR); 100 pam_end(pamh, pam_err); 101 t_fclose(tf); 102 return (ret); 103 } 104 105 static struct t_pam_return_case { 106 int facility; 107 int primitive; 108 int flags; 109 struct { 110 int ctlflag; 111 int modret; 112 } mod[2]; 113 int result; 114 } t_pam_return_cases[] = { 115 { 116 PAM_AUTH, PAM_SM_AUTHENTICATE, 0, 117 { 118 { PAM_REQUIRED, PAM_SUCCESS }, 119 { PAM_REQUIRED, PAM_SUCCESS }, 120 }, 121 PAM_SUCCESS, 122 }, 123 }; 124 125 T_FUNC(mod_return, "module return value") 126 { 127 struct t_pam_return_case *tc; 128 struct t_pam_conv_script script; 129 struct pam_conv pamc; 130 struct t_file *tf; 131 pam_handle_t *pamh; 132 unsigned int i, j, n; 133 int pam_err; 134 135 memset(&script, 0, sizeof script); 136 pamc.conv = &t_pam_conv; 137 pamc.appdata_ptr = &script; 138 n = sizeof t_pam_return_cases / sizeof t_pam_return_cases[0]; 139 for (i = 0; i < n; ++i) { 140 tc = &t_pam_return_cases[i]; 141 tf = t_fopen(NULL); 142 for (j = 0; j < 2; ++j) { 143 t_fprintf(tf, "%s %s %s error=%s\n", 144 pam_facility_name[tc->facility], 145 pam_control_flag_name[tc->mod[j].ctlflag], 146 pam_return_so, 147 pam_err_name[tc->mod[j].modret]); 148 } 149 pam_err = pam_start(tf->name, "test", &pamc, &pamh); 150 if (pam_err != PAM_SUCCESS) { 151 t_printv("pam_start() returned %d\n", pam_err); 152 t_fclose(tf); 153 continue; 154 } 155 switch (tc->primitive) { 156 case PAM_SM_AUTHENTICATE: 157 pam_err = pam_authenticate(pamh, tc->flags); 158 break; 159 case PAM_SM_SETCRED: 160 pam_err = pam_setcred(pamh, tc->flags); 161 break; 162 case PAM_SM_ACCT_MGMT: 163 pam_err = pam_acct_mgmt(pamh, tc->flags); 164 break; 165 case PAM_SM_OPEN_SESSION: 166 pam_err = pam_open_session(pamh, tc->flags); 167 break; 168 case PAM_SM_CLOSE_SESSION: 169 pam_err = pam_close_session(pamh, tc->flags); 170 break; 171 case PAM_SM_CHAUTHTOK: 172 pam_err = pam_chauthtok(pamh, tc->flags); 173 break; 174 } 175 t_printv("%s returned %d\n", 176 pam_func_name[tc->primitive], pam_err); 177 pam_end(pamh, pam_err); 178 t_printv("here\n"); 179 t_fclose(tf); 180 } 181 return (1); 182 } 183 184 185 /*************************************************************************** 186 * Boilerplate 187 */ 188 189 static int 190 t_prepare(int argc, char *argv[]) 191 { 192 193 (void)argc; 194 (void)argv; 195 196 if ((pam_return_so = getenv("PAM_RETURN_SO")) == NULL) { 197 t_printv("define PAM_RETURN_SO before running these tests\n"); 198 return (0); 199 } 200 201 openpam_set_feature(OPENPAM_RESTRICT_MODULE_NAME, 0); 202 openpam_set_feature(OPENPAM_VERIFY_MODULE_FILE, 0); 203 openpam_set_feature(OPENPAM_RESTRICT_SERVICE_NAME, 0); 204 openpam_set_feature(OPENPAM_VERIFY_POLICY_FILE, 0); 205 openpam_set_feature(OPENPAM_FALLBACK_TO_OTHER, 0); 206 207 T(empty_policy); 208 T(mod_return); 209 210 return (0); 211 } 212 213 int 214 main(int argc, char *argv[]) 215 { 216 217 t_main(t_prepare, NULL, argc, argv); 218 } 219