414dd46a6b07146d807d91e27376ae1ffa6123c3
[metze/samba/wip.git] / auth / credentials / tests / test_creds.c
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 static int setup_talloc_context(void **state)
30 {
31         TALLOC_CTX *frame = talloc_stackframe();
32
33         *state = frame;
34         return 0;
35 }
36
37 static int teardown_talloc_context(void **state)
38 {
39         TALLOC_CTX *frame = *state;
40         TALLOC_FREE(frame);
41         return 0;
42 }
43
44 static void torture_creds_init(void **state)
45 {
46         TALLOC_CTX *mem_ctx = *state;
47         struct cli_credentials *creds = NULL;
48         const char *username = NULL;
49         const char *domain = NULL;
50         const char *password = NULL;
51         enum credentials_obtained usr_obtained = CRED_UNINITIALISED;
52         enum credentials_obtained pwd_obtained = CRED_UNINITIALISED;
53         bool ok;
54
55         creds = cli_credentials_init(mem_ctx);
56         assert_non_null(creds);
57         assert_null(creds->username);
58         assert_int_equal(creds->username_obtained, CRED_UNINITIALISED);
59
60         domain = cli_credentials_get_domain(creds);
61         assert_null(domain);
62         ok = cli_credentials_set_domain(creds, "WURST", CRED_SPECIFIED);
63         assert_true(ok);
64         assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
65         domain = cli_credentials_get_domain(creds);
66         assert_string_equal(domain, "WURST");
67
68         username = cli_credentials_get_username(creds);
69         assert_null(username);
70         ok = cli_credentials_set_username(creds, "brot", CRED_SPECIFIED);
71         assert_true(ok);
72         assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
73         username = cli_credentials_get_username(creds);
74         assert_string_equal(username, "brot");
75
76         username = cli_credentials_get_username_and_obtained(creds,
77                                                              &usr_obtained);
78         assert_int_equal(usr_obtained, CRED_SPECIFIED);
79         assert_string_equal(username, "brot");
80
81         password = cli_credentials_get_password(creds);
82         assert_null(password);
83         ok = cli_credentials_set_password(creds, "SECRET", CRED_SPECIFIED);
84         assert_true(ok);
85         assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
86         password = cli_credentials_get_password(creds);
87         assert_string_equal(password, "SECRET");
88
89         password = cli_credentials_get_password_and_obtained(creds,
90                                                              &pwd_obtained);
91         assert_int_equal(pwd_obtained, CRED_SPECIFIED);
92         assert_string_equal(password, "SECRET");
93
94         /* Run dump to check it works */
95         cli_credentials_dump(creds);
96 }
97
98 static void torture_creds_init_anonymous(void **state)
99 {
100         TALLOC_CTX *mem_ctx = *state;
101         struct cli_credentials *creds = NULL;
102
103         creds = cli_credentials_init_anon(mem_ctx);
104         assert_non_null(creds);
105
106         assert_string_equal(creds->domain, "");
107         assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
108
109         assert_string_equal(creds->username, "");
110         assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
111
112         assert_null(creds->password);
113         assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
114 }
115
116 static void torture_creds_guess(void **state)
117 {
118         TALLOC_CTX *mem_ctx = *state;
119         struct cli_credentials *creds = NULL;
120         const char *env_user = getenv("USER");
121         bool ok;
122
123         creds = cli_credentials_init(mem_ctx);
124         assert_non_null(creds);
125
126         setenv("PASSWD", "SECRET", 1);
127         ok = cli_credentials_guess(creds, NULL);
128         assert_true(ok);
129
130         assert_string_equal(creds->username, env_user);
131         assert_int_equal(creds->username_obtained, CRED_GUESS_ENV);
132
133         assert_string_equal(creds->password, "SECRET");
134         assert_int_equal(creds->password_obtained, CRED_GUESS_ENV);
135         unsetenv("PASSWD");
136 }
137
138 static void torture_creds_anon_guess(void **state)
139 {
140         TALLOC_CTX *mem_ctx = *state;
141         struct cli_credentials *creds = NULL;
142         bool ok;
143
144         creds = cli_credentials_init_anon(mem_ctx);
145         assert_non_null(creds);
146
147         setenv("PASSWD", "SECRET", 1);
148         ok = cli_credentials_guess(creds, NULL);
149         assert_true(ok);
150
151         assert_string_equal(creds->username, "");
152         assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
153
154         assert_null(creds->password);
155         assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
156         unsetenv("PASSWD");
157 }
158
159 static void torture_creds_parse_string(void **state)
160 {
161         TALLOC_CTX *mem_ctx = *state;
162         struct cli_credentials *creds = NULL;
163
164         creds = cli_credentials_init(mem_ctx);
165         assert_non_null(creds);
166
167         /* Anonymous */
168         cli_credentials_parse_string(creds, "%", CRED_SPECIFIED);
169
170         assert_string_equal(creds->domain, "");
171         assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
172
173         assert_string_equal(creds->username, "");
174         assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
175
176         assert_null(creds->password);
177         assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
178
179         /* Username + password */
180         cli_credentials_parse_string(creds, "wurst%BROT", CRED_SPECIFIED);
181
182         assert_string_equal(creds->domain, "");
183         assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
184
185         assert_string_equal(creds->username, "wurst");
186         assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
187
188         assert_string_equal(creds->password, "BROT");
189         assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
190
191         /* Domain + username + password */
192         cli_credentials_parse_string(creds, "XXL\\wurst%BROT", CRED_SPECIFIED);
193
194         assert_string_equal(creds->domain, "XXL");
195         assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
196
197         assert_string_equal(creds->username, "wurst");
198         assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
199
200         assert_string_equal(creds->password, "BROT");
201         assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
202
203         /* Principal */
204         cli_credentials_parse_string(creds, "wurst@brot.realm", CRED_SPECIFIED);
205
206         assert_string_equal(creds->domain, "");
207         assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
208
209         assert_string_equal(creds->username, "wurst@brot.realm");
210         assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
211
212         assert_string_equal(creds->principal, "wurst@brot.realm");
213         assert_int_equal(creds->principal_obtained, CRED_SPECIFIED);
214
215         assert_string_equal(creds->password, "BROT");
216         assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
217 }
218
219 static void torture_creds_krb5_state(void **state)
220 {
221         TALLOC_CTX *mem_ctx = *state;
222         struct cli_credentials *creds = NULL;
223         struct loadparm_context *lp_ctx = NULL;
224         bool ok;
225
226         lp_ctx = loadparm_init_global(true);
227         assert_non_null(lp_ctx);
228
229         creds = cli_credentials_init(mem_ctx);
230         assert_non_null(creds);
231         assert_int_equal(creds->kerberos_state_obtained, CRED_UNINITIALISED);
232         assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
233
234         ok = cli_credentials_set_conf(creds, lp_ctx);
235         assert_true(ok);
236         assert_int_equal(creds->kerberos_state_obtained, CRED_SMB_CONF);
237         assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
238
239         ok = cli_credentials_guess(creds, lp_ctx);
240         assert_true(ok);
241         assert_int_equal(creds->kerberos_state_obtained, CRED_SMB_CONF);
242         assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_DESIRED);
243         assert_int_equal(creds->ccache_obtained, CRED_GUESS_FILE);
244         assert_non_null(creds->ccache);
245
246         ok = cli_credentials_set_kerberos_state(creds,
247                                                 CRED_USE_KERBEROS_REQUIRED,
248                                                 CRED_SPECIFIED);
249         assert_true(ok);
250         assert_int_equal(creds->kerberos_state_obtained, CRED_SPECIFIED);
251         assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_REQUIRED);
252
253         ok = cli_credentials_set_kerberos_state(creds,
254                                                 CRED_USE_KERBEROS_DISABLED,
255                                                 CRED_SMB_CONF);
256         assert_false(ok);
257         assert_int_equal(creds->kerberos_state_obtained, CRED_SPECIFIED);
258         assert_int_equal(creds->kerberos_state, CRED_USE_KERBEROS_REQUIRED);
259
260 }
261
262 static void torture_creds_gensec_feature(void **state)
263 {
264         TALLOC_CTX *mem_ctx = *state;
265         struct cli_credentials *creds = NULL;
266         bool ok;
267
268         creds = cli_credentials_init(mem_ctx);
269         assert_non_null(creds);
270         assert_int_equal(creds->gensec_features_obtained, CRED_UNINITIALISED);
271         assert_int_equal(creds->gensec_features, 0);
272
273         ok = cli_credentials_set_gensec_features(creds,
274                                                  GENSEC_FEATURE_SIGN,
275                                                  CRED_SPECIFIED);
276         assert_true(ok);
277         assert_int_equal(creds->gensec_features_obtained, CRED_SPECIFIED);
278         assert_int_equal(creds->gensec_features, GENSEC_FEATURE_SIGN);
279
280         ok = cli_credentials_set_gensec_features(creds,
281                                                  GENSEC_FEATURE_SEAL,
282                                                  CRED_SMB_CONF);
283         assert_false(ok);
284         assert_int_equal(creds->gensec_features_obtained, CRED_SPECIFIED);
285         assert_int_equal(creds->gensec_features, GENSEC_FEATURE_SIGN);
286 }
287
288 static const char *torture_get_password(struct cli_credentials *creds)
289 {
290         return talloc_strdup(creds, "SECRET");
291 }
292
293 static void torture_creds_password_callback(void **state)
294 {
295         TALLOC_CTX *mem_ctx = *state;
296         struct cli_credentials *creds = NULL;
297         const char *password = NULL;
298         enum credentials_obtained pwd_obtained = CRED_UNINITIALISED;
299         bool ok;
300
301         creds = cli_credentials_init(mem_ctx);
302         assert_non_null(creds);
303
304         ok = cli_credentials_set_domain(creds, "WURST", CRED_SPECIFIED);
305         assert_true(ok);
306         ok = cli_credentials_set_username(creds, "brot", CRED_SPECIFIED);
307         assert_true(ok);
308
309         ok = cli_credentials_set_password_callback(creds, torture_get_password);
310         assert_true(ok);
311         assert_int_equal(creds->password_obtained, CRED_CALLBACK);
312
313         password = cli_credentials_get_password_and_obtained(creds,
314                                                              &pwd_obtained);
315         assert_int_equal(pwd_obtained, CRED_CALLBACK_RESULT);
316         assert_string_equal(password, "SECRET");
317 }
318
319 int main(int argc, char *argv[])
320 {
321         int rc;
322         const struct CMUnitTest tests[] = {
323                 cmocka_unit_test(torture_creds_init),
324                 cmocka_unit_test(torture_creds_init_anonymous),
325                 cmocka_unit_test(torture_creds_guess),
326                 cmocka_unit_test(torture_creds_anon_guess),
327                 cmocka_unit_test(torture_creds_parse_string),
328                 cmocka_unit_test(torture_creds_krb5_state),
329                 cmocka_unit_test(torture_creds_gensec_feature),
330                 cmocka_unit_test(torture_creds_password_callback)
331         };
332
333         if (argc == 2) {
334                 cmocka_set_test_filter(argv[1]);
335         }
336         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
337
338         rc = cmocka_run_group_tests(tests,
339                                     setup_talloc_context,
340                                     teardown_talloc_context);
341
342         return rc;
343 }