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