diff options
Diffstat (limited to 'regress/unittests/authopt/tests.c')
-rw-r--r-- | regress/unittests/authopt/tests.c | 573 |
1 files changed, 573 insertions, 0 deletions
diff --git a/regress/unittests/authopt/tests.c b/regress/unittests/authopt/tests.c new file mode 100644 index 000000000..0e8aacb91 --- /dev/null +++ b/regress/unittests/authopt/tests.c | |||
@@ -0,0 +1,573 @@ | |||
1 | /* $OpenBSD: tests.c,v 1.1 2018/03/03 03:16:17 djm Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * Regress test for keys options functions. | ||
5 | * | ||
6 | * Placed in the public domain | ||
7 | */ | ||
8 | |||
9 | #include <sys/types.h> | ||
10 | #include <sys/param.h> | ||
11 | #include <stdio.h> | ||
12 | #include <stdint.h> | ||
13 | #include <stdlib.h> | ||
14 | #include <string.h> | ||
15 | |||
16 | #include "test_helper.h" | ||
17 | |||
18 | #include "sshkey.h" | ||
19 | #include "authfile.h" | ||
20 | #include "auth-options.h" | ||
21 | #include "misc.h" | ||
22 | #include "log.h" | ||
23 | |||
24 | static struct sshkey * | ||
25 | load_key(const char *name) | ||
26 | { | ||
27 | struct sshkey *ret; | ||
28 | int r; | ||
29 | |||
30 | r = sshkey_load_public(test_data_file(name), &ret, NULL); | ||
31 | ASSERT_INT_EQ(r, 0); | ||
32 | ASSERT_PTR_NE(ret, NULL); | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | static struct sshauthopt * | ||
37 | default_authkey_opts(void) | ||
38 | { | ||
39 | struct sshauthopt *ret = sshauthopt_new(); | ||
40 | |||
41 | ASSERT_PTR_NE(ret, NULL); | ||
42 | ret->permit_port_forwarding_flag = 1; | ||
43 | ret->permit_agent_forwarding_flag = 1; | ||
44 | ret->permit_x11_forwarding_flag = 1; | ||
45 | ret->permit_pty_flag = 1; | ||
46 | ret->permit_user_rc = 1; | ||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static struct sshauthopt * | ||
51 | default_authkey_restrict_opts(void) | ||
52 | { | ||
53 | struct sshauthopt *ret = sshauthopt_new(); | ||
54 | |||
55 | ASSERT_PTR_NE(ret, NULL); | ||
56 | ret->permit_port_forwarding_flag = 0; | ||
57 | ret->permit_agent_forwarding_flag = 0; | ||
58 | ret->permit_x11_forwarding_flag = 0; | ||
59 | ret->permit_pty_flag = 0; | ||
60 | ret->permit_user_rc = 0; | ||
61 | ret->restricted = 1; | ||
62 | return ret; | ||
63 | } | ||
64 | |||
65 | static char ** | ||
66 | commasplit(const char *s, size_t *np) | ||
67 | { | ||
68 | char *ocp, *cp, *cp2, **ret = NULL; | ||
69 | size_t n; | ||
70 | |||
71 | ocp = cp = strdup(s); | ||
72 | ASSERT_PTR_NE(cp, NULL); | ||
73 | for (n = 0; (cp2 = strsep(&cp, ",")) != NULL;) { | ||
74 | ret = recallocarray(ret, n, n + 1, sizeof(*ret)); | ||
75 | ASSERT_PTR_NE(ret, NULL); | ||
76 | cp2 = strdup(cp2); | ||
77 | ASSERT_PTR_NE(cp2, NULL); | ||
78 | ret[n++] = cp2; | ||
79 | } | ||
80 | free(ocp); | ||
81 | *np = n; | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | static void | ||
86 | compare_opts(const struct sshauthopt *opts, | ||
87 | const struct sshauthopt *expected) | ||
88 | { | ||
89 | size_t i; | ||
90 | |||
91 | ASSERT_PTR_NE(opts, NULL); | ||
92 | ASSERT_PTR_NE(expected, NULL); | ||
93 | ASSERT_PTR_NE(expected, opts); /* bozo :) */ | ||
94 | |||
95 | #define FLAG_EQ(x) ASSERT_INT_EQ(opts->x, expected->x) | ||
96 | FLAG_EQ(permit_port_forwarding_flag); | ||
97 | FLAG_EQ(permit_agent_forwarding_flag); | ||
98 | FLAG_EQ(permit_x11_forwarding_flag); | ||
99 | FLAG_EQ(permit_pty_flag); | ||
100 | FLAG_EQ(permit_user_rc); | ||
101 | FLAG_EQ(restricted); | ||
102 | FLAG_EQ(cert_authority); | ||
103 | #undef FLAG_EQ | ||
104 | |||
105 | #define STR_EQ(x) \ | ||
106 | do { \ | ||
107 | if (expected->x == NULL) \ | ||
108 | ASSERT_PTR_EQ(opts->x, expected->x); \ | ||
109 | else \ | ||
110 | ASSERT_STRING_EQ(opts->x, expected->x); \ | ||
111 | } while (0) | ||
112 | STR_EQ(cert_principals); | ||
113 | STR_EQ(force_command); | ||
114 | STR_EQ(required_from_host_cert); | ||
115 | STR_EQ(required_from_host_keys); | ||
116 | #undef STR_EQ | ||
117 | |||
118 | #define ARRAY_EQ(nx, x) \ | ||
119 | do { \ | ||
120 | ASSERT_SIZE_T_EQ(opts->nx, expected->nx); \ | ||
121 | if (expected->nx == 0) \ | ||
122 | break; \ | ||
123 | for (i = 0; i < expected->nx; i++) \ | ||
124 | ASSERT_STRING_EQ(opts->x[i], expected->x[i]); \ | ||
125 | } while (0) | ||
126 | ARRAY_EQ(nenv, env); | ||
127 | ARRAY_EQ(npermitopen, permitopen); | ||
128 | #undef ARRAY_EQ | ||
129 | } | ||
130 | |||
131 | static void | ||
132 | test_authkeys_parse(void) | ||
133 | { | ||
134 | struct sshauthopt *opts, *expected; | ||
135 | const char *errstr; | ||
136 | |||
137 | #define FAIL_TEST(label, keywords) \ | ||
138 | do { \ | ||
139 | TEST_START("sshauthopt_parse invalid " label); \ | ||
140 | opts = sshauthopt_parse(keywords, &errstr); \ | ||
141 | ASSERT_PTR_EQ(opts, NULL); \ | ||
142 | ASSERT_PTR_NE(errstr, NULL); \ | ||
143 | TEST_DONE(); \ | ||
144 | } while (0) | ||
145 | #define CHECK_SUCCESS_AND_CLEANUP() \ | ||
146 | do { \ | ||
147 | if (errstr != NULL) \ | ||
148 | ASSERT_STRING_EQ(errstr, ""); \ | ||
149 | compare_opts(opts, expected); \ | ||
150 | sshauthopt_free(expected); \ | ||
151 | sshauthopt_free(opts); \ | ||
152 | } while (0) | ||
153 | |||
154 | /* Basic tests */ | ||
155 | TEST_START("sshauthopt_parse empty"); | ||
156 | expected = default_authkey_opts(); | ||
157 | opts = sshauthopt_parse("", &errstr); | ||
158 | CHECK_SUCCESS_AND_CLEANUP(); | ||
159 | TEST_DONE(); | ||
160 | |||
161 | TEST_START("sshauthopt_parse trailing whitespace"); | ||
162 | expected = default_authkey_opts(); | ||
163 | opts = sshauthopt_parse(" ", &errstr); | ||
164 | CHECK_SUCCESS_AND_CLEANUP(); | ||
165 | TEST_DONE(); | ||
166 | |||
167 | TEST_START("sshauthopt_parse restrict"); | ||
168 | expected = default_authkey_restrict_opts(); | ||
169 | opts = sshauthopt_parse("restrict", &errstr); | ||
170 | CHECK_SUCCESS_AND_CLEANUP(); | ||
171 | TEST_DONE(); | ||
172 | |||
173 | /* Invalid syntax */ | ||
174 | FAIL_TEST("trailing comma", "restrict,"); | ||
175 | FAIL_TEST("bare comma", ","); | ||
176 | FAIL_TEST("unknown option", "BLAH"); | ||
177 | FAIL_TEST("unknown option with trailing comma", "BLAH,"); | ||
178 | FAIL_TEST("unknown option with trailing whitespace", "BLAH "); | ||
179 | |||
180 | /* force_tun_device */ | ||
181 | TEST_START("sshauthopt_parse tunnel explicit"); | ||
182 | expected = default_authkey_opts(); | ||
183 | expected->force_tun_device = 1; | ||
184 | opts = sshauthopt_parse("tunnel=\"1\"", &errstr); | ||
185 | CHECK_SUCCESS_AND_CLEANUP(); | ||
186 | TEST_DONE(); | ||
187 | |||
188 | TEST_START("sshauthopt_parse tunnel any"); | ||
189 | expected = default_authkey_opts(); | ||
190 | expected->force_tun_device = SSH_TUNID_ANY; | ||
191 | opts = sshauthopt_parse("tunnel=\"any\"", &errstr); | ||
192 | CHECK_SUCCESS_AND_CLEANUP(); | ||
193 | TEST_DONE(); | ||
194 | |||
195 | FAIL_TEST("tunnel", "tunnel=\"blah\""); | ||
196 | |||
197 | /* Flag options */ | ||
198 | #define FLAG_TEST(keyword, var, val) \ | ||
199 | do { \ | ||
200 | TEST_START("sshauthopt_parse " keyword); \ | ||
201 | expected = default_authkey_opts(); \ | ||
202 | expected->var = val; \ | ||
203 | opts = sshauthopt_parse(keyword, &errstr); \ | ||
204 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
205 | expected = default_authkey_restrict_opts(); \ | ||
206 | expected->var = val; \ | ||
207 | opts = sshauthopt_parse("restrict,"keyword, &errstr); \ | ||
208 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
209 | TEST_DONE(); \ | ||
210 | } while (0) | ||
211 | /* Positive flags */ | ||
212 | FLAG_TEST("cert-authority", cert_authority, 1); | ||
213 | FLAG_TEST("port-forwarding", permit_port_forwarding_flag, 1); | ||
214 | FLAG_TEST("agent-forwarding", permit_agent_forwarding_flag, 1); | ||
215 | FLAG_TEST("x11-forwarding", permit_x11_forwarding_flag, 1); | ||
216 | FLAG_TEST("pty", permit_pty_flag, 1); | ||
217 | FLAG_TEST("user-rc", permit_user_rc, 1); | ||
218 | /* Negative flags */ | ||
219 | FLAG_TEST("no-port-forwarding", permit_port_forwarding_flag, 0); | ||
220 | FLAG_TEST("no-agent-forwarding", permit_agent_forwarding_flag, 0); | ||
221 | FLAG_TEST("no-x11-forwarding", permit_x11_forwarding_flag, 0); | ||
222 | FLAG_TEST("no-pty", permit_pty_flag, 0); | ||
223 | FLAG_TEST("no-user-rc", permit_user_rc, 0); | ||
224 | #undef FLAG_TEST | ||
225 | FAIL_TEST("no-cert-authority", "no-cert-authority"); | ||
226 | |||
227 | /* String options */ | ||
228 | #define STRING_TEST(keyword, var, val) \ | ||
229 | do { \ | ||
230 | TEST_START("sshauthopt_parse " keyword); \ | ||
231 | expected = default_authkey_opts(); \ | ||
232 | expected->var = strdup(val); \ | ||
233 | ASSERT_PTR_NE(expected->var, NULL); \ | ||
234 | opts = sshauthopt_parse(keyword "=" #val, &errstr); \ | ||
235 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
236 | expected = default_authkey_restrict_opts(); \ | ||
237 | expected->var = strdup(val); \ | ||
238 | ASSERT_PTR_NE(expected->var, NULL); \ | ||
239 | opts = sshauthopt_parse( \ | ||
240 | "restrict," keyword "=" #val ",restrict", &errstr); \ | ||
241 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
242 | TEST_DONE(); \ | ||
243 | } while (0) | ||
244 | STRING_TEST("command", force_command, "/bin/true"); | ||
245 | STRING_TEST("principals", cert_principals, "gregor,josef,K"); | ||
246 | STRING_TEST("from", required_from_host_keys, "127.0.0.0/8"); | ||
247 | #undef STRING_TEST | ||
248 | FAIL_TEST("unquoted command", "command=oops"); | ||
249 | FAIL_TEST("unquoted principals", "principals=estragon"); | ||
250 | FAIL_TEST("unquoted from", "from=127.0.0.1"); | ||
251 | |||
252 | /* String array option tests */ | ||
253 | #define ARRAY_TEST(label, keywords, var, nvar, val) \ | ||
254 | do { \ | ||
255 | TEST_START("sshauthopt_parse " label); \ | ||
256 | expected = default_authkey_opts(); \ | ||
257 | expected->var = commasplit(val, &expected->nvar); \ | ||
258 | ASSERT_PTR_NE(expected->var, NULL); \ | ||
259 | opts = sshauthopt_parse(keywords, &errstr); \ | ||
260 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
261 | expected = default_authkey_restrict_opts(); \ | ||
262 | expected->var = commasplit(val, &expected->nvar); \ | ||
263 | ASSERT_PTR_NE(expected->var, NULL); \ | ||
264 | opts = sshauthopt_parse( \ | ||
265 | "restrict," keywords ",restrict", &errstr); \ | ||
266 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
267 | TEST_DONE(); \ | ||
268 | } while (0) | ||
269 | ARRAY_TEST("environment", "environment=\"foo=1\",environment=\"bar=2\"", | ||
270 | env, nenv, "foo=1,bar=2"); | ||
271 | ARRAY_TEST("permitopen", "permitopen=\"foo:123\",permitopen=\"bar:*\"", | ||
272 | permitopen, npermitopen, "foo:123,bar:*"); | ||
273 | #undef ARRAY_TEST | ||
274 | FAIL_TEST("environment", "environment=\",=bah\""); | ||
275 | FAIL_TEST("permitopen port", "foo:bar"); | ||
276 | FAIL_TEST("permitopen missing port", "foo:"); | ||
277 | FAIL_TEST("permitopen missing port specification", "foo"); | ||
278 | FAIL_TEST("permitopen invalid host", "[:"); | ||
279 | |||
280 | #undef CHECK_SUCCESS_AND_CLEANUP | ||
281 | #undef FAIL_TEST | ||
282 | } | ||
283 | |||
284 | static void | ||
285 | test_cert_parse(void) | ||
286 | { | ||
287 | struct sshkey *cert; | ||
288 | struct sshauthopt *opts, *expected; | ||
289 | |||
290 | #define CHECK_SUCCESS_AND_CLEANUP() \ | ||
291 | do { \ | ||
292 | compare_opts(opts, expected); \ | ||
293 | sshauthopt_free(expected); \ | ||
294 | sshauthopt_free(opts); \ | ||
295 | sshkey_free(cert); \ | ||
296 | } while (0) | ||
297 | #define FLAG_TEST(keybase, var) \ | ||
298 | do { \ | ||
299 | TEST_START("sshauthopt_from_cert no_" keybase); \ | ||
300 | cert = load_key("no_" keybase ".cert"); \ | ||
301 | expected = default_authkey_opts(); \ | ||
302 | expected->var = 0; \ | ||
303 | opts = sshauthopt_from_cert(cert); \ | ||
304 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
305 | TEST_DONE(); \ | ||
306 | TEST_START("sshauthopt_from_cert only_" keybase); \ | ||
307 | cert = load_key("only_" keybase ".cert"); \ | ||
308 | expected = sshauthopt_new(); \ | ||
309 | ASSERT_PTR_NE(expected, NULL); \ | ||
310 | expected->var = 1; \ | ||
311 | opts = sshauthopt_from_cert(cert); \ | ||
312 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
313 | TEST_DONE(); \ | ||
314 | } while (0) | ||
315 | FLAG_TEST("agentfwd", permit_agent_forwarding_flag); | ||
316 | FLAG_TEST("portfwd", permit_port_forwarding_flag); | ||
317 | FLAG_TEST("pty", permit_pty_flag); | ||
318 | FLAG_TEST("user_rc", permit_user_rc); | ||
319 | FLAG_TEST("x11fwd", permit_x11_forwarding_flag); | ||
320 | #undef FLAG_TEST | ||
321 | |||
322 | TEST_START("sshauthopt_from_cert all permitted"); | ||
323 | cert = load_key("all_permit.cert"); | ||
324 | expected = default_authkey_opts(); | ||
325 | opts = sshauthopt_from_cert(cert); | ||
326 | CHECK_SUCCESS_AND_CLEANUP(); | ||
327 | TEST_DONE(); | ||
328 | |||
329 | TEST_START("sshauthopt_from_cert nothing permitted"); | ||
330 | cert = load_key("no_permit.cert"); | ||
331 | expected = sshauthopt_new(); | ||
332 | ASSERT_PTR_NE(expected, NULL); | ||
333 | opts = sshauthopt_from_cert(cert); | ||
334 | CHECK_SUCCESS_AND_CLEANUP(); | ||
335 | TEST_DONE(); | ||
336 | |||
337 | TEST_START("sshauthopt_from_cert force-command"); | ||
338 | cert = load_key("force_command.cert"); | ||
339 | expected = default_authkey_opts(); | ||
340 | expected->force_command = strdup("foo"); | ||
341 | ASSERT_PTR_NE(expected->force_command, NULL); | ||
342 | opts = sshauthopt_from_cert(cert); | ||
343 | CHECK_SUCCESS_AND_CLEANUP(); | ||
344 | TEST_DONE(); | ||
345 | |||
346 | TEST_START("sshauthopt_from_cert source-address"); | ||
347 | cert = load_key("sourceaddr.cert"); | ||
348 | expected = default_authkey_opts(); | ||
349 | expected->required_from_host_cert = strdup("127.0.0.1/32,::1/128"); | ||
350 | ASSERT_PTR_NE(expected->required_from_host_cert, NULL); | ||
351 | opts = sshauthopt_from_cert(cert); | ||
352 | CHECK_SUCCESS_AND_CLEANUP(); | ||
353 | TEST_DONE(); | ||
354 | #undef CHECK_SUCCESS_AND_CLEANUP | ||
355 | |||
356 | #define FAIL_TEST(keybase) \ | ||
357 | do { \ | ||
358 | TEST_START("sshauthopt_from_cert " keybase); \ | ||
359 | cert = load_key(keybase ".cert"); \ | ||
360 | opts = sshauthopt_from_cert(cert); \ | ||
361 | ASSERT_PTR_EQ(opts, NULL); \ | ||
362 | sshkey_free(cert); \ | ||
363 | TEST_DONE(); \ | ||
364 | } while (0) | ||
365 | FAIL_TEST("host"); | ||
366 | FAIL_TEST("bad_sourceaddr"); | ||
367 | FAIL_TEST("unknown_critical"); | ||
368 | #undef FAIL_TEST | ||
369 | } | ||
370 | |||
371 | static void | ||
372 | test_merge(void) | ||
373 | { | ||
374 | struct sshkey *cert; | ||
375 | struct sshauthopt *key_opts, *cert_opts, *merge_opts, *expected; | ||
376 | const char *errstr; | ||
377 | |||
378 | /* | ||
379 | * Prepare for a test by making some key and cert options and | ||
380 | * attempting to merge them. | ||
381 | */ | ||
382 | #define PREPARE(label, keyname, keywords) \ | ||
383 | do { \ | ||
384 | expected = NULL; \ | ||
385 | TEST_START("sshauthopt_merge " label); \ | ||
386 | cert = load_key(keyname ".cert"); \ | ||
387 | cert_opts = sshauthopt_from_cert(cert); \ | ||
388 | ASSERT_PTR_NE(cert_opts, NULL); \ | ||
389 | key_opts = sshauthopt_parse(keywords, &errstr); \ | ||
390 | if (errstr != NULL) \ | ||
391 | ASSERT_STRING_EQ(errstr, ""); \ | ||
392 | ASSERT_PTR_NE(key_opts, NULL); \ | ||
393 | merge_opts = sshauthopt_merge(key_opts, \ | ||
394 | cert_opts, &errstr); \ | ||
395 | } while (0) | ||
396 | |||
397 | /* Cleanup stuff allocated by PREPARE() */ | ||
398 | #define CLEANUP() \ | ||
399 | do { \ | ||
400 | sshauthopt_free(expected); \ | ||
401 | sshauthopt_free(merge_opts); \ | ||
402 | sshauthopt_free(key_opts); \ | ||
403 | sshauthopt_free(cert_opts); \ | ||
404 | sshkey_free(cert); \ | ||
405 | } while (0) | ||
406 | |||
407 | /* Check the results of PREPARE() against expectation; calls CLEANUP */ | ||
408 | #define CHECK_SUCCESS_AND_CLEANUP() \ | ||
409 | do { \ | ||
410 | if (errstr != NULL) \ | ||
411 | ASSERT_STRING_EQ(errstr, ""); \ | ||
412 | compare_opts(merge_opts, expected); \ | ||
413 | CLEANUP(); \ | ||
414 | } while (0) | ||
415 | |||
416 | /* Check a single case of merging of flag options */ | ||
417 | #define FLAG_CASE(keybase, label, keyname, keywords, mostly_off, var, val) \ | ||
418 | do { \ | ||
419 | PREPARE(keybase " " label, keyname, keywords); \ | ||
420 | expected = mostly_off ? \ | ||
421 | sshauthopt_new() : default_authkey_opts(); \ | ||
422 | expected->var = val; \ | ||
423 | ASSERT_PTR_NE(expected, NULL); \ | ||
424 | CHECK_SUCCESS_AND_CLEANUP(); \ | ||
425 | TEST_DONE(); \ | ||
426 | } while (0) | ||
427 | |||
428 | /* | ||
429 | * Fairly exhaustive exercise of a flag option. Tests | ||
430 | * option both set and clear in certificate, set and clear in | ||
431 | * authorized_keys and set and cleared via restrict keyword. | ||
432 | */ | ||
433 | #define FLAG_TEST(keybase, keyword, var) \ | ||
434 | do { \ | ||
435 | FLAG_CASE(keybase, "keys:default,yes cert:default,no", \ | ||
436 | "no_" keybase, keyword, 0, var, 0); \ | ||
437 | FLAG_CASE(keybase,"keys:-*,yes cert:default,no", \ | ||
438 | "no_" keybase, "restrict," keyword, 1, var, 0); \ | ||
439 | FLAG_CASE(keybase, "keys:default,no cert:default,no", \ | ||
440 | "no_" keybase, "no-" keyword, 0, var, 0); \ | ||
441 | FLAG_CASE(keybase, "keys:-*,no cert:default,no", \ | ||
442 | "no_" keybase, "restrict,no-" keyword, 1, var, 0); \ | ||
443 | \ | ||
444 | FLAG_CASE(keybase, "keys:default,yes cert:-*,yes", \ | ||
445 | "only_" keybase, keyword, 1, var, 1); \ | ||
446 | FLAG_CASE(keybase,"keys:-*,yes cert:-*,yes", \ | ||
447 | "only_" keybase, "restrict," keyword, 1, var, 1); \ | ||
448 | FLAG_CASE(keybase, "keys:default,no cert:-*,yes", \ | ||
449 | "only_" keybase, "no-" keyword, 1, var, 0); \ | ||
450 | FLAG_CASE(keybase, "keys:-*,no cert:-*,yes", \ | ||
451 | "only_" keybase, "restrict,no-" keyword, 1, var, 0); \ | ||
452 | \ | ||
453 | FLAG_CASE(keybase, "keys:default,yes cert:-*", \ | ||
454 | "no_permit", keyword, 1, var, 0); \ | ||
455 | FLAG_CASE(keybase,"keys:-*,yes cert:-*", \ | ||
456 | "no_permit", "restrict," keyword, 1, var, 0); \ | ||
457 | FLAG_CASE(keybase, "keys:default,no cert:-*", \ | ||
458 | "no_permit", "no-" keyword, 1, var, 0); \ | ||
459 | FLAG_CASE(keybase, "keys:-*,no cert:-*", \ | ||
460 | "no_permit", "restrict,no-" keyword, 1, var, 0); \ | ||
461 | \ | ||
462 | FLAG_CASE(keybase, "keys:default,yes cert:*", \ | ||
463 | "all_permit", keyword, 0, var, 1); \ | ||
464 | FLAG_CASE(keybase,"keys:-*,yes cert:*", \ | ||
465 | "all_permit", "restrict," keyword, 1, var, 1); \ | ||
466 | FLAG_CASE(keybase, "keys:default,no cert:*", \ | ||
467 | "all_permit", "no-" keyword, 0, var, 0); \ | ||
468 | FLAG_CASE(keybase, "keys:-*,no cert:*", \ | ||
469 | "all_permit", "restrict,no-" keyword, 1, var, 0); \ | ||
470 | \ | ||
471 | } while (0) | ||
472 | FLAG_TEST("portfwd", "port-forwarding", permit_port_forwarding_flag); | ||
473 | FLAG_TEST("agentfwd", "agent-forwarding", permit_agent_forwarding_flag); | ||
474 | FLAG_TEST("pty", "pty", permit_pty_flag); | ||
475 | FLAG_TEST("user_rc", "user-rc", permit_user_rc); | ||
476 | FLAG_TEST("x11fwd", "x11-forwarding", permit_x11_forwarding_flag); | ||
477 | #undef FLAG_TEST | ||
478 | |||
479 | PREPARE("source-address both", "sourceaddr", "from=\"127.0.0.1\""); | ||
480 | expected = default_authkey_opts(); | ||
481 | expected->required_from_host_cert = strdup("127.0.0.1/32,::1/128"); | ||
482 | ASSERT_PTR_NE(expected->required_from_host_cert, NULL); | ||
483 | expected->required_from_host_keys = strdup("127.0.0.1"); | ||
484 | ASSERT_PTR_NE(expected->required_from_host_keys, NULL); | ||
485 | CHECK_SUCCESS_AND_CLEANUP(); | ||
486 | TEST_DONE(); | ||
487 | |||
488 | PREPARE("source-address none", "all_permit", ""); | ||
489 | expected = default_authkey_opts(); | ||
490 | CHECK_SUCCESS_AND_CLEANUP(); | ||
491 | TEST_DONE(); | ||
492 | |||
493 | PREPARE("source-address keys", "all_permit", "from=\"127.0.0.1\""); | ||
494 | expected = default_authkey_opts(); | ||
495 | expected->required_from_host_keys = strdup("127.0.0.1"); | ||
496 | ASSERT_PTR_NE(expected->required_from_host_keys, NULL); | ||
497 | CHECK_SUCCESS_AND_CLEANUP(); | ||
498 | TEST_DONE(); | ||
499 | |||
500 | PREPARE("source-address cert", "sourceaddr", ""); | ||
501 | expected = default_authkey_opts(); | ||
502 | expected->required_from_host_cert = strdup("127.0.0.1/32,::1/128"); | ||
503 | ASSERT_PTR_NE(expected->required_from_host_cert, NULL); | ||
504 | CHECK_SUCCESS_AND_CLEANUP(); | ||
505 | TEST_DONE(); | ||
506 | |||
507 | PREPARE("force-command both", "force_command", "command=\"foo\""); | ||
508 | expected = default_authkey_opts(); | ||
509 | expected->force_command = strdup("foo"); | ||
510 | ASSERT_PTR_NE(expected->force_command, NULL); | ||
511 | CHECK_SUCCESS_AND_CLEANUP(); | ||
512 | TEST_DONE(); | ||
513 | |||
514 | PREPARE("force-command none", "all_permit", ""); | ||
515 | expected = default_authkey_opts(); | ||
516 | CHECK_SUCCESS_AND_CLEANUP(); | ||
517 | TEST_DONE(); | ||
518 | |||
519 | PREPARE("force-command keys", "all_permit", "command=\"bar\""); | ||
520 | expected = default_authkey_opts(); | ||
521 | expected->force_command = strdup("bar"); | ||
522 | ASSERT_PTR_NE(expected->force_command, NULL); | ||
523 | CHECK_SUCCESS_AND_CLEANUP(); | ||
524 | TEST_DONE(); | ||
525 | |||
526 | PREPARE("force-command cert", "force_command", ""); | ||
527 | expected = default_authkey_opts(); | ||
528 | expected->force_command = strdup("foo"); | ||
529 | ASSERT_PTR_NE(expected->force_command, NULL); | ||
530 | CHECK_SUCCESS_AND_CLEANUP(); | ||
531 | TEST_DONE(); | ||
532 | |||
533 | PREPARE("force-command mismatch", "force_command", "command=\"bar\""); | ||
534 | ASSERT_PTR_EQ(merge_opts, NULL); | ||
535 | CLEANUP(); | ||
536 | TEST_DONE(); | ||
537 | |||
538 | PREPARE("tunnel", "all_permit", "tunnel=\"6\""); | ||
539 | expected = default_authkey_opts(); | ||
540 | expected->force_tun_device = 6; | ||
541 | CHECK_SUCCESS_AND_CLEANUP(); | ||
542 | TEST_DONE(); | ||
543 | |||
544 | PREPARE("permitopen", "all_permit", | ||
545 | "permitopen=\"127.0.0.1:*\",permitopen=\"127.0.0.1:123\""); | ||
546 | expected = default_authkey_opts(); | ||
547 | expected->permitopen = commasplit("127.0.0.1:*,127.0.0.1:123", | ||
548 | &expected->npermitopen); | ||
549 | CHECK_SUCCESS_AND_CLEANUP(); | ||
550 | TEST_DONE(); | ||
551 | |||
552 | PREPARE("environment", "all_permit", | ||
553 | "environment=\"foo=a\",environment=\"bar=b\""); | ||
554 | expected = default_authkey_opts(); | ||
555 | expected->env = commasplit("foo=a,bar=b", &expected->nenv); | ||
556 | CHECK_SUCCESS_AND_CLEANUP(); | ||
557 | TEST_DONE(); | ||
558 | } | ||
559 | |||
560 | void | ||
561 | tests(void) | ||
562 | { | ||
563 | extern char *__progname; | ||
564 | LogLevel ll = test_is_verbose() ? | ||
565 | SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_QUIET; | ||
566 | |||
567 | /* test_cert_parse() are a bit spammy to error() by default... */ | ||
568 | log_init(__progname, ll, SYSLOG_FACILITY_USER, 1); | ||
569 | |||
570 | test_authkeys_parse(); | ||
571 | test_cert_parse(); | ||
572 | test_merge(); | ||
573 | } | ||