Line data Source code
1 : /*
2 : Authors:
3 : Sumit Bose <sbose@redhat.com>
4 :
5 : Copyright (C) 2014 Red Hat
6 :
7 : SSSD tests: Tests keytab utilities
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include <stdio.h>
24 : #include <popt.h>
25 :
26 : #include "util/sss_krb5.h"
27 : #include "providers/krb5/krb5_common.h"
28 : #include "tests/cmocka/common_mock.h"
29 : #include "tests/cmocka/common_mock_krb5.h"
30 :
31 : #define TESTS_PATH "tp_" BASE_FILE_STEM
32 : #define KEYTAB_TEST_PRINC "test/keytab@TEST.KEYTAB"
33 : #define KEYTAB_PATH TESTS_PATH "/keytab_test.keytab"
34 : #define EMPTY_KEYTAB_PATH TESTS_PATH "/empty_keytab_test.keytab"
35 :
36 : struct keytab_test_ctx {
37 : krb5_context kctx;
38 : const char *keytab_file_name;
39 : krb5_principal principal;
40 : };
41 :
42 3 : static int setup_keytab(void **state)
43 3 : {
44 : struct keytab_test_ctx *test_ctx;
45 : krb5_error_code kerr;
46 3 : size_t nkeys = 4;
47 3 : krb5_keytab_entry keys[nkeys];
48 :
49 3 : test_dom_suite_setup(TESTS_PATH);
50 :
51 3 : assert_true(leak_check_setup());
52 :
53 3 : test_ctx = talloc_zero(global_talloc_context, struct keytab_test_ctx);
54 3 : assert_non_null(test_ctx);
55 :
56 3 : kerr = krb5_init_context(&test_ctx->kctx);
57 3 : assert_int_equal(kerr, 0);
58 :
59 3 : test_ctx->keytab_file_name = "FILE:" KEYTAB_PATH;
60 :
61 3 : kerr = krb5_parse_name(test_ctx->kctx, KEYTAB_TEST_PRINC,
62 : &test_ctx->principal);
63 3 : assert_int_equal(kerr, 0);
64 :
65 3 : memset(&keys, nkeys, nkeys * sizeof(krb5_keytab_entry));
66 :
67 3 : mock_krb5_keytab_entry(&keys[0], test_ctx->principal, 12345, 1, 1, "11");
68 3 : mock_krb5_keytab_entry(&keys[1], test_ctx->principal, 12345, 1, 2, "12");
69 3 : mock_krb5_keytab_entry(&keys[2], test_ctx->principal, 12345, 2, 1, "21");
70 3 : mock_krb5_keytab_entry(&keys[3], test_ctx->principal, 12345, 2, 2, "22");
71 :
72 3 : kerr = mock_keytab(test_ctx->kctx, test_ctx->keytab_file_name, keys, nkeys);
73 3 : assert_int_equal(kerr, 0);
74 :
75 3 : check_leaks_push(test_ctx);
76 3 : *state = test_ctx;
77 3 : return 0;
78 : }
79 :
80 3 : static int teardown_keytab(void **state)
81 : {
82 : int ret;
83 3 : struct keytab_test_ctx *test_ctx = talloc_get_type(*state,
84 : struct keytab_test_ctx);
85 3 : assert_non_null(test_ctx);
86 :
87 3 : krb5_free_principal(test_ctx->kctx, test_ctx->principal);
88 3 : krb5_free_context(test_ctx->kctx);
89 :
90 3 : ret = unlink(KEYTAB_PATH);
91 3 : assert_int_equal(ret, 0);
92 :
93 3 : assert_true(check_leaks_pop(test_ctx) == true);
94 3 : talloc_free(test_ctx);
95 3 : assert_true(leak_check_teardown());
96 :
97 3 : ret = rmdir(TESTS_PATH);
98 3 : assert_return_code(ret, errno);
99 :
100 3 : return 0;
101 : }
102 :
103 1 : void test_copy_keytab(void **state)
104 : {
105 : krb5_error_code kerr;
106 : char *mem_keytab_name;
107 : krb5_keytab mem_keytab;
108 : krb5_keytab keytab;
109 : krb5_keytab_entry kent;
110 1 : struct keytab_test_ctx *test_ctx = talloc_get_type(*state,
111 : struct keytab_test_ctx);
112 1 : assert_non_null(test_ctx);
113 :
114 1 : kerr = copy_keytab_into_memory(test_ctx, test_ctx->kctx,
115 : test_ctx->keytab_file_name,
116 : &mem_keytab_name, &mem_keytab);
117 1 : assert_int_equal(kerr, 0);
118 1 : assert_non_null(mem_keytab_name);
119 :
120 1 : kerr = krb5_kt_resolve(test_ctx->kctx, mem_keytab_name, &keytab);
121 1 : assert_int_equal(kerr, 0);
122 :
123 1 : kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 9, 9,
124 : &kent);
125 1 : assert_int_not_equal(kerr, 0);
126 :
127 1 : kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 1, 1,
128 : &kent);
129 1 : assert_int_equal(kerr, 0);
130 1 : krb5_free_keytab_entry_contents(test_ctx->kctx, &kent);
131 :
132 1 : kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 1, 2,
133 : &kent);
134 1 : assert_int_equal(kerr, 0);
135 1 : krb5_free_keytab_entry_contents(test_ctx->kctx, &kent);
136 :
137 1 : kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 2, 1,
138 : &kent);
139 1 : assert_int_equal(kerr, 0);
140 1 : krb5_free_keytab_entry_contents(test_ctx->kctx, &kent);
141 :
142 1 : kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 2, 2,
143 : &kent);
144 1 : assert_int_equal(kerr, 0);
145 1 : krb5_free_keytab_entry_contents(test_ctx->kctx, &kent);
146 :
147 1 : talloc_free(mem_keytab_name);
148 :
149 1 : kerr = krb5_kt_close(test_ctx->kctx, keytab);
150 1 : assert_int_equal(kerr, 0);
151 :
152 1 : kerr = krb5_kt_close(test_ctx->kctx, mem_keytab);
153 1 : assert_int_equal(kerr, 0);
154 1 : }
155 :
156 1 : void test_sss_krb5_kt_have_content(void **state)
157 : {
158 : krb5_error_code kerr;
159 : krb5_keytab keytab;
160 1 : struct keytab_test_ctx *test_ctx = talloc_get_type(*state,
161 : struct keytab_test_ctx);
162 1 : assert_non_null(test_ctx);
163 :
164 1 : kerr = krb5_kt_resolve(test_ctx->kctx, test_ctx->keytab_file_name, &keytab);
165 1 : assert_int_equal(kerr, 0);
166 :
167 1 : kerr = sss_krb5_kt_have_content(test_ctx->kctx, keytab);
168 1 : assert_int_equal(kerr, 0);
169 :
170 1 : kerr = krb5_kt_close(test_ctx->kctx, keytab);
171 1 : assert_int_equal(kerr, 0);
172 :
173 1 : kerr = krb5_kt_resolve(test_ctx->kctx, "FILE:" EMPTY_KEYTAB_PATH, &keytab);
174 1 : assert_int_equal(kerr, 0);
175 :
176 1 : kerr = sss_krb5_kt_have_content(test_ctx->kctx, keytab);
177 1 : assert_int_equal(kerr, KRB5_KT_NOTFOUND);
178 :
179 1 : kerr = krb5_kt_close(test_ctx->kctx, keytab);
180 1 : assert_int_equal(kerr, 0);
181 :
182 : /* no need to remove EMPTY_KEYTAB_PATH because krb5_kt_close() does not
183 : * create empty keytab files */
184 1 : }
185 :
186 4 : static bool keytab_entries_equal(krb5_keytab_entry kent1,
187 : krb5_keytab_entry kent2)
188 : {
189 4 : if (kent1.vno != kent2.vno
190 4 : || kent1.key.enctype != kent2.key.enctype
191 4 : || kent1.key.length != kent2.key.length
192 4 : || memcmp(kent1.key.contents, kent2.key.contents,
193 4 : kent1.key.length) != 0 ) {
194 0 : return false;
195 : }
196 :
197 4 : return true;
198 : }
199 :
200 1 : void test_copy_keytab_order(void **state)
201 : {
202 : krb5_error_code kerr;
203 : krb5_error_code kerr_mem;
204 : char *mem_keytab_name;
205 : krb5_keytab mem_keytab;
206 : krb5_kt_cursor mem_cursor;
207 : krb5_keytab_entry mem_kent;
208 : krb5_keytab keytab;
209 : krb5_kt_cursor cursor;
210 : krb5_keytab_entry kent;
211 1 : struct keytab_test_ctx *test_ctx = talloc_get_type(*state,
212 : struct keytab_test_ctx);
213 1 : assert_non_null(test_ctx);
214 :
215 1 : kerr = copy_keytab_into_memory(test_ctx, test_ctx->kctx,
216 : test_ctx->keytab_file_name,
217 : &mem_keytab_name, &mem_keytab);
218 1 : assert_int_equal(kerr, 0);
219 1 : assert_non_null(mem_keytab_name);
220 :
221 1 : kerr = krb5_kt_resolve(test_ctx->kctx, mem_keytab_name, &mem_keytab);
222 1 : assert_int_equal(kerr, 0);
223 :
224 1 : kerr = krb5_kt_resolve(test_ctx->kctx, test_ctx->keytab_file_name, &keytab);
225 1 : assert_int_equal(kerr, 0);
226 :
227 1 : kerr = krb5_kt_start_seq_get(test_ctx->kctx, mem_keytab, &mem_cursor);
228 1 : assert_int_equal(kerr, 0);
229 :
230 1 : kerr = krb5_kt_start_seq_get(test_ctx->kctx, keytab, &cursor);
231 1 : assert_int_equal(kerr, 0);
232 :
233 6 : while ((kerr = krb5_kt_next_entry(test_ctx->kctx, keytab, &kent,
234 : &cursor)) == 0) {
235 4 : kerr_mem = krb5_kt_next_entry(test_ctx->kctx, mem_keytab, &mem_kent,
236 : &mem_cursor);
237 4 : assert_int_equal(kerr_mem, 0);
238 :
239 4 : assert_true(keytab_entries_equal(kent, mem_kent));
240 :
241 4 : krb5_free_keytab_entry_contents(test_ctx->kctx, &kent);
242 4 : krb5_free_keytab_entry_contents(test_ctx->kctx, &mem_kent);
243 : }
244 :
245 1 : assert_int_equal(kerr, KRB5_KT_END);
246 :
247 1 : kerr_mem = krb5_kt_next_entry(test_ctx->kctx, mem_keytab, &mem_kent,
248 : &mem_cursor);
249 1 : assert_int_equal(kerr_mem, KRB5_KT_END);
250 :
251 1 : kerr = krb5_kt_end_seq_get(test_ctx->kctx, mem_keytab, &mem_cursor);
252 1 : assert_int_equal(kerr, 0);
253 :
254 1 : kerr = krb5_kt_end_seq_get(test_ctx->kctx, keytab, &cursor);
255 1 : assert_int_equal(kerr, 0);
256 :
257 1 : talloc_free(mem_keytab_name);
258 :
259 1 : kerr = krb5_kt_close(test_ctx->kctx, keytab);
260 1 : assert_int_equal(kerr, 0);
261 :
262 1 : kerr = krb5_kt_close(test_ctx->kctx, mem_keytab);
263 1 : assert_int_equal(kerr, 0);
264 1 : }
265 :
266 1 : int main(int argc, const char *argv[])
267 : {
268 : poptContext pc;
269 : int opt;
270 : int rv;
271 6 : struct poptOption long_options[] = {
272 : POPT_AUTOHELP
273 5 : SSSD_DEBUG_OPTS
274 : POPT_TABLEEND
275 : };
276 :
277 1 : const struct CMUnitTest tests[] = {
278 : cmocka_unit_test_setup_teardown(test_copy_keytab,
279 : setup_keytab, teardown_keytab),
280 : cmocka_unit_test_setup_teardown(test_sss_krb5_kt_have_content,
281 : setup_keytab, teardown_keytab),
282 : cmocka_unit_test_setup_teardown(test_copy_keytab_order,
283 : setup_keytab, teardown_keytab),
284 : };
285 :
286 : /* Set debug level to invalid value so we can deside if -d 0 was used. */
287 1 : debug_level = SSSDBG_INVALID;
288 :
289 1 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
290 1 : while((opt = poptGetNextOpt(pc)) != -1) {
291 : switch(opt) {
292 : default:
293 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
294 : poptBadOption(pc, 0), poptStrerror(opt));
295 0 : poptPrintUsage(pc, stderr, 0);
296 0 : return 1;
297 : }
298 : }
299 1 : poptFreeContext(pc);
300 :
301 1 : DEBUG_CLI_INIT(debug_level);
302 :
303 : /* Even though normally the tests should clean up after themselves
304 : * they might not after a failed run. Remove the old db to be sure */
305 1 : tests_set_cwd();
306 :
307 1 : rv = cmocka_run_group_tests(tests, NULL, NULL);
308 :
309 1 : return rv;
310 : }
|