xref: /freebsd/lib/libcasper/services/cap_dns/tests/dns_test.c (revision 1e570722dced7a3afc0a35b10af047b835e51567)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2013 The FreeBSD Foundation
5  *
6  * This software was developed by Pawel Jakub Dawidek under sponsorship from
7  * the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/capsicum.h>
32 #include <sys/nv.h>
33 
34 #include <arpa/inet.h>
35 #include <netinet/in.h>
36 
37 #include <assert.h>
38 #include <err.h>
39 #include <errno.h>
40 #include <netdb.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45 
46 #include <libcasper.h>
47 #include <casper/cap_dns.h>
48 
49 #include <atf-c.h>
50 
51 #define	GETHOSTBYNAME			0x01
52 #define	GETHOSTBYNAME2_AF_INET		0x02
53 #define	GETHOSTBYNAME2_AF_INET6		0x04
54 #define	GETHOSTBYADDR_AF_INET		0x08
55 #define	GETHOSTBYADDR_AF_INET6		0x10
56 #define	GETADDRINFO_AF_UNSPEC		0x20
57 #define	GETADDRINFO_AF_INET		0x40
58 #define	GETADDRINFO_AF_INET6		0x80
59 
60 static bool
addrinfo_compare(struct addrinfo * ai0,struct addrinfo * ai1)61 addrinfo_compare(struct addrinfo *ai0, struct addrinfo *ai1)
62 {
63 	struct addrinfo *at0, *at1;
64 
65 	if (ai0 == NULL && ai1 == NULL)
66 		return (true);
67 	if (ai0 == NULL || ai1 == NULL)
68 		return (false);
69 
70 	at0 = ai0;
71 	at1 = ai1;
72 	while (true) {
73 		if ((at0->ai_flags == at1->ai_flags) &&
74 		    (at0->ai_family == at1->ai_family) &&
75 		    (at0->ai_socktype == at1->ai_socktype) &&
76 		    (at0->ai_protocol == at1->ai_protocol) &&
77 		    (at0->ai_addrlen == at1->ai_addrlen) &&
78 		    (memcmp(at0->ai_addr, at1->ai_addr,
79 			at0->ai_addrlen) == 0)) {
80 			if (at0->ai_canonname != NULL &&
81 			    at1->ai_canonname != NULL) {
82 				if (strcmp(at0->ai_canonname,
83 				    at1->ai_canonname) != 0) {
84 					return (false);
85 				}
86 			}
87 
88 			if (at0->ai_canonname == NULL &&
89 			    at1->ai_canonname != NULL) {
90 				return (false);
91 			}
92 			if (at0->ai_canonname != NULL &&
93 			    at1->ai_canonname == NULL) {
94 				return (false);
95 			}
96 
97 			if (at0->ai_next == NULL && at1->ai_next == NULL)
98 				return (true);
99 			if (at0->ai_next == NULL || at1->ai_next == NULL)
100 				return (false);
101 
102 			at0 = at0->ai_next;
103 			at1 = at1->ai_next;
104 		} else {
105 			return (false);
106 		}
107 	}
108 
109 	/* NOTREACHED */
110 	fprintf(stderr, "Dead code reached in addrinfo_compare()\n");
111 	exit(1);
112 }
113 
114 static bool
hostent_aliases_compare(char ** aliases0,char ** aliases1)115 hostent_aliases_compare(char **aliases0, char **aliases1)
116 {
117 	int i0, i1;
118 
119 	if (aliases0 == NULL && aliases1 == NULL)
120 		return (true);
121 	if (aliases0 == NULL || aliases1 == NULL)
122 		return (false);
123 
124 	for (i0 = 0; aliases0[i0] != NULL; i0++) {
125 		for (i1 = 0; aliases1[i1] != NULL; i1++) {
126 			if (strcmp(aliases0[i0], aliases1[i1]) == 0)
127 				break;
128 		}
129 		if (aliases1[i1] == NULL)
130 			return (false);
131 	}
132 
133 	return (true);
134 }
135 
136 static bool
hostent_addr_list_compare(char ** addr_list0,char ** addr_list1,int length)137 hostent_addr_list_compare(char **addr_list0, char **addr_list1, int length)
138 {
139 	int i0, i1;
140 
141 	if (addr_list0 == NULL && addr_list1 == NULL)
142 		return (true);
143 	if (addr_list0 == NULL || addr_list1 == NULL)
144 		return (false);
145 
146 	for (i0 = 0; addr_list0[i0] != NULL; i0++) {
147 		for (i1 = 0; addr_list1[i1] != NULL; i1++) {
148 			if (memcmp(addr_list0[i0], addr_list1[i1], length) == 0)
149 				break;
150 		}
151 		if (addr_list1[i1] == NULL)
152 			return (false);
153 	}
154 
155 	return (true);
156 }
157 
158 static bool
hostent_compare(const struct hostent * hp0,const struct hostent * hp1)159 hostent_compare(const struct hostent *hp0, const struct hostent *hp1)
160 {
161 
162 	if (hp0 == NULL && hp1 != NULL)
163 		return (true);
164 
165 	if (hp0 == NULL || hp1 == NULL)
166 		return (false);
167 
168 	if (hp0->h_name != NULL || hp1->h_name != NULL) {
169 		if (hp0->h_name == NULL || hp1->h_name == NULL)
170 			return (false);
171 		if (strcmp(hp0->h_name, hp1->h_name) != 0)
172 			return (false);
173 	}
174 
175 	if (!hostent_aliases_compare(hp0->h_aliases, hp1->h_aliases))
176 		return (false);
177 	if (!hostent_aliases_compare(hp1->h_aliases, hp0->h_aliases))
178 		return (false);
179 
180 	if (hp0->h_addrtype != hp1->h_addrtype)
181 		return (false);
182 
183 	if (hp0->h_length != hp1->h_length)
184 		return (false);
185 
186 	if (!hostent_addr_list_compare(hp0->h_addr_list, hp1->h_addr_list,
187 	    hp0->h_length)) {
188 		return (false);
189 	}
190 	if (!hostent_addr_list_compare(hp1->h_addr_list, hp0->h_addr_list,
191 	    hp0->h_length)) {
192 		return (false);
193 	}
194 
195 	return (true);
196 }
197 
198 static void
runtest(cap_channel_t * capdns,unsigned int expected)199 runtest(cap_channel_t *capdns, unsigned int expected)
200 {
201 	unsigned int result;
202 	struct addrinfo *ais, *aic, hints, *hintsp;
203 	struct hostent *hps, *hpc;
204 	struct in_addr ip4;
205 	struct in6_addr ip6;
206 	int caperr, syserr;
207 
208 	result = 0;
209 
210 	hps = gethostbyname("example.com");
211 	if (hps == NULL) {
212 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
213 	} else {
214 		hpc = cap_gethostbyname(capdns, "example.com");
215 		if (hostent_compare(hps, hpc))
216 			result |= GETHOSTBYNAME;
217 	}
218 
219 	hps = gethostbyname2("example.com", AF_INET);
220 	if (hps == NULL) {
221 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
222 	} else {
223 		hpc = cap_gethostbyname2(capdns, "example.com", AF_INET);
224 		if (hostent_compare(hps, hpc))
225 			result |= GETHOSTBYNAME2_AF_INET;
226 	}
227 
228 	hps = gethostbyname2("example.com", AF_INET6);
229 	if (hps == NULL) {
230 		fprintf(stderr, "Unable to resolve %s IPv6.\n", "example.com");
231 	} else {
232 		hpc = cap_gethostbyname2(capdns, "example.com", AF_INET6);
233 		if (hostent_compare(hps, hpc))
234 			result |= GETHOSTBYNAME2_AF_INET6;
235 	}
236 
237 	hints.ai_flags = 0;
238 	hints.ai_family = AF_UNSPEC;
239 	hints.ai_socktype = 0;
240 	hints.ai_protocol = 0;
241 	hints.ai_addrlen = 0;
242 	hints.ai_addr = NULL;
243 	hints.ai_canonname = NULL;
244 	hints.ai_next = NULL;
245 
246 	hintsp = &hints;
247 
248 	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
249 	if (syserr != 0) {
250 		fprintf(stderr,
251 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
252 		    gai_strerror(syserr));
253 	} else {
254 		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
255 		    &aic);
256 		if (caperr == 0) {
257 			if (addrinfo_compare(ais, aic))
258 				result |= GETADDRINFO_AF_UNSPEC;
259 			freeaddrinfo(ais);
260 			freeaddrinfo(aic);
261 		}
262 	}
263 
264 	hints.ai_family = AF_INET;
265 	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
266 	if (syserr != 0) {
267 		fprintf(stderr,
268 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
269 		    gai_strerror(syserr));
270 	} else {
271 		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
272 		    &aic);
273 		if (caperr == 0) {
274 			if (addrinfo_compare(ais, aic))
275 				result |= GETADDRINFO_AF_INET;
276 			freeaddrinfo(ais);
277 			freeaddrinfo(aic);
278 		}
279 	}
280 
281 	hints.ai_family = AF_INET6;
282 	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
283 	if (syserr != 0) {
284 		fprintf(stderr,
285 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
286 		    gai_strerror(syserr));
287 	} else {
288 		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
289 		    &aic);
290 		if (caperr == 0) {
291 			if (addrinfo_compare(ais, aic))
292 				result |= GETADDRINFO_AF_INET6;
293 			freeaddrinfo(ais);
294 			freeaddrinfo(aic);
295 		}
296 	}
297 
298 	/* XXX: hardcoded addresses for "google-public-dns-a.google.com". */
299 #define	GOOGLE_DNS_IPV4	"8.8.8.8"
300 #define	GOOGLE_DNS_IPV6	"2001:4860:4860::8888"
301 
302 	inet_pton(AF_INET, GOOGLE_DNS_IPV4, &ip4);
303 	hps = gethostbyaddr(&ip4, sizeof(ip4), AF_INET);
304 	if (hps == NULL) {
305 		fprintf(stderr, "Unable to resolve %s.\n", GOOGLE_DNS_IPV4);
306 	} else {
307 		hpc = cap_gethostbyaddr(capdns, &ip4, sizeof(ip4), AF_INET);
308 		if (hostent_compare(hps, hpc))
309 			result |= GETHOSTBYADDR_AF_INET;
310 	}
311 
312 	inet_pton(AF_INET6, GOOGLE_DNS_IPV6, &ip6);
313 	hps = gethostbyaddr(&ip6, sizeof(ip6), AF_INET6);
314 	if (hps == NULL) {
315 		fprintf(stderr, "Unable to resolve %s.\n", GOOGLE_DNS_IPV6);
316 	} else {
317 		hpc = cap_gethostbyaddr(capdns, &ip6, sizeof(ip6), AF_INET6);
318 		if (hostent_compare(hps, hpc)) {
319 			caperr = h_errno;
320 			result |= GETHOSTBYADDR_AF_INET6;
321 		}
322 	}
323 
324 	ATF_REQUIRE_MSG(result == expected,
325 	    "expected 0x%x, got 0x%x", expected, result);
326 }
327 
328 static cap_channel_t *
cap_dns_init(void)329 cap_dns_init(void)
330 {
331 	cap_channel_t *capcas, *capdns;
332 
333 	capcas = cap_init();
334 	ATF_REQUIRE(capcas != NULL);
335 
336 	capdns = cap_service_open(capcas, "system.dns");
337 	ATF_REQUIRE(capdns != NULL);
338 
339 	cap_close(capcas);
340 
341 	return (capdns);
342 }
343 
344 ATF_TC(dns_no_limits);
ATF_TC_HEAD(dns_no_limits,tc)345 ATF_TC_HEAD(dns_no_limits, tc)
346 {
347 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
348 }
ATF_TC_BODY(dns_no_limits,tc)349 ATF_TC_BODY(dns_no_limits, tc)
350 {
351 	cap_channel_t *capdns;
352 
353 	capdns = cap_dns_init();
354 
355 	runtest(capdns,
356 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
357 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
358 	     GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET |
359 	     GETADDRINFO_AF_INET6));
360 
361 	cap_close(capdns);
362 }
363 
364 ATF_TC(dns_all_limits);
ATF_TC_HEAD(dns_all_limits,tc)365 ATF_TC_HEAD(dns_all_limits, tc)
366 {
367 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
368 }
ATF_TC_BODY(dns_all_limits,tc)369 ATF_TC_BODY(dns_all_limits, tc)
370 {
371 	cap_channel_t *capdns;
372 	const char *types[2];
373 	int families[2];
374 
375 	capdns = cap_dns_init();
376 
377 	types[0] = "NAME2ADDR";
378 	types[1] = "ADDR2NAME";
379 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
380 	families[0] = AF_INET;
381 	families[1] = AF_INET6;
382 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
383 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
384 	    cap_dns_family_limit(capdns, NULL, 0) == -1);
385 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
386 	    cap_dns_type_limit(capdns, NULL, 0) == -1);
387 
388 	runtest(capdns,
389 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
390 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
391 	     GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
392 
393 	cap_close(capdns);
394 }
395 
396 ATF_TC(dns_name_limit);
ATF_TC_HEAD(dns_name_limit,tc)397 ATF_TC_HEAD(dns_name_limit, tc)
398 {
399 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
400 }
ATF_TC_BODY(dns_name_limit,tc)401 ATF_TC_BODY(dns_name_limit, tc)
402 {
403 	cap_channel_t *capdns;
404 	const char *types[2];
405 	int families[2];
406 
407 	capdns = cap_dns_init();
408 
409 	types[0] = "NAME2ADDR";
410 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
411 	types[1] = "ADDR2NAME";
412 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
413 	    cap_dns_type_limit(capdns, types, 2) == -1);
414 	types[0] = "ADDR2NAME";
415 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
416 	    cap_dns_type_limit(capdns, types, 1) == -1);
417 	families[0] = AF_INET;
418 	families[1] = AF_INET6;
419 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
420 
421 	runtest(capdns,
422 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
423 	    GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
424 
425 	cap_close(capdns);
426 }
427 
428 ATF_TC(dns_addr_limit);
ATF_TC_HEAD(dns_addr_limit,tc)429 ATF_TC_HEAD(dns_addr_limit, tc)
430 {
431 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
432 }
ATF_TC_BODY(dns_addr_limit,tc)433 ATF_TC_BODY(dns_addr_limit, tc)
434 {
435 	cap_channel_t *capdns;
436 	const char *types[2];
437 	int families[2];
438 
439 	capdns = cap_dns_init();
440 
441 	types[0] = "ADDR2NAME";
442 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
443 	types[1] = "NAME2ADDR";
444 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
445 	    cap_dns_type_limit(capdns, types, 2) == -1);
446 	types[0] = "NAME2ADDR";
447 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
448 	    cap_dns_type_limit(capdns, types, 1) == -1);
449 	families[0] = AF_INET;
450 	families[1] = AF_INET6;
451 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
452 
453 	runtest(capdns,
454 	    (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));
455 
456 	cap_close(capdns);
457 }
458 
459 ATF_TC(dns_inet_limit);
ATF_TC_HEAD(dns_inet_limit,tc)460 ATF_TC_HEAD(dns_inet_limit, tc)
461 {
462 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
463 }
ATF_TC_BODY(dns_inet_limit,tc)464 ATF_TC_BODY(dns_inet_limit, tc)
465 {
466 	cap_channel_t *capdns;
467 	const char *types[2];
468 	int families[2];
469 
470 	capdns = cap_dns_init();
471 
472 	types[0] = "NAME2ADDR";
473 	types[1] = "ADDR2NAME";
474 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
475 	families[0] = AF_INET;
476 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
477 	families[1] = AF_INET6;
478 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
479 	    cap_dns_family_limit(capdns, families, 2) == -1);
480 	families[0] = AF_INET6;
481 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
482 	    cap_dns_family_limit(capdns, families, 1) == -1);
483 
484 	runtest(capdns,
485 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET |
486 	    GETADDRINFO_AF_INET));
487 
488 	cap_close(capdns);
489 }
490 
491 ATF_TC(dns_inet6_limit);
ATF_TC_HEAD(dns_inet6_limit,tc)492 ATF_TC_HEAD(dns_inet6_limit, tc)
493 {
494 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
495 }
ATF_TC_BODY(dns_inet6_limit,tc)496 ATF_TC_BODY(dns_inet6_limit, tc)
497 {
498 	cap_channel_t *capdns;
499 	const char *types[2];
500 	int families[2];
501 
502 	capdns = cap_dns_init();
503 
504 	types[0] = "NAME2ADDR";
505 	types[1] = "ADDR2NAME";
506 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
507 	families[0] = AF_INET6;
508 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
509 	families[1] = AF_INET;
510 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
511 	    cap_dns_family_limit(capdns, families, 2) == -1);
512 	families[0] = AF_INET;
513 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
514 	    cap_dns_family_limit(capdns, families, 1) == -1);
515 
516 	runtest(capdns,
517 	    (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6 |
518 	    GETADDRINFO_AF_INET6));
519 
520 	cap_close(capdns);
521 }
522 
523 ATF_TC(dns_name_inet_limit);
ATF_TC_HEAD(dns_name_inet_limit,tc)524 ATF_TC_HEAD(dns_name_inet_limit, tc)
525 {
526 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
527 }
ATF_TC_BODY(dns_name_inet_limit,tc)528 ATF_TC_BODY(dns_name_inet_limit, tc)
529 {
530 	cap_channel_t *capdns;
531 	const char *types[2];
532 	int families[2];
533 
534 	capdns = cap_dns_init();
535 
536 	types[0] = "NAME2ADDR";
537 	types[1] = "ADDR2NAME";
538 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
539 	families[0] = AF_INET;
540 	families[1] = AF_INET6;
541 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
542 	types[0] = "NAME2ADDR";
543 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
544 	types[1] = "ADDR2NAME";
545 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
546 	    cap_dns_type_limit(capdns, types, 2) == -1);
547 	types[0] = "ADDR2NAME";
548 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
549 	    cap_dns_type_limit(capdns, types, 1) == -1);
550 	families[0] = AF_INET;
551 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
552 	families[1] = AF_INET6;
553 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
554 	    cap_dns_family_limit(capdns, families, 2) == -1);
555 	families[0] = AF_INET6;
556 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
557 	    cap_dns_family_limit(capdns, families, 1) == -1);
558 
559 	runtest(capdns,
560 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETADDRINFO_AF_INET));
561 
562 	cap_close(capdns);
563 }
564 
565 ATF_TC(dns_name_inet6_limit);
ATF_TC_HEAD(dns_name_inet6_limit,tc)566 ATF_TC_HEAD(dns_name_inet6_limit, tc)
567 {
568 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
569 }
ATF_TC_BODY(dns_name_inet6_limit,tc)570 ATF_TC_BODY(dns_name_inet6_limit, tc)
571 {
572 	cap_channel_t *capdns;
573 	const char *types[2];
574 	int families[2];
575 
576 	capdns = cap_dns_init();
577 
578 	types[0] = "NAME2ADDR";
579 	types[1] = "ADDR2NAME";
580 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
581 	families[0] = AF_INET6;
582 	families[1] = AF_INET;
583 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
584 	types[0] = "NAME2ADDR";
585 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
586 	types[1] = "ADDR2NAME";
587 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
588 	    cap_dns_type_limit(capdns, types, 2) == -1);
589 	types[0] = "ADDR2NAME";
590 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
591 	    cap_dns_type_limit(capdns, types, 1) == -1);
592 	families[0] = AF_INET6;
593 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
594 	families[1] = AF_INET;
595 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
596 	    cap_dns_family_limit(capdns, families, 2) == -1);
597 	families[0] = AF_INET;
598 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
599 	    cap_dns_family_limit(capdns, families, 1) == -1);
600 
601 	runtest(capdns,
602 	    (GETHOSTBYNAME2_AF_INET6 | GETADDRINFO_AF_INET6));
603 
604 	cap_close(capdns);
605 }
606 
607 ATF_TC(dns_addr_inet_limit);
ATF_TC_HEAD(dns_addr_inet_limit,tc)608 ATF_TC_HEAD(dns_addr_inet_limit, tc)
609 {
610 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
611 }
ATF_TC_BODY(dns_addr_inet_limit,tc)612 ATF_TC_BODY(dns_addr_inet_limit, tc)
613 {
614 	cap_channel_t *capdns;
615 	const char *types[2];
616 	int families[2];
617 
618 	capdns = cap_dns_init();
619 
620 	types[0] = "NAME2ADDR";
621 	types[1] = "ADDR2NAME";
622 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
623 	families[0] = AF_INET;
624 	families[1] = AF_INET6;
625 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
626 	types[0] = "ADDR2NAME";
627 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
628 	types[1] = "NAME2ADDR";
629 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
630 	    cap_dns_type_limit(capdns, types, 2) == -1);
631 	types[0] = "NAME2ADDR";
632 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
633 	    cap_dns_type_limit(capdns, types, 1) == -1);
634 	families[0] = AF_INET;
635 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
636 	families[1] = AF_INET6;
637 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
638 	    cap_dns_family_limit(capdns, families, 2) == -1);
639 	families[0] = AF_INET6;
640 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
641 	    cap_dns_family_limit(capdns, families, 1) == -1);
642 
643 	runtest(capdns, GETHOSTBYADDR_AF_INET);
644 
645 	cap_close(capdns);
646 }
647 
648 ATF_TC(dns_addr_inet6_limit);
ATF_TC_HEAD(dns_addr_inet6_limit,tc)649 ATF_TC_HEAD(dns_addr_inet6_limit, tc)
650 {
651 	atf_tc_set_md_var(tc, "require.config", "allow_network_access");
652 }
ATF_TC_BODY(dns_addr_inet6_limit,tc)653 ATF_TC_BODY(dns_addr_inet6_limit, tc)
654 {
655 	cap_channel_t *capdns;
656 	const char *types[2];
657 	int families[2];
658 
659 	capdns = cap_dns_init();
660 
661 	types[0] = "NAME2ADDR";
662 	types[1] = "ADDR2NAME";
663 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
664 	families[0] = AF_INET6;
665 	families[1] = AF_INET;
666 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
667 	types[0] = "ADDR2NAME";
668 	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
669 	types[1] = "NAME2ADDR";
670 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
671 	    cap_dns_type_limit(capdns, types, 2) == -1);
672 	types[0] = "NAME2ADDR";
673 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
674 	    cap_dns_type_limit(capdns, types, 1) == -1);
675 	families[0] = AF_INET6;
676 	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
677 	families[1] = AF_INET;
678 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
679 	    cap_dns_family_limit(capdns, families, 2) == -1);
680 	families[0] = AF_INET;
681 	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
682 	    cap_dns_family_limit(capdns, families, 1) == -1);
683 
684 	runtest(capdns, GETHOSTBYADDR_AF_INET6);
685 
686 	cap_close(capdns);
687 }
688 
ATF_TP_ADD_TCS(tp)689 ATF_TP_ADD_TCS(tp)
690 {
691 	ATF_TP_ADD_TC(tp, dns_no_limits);
692 	ATF_TP_ADD_TC(tp, dns_all_limits);
693 	ATF_TP_ADD_TC(tp, dns_name_limit);
694 	ATF_TP_ADD_TC(tp, dns_addr_limit);
695 	ATF_TP_ADD_TC(tp, dns_inet_limit);
696 	ATF_TP_ADD_TC(tp, dns_inet6_limit);
697 	ATF_TP_ADD_TC(tp, dns_name_inet_limit);
698 	ATF_TP_ADD_TC(tp, dns_name_inet6_limit);
699 	ATF_TP_ADD_TC(tp, dns_addr_inet_limit);
700 	ATF_TP_ADD_TC(tp, dns_addr_inet6_limit);
701 
702 	return atf_no_error();
703 }
704