]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/regression/capsicum/libcasper/dns.c
Add simple support for CloudABI processes to kdump(1).
[FreeBSD/FreeBSD.git] / tools / regression / capsicum / libcasper / dns.c
1 /*-
2  * Copyright (c) 2013 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Pawel Jakub Dawidek under sponsorship from
6  * the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/capsicum.h>
34
35 #include <arpa/inet.h>
36 #include <netinet/in.h>
37
38 #include <assert.h>
39 #include <err.h>
40 #include <errno.h>
41 #include <netdb.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include <libcasper.h>
48
49 #include <casper/cap_dns.h>
50
51 static int ntest = 1;
52
53 #define CHECK(expr)     do {                                            \
54         if ((expr))                                                     \
55                 printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__);     \
56         else                                                            \
57                 printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__); \
58         ntest++;                                                        \
59 } while (0)
60 #define CHECKX(expr)     do {                                           \
61         if ((expr)) {                                                   \
62                 printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__);     \
63         } else {                                                        \
64                 printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__); \
65                 exit(1);                                                \
66         }                                                               \
67         ntest++;                                                        \
68 } while (0)
69
70 #define GETHOSTBYNAME                   0x01
71 #define GETHOSTBYNAME2_AF_INET          0x02
72 #define GETHOSTBYNAME2_AF_INET6         0x04
73 #define GETHOSTBYADDR_AF_INET           0x08
74 #define GETHOSTBYADDR_AF_INET6          0x10
75
76 static bool
77 hostent_aliases_compare(char **aliases0, char **aliases1)
78 {
79         int i0, i1;
80
81         if (aliases0 == NULL && aliases1 == NULL)
82                 return (true);
83         if (aliases0 == NULL || aliases1 == NULL)
84                 return (false);
85
86         for (i0 = 0; aliases0[i0] != NULL; i0++) {
87                 for (i1 = 0; aliases1[i1] != NULL; i1++) {
88                         if (strcmp(aliases0[i0], aliases1[i1]) == 0)
89                                 break;
90                 }
91                 if (aliases1[i1] == NULL)
92                         return (false);
93         }
94
95         return (true);
96 }
97
98 static bool
99 hostent_addr_list_compare(char **addr_list0, char **addr_list1, int length)
100 {
101         int i0, i1;
102
103         if (addr_list0 == NULL && addr_list1 == NULL)
104                 return (true);
105         if (addr_list0 == NULL || addr_list1 == NULL)
106                 return (false);
107
108         for (i0 = 0; addr_list0[i0] != NULL; i0++) {
109                 for (i1 = 0; addr_list1[i1] != NULL; i1++) {
110                         if (memcmp(addr_list0[i0], addr_list1[i1], length) == 0)
111                                 break;
112                 }
113                 if (addr_list1[i1] == NULL)
114                         return (false);
115         }
116
117         return (true);
118 }
119
120 static bool
121 hostent_compare(const struct hostent *hp0, const struct hostent *hp1)
122 {
123
124         if (hp0 == NULL && hp1 != NULL)
125                 return (true);
126
127         if (hp0 == NULL || hp1 == NULL)
128                 return (false);
129
130         if (hp0->h_name != NULL || hp1->h_name != NULL) {
131                 if (hp0->h_name == NULL || hp1->h_name == NULL)
132                         return (false);
133                 if (strcmp(hp0->h_name, hp1->h_name) != 0)
134                         return (false);
135         }
136
137         if (!hostent_aliases_compare(hp0->h_aliases, hp1->h_aliases))
138                 return (false);
139         if (!hostent_aliases_compare(hp1->h_aliases, hp0->h_aliases))
140                 return (false);
141
142         if (hp0->h_addrtype != hp1->h_addrtype)
143                 return (false);
144
145         if (hp0->h_length != hp1->h_length)
146                 return (false);
147
148         if (!hostent_addr_list_compare(hp0->h_addr_list, hp1->h_addr_list,
149             hp0->h_length)) {
150                 return (false);
151         }
152         if (!hostent_addr_list_compare(hp1->h_addr_list, hp0->h_addr_list,
153             hp0->h_length)) {
154                 return (false);
155         }
156
157         return (true);
158 }
159
160 static unsigned int
161 runtest(cap_channel_t *capdns)
162 {
163         unsigned int result;
164         struct hostent *hps, *hpc;
165         struct in_addr ip4;
166         struct in6_addr ip6;
167
168         result = 0;
169
170         hps = gethostbyname("example.com");
171         if (hps == NULL)
172                 fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
173         hpc = cap_gethostbyname(capdns, "example.com");
174         if (hostent_compare(hps, hpc))
175                 result |= GETHOSTBYNAME;
176
177         hps = gethostbyname2("example.com", AF_INET);
178         if (hps == NULL)
179                 fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
180         hpc = cap_gethostbyname2(capdns, "example.com", AF_INET);
181         if (hostent_compare(hps, hpc))
182                 result |= GETHOSTBYNAME2_AF_INET;
183
184         hps = gethostbyname2("example.com", AF_INET6);
185         if (hps == NULL)
186                 fprintf(stderr, "Unable to resolve %s IPv6.\n", "example.com");
187         hpc = cap_gethostbyname2(capdns, "example.com", AF_INET6);
188         if (hostent_compare(hps, hpc))
189                 result |= GETHOSTBYNAME2_AF_INET6;
190
191         /*
192          * 8.8.178.135 is IPv4 address of freefall.freebsd.org
193          * as of 27 October 2013.
194          */
195         inet_pton(AF_INET, "8.8.178.135", &ip4);
196         hps = gethostbyaddr(&ip4, sizeof(ip4), AF_INET);
197         if (hps == NULL)
198                 fprintf(stderr, "Unable to resolve %s.\n", "8.8.178.135");
199         hpc = cap_gethostbyaddr(capdns, &ip4, sizeof(ip4), AF_INET);
200         if (hostent_compare(hps, hpc))
201                 result |= GETHOSTBYADDR_AF_INET;
202
203         /*
204          * 2001:1900:2254:206c::16:87 is IPv6 address of freefall.freebsd.org
205          * as of 27 October 2013.
206          */
207         inet_pton(AF_INET6, "2001:1900:2254:206c::16:87", &ip6);
208         hps = gethostbyaddr(&ip6, sizeof(ip6), AF_INET6);
209         if (hps == NULL) {
210                 fprintf(stderr, "Unable to resolve %s.\n",
211                     "2001:1900:2254:206c::16:87");
212         }
213         hpc = cap_gethostbyaddr(capdns, &ip6, sizeof(ip6), AF_INET6);
214         if (hostent_compare(hps, hpc))
215                 result |= GETHOSTBYADDR_AF_INET6;
216
217         return (result);
218 }
219
220 int
221 main(void)
222 {
223         cap_channel_t *capcas, *capdns, *origcapdns;
224         const char *types[2];
225         int families[2];
226
227         printf("1..91\n");
228
229         capcas = cap_init();
230         CHECKX(capcas != NULL);
231
232         origcapdns = capdns = cap_service_open(capcas, "system.dns");
233         CHECKX(capdns != NULL);
234
235         cap_close(capcas);
236
237         /* No limits set. */
238
239         CHECK(runtest(capdns) ==
240             (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
241              GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));
242
243         /*
244          * Allow:
245          * type: NAME, ADDR
246          * family: AF_INET, AF_INET6
247          */
248
249         capdns = cap_clone(origcapdns);
250         CHECK(capdns != NULL);
251
252         types[0] = "NAME";
253         types[1] = "ADDR";
254         CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
255         families[0] = AF_INET;
256         families[1] = AF_INET6;
257         CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
258
259         CHECK(runtest(capdns) ==
260             (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
261              GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));
262
263         cap_close(capdns);
264
265         /*
266          * Allow:
267          * type: NAME
268          * family: AF_INET, AF_INET6
269          */
270
271         capdns = cap_clone(origcapdns);
272         CHECK(capdns != NULL);
273
274         types[0] = "NAME";
275         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
276         types[1] = "ADDR";
277         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
278             errno == ENOTCAPABLE);
279         types[0] = "ADDR";
280         CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
281             errno == ENOTCAPABLE);
282         families[0] = AF_INET;
283         families[1] = AF_INET6;
284         CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
285
286         CHECK(runtest(capdns) ==
287             (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6));
288
289         cap_close(capdns);
290
291         /*
292          * Allow:
293          * type: ADDR
294          * family: AF_INET, AF_INET6
295          */
296
297         capdns = cap_clone(origcapdns);
298         CHECK(capdns != NULL);
299
300         types[0] = "ADDR";
301         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
302         types[1] = "NAME";
303         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
304             errno == ENOTCAPABLE);
305         types[0] = "NAME";
306         CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
307             errno == ENOTCAPABLE);
308         families[0] = AF_INET;
309         families[1] = AF_INET6;
310         CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
311
312         CHECK(runtest(capdns) ==
313             (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));
314
315         cap_close(capdns);
316
317         /*
318          * Allow:
319          * type: NAME, ADDR
320          * family: AF_INET
321          */
322
323         capdns = cap_clone(origcapdns);
324         CHECK(capdns != NULL);
325
326         types[0] = "NAME";
327         types[1] = "ADDR";
328         CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
329         families[0] = AF_INET;
330         CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
331         families[1] = AF_INET6;
332         CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
333             errno == ENOTCAPABLE);
334         families[0] = AF_INET6;
335         CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
336             errno == ENOTCAPABLE);
337
338         CHECK(runtest(capdns) ==
339             (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET));
340
341         cap_close(capdns);
342
343         /*
344          * Allow:
345          * type: NAME, ADDR
346          * family: AF_INET6
347          */
348
349         capdns = cap_clone(origcapdns);
350         CHECK(capdns != NULL);
351
352         types[0] = "NAME";
353         types[1] = "ADDR";
354         CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
355         families[0] = AF_INET6;
356         CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
357         families[1] = AF_INET;
358         CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
359             errno == ENOTCAPABLE);
360         families[0] = AF_INET;
361         CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
362             errno == ENOTCAPABLE);
363
364         CHECK(runtest(capdns) ==
365             (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6));
366
367         cap_close(capdns);
368
369         /* Below we also test further limiting capability. */
370
371         /*
372          * Allow:
373          * type: NAME
374          * family: AF_INET
375          */
376
377         capdns = cap_clone(origcapdns);
378         CHECK(capdns != NULL);
379
380         types[0] = "NAME";
381         types[1] = "ADDR";
382         CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
383         families[0] = AF_INET;
384         families[1] = AF_INET6;
385         CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
386         types[0] = "NAME";
387         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
388         types[1] = "ADDR";
389         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
390             errno == ENOTCAPABLE);
391         types[0] = "ADDR";
392         CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
393             errno == ENOTCAPABLE);
394         families[0] = AF_INET;
395         CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
396         families[1] = AF_INET6;
397         CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
398             errno == ENOTCAPABLE);
399         families[0] = AF_INET6;
400         CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
401             errno == ENOTCAPABLE);
402
403         CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET));
404
405         cap_close(capdns);
406
407         /*
408          * Allow:
409          * type: NAME
410          * family: AF_INET6
411          */
412
413         capdns = cap_clone(origcapdns);
414         CHECK(capdns != NULL);
415
416         types[0] = "NAME";
417         types[1] = "ADDR";
418         CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
419         families[0] = AF_INET;
420         families[1] = AF_INET6;
421         CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
422         types[0] = "NAME";
423         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
424         types[1] = "ADDR";
425         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
426             errno == ENOTCAPABLE);
427         types[0] = "ADDR";
428         CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
429             errno == ENOTCAPABLE);
430         families[0] = AF_INET6;
431         CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
432         families[1] = AF_INET;
433         CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
434             errno == ENOTCAPABLE);
435         families[0] = AF_INET;
436         CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
437             errno == ENOTCAPABLE);
438
439         CHECK(runtest(capdns) == GETHOSTBYNAME2_AF_INET6);
440
441         cap_close(capdns);
442
443         /*
444          * Allow:
445          * type: ADDR
446          * family: AF_INET
447          */
448
449         capdns = cap_clone(origcapdns);
450         CHECK(capdns != NULL);
451
452         types[0] = "NAME";
453         types[1] = "ADDR";
454         CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
455         families[0] = AF_INET;
456         families[1] = AF_INET6;
457         CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
458         types[0] = "ADDR";
459         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
460         types[1] = "NAME";
461         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
462             errno == ENOTCAPABLE);
463         types[0] = "NAME";
464         CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
465             errno == ENOTCAPABLE);
466         families[0] = AF_INET;
467         CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
468         families[1] = AF_INET6;
469         CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
470             errno == ENOTCAPABLE);
471         families[0] = AF_INET6;
472         CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
473             errno == ENOTCAPABLE);
474
475         CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET);
476
477         cap_close(capdns);
478
479         /*
480          * Allow:
481          * type: ADDR
482          * family: AF_INET6
483          */
484
485         capdns = cap_clone(origcapdns);
486         CHECK(capdns != NULL);
487
488         types[0] = "NAME";
489         types[1] = "ADDR";
490         CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
491         families[0] = AF_INET;
492         families[1] = AF_INET6;
493         CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
494         types[0] = "ADDR";
495         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
496         types[1] = "NAME";
497         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
498             errno == ENOTCAPABLE);
499         types[0] = "NAME";
500         CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
501             errno == ENOTCAPABLE);
502         families[0] = AF_INET6;
503         CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
504         families[1] = AF_INET;
505         CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
506             errno == ENOTCAPABLE);
507         families[0] = AF_INET;
508         CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
509             errno == ENOTCAPABLE);
510
511         CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET6);
512
513         cap_close(capdns);
514
515         /* Trying to rise the limits. */
516
517         capdns = cap_clone(origcapdns);
518         CHECK(capdns != NULL);
519
520         types[0] = "NAME";
521         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
522         families[0] = AF_INET;
523         CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
524
525         types[0] = "NAME";
526         types[1] = "ADDR";
527         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
528             errno == ENOTCAPABLE);
529         families[0] = AF_INET;
530         families[1] = AF_INET6;
531         CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
532             errno == ENOTCAPABLE);
533
534         types[0] = "ADDR";
535         CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
536             errno == ENOTCAPABLE);
537         families[0] = AF_INET6;
538         CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
539             errno == ENOTCAPABLE);
540
541         CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
542             errno == ENOTCAPABLE);
543         CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
544             errno == ENOTCAPABLE);
545
546         /* Do the limits still hold? */
547         CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET));
548
549         cap_close(capdns);
550
551         capdns = cap_clone(origcapdns);
552         CHECK(capdns != NULL);
553
554         types[0] = "ADDR";
555         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
556         families[0] = AF_INET6;
557         CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
558
559         types[0] = "NAME";
560         types[1] = "ADDR";
561         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
562             errno == ENOTCAPABLE);
563         families[0] = AF_INET;
564         families[1] = AF_INET6;
565         CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
566             errno == ENOTCAPABLE);
567
568         types[0] = "NAME";
569         CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
570             errno == ENOTCAPABLE);
571         families[0] = AF_INET;
572         CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
573             errno == ENOTCAPABLE);
574
575         CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
576             errno == ENOTCAPABLE);
577         CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
578             errno == ENOTCAPABLE);
579
580         /* Do the limits still hold? */
581         CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET6);
582
583         cap_close(capdns);
584
585         cap_close(origcapdns);
586
587         exit(0);
588 }