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