1/* $NetBSD: keydelete.c,v 1.8 2024/02/21 22:51:37 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#include <stdlib.h> 17#include <string.h> 18 19#include <isc/app.h> 20#include <isc/base64.h> 21#include <isc/hash.h> 22#include <isc/log.h> 23#include <isc/managers.h> 24#include <isc/mem.h> 25#include <isc/netmgr.h> 26#include <isc/print.h> 27#include <isc/random.h> 28#include <isc/result.h> 29#include <isc/sockaddr.h> 30#include <isc/task.h> 31#include <isc/util.h> 32 33#include <dns/dispatch.h> 34#include <dns/fixedname.h> 35#include <dns/keyvalues.h> 36#include <dns/message.h> 37#include <dns/name.h> 38#include <dns/request.h> 39#include <dns/result.h> 40#include <dns/tkey.h> 41#include <dns/tsig.h> 42#include <dns/view.h> 43 44#define CHECK(str, x) \ 45 { \ 46 if ((x) != ISC_R_SUCCESS) { \ 47 fprintf(stderr, "I:%s: %s\n", (str), \ 48 isc_result_totext(x)); \ 49 exit(-1); \ 50 } \ 51 } 52 53#define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS) 54 55#define TIMEOUT 30 56 57static char *ip_address = NULL; 58static int port; 59static isc_mem_t *mctx = NULL; 60static dns_tsigkey_t *tsigkey = NULL; 61static dns_tsig_keyring_t *ring = NULL; 62static dns_requestmgr_t *requestmgr = NULL; 63 64static void 65recvquery(isc_task_t *task, isc_event_t *event) { 66 dns_requestevent_t *reqev = (dns_requestevent_t *)event; 67 isc_result_t result; 68 dns_message_t *query = NULL, *response = NULL; 69 70 UNUSED(task); 71 72 REQUIRE(reqev != NULL); 73 74 if (reqev->result != ISC_R_SUCCESS) { 75 fprintf(stderr, "I:request event result: %s\n", 76 isc_result_totext(reqev->result)); 77 exit(-1); 78 } 79 80 query = reqev->ev_arg; 81 82 dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); 83 84 result = dns_request_getresponse(reqev->request, response, 85 DNS_MESSAGEPARSE_PRESERVEORDER); 86 CHECK("dns_request_getresponse", result); 87 88 if (response->rcode != dns_rcode_noerror) { 89 result = dns_result_fromrcode(response->rcode); 90 fprintf(stderr, "I:response rcode: %s\n", 91 isc_result_totext(result)); 92 exit(-1); 93 } 94 95 result = dns_tkey_processdeleteresponse(query, response, ring); 96 CHECK("dns_tkey_processdhresponse", result); 97 98 dns_message_detach(&query); 99 dns_message_detach(&response); 100 dns_request_destroy(&reqev->request); 101 isc_event_free(&event); 102 isc_app_shutdown(); 103 return; 104} 105 106static void 107sendquery(isc_task_t *task, isc_event_t *event) { 108 struct in_addr inaddr; 109 isc_sockaddr_t address; 110 isc_result_t result; 111 dns_message_t *query = NULL; 112 dns_request_t *request = NULL; 113 114 isc_event_free(&event); 115 116 result = ISC_R_FAILURE; 117 if (inet_pton(AF_INET, ip_address, &inaddr) != 1) { 118 CHECK("inet_pton", result); 119 } 120 isc_sockaddr_fromin(&address, &inaddr, port); 121 122 dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query); 123 124 result = dns_tkey_builddeletequery(query, tsigkey); 125 CHECK("dns_tkey_builddeletequery", result); 126 127 result = dns_request_create(requestmgr, query, NULL, &address, 128 DNS_REQUESTOPT_TCP, tsigkey, TIMEOUT, 0, 0, 129 task, recvquery, query, &request); 130 CHECK("dns_request_create", result); 131} 132 133int 134main(int argc, char **argv) { 135 char *keyname = NULL; 136 isc_nm_t *netmgr = NULL; 137 isc_taskmgr_t *taskmgr = NULL; 138 isc_sockaddr_t bind_any; 139 dns_dispatchmgr_t *dispatchmgr = NULL; 140 dns_dispatch_t *dispatchv4 = NULL; 141 dns_view_t *view = NULL; 142 dns_tkeyctx_t *tctx = NULL; 143 dst_key_t *dstkey = NULL; 144 isc_log_t *log = NULL; 145 isc_logconfig_t *logconfig = NULL; 146 isc_task_t *task = NULL; 147 isc_result_t result; 148 int type; 149 150 RUNCHECK(isc_app_start()); 151 152 if (argc < 4) { 153 fprintf(stderr, "I:no key to delete\n"); 154 exit(-1); 155 } 156 if (strcmp(argv[1], "-r") == 0) { 157 fprintf(stderr, "I:The -r options has been deprecated\n"); 158 exit(-1); 159 } 160 ip_address = argv[1]; 161 port = atoi(argv[2]); 162 keyname = argv[3]; 163 164 isc_mem_create(&mctx); 165 166 isc_log_create(mctx, &log, &logconfig); 167 168 RUNCHECK(dst_lib_init(mctx, NULL)); 169 170 isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL); 171 172 RUNCHECK(isc_task_create(taskmgr, 0, &task)); 173 RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr)); 174 isc_sockaddr_any(&bind_any); 175 RUNCHECK(dns_dispatch_createudp(dispatchmgr, &bind_any, &dispatchv4)); 176 RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4, 177 NULL, &requestmgr)); 178 179 RUNCHECK(dns_tsigkeyring_create(mctx, &ring)); 180 RUNCHECK(dns_tkeyctx_create(mctx, &tctx)); 181 182 RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); 183 dns_view_setkeyring(view, ring); 184 185 RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL)); 186 187 type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY; 188 result = dst_key_fromnamedfile(keyname, NULL, type, mctx, &dstkey); 189 CHECK("dst_key_fromnamedfile", result); 190 result = dns_tsigkey_createfromkey(dst_key_name(dstkey), 191 DNS_TSIG_HMACMD5_NAME, dstkey, true, 192 NULL, 0, 0, mctx, ring, &tsigkey); 193 dst_key_free(&dstkey); 194 CHECK("dns_tsigkey_createfromkey", result); 195 196 (void)isc_app_run(); 197 198 dns_requestmgr_shutdown(requestmgr); 199 dns_requestmgr_detach(&requestmgr); 200 dns_dispatch_detach(&dispatchv4); 201 dns_dispatchmgr_detach(&dispatchmgr); 202 isc_task_shutdown(task); 203 isc_task_detach(&task); 204 isc_managers_destroy(&netmgr, &taskmgr, NULL); 205 206 dns_tsigkeyring_detach(&ring); 207 208 dns_tsigkey_detach(&tsigkey); 209 210 dns_tkeyctx_destroy(&tctx); 211 212 dns_view_detach(&view); 213 214 isc_log_destroy(&log); 215 216 dst_lib_destroy(); 217 218 isc_mem_destroy(&mctx); 219 220 isc_app_finish(); 221 222 return (0); 223} 224