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 :
170 1 : creds = cli_credentials_init(mem_ctx);
171 1 : assert_non_null(creds);
172 :
173 : /* Anonymous */
174 1 : cli_credentials_parse_string(creds, "%", CRED_SPECIFIED);
175 :
176 1 : assert_string_equal(creds->domain, "");
177 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
178 :
179 1 : assert_string_equal(creds->username, "");
180 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
181 :
182 1 : assert_null(creds->password);
183 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
184 :
185 : /* Username + password */
186 1 : cli_credentials_parse_string(creds, "wurst%BROT", CRED_SPECIFIED);
187 :
188 1 : assert_string_equal(creds->domain, "");
189 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
190 :
191 1 : assert_string_equal(creds->username, "wurst");
192 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
193 :
194 1 : assert_string_equal(creds->password, "BROT");
195 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
196 :
197 : /* Domain + username + password */
198 1 : cli_credentials_parse_string(creds, "XXL\\wurst%BROT", CRED_SPECIFIED);
199 :
200 1 : assert_string_equal(creds->domain, "XXL");
201 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
202 :
203 1 : assert_string_equal(creds->username, "wurst");
204 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
205 :
206 1 : assert_string_equal(creds->password, "BROT");
207 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
208 :
209 : /* Principal */
210 1 : cli_credentials_parse_string(creds, "wurst@brot.realm", CRED_SPECIFIED);
211 :
212 1 : assert_string_equal(creds->domain, "");
213 1 : assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
214 :
215 1 : assert_string_equal(creds->username, "wurst@brot.realm");
216 1 : assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
217 :
218 1 : assert_string_equal(creds->principal, "wurst@brot.realm");
219 1 : assert_int_equal(creds->principal_obtained, CRED_SPECIFIED);
220 :
221 1 : assert_string_equal(creds->password, "BROT");
222 1 : assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
223 1 : }
224 :
225 1 : static void torture_creds_krb5_state(void **state)
226 : {
227 1 : TALLOC_CTX *mem_ctx = *state;
228 1 : struct cli_credentials *creds = NULL;
229 1 : struct loadparm_context *lp_ctx = NULL;
230 1 : bool ok;
231 :
232 1 : lp_ctx = loadparm_init_global(true);
233 1 : assert_non_null(lp_ctx);
234 :
235 1 : creds = cli_credentials_init(mem_ctx);
236 1 : assert_non_null(creds);
237 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_UNINITIALISED);
238 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
239 :
240 1 : ok = cli_credentials_set_conf(creds, lp_ctx);
241 1 : assert_true(ok);
242 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_SMB_CONF);
243 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
244 :
245 1 : ok = cli_credentials_guess(creds, lp_ctx);
246 1 : assert_true(ok);
247 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_SMB_CONF);
248 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
249 1 : assert_int_equal(creds->ccache_obtained, CRED_GUESS_FILE);
250 1 : assert_non_null(creds->ccache);
251 :
252 1 : ok = cli_credentials_set_kerberos_state(creds,
253 : CRED_USE_KERBEROS_REQUIRED,
254 : CRED_SPECIFIED);
255 1 : assert_true(ok);
256 1 : assert_int_equal(creds->kerberos_state_obtained, CRED_SPECIFIED);
257 1 : assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_REQUIRED);
258 :
259 1 : ok = cli_credentials_set_kerberos_state(creds,
260 : CRED_USE_KERBEROS_DISABLED,
261 : CRED_SMB_CONF);
262 1 : assert_false(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 : }
267 :
268 1 : static void torture_creds_gensec_feature(void **state)
269 : {
270 1 : TALLOC_CTX *mem_ctx = *state;
271 1 : struct cli_credentials *creds = NULL;
272 1 : bool ok;
273 :
274 1 : creds = cli_credentials_init(mem_ctx);
275 1 : assert_non_null(creds);
276 1 : assert_int_equal(creds->gensec_features_obtained, CRED_UNINITIALISED);
277 1 : assert_int_equal(creds->gensec_features, 0);
278 :
279 1 : ok = cli_credentials_set_gensec_features(creds,
280 : GENSEC_FEATURE_SIGN,
281 : CRED_SPECIFIED);
282 1 : assert_true(ok);
283 1 : assert_int_equal(creds->gensec_features_obtained, CRED_SPECIFIED);
284 1 : assert_int_equal(creds->gensec_features, GENSEC_FEATURE_SIGN);
285 :
286 1 : ok = cli_credentials_set_gensec_features(creds,
287 : GENSEC_FEATURE_SEAL,
288 : CRED_SMB_CONF);
289 1 : assert_false(ok);
290 1 : assert_int_equal(creds->gensec_features_obtained, CRED_SPECIFIED);
291 1 : assert_int_equal(creds->gensec_features, GENSEC_FEATURE_SIGN);
292 1 : }
293 :
294 1 : static const char *torture_get_password(struct cli_credentials *creds)
295 : {
296 1 : return talloc_strdup(creds, "SECRET");
297 : }
298 :
299 1 : static void torture_creds_password_callback(void **state)
300 : {
301 1 : TALLOC_CTX *mem_ctx = *state;
302 1 : struct cli_credentials *creds = NULL;
303 1 : const char *password = NULL;
304 1 : enum credentials_obtained pwd_obtained = CRED_UNINITIALISED;
305 1 : bool ok;
306 :
307 1 : creds = cli_credentials_init(mem_ctx);
308 1 : assert_non_null(creds);
309 :
310 1 : ok = cli_credentials_set_domain(creds, "WURST", CRED_SPECIFIED);
311 1 : assert_true(ok);
312 1 : ok = cli_credentials_set_username(creds, "brot", CRED_SPECIFIED);
313 1 : assert_true(ok);
314 :
315 1 : ok = cli_credentials_set_password_callback(creds, torture_get_password);
316 1 : assert_true(ok);
317 1 : assert_int_equal(creds->password_obtained, CRED_CALLBACK);
318 :
319 1 : password = cli_credentials_get_password_and_obtained(creds,
320 : &pwd_obtained);
321 1 : assert_int_equal(pwd_obtained, CRED_CALLBACK_RESULT);
322 1 : assert_string_equal(password, "SECRET");
323 1 : }
324 :
325 1 : int main(int argc, char *argv[])
326 : {
327 1 : int rc;
328 1 : const struct CMUnitTest tests[] = {
329 : cmocka_unit_test(torture_creds_init),
330 : cmocka_unit_test(torture_creds_init_anonymous),
331 : cmocka_unit_test(torture_creds_guess),
332 : cmocka_unit_test(torture_creds_anon_guess),
333 : cmocka_unit_test(torture_creds_parse_string),
334 : cmocka_unit_test(torture_creds_krb5_state),
335 : cmocka_unit_test(torture_creds_gensec_feature),
336 : cmocka_unit_test(torture_creds_password_callback)
337 : };
338 :
339 1 : if (argc == 2) {
340 0 : cmocka_set_test_filter(argv[1]);
341 : }
342 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
343 :
344 1 : rc = cmocka_run_group_tests(tests,
345 : setup_talloc_context,
346 : teardown_talloc_context);
347 :
348 1 : return rc;
349 : }
|