xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/rpz/dnsrps.c (revision eceb233b9bd0dfebb902ed73b531ae6964fa3f9b)
1 /*	$NetBSD: dnsrps.c,v 1.4 2020/05/24 19:46:18 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 /*
15  * -a		exit(0) if dnsrps is available or dlopen() msg if not
16  * -p		print the path to dnsrpzd configured in dnsrps so that
17  *		    dnsrpzd can be run by a setup.sh script.
18  *		    Exit(1) if dnsrps is not available
19  * -n domain	print the serial number of a domain to check if a new
20  *		    version of a policy zone has been transferred to dnsrpzd.
21  *		    Exit(1) if dnsrps is not available
22  * -w sec.ond	wait for seconds, because `sleep 0.1` is not portable
23  */
24 
25 #include <errno.h>
26 #include <inttypes.h>
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <unistd.h>
35 
36 #include <isc/print.h>
37 #include <isc/util.h>
38 
39 #ifdef USE_DNSRPS
40 #define LIBRPZ_LIB_OPEN DNSRPS_LIB_OPEN
41 #include <dns/librpz.h>
42 
43 librpz_t *librpz;
44 #else  /* ifdef USE_DNSRPS */
45 typedef struct {
46 	char c[120];
47 } librpz_emsg_t;
48 #endif /* ifdef USE_DNSRPS */
49 
50 static bool
51 link_dnsrps(librpz_emsg_t *emsg);
52 
53 #define USAGE "usage: [-ap] [-n domain] [-w sec.onds]\n"
54 
55 int
56 main(int argc, char **argv) {
57 #ifdef USE_DNSRPS
58 	char cstr[sizeof("zone ") + 1024 + 10];
59 	librpz_clist_t *clist;
60 	librpz_client_t *client;
61 	librpz_rsp_t *rsp;
62 	uint32_t serial;
63 #endif /* ifdef USE_DNSRPS */
64 	double seconds;
65 	librpz_emsg_t emsg;
66 	char *p;
67 	int i;
68 
69 	while ((i = getopt(argc, argv, "apn:w:")) != -1) {
70 		switch (i) {
71 		case 'a':
72 			if (!link_dnsrps(&emsg)) {
73 				printf("I:%s\n", emsg.c);
74 				return (1);
75 			}
76 			return (0);
77 
78 		case 'p':
79 			if (!link_dnsrps(&emsg)) {
80 				fprintf(stderr, "## %s\n", emsg.c);
81 				return (1);
82 			}
83 #ifdef USE_DNSRPS
84 			printf("%s\n", librpz->dnsrpzd_path);
85 #else  /* ifdef USE_DNSRPS */
86 			INSIST(0);
87 			ISC_UNREACHABLE();
88 #endif /* ifdef USE_DNSRPS */
89 			return (0);
90 
91 		case 'n':
92 			if (!link_dnsrps(&emsg)) {
93 				fprintf(stderr, "## %s\n", emsg.c);
94 				return (1);
95 			}
96 #ifdef USE_DNSRPS
97 			/*
98 			 * Get the serial number of a policy zone from
99 			 * a running dnsrpzd daemon.
100 			 */
101 			clist = librpz->clist_create(&emsg, NULL, NULL, NULL,
102 						     NULL, NULL);
103 			if (clist == NULL) {
104 				fprintf(stderr, "## %s: %s\n", optarg, emsg.c);
105 				return (1);
106 			}
107 			snprintf(cstr, sizeof(cstr),
108 				 "zone %s; dnsrpzd \"\";"
109 				 " dnsrpzd-sock dnsrpzd.sock;"
110 				 " dnsrpzd-rpzf dnsrpzd.rpzf",
111 				 optarg);
112 			client = librpz->client_create(&emsg, clist, cstr,
113 						       true);
114 			if (client == NULL) {
115 				fprintf(stderr, "## %s\n", emsg.c);
116 				return (1);
117 			}
118 
119 			rsp = NULL;
120 			if (!librpz->rsp_create(&emsg, &rsp, NULL, client, true,
121 						false) ||
122 			    rsp == NULL) {
123 				fprintf(stderr, "## %s\n", emsg.c);
124 				librpz->client_detach(&client);
125 				return (1);
126 			}
127 
128 			if (!librpz->soa_serial(&emsg, &serial, optarg, rsp)) {
129 				fprintf(stderr, "## %s\n", emsg.c);
130 				librpz->client_detach(&client);
131 				return (1);
132 			}
133 			librpz->rsp_detach(&rsp);
134 			librpz->client_detach(&client);
135 			printf("%u\n", serial);
136 #else  /* ifdef USE_DNSRPS */
137 			INSIST(0);
138 			ISC_UNREACHABLE();
139 #endif /* ifdef USE_DNSRPS */
140 			return (0);
141 
142 		case 'w':
143 			seconds = strtod(optarg, &p);
144 			if (seconds <= 0 || *p != '\0') {
145 				fputs(USAGE, stderr);
146 				return (1);
147 			}
148 			usleep((int)(seconds * 1000.0 * 1000.0));
149 			return (0);
150 
151 		default:
152 			fputs(USAGE, stderr);
153 			return (1);
154 		}
155 	}
156 	fputs(USAGE, stderr);
157 	return (1);
158 }
159 
160 static bool
161 link_dnsrps(librpz_emsg_t *emsg) {
162 #ifdef USE_DNSRPS
163 	librpz = librpz_lib_open(emsg, NULL, DNSRPS_LIBRPZ_PATH);
164 	if (librpz == NULL) {
165 		return (false);
166 	}
167 
168 	return (true);
169 #else  /* ifdef USE_DNSRPS */
170 	snprintf(emsg->c, sizeof(emsg->c), "DNSRPS not configured");
171 	return (false);
172 #endif /* ifdef USE_DNSRPS */
173 }
174