xref: /freebsd/crypto/openssh/regress/unittests/authopt/tests.c (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
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 }
574