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