No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / bind / dist / bin / tests / dst / gsstest.c
blob913abefee0faa2341f08ec850cef5d1ac7d9f918
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2006, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* Id: gsstest.c,v 1.8 2009/09/02 23:48:01 tbox Exp */
21 #include <config.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #include <isc/app.h>
27 #include <isc/base64.h>
28 #include <isc/entropy.h>
29 #include <isc/log.h>
30 #include <isc/mem.h>
31 #include <isc/sockaddr.h>
32 #include <isc/socket.h>
33 #include <isc/task.h>
34 #include <isc/timer.h>
35 #include <isc/util.h>
37 #include <dns/dispatch.h>
38 #include <dns/fixedname.h>
39 #include <dns/keyvalues.h>
40 #include <dns/log.h>
41 #include <dns/message.h>
42 #include <dns/name.h>
43 #include <dns/request.h>
44 #include <dns/result.h>
45 #include <dns/tkey.h>
46 #include <dns/tsig.h>
47 #include <dns/view.h>
49 #include <dns/dnssec.h>
50 #include <dns/events.h>
51 #include <dns/masterdump.h>
52 #include <dns/rdataset.h>
53 #include <dns/resolver.h>
54 #include <dns/types.h>
56 #include <dst/result.h>
58 #ifdef GSSAPI
59 #include ISC_PLATFORM_GSSAPIHEADER
61 struct dst_context {
62 unsigned int magic;
63 dst_key_t *key;
64 isc_mem_t *mctx;
65 void *opaque;
68 #define CHECK(str, x) { \
69 if ((x) != ISC_R_SUCCESS) { \
70 fprintf(stderr, "I:%d:%s: %s\n", __LINE__, (str), isc_result_totext(x)); \
71 goto end; \
72 } \
75 static char contextname[512];
76 static char gssid[512];
77 static char serveraddress[512];
78 static dns_fixedname_t servername, gssname;
80 static isc_mem_t *mctx;
81 static dns_requestmgr_t *requestmgr;
82 static isc_sockaddr_t address;
84 static dns_tsig_keyring_t *ring;
85 static dns_tsigkey_t *tsigkey = NULL;
86 static gss_ctx_id_t gssctx;
87 static gss_ctx_id_t *gssctxp = &gssctx;
89 #define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS)
91 #define PORT 53
92 #define TIMEOUT 30
94 static void initctx1(isc_task_t *task, isc_event_t *event);
95 static void sendquery(isc_task_t *task, isc_event_t *event);
96 static void setup();
98 static void
99 console(isc_task_t *task, isc_event_t *event)
101 char buf[32];
102 isc_event_t *ev = NULL;
104 isc_event_free(&event);
106 while(1) {
107 printf("\nCommand => ");
108 scanf("%s", buf);
110 if(strcmp(buf, "quit") == 0) {
111 isc_app_shutdown();
112 return;
115 if(strcmp(buf, "initctx") == 0) {
116 ev = isc_event_allocate(mctx, (void *)1, 1, initctx1,
117 NULL, sizeof(*event));
118 isc_task_send(task, &ev);
119 return;
122 if(strcmp(buf, "query") == 0) {
123 ev = isc_event_allocate(mctx, (void *)1, 1, sendquery,
124 NULL, sizeof(*event));
125 isc_task_send(task, &ev);
126 return;
129 printf("Unknown command\n");
133 static void
134 recvresponse(isc_task_t *task, isc_event_t *event) {
135 dns_requestevent_t *reqev = (dns_requestevent_t *)event;
136 isc_result_t result, result2;
137 dns_message_t *query, *response = NULL;
138 isc_buffer_t outtoken;
139 isc_buffer_t outbuf;
140 char output[10 * 1024];
142 unsigned char array[DNS_NAME_MAXTEXT + 1];
143 isc_buffer_init(&outtoken, array, sizeof(array));
145 UNUSED(task);
147 REQUIRE(reqev != NULL);
149 if (reqev->result != ISC_R_SUCCESS) {
150 fprintf(stderr, "I:request event result: %s\n",
151 isc_result_totext(reqev->result));
152 goto end;
155 query = reqev->ev_arg;
157 response = NULL;
158 result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
159 CHECK("dns_message_create", result);
161 printf("\nReceived Response:\n");
163 result2 = dns_request_getresponse(reqev->request, response,
164 DNS_MESSAGEPARSE_PRESERVEORDER);
165 isc_buffer_init(&outbuf, output, sizeof(output));
166 result = dns_message_totext(response, &dns_master_style_debug, 0,
167 &outbuf);
168 CHECK("dns_message_totext", result);
169 printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf),
170 (char *)isc_buffer_base(&outbuf));
172 CHECK("dns_request_getresponse", result2);
174 if (response)
175 dns_message_destroy(&response);
177 end:
178 if (query)
179 dns_message_destroy(&query);
181 if (reqev->request)
182 dns_request_destroy(&reqev->request);
184 isc_event_free(&event);
186 event = isc_event_allocate(mctx, (void *)1, 1, console, NULL,
187 sizeof(*event));
188 isc_task_send(task, &event);
189 return;
193 static void
194 sendquery(isc_task_t *task, isc_event_t *event)
196 dns_request_t *request = NULL;
197 dns_message_t *message = NULL;
198 dns_name_t *qname = NULL;
199 dns_rdataset_t *qrdataset = NULL;
200 isc_result_t result;
201 dns_fixedname_t queryname;
202 isc_buffer_t buf;
203 isc_buffer_t outbuf;
204 char output[10 * 1024];
206 static char host[256];
208 isc_event_free(&event);
210 printf("Query => ");
211 scanf("%s", host);
213 dns_fixedname_init(&queryname);
214 isc_buffer_init(&buf, host, strlen(host));
215 isc_buffer_add(&buf, strlen(host));
216 result = dns_name_fromtext(dns_fixedname_name(&queryname), &buf,
217 dns_rootname, 0, NULL);
218 CHECK("dns_name_fromtext", result);
220 result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
222 message->opcode = dns_opcode_query;
223 message->rdclass = dns_rdataclass_in;
224 message->id = (unsigned short)(random() & 0xFFFF);
226 result = dns_message_gettempname(message, &qname);
227 if (result != ISC_R_SUCCESS)
228 goto end;
230 result = dns_message_gettemprdataset(message, &qrdataset);
231 if (result != ISC_R_SUCCESS)
232 goto end;
234 dns_name_init(qname, NULL);
235 dns_name_clone(dns_fixedname_name(&queryname), qname);
236 dns_rdataset_init(qrdataset);
237 dns_rdataset_makequestion(qrdataset, dns_rdataclass_in,
238 dns_rdatatype_a);
239 ISC_LIST_APPEND(qname->list, qrdataset, link);
240 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
242 result = dns_request_create(requestmgr, message, &address, 0, tsigkey,
243 TIMEOUT, task, recvresponse,
244 message, &request);
245 CHECK("dns_request_create", result);
247 printf("Submitting query:\n");
248 isc_buffer_init(&outbuf, output, sizeof(output));
249 result = dns_message_totext(message, &dns_master_style_debug, 0,
250 &outbuf);
251 CHECK("dns_message_totext", result);
252 printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf),
253 (char *)isc_buffer_base(&outbuf));
255 return;
257 end:
258 if (qname != NULL)
259 dns_message_puttempname(message, &qname);
260 if (qrdataset != NULL)
261 dns_message_puttemprdataset(message, &qrdataset);
262 if (message != NULL)
263 dns_message_destroy(&message);
266 static void
267 initctx2(isc_task_t *task, isc_event_t *event) {
268 dns_requestevent_t *reqev = (dns_requestevent_t *)event;
269 isc_result_t result;
270 dns_message_t *query, *response = NULL;
271 isc_buffer_t outtoken;
272 unsigned char array[DNS_NAME_MAXTEXT + 1];
273 dns_rdataset_t *rdataset;
274 dns_rdatatype_t qtype;
275 dns_name_t *question_name;
277 UNUSED(task);
279 REQUIRE(reqev != NULL);
281 if (reqev->result != ISC_R_SUCCESS) {
282 fprintf(stderr, "I:request event result: %s\n",
283 isc_result_totext(reqev->result));
284 goto end;
287 query = reqev->ev_arg;
289 response = NULL;
290 result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
291 CHECK("dns_message_create", result);
293 result = dns_request_getresponse(reqev->request, response,
294 DNS_MESSAGEPARSE_PRESERVEORDER);
295 CHECK("dns_request_getresponse", result);
297 if (response->rcode != dns_rcode_noerror) {
298 result = ISC_RESULTCLASS_DNSRCODE + response->rcode;
299 fprintf(stderr, "I:response rcode: %s\n",
300 isc_result_totext(result));
301 goto end;
304 printf("Received token from server, calling gss_init_sec_context()\n");
305 isc_buffer_init(&outtoken, array, DNS_NAME_MAXTEXT + 1);
306 result = dns_tkey_processgssresponse(query, response,
307 dns_fixedname_name(&gssname),
308 &gssctx, &outtoken,
309 &tsigkey, ring);
310 gssctx = *gssctxp;
311 CHECK("dns_tkey_processgssresponse", result);
312 printf("Context accepted\n");
314 question_name = NULL;
315 dns_message_currentname(response, DNS_SECTION_ANSWER, &question_name);
316 rdataset = ISC_LIST_HEAD(question_name->list);
317 INSIST(rdataset != NULL);
318 qtype = rdataset->type;
319 if(qtype == dns_rdatatype_tkey) {
320 printf("Received TKEY response from server\n");
321 printf("Context completed\n");
322 } else {
323 printf("Did not receive TKEY response from server\n");
324 printf("Context not completed\n");
325 dns_tsigkey_detach(&tsigkey);
326 tsigkey = NULL;
329 if(response)
330 dns_message_destroy(&response);
332 end:
333 if(query)
334 dns_message_destroy(&query);
336 if(reqev->request)
337 dns_request_destroy(&reqev->request);
339 isc_event_free(&event);
341 event = isc_event_allocate(mctx, (void *)1, 1, console, NULL,
342 sizeof(*event));
343 isc_task_send(task, &event);
344 return;
347 static void
348 initctx1(isc_task_t *task, isc_event_t *event) {
349 isc_result_t result;
350 isc_buffer_t buf;
351 dns_message_t *query;
352 dns_request_t *request;
354 isc_event_free(&event);
356 printf("Initctx - GSS name => ");
357 scanf("%s", gssid);
359 sprintf(contextname, "gsstest.context.%d.", (int)time(NULL));
361 printf("Initctx - context name we're using: %s\n", contextname);
363 printf("Negotiating GSSAPI context: ");
364 printf(gssid);
365 printf("\n");
368 * Setup a GSSAPI context with the server
370 dns_fixedname_init(&servername);
371 isc_buffer_init(&buf, contextname, strlen(contextname));
372 isc_buffer_add(&buf, strlen(contextname));
373 result = dns_name_fromtext(dns_fixedname_name(&servername), &buf,
374 dns_rootname, 0, NULL);
375 CHECK("dns_name_fromtext", result);
377 /* Make name happen */
378 dns_fixedname_init(&gssname);
379 isc_buffer_init(&buf, gssid, strlen(gssid));
380 isc_buffer_add(&buf, strlen(gssid));
381 result = dns_name_fromtext(dns_fixedname_name(&gssname), &buf,
382 dns_rootname, 0, NULL);
383 CHECK("dns_name_fromtext", result);
385 query = NULL;
386 result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
387 CHECK("dns_message_create", result);
389 printf("Calling gss_init_sec_context()\n");
390 gssctx = GSS_C_NO_CONTEXT;
391 result = dns_tkey_buildgssquery(query, dns_fixedname_name(&servername),
392 dns_fixedname_name(&gssname),
393 NULL, 36000, &gssctx, ISC_TRUE);
394 CHECK("dns_tkey_buildgssquery", result);
396 printf("Sending context token to server\n");
397 request = NULL;
398 result = dns_request_create(requestmgr, query, &address, 0, NULL,
399 TIMEOUT, task, initctx2, query, &request);
400 CHECK("dns_request_create", result);
402 return;
403 end:
404 event = isc_event_allocate(mctx, (void *)1, 1, console, NULL,
405 sizeof(*event));
406 isc_task_send(task, &event);return;
409 static void
410 setup(void)
412 struct in_addr inaddr;
413 int c;
415 while (1) {
416 printf("Server IP => ");
417 c = scanf("%s", serveraddress);
419 if(c == EOF || strcmp(serveraddress, "quit") == 0) {
420 isc_app_shutdown();
421 return;
424 if (inet_pton(AF_INET, serveraddress, &inaddr) == 1) {
425 isc_sockaddr_fromin(&address, &inaddr, PORT);
426 return;
433 main(int argc, char *argv[]) {
434 isc_taskmgr_t *taskmgr;
435 isc_timermgr_t *timermgr;
436 isc_socketmgr_t *socketmgr;
437 isc_socket_t *sock;
438 unsigned int attrs, attrmask;
439 isc_sockaddr_t bind_any;
440 dns_dispatchmgr_t *dispatchmgr;
441 dns_dispatch_t *dispatchv4;
442 dns_view_t *view;
443 isc_entropy_t *ectx;
444 isc_task_t *task;
445 isc_log_t *lctx = NULL;
446 isc_logconfig_t *lcfg = NULL;
447 isc_logdestination_t destination;
449 UNUSED(argv);
450 UNUSED(argc);
452 RUNCHECK(isc_app_start());
454 dns_result_register();
456 mctx = NULL;
457 RUNCHECK(isc_mem_create(0, 0, &mctx));
459 RUNCHECK(isc_log_create(mctx, &lctx, &lcfg));
460 isc_log_setcontext(lctx);
461 dns_log_init(lctx);
462 dns_log_setcontext(lctx);
465 * Create and install the default channel.
467 destination.file.stream = stderr;
468 destination.file.name = NULL;
469 destination.file.versions = ISC_LOG_ROLLNEVER;
470 destination.file.maximum_size = 0;
471 RUNCHECK(isc_log_createchannel(lcfg, "_default",
472 ISC_LOG_TOFILEDESC,
473 ISC_LOG_DYNAMIC,
474 &destination, ISC_LOG_PRINTTIME));
475 RUNCHECK(isc_log_usechannel(lcfg, "_default", NULL, NULL));
477 isc_log_setdebuglevel(lctx, 9);
479 ectx = NULL;
480 RUNCHECK(isc_entropy_create(mctx, &ectx));
481 RUNCHECK(isc_entropy_createfilesource(ectx, "/dev/urandom"));
483 RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY));
485 taskmgr = NULL;
486 RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
487 task = NULL;
488 RUNCHECK(isc_task_create(taskmgr, 0, &task));
489 timermgr = NULL;
490 RUNCHECK(isc_timermgr_create(mctx, &timermgr));
491 socketmgr = NULL;
492 RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
493 dispatchmgr = NULL;
494 RUNCHECK(dns_dispatchmgr_create(mctx, ectx, &dispatchmgr));
495 isc_sockaddr_any(&bind_any);
496 attrs = DNS_DISPATCHATTR_UDP |
497 DNS_DISPATCHATTR_MAKEQUERY |
498 DNS_DISPATCHATTR_IPV4;
499 attrmask = DNS_DISPATCHATTR_UDP |
500 DNS_DISPATCHATTR_TCP |
501 DNS_DISPATCHATTR_IPV4 |
502 DNS_DISPATCHATTR_IPV6;
503 dispatchv4 = NULL;
504 RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
505 &bind_any, 4096, 4, 2, 3, 5,
506 attrs, attrmask, &dispatchv4));
507 requestmgr = NULL;
508 RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
509 dispatchmgr, dispatchv4, NULL,
510 &requestmgr));
512 ring = NULL;
513 RUNCHECK(dns_tsigkeyring_create(mctx, &ring));
515 view = NULL;
516 RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
517 dns_view_setkeyring(view, ring);
519 sock = NULL;
520 RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp,
521 &sock));
523 setup();
525 RUNCHECK(isc_app_onrun(mctx, task, console, NULL));
527 (void)isc_app_run();
529 if (tsigkey)
530 dns_tsigkey_detach(&tsigkey);
532 dns_requestmgr_shutdown(requestmgr);
533 dns_requestmgr_detach(&requestmgr);
535 dns_dispatch_detach(&dispatchv4);
536 dns_dispatchmgr_destroy(&dispatchmgr);
538 isc_timermgr_destroy(&timermgr);
540 isc_task_detach(&task);
541 isc_taskmgr_destroy(&taskmgr);
543 isc_socket_detach(&sock);
544 isc_socketmgr_destroy(&socketmgr);
546 isc_mem_stats(mctx, stdout);
548 dns_view_detach(&view);
550 dst_lib_destroy();
551 isc_entropy_detach(&ectx);
553 isc_mem_stats(mctx, stdout);
554 isc_mem_destroy(&mctx);
556 isc_app_finish();
558 return (0);
560 #else
562 main(int argc, char *argv[]) {
563 UNUSED(argc);
564 UNUSED(argv);
565 fprintf(stderr, "R:GSSAPIONLY\n");
566 return (0);
568 #endif