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