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
t_prepare(int argc,char * argv[])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
main(int argc,char * argv[])214 main(int argc, char *argv[])
215 {
216
217 t_main(t_prepare, NULL, argc, argv);
218 }
219