Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : *
4 : * Copyright (C) 2018-2019 Andreas Schneider <asn@samba.org>
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <stdarg.h>
21 : #include <stddef.h>
22 : #include <stdint.h>
23 : #include <setjmp.h>
24 : #include <cmocka.h>
25 :
26 : #include "lib/replace/replace.h"
27 : #include "auth/credentials/credentials.c"
28 :
29 1 : static int setup_talloc_context(void **state)
30 : {
31 1 : TALLOC_CTX *frame = talloc_stackframe();
32 :
33 1 : *state = frame;
34 1 : return 0;
35 : }
36 :
37 1 : static int teardown_talloc_context(void **state)
38 : {
39 1 : TALLOC_CTX *frame = *state;
40 1 : TALLOC_FREE(frame);
41 1 : return 0;
42 : }
43 :
44 1 : static void torture_creds_init(void **state)
45 : {
46 1 : TALLOC_CTX *mem_ctx = *state;
47 1 : struct cli_credentials *creds = NULL;
48 1 : const char *username = NULL;
49 1 : const char *domain = NULL;
50 1 : const char *password = NULL;
51 1 : enum credentials_obtained dom_obtained = CRED_UNINITIALISED;
52 1 : enum credentials_obtained usr_obtained = CRED_UNINITIALISED;
53 1 : enum credentials_obtained pwd_obtained = CRED_UNINITIALISED;
54 1 : bool ok;
55 :
56 1 : creds = cli_credentials_init(mem_ctx);
57 1 : assert_non_null(creds);
58 1 : assert_null(creds->username);
59 1 : assert_int_equal(creds->username_obtained, CRED_UNINITIALISED);
60 :
61 1 : domain = cli_credentials_get_domain(creds);
62 1 : assert_null(domain);
63 1 : ok = cli_credentials_set_domain(creds, "WURST", CRED_SPECIFIED);
64 1 : assert_true(ok);
65 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
66 1 : domain = cli_credentials_get_domain(creds);
67 1 : assert_string_equal(domain, "WURST");
68 :
69 1 : domain = cli_credentials_get_domain_and_obtained(creds,
70 : &dom_obtained);
71 1 : assert_int_equal(dom_obtained, CRED_SPECIFIED);
72 1 : assert_string_equal(domain, "WURST");
73 :
74 1 : username = cli_credentials_get_username(creds);
75 1 : assert_null(username);
76 1 : ok = cli_credentials_set_username(creds, "brot", CRED_SPECIFIED);
77 1 : assert_true(ok);
78 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
79 1 : username = cli_credentials_get_username(creds);
80 1 : assert_string_equal(username, "brot");
81 :
82 1 : username = cli_credentials_get_username_and_obtained(creds,
83 : &usr_obtained);
84 1 : assert_int_equal(usr_obtained, CRED_SPECIFIED);
85 1 : assert_string_equal(username, "brot");
86 :
87 1 : password = cli_credentials_get_password(creds);
88 1 : assert_null(password);
89 1 : ok = cli_credentials_set_password(creds, "SECRET", CRED_SPECIFIED);
90 1 : assert_true(ok);
91 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
92 1 : password = cli_credentials_get_password(creds);
93 1 : assert_string_equal(password, "SECRET");
94 :
95 1 : password = cli_credentials_get_password_and_obtained(creds,
96 : &pwd_obtained);
97 1 : assert_int_equal(pwd_obtained, CRED_SPECIFIED);
98 1 : assert_string_equal(password, "SECRET");
99 :
100 : /* Run dump to check it works */
101 1 : cli_credentials_dump(creds);
102 1 : }
103 :
104 1 : static void torture_creds_init_anonymous(void **state)
105 : {
106 1 : TALLOC_CTX *mem_ctx = *state;
107 1 : struct cli_credentials *creds = NULL;
108 :
109 1 : creds = cli_credentials_init_anon(mem_ctx);
110 1 : assert_non_null(creds);
111 :
112 1 : assert_string_equal(creds->domain, "");
113 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
114 :
115 1 : assert_string_equal(creds->username, "");
116 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
117 :
118 1 : assert_null(creds->password);
119 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
120 1 : }
121 :
122 1 : static void torture_creds_guess(void **state)
123 : {
124 1 : TALLOC_CTX *mem_ctx = *state;
125 1 : struct cli_credentials *creds = NULL;
126 1 : const char *env_user = getenv("USER");
127 1 : bool ok;
128 :
129 1 : creds = cli_credentials_init(mem_ctx);
130 1 : assert_non_null(creds);
131 :
132 1 : setenv("PASSWD", "SECRET", 1);
133 1 : ok = cli_credentials_guess(creds, NULL);
134 1 : assert_true(ok);
135 :
136 1 : assert_string_equal(creds->username, env_user);
137 1 : assert_int_equal(creds->username_obtained, CRED_GUESS_ENV);
138 :
139 1 : assert_string_equal(creds->password, "SECRET");
140 1 : assert_int_equal(creds->password_obtained, CRED_GUESS_ENV);
141 1 : unsetenv("PASSWD");
142 1 : }
143 :
144 1 : static void torture_creds_anon_guess(void **state)
145 : {
146 1 : TALLOC_CTX *mem_ctx = *state;
147 1 : struct cli_credentials *creds = NULL;
148 1 : bool ok;
149 :
150 1 : creds = cli_credentials_init_anon(mem_ctx);
151 1 : assert_non_null(creds);
152 :
153 1 : setenv("PASSWD", "SECRET", 1);
154 1 : ok = cli_credentials_guess(creds, NULL);
155 1 : assert_true(ok);
156 :
157 1 : assert_string_equal(creds->username, "");
158 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
159 :
160 1 : assert_null(creds->password);
161 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
162 1 : unsetenv("PASSWD");
163 1 : }
164 :
165 1 : static void torture_creds_parse_string(void **state)
166 : {
167 1 : TALLOC_CTX *mem_ctx = *state;
168 1 : struct cli_credentials *creds = NULL;
169 1 : enum credentials_obtained princ_obtained = CRED_UNINITIALISED;
170 1 : enum credentials_obtained usr_obtained = CRED_UNINITIALISED;
171 1 : enum credentials_obtained pwd_obtained = CRED_UNINITIALISED;
172 :
173 1 : creds = cli_credentials_init(mem_ctx);
174 1 : assert_non_null(creds);
175 :
176 : /* Anonymous */
177 1 : cli_credentials_parse_string(creds, "%", CRED_SPECIFIED);
178 :
179 1 : assert_string_equal(creds->domain, "");
180 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
181 :
182 1 : assert_string_equal(creds->username, "");
183 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
184 :
185 1 : assert_null(creds->password);
186 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
187 :
188 : /* Username + password */
189 1 : cli_credentials_parse_string(creds, "wurst%BROT", CRED_SPECIFIED);
190 :
191 1 : assert_string_equal(creds->domain, "");
192 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
193 :
194 1 : assert_string_equal(creds->username, "wurst");
195 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
196 :
197 1 : assert_string_equal(creds->password, "BROT");
198 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
199 :
200 : /* Domain + username + password */
201 1 : cli_credentials_parse_string(creds, "XXL\\wurst%BROT", CRED_SPECIFIED);
202 :
203 1 : assert_string_equal(creds->domain, "XXL");
204 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
205 :
206 1 : assert_string_equal(creds->username, "wurst");
207 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
208 :
209 1 : assert_string_equal(creds->password, "BROT");
210 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
211 :
212 : /* Principal */
213 1 : cli_credentials_parse_string(creds, "wurst@brot.realm", CRED_SPECIFIED);
214 :
215 1 : assert_string_equal(creds->domain, "");
216 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
217 :
218 1 : assert_string_equal(creds->username, "wurst@brot.realm");
219 1 : usr_obtained = cli_credentials_get_username_obtained(creds);
220 1 : assert_int_equal(usr_obtained, CRED_SPECIFIED);
221 :
222 1 : assert_string_equal(creds->principal, "wurst@brot.realm");
223 1 : princ_obtained = cli_credentials_get_principal_obtained(creds);
224 1 : assert_int_equal(princ_obtained, CRED_SPECIFIED);
225 :
226 1 : assert_string_equal(creds->password, "BROT");
227 1 : pwd_obtained = cli_credentials_get_password_obtained(creds);
228 1 : assert_int_equal(pwd_obtained, CRED_SPECIFIED);
229 :
230 1 : }
231 :
232 1 : static void torture_creds_krb5_state(void **state)
233 : {
234 1 : TALLOC_CTX *mem_ctx = *state;
235 1 : struct cli_credentials *creds = NULL;
236 1 : struct loadparm_context *lp_ctx = NULL;
237 1 : bool ok;
238 :
239 1 : lp_ctx = loadparm_init_global(true);
240 1 : assert_non_null(lp_ctx);
241 :
242 1 : creds = cli_credentials_init(mem_ctx);
243 1 : assert_non_null(creds);
244 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_UNINITIALISED);
245 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
246 :
247 1 : ok = cli_credentials_set_conf(creds, lp_ctx);
248 1 : assert_true(ok);
249 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_SMB_CONF);
250 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
251 :
252 1 : ok = cli_credentials_guess(creds, lp_ctx);
253 1 : assert_true(ok);
254 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_SMB_CONF);
255 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
256 1 : assert_int_equal(creds->ccache_obtained, CRED_GUESS_FILE);
257 1 : assert_non_null(creds->ccache);
258 :
259 1 : ok = cli_credentials_set_kerberos_state(creds,
260 : CRED_USE_KERBEROS_REQUIRED,
261 : CRED_SPECIFIED);
262 1 : assert_true(ok);
263 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_SPECIFIED);
264 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_REQUIRED);
265 :
266 1 : ok = cli_credentials_set_kerberos_state(creds,
267 : CRED_USE_KERBEROS_DISABLED,
268 : CRED_SMB_CONF);
269 1 : assert_false(ok);
270 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_SPECIFIED);
271 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_REQUIRED);
272 :
273 1 : }
274 :
275 1 : static void torture_creds_gensec_feature(void **state)
276 : {
277 1 : TALLOC_CTX *mem_ctx = *state;
278 1 : struct cli_credentials *creds = NULL;
279 1 : bool ok;
280 :
281 1 : creds = cli_credentials_init(mem_ctx);
282 1 : assert_non_null(creds);
283 1 : assert_int_equal(creds->gensec_features_obtained, CRED_UNINITIALISED);
284 1 : assert_int_equal(creds->gensec_features, 0);
285 :
286 1 : ok = cli_credentials_set_gensec_features(creds,
287 : GENSEC_FEATURE_SIGN,
288 : CRED_SPECIFIED);
289 1 : assert_true(ok);
290 1 : assert_int_equal(creds->gensec_features_obtained, CRED_SPECIFIED);
291 1 : assert_int_equal(creds->gensec_features, GENSEC_FEATURE_SIGN);
292 :
293 1 : ok = cli_credentials_set_gensec_features(creds,
294 : GENSEC_FEATURE_SEAL,
295 : CRED_SMB_CONF);
296 1 : assert_false(ok);
297 1 : assert_int_equal(creds->gensec_features_obtained, CRED_SPECIFIED);
298 1 : assert_int_equal(creds->gensec_features, GENSEC_FEATURE_SIGN);
299 1 : }
300 :
301 1 : static const char *torture_get_password(struct cli_credentials *creds)
302 : {
303 1 : return talloc_strdup(creds, "SECRET");
304 : }
305 :
306 1 : static void torture_creds_password_callback(void **state)
307 : {
308 1 : TALLOC_CTX *mem_ctx = *state;
309 1 : struct cli_credentials *creds = NULL;
310 1 : const char *password = NULL;
311 1 : enum credentials_obtained pwd_obtained = CRED_UNINITIALISED;
312 1 : bool ok;
313 :
314 1 : creds = cli_credentials_init(mem_ctx);
315 1 : assert_non_null(creds);
316 :
317 1 : ok = cli_credentials_set_domain(creds, "WURST", CRED_SPECIFIED);
318 1 : assert_true(ok);
319 1 : ok = cli_credentials_set_username(creds, "brot", CRED_SPECIFIED);
320 1 : assert_true(ok);
321 :
322 1 : ok = cli_credentials_set_password_callback(creds, torture_get_password);
323 1 : assert_true(ok);
324 1 : assert_int_equal(creds->password_obtained, CRED_CALLBACK);
325 :
326 1 : password = cli_credentials_get_password_and_obtained(creds,
327 : &pwd_obtained);
328 1 : assert_int_equal(pwd_obtained, CRED_CALLBACK_RESULT);
329 1 : assert_string_equal(password, "SECRET");
330 1 : }
331 :
332 1 : int main(int argc, char *argv[])
333 : {
334 1 : int rc;
335 1 : const struct CMUnitTest tests[] = {
336 : cmocka_unit_test(torture_creds_init),
337 : cmocka_unit_test(torture_creds_init_anonymous),
338 : cmocka_unit_test(torture_creds_guess),
339 : cmocka_unit_test(torture_creds_anon_guess),
340 : cmocka_unit_test(torture_creds_parse_string),
341 : cmocka_unit_test(torture_creds_krb5_state),
342 : cmocka_unit_test(torture_creds_gensec_feature),
343 : cmocka_unit_test(torture_creds_password_callback)
344 : };
345 :
346 1 : if (argc == 2) {
347 0 : cmocka_set_test_filter(argv[1]);
348 : }
349 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
350 :
351 1 : rc = cmocka_run_group_tests(tests,
352 : setup_talloc_context,
353 : teardown_talloc_context);
354 :
355 1 : return rc;
356 : }
|