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