summaryrefslogtreecommitdiff
path: root/programs/lwdnsq/lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'programs/lwdnsq/lookup.c')
-rw-r--r--programs/lwdnsq/lookup.c632
1 files changed, 0 insertions, 632 deletions
diff --git a/programs/lwdnsq/lookup.c b/programs/lwdnsq/lookup.c
deleted file mode 100644
index 700c4adbe..000000000
--- a/programs/lwdnsq/lookup.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * DNS KEY lookup helper
- * Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char lookup_c_version[] = "@(#) RCSID $Id: lookup.c,v 1.1 2004/03/15 20:35:28 as Exp $";
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <freeswan.h>
-
-#include <errno.h>
-#include <getopt.h>
-#include <setjmp.h>
-#include <ctype.h>
-#include <signal.h>
-
-#include <isc/mem.h>
-#include <isc/buffer.h>
-#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
-#include <dns/name.h>
-#include <lwres/netdb.h>
-#include <lwres/async.h>
-#include "lwdnsq.h"
-
-static int lwresd_has_spoken = 0;
-
-char *xstrdup(const char *s)
-{
- char *n;
-
- n = strdup(s);
- if(n == NULL) {
- abort();
- }
- return n;
-}
-
-void free_dl(dnskey_glob *gs, dnskey_lookup *dl)
-{
- dnskey_lookup **walk;
-
- walk = &gs->dns_outstanding;
- while(*walk!=NULL && *walk != dl)
- {
- walk = &((*walk)->next);
- }
- if(*walk != NULL)
- {
- /* if we exit with it non-null, then we
- * found a matching location, remove
- * it.
- */
- *walk = dl->next;
- dl->next = NULL;
- }
- gs->dns_inflight--;
-
- if(dl->tracking_id) {
- free(dl->tracking_id);
- dl->tracking_id = NULL;
- }
- if(dl->wantedtype_name) {
- free(dl->wantedtype_name);
- dl->wantedtype_name = NULL;
- }
- if(dl->fqdn) {
- free(dl->fqdn);
- dl->fqdn = NULL;
- }
-#if 0
- if(dl->last_cname_used) {
- dns_name_free(&dl->last_cname, gs->iscmem);
- }
-#endif
-
- free(dl);
-}
-
-void lookup_thing(dnskey_glob *gs,
- dns_rdatatype_t wantedtype,
- char *wantedtype_name,
- char *id,
- char *fqdn)
-{
- isc_mem_t *iscmem;
- isc_buffer_t *iscbuf;
- int success;
- dnskey_lookup *dl;
-
- iscmem=NULL;
- iscbuf=NULL;
- dl = malloc(sizeof(*dl));
- memset(dl, 0, sizeof(*dl));
-
- dl->tracking_id = strdup(id);
- dl->step = dkl_start;
-
- output_transaction_line(gs, id, 0, "START", NULL);
-
- success = lwres_getrrsetbyname_init(fqdn, dns_rdataclass_in,
- wantedtype, 0 /*flags*/,
- gs->lwctx, &dl->las);
-
- if(success != ERRSET_SUCCESS) {
- /* screwed: */
- output_transaction_line(gs, id, 0, "FATAL", "isc buffer error");
- return;
- }
-
- lwres_getrrsetbyname_xmit(gs->lwctx, &dl->las);
-
- dl->step = dkl_first;
- dl->wantedtype = wantedtype;
- dl->wantedtype_name = xstrdup(wantedtype_name);
- dl->fqdn = xstrdup(fqdn);
- dl->tracking_id = xstrdup(id);
-
- /* link it in */
- dl->next = gs->dns_outstanding;
- gs->dns_outstanding = dl;
-
- gs->dns_inflight++;
-
- return;
-}
-
-
-int setup_follow_possible_cname(dnskey_glob *gs,
- dnskey_lookup *dl)
-{
- int ret;
-
- dl->cname_count++;
-
- /*
- * If we are on an odd cycle (starting with 1),
- * then convert to dns_name_t so that we can compare later.
- *
- * This detects loops in the CNAME processing, while still
- * allowing an arbitrary number of CNAMEs to be followed.
- */
- if(dl->cname_count & 1)
- {
- isc_buffer_t fqdn_src;
- isc_buffer_t *fqdn_dst;
-
- if(dl->cname_count == 1)
- {
- memset(&dl->last_cname, 0, sizeof(dl->last_cname));
- dns_name_init(&dl->last_cname, NULL);
- }
- else
- {
- dns_name_reset(&dl->last_cname);
- }
-
- fqdn_dst=NULL;
-
- isc_buffer_init(&fqdn_src, dl->fqdn, strlen(dl->fqdn));
- isc_buffer_add(&fqdn_src, strlen(dl->fqdn));
-
- isc_buffer_allocate(gs->iscmem, &fqdn_dst, strlen(dl->fqdn)+1);
-
-#if 0
- if(dl->last_cname_used) {
- dns_name_free(&dl->last_cname, gs->iscmem);
- }
-#endif
- dl->last_cname_used = 1;
- if(dns_name_fromtext(&dl->last_cname,
- &fqdn_src,
- NULL,
- 1,
- fqdn_dst) != ISC_R_SUCCESS) {
- return 0;
- }
-
- /* something else here ? */
- }
-
- ret = lwres_getrrsetbyname_init(dl->fqdn, dns_rdataclass_in,
- dns_rdatatype_cname, 0 /*flags*/,
- gs->lwctx,
- &dl->las);
-
- if(ret != ERRSET_SUCCESS) {
- return 0;
- }
-
- lwres_getrrsetbyname_xmit(gs->lwctx, &dl->las);
-
- return 1;
-}
-
-
-/*
- * we asked for, and got a CNAME of some kind.
- */
-void process_step_cname(dnskey_glob *gs,
- dnskey_lookup *dl,
- struct rrsetinfo *ans,
- int success)
-{
- struct rdatainfo *ri;
- isc_region_t region;
- dns_rdata_t rd;
- dns_rdata_cname_t cn;
- char simplebuf[80];
- isc_buffer_t *cname_text;
- char cname_buf[DNS_NAME_MAXTEXT];
- /* char cname_buf2[DNS_NAME_MAXTEXT]; */
-
- switch(success) {
- case ERRSET_NONAME:
- case ERRSET_NODATA:
- /* no, no CNAME found, thing isn't there */
- snprintf(simplebuf, sizeof(simplebuf),
- "RR of type %s for %s was not found (tried CNAMEs)",
- dl->wantedtype_name,
- dl->fqdn);
- output_transaction_line(gs, dl->tracking_id, 0, "RETRY",
- simplebuf);
- dl->step = dkl_done;
- return;
-
- case 0:
- /* aha! found a CNAME */
- break;
-
- default:
- fatal:
- /* some other error */
- snprintf(simplebuf, sizeof(simplebuf), "err=%d", success);
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf);
- dl->step = dkl_done;
- return;
- }
-
- /*
- * now process out the CNAMEs, and look them up, one by one...
- * there should be only one... We just use the first one that works.
- */
-
- if(ans->rri_flags & RRSET_VALIDATED) {
- output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "OKAY");
- } else {
- output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "not present");
- }
-
- if(ans->rri_nrdatas != 1) {
- /* we got a number of CNAMEs different from 1! */
- success=0;
- snprintf(simplebuf, sizeof(simplebuf), "illegal number of CNAMES: %d", ans->rri_nrdatas);
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf);
- dl->step = dkl_done;
- return;
- }
-
- /* process first CNAME record */
- ri= &ans->rri_rdatas[0];
-
- memset(&region, 0, sizeof(region));
- memset(&rd, 0, sizeof(rd));
-
- region.base = ri->rdi_data;
- region.length = ri->rdi_length;
-
- dns_rdata_fromregion(&rd, dns_rdataclass_in,
- dns_rdatatype_cname, &region);
-
- /* we set mctx to NULL, which means that the tenure for
- * the stuff pointed to by cn will persist only as long
- * as rd persists.
- */
- if(dns_rdata_tostruct(&rd, &cn, NULL) != ISC_R_SUCCESS) {
- /* failed, try next return error */
- success=0;
- goto fatal;
- }
-
- cname_text=NULL;
- if(isc_buffer_allocate(gs->iscmem, &cname_text, DNS_NAME_MAXTEXT)) {
- success=0;
- goto fatal;
- }
-
- if(dns_name_totext(&cn.cname, ISC_TRUE, cname_text) !=
- ISC_R_SUCCESS) {
- success=0;
- goto fatal;
- }
-
- cname_buf[0]='\0';
- strncat(cname_buf,
- isc_buffer_base(cname_text),
- isc_buffer_usedlength(cname_text));
-
- /* free up buffer */
- isc_buffer_free(&cname_text);
-
- {
- /* add a trailing . */
- char *end;
- end = &cname_buf[strlen(cname_buf)];
- if(*end != '.') {
- strncat(cname_buf, ".", sizeof(cname_buf));
- }
- }
-
- /* format out a text version */
- output_transaction_line(gs, dl->tracking_id, 0, "CNAME", cname_buf);
- output_transaction_line(gs, dl->tracking_id, 0, "CNAMEFROM", dl->fqdn);
-
- /* check for loops in the CNAMEs! */
- if(dns_name_equal(&dl->last_cname, &cn.cname) == ISC_TRUE) {
- /* damn, we found a loop! */
- dl->step = dkl_done;
- return;
- }
-
- /* send new request. */
- /* okay, so look this new thing up */
- success = lwres_getrrsetbyname_init(cname_buf, dns_rdataclass_in,
- dl->wantedtype, 0 /*flags*/,
- gs->lwctx, &dl->las);
-
- if(success != ERRSET_SUCCESS) {
- return;
- }
-
- lwres_getrrsetbyname_xmit(gs->lwctx, &dl->las);
-
- dl->step = dkl_second;
-}
-
-void process_step_first(dnskey_glob *gs,
- dnskey_lookup *dl,
- struct rrsetinfo *ans,
- int success,
- int attempt) /* attempt = 0 first time, 1 after cname */
-{
- char simplebuf[132], typebuf[16];
- char txtbuf[1024];
- int i;
-
- switch(success) {
- case ERRSET_NODATA:
- if(attempt == 0) {
- lwresd_has_spoken = 1;
- setup_follow_possible_cname(gs, dl);
- dl->step = dkl_cname;
- return;
- }
- /* FALLTHROUGH */
- case ERRSET_NONAME:
- lwresd_has_spoken = 1;
- snprintf(simplebuf, sizeof(simplebuf),
- "RR of type %s for %s was not found",
- dl->wantedtype_name,
- dl->fqdn);
- output_transaction_line(gs, dl->tracking_id, 0, "RETRY",
- simplebuf);
- dl->step = dkl_done;
- goto done;
-
- case ERRSET_NOMEMORY:
- snprintf(simplebuf, sizeof(simplebuf),
- "ran out of memory while looking up RR of type %s for %s",
- dl->wantedtype_name, dl->fqdn);
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf);
- dl->step = dkl_done;
- goto done;
-
- case ERRSET_FAIL:
- snprintf(simplebuf, sizeof(simplebuf),
- "unspecified failure while looking up RR of type %s for %s%s",
- dl->wantedtype_name, dl->fqdn,
- lwresd_has_spoken ? "" : " (is lwresd running?)");
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf);
- dl->step = dkl_done;
- goto done;
-
- case ERRSET_INVAL:
- snprintf(simplebuf, sizeof(simplebuf),
- "invalid input while looking up RR of type %s for %s",
- dl->wantedtype_name, dl->fqdn);
- output_transaction_line(gs, dl->tracking_id, 0, "RETRY", simplebuf);
- dl->step = dkl_done;
- goto done;
-
- default:
- snprintf(simplebuf, sizeof(simplebuf), " unknown error %d", success);
- output_transaction_line(gs, dl->tracking_id, 0, "RETRY", simplebuf);
- dl->step = dkl_done;
- done:
- return;
-
- case 0:
- /* everything okay */
- lwresd_has_spoken = 1;
- dl->step = dkl_done;
- break;
- }
-
- /* output the rest of the data */
-
- if(ans->rri_flags & RRSET_VALIDATED) {
- output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "OKAY");
- snprintf(typebuf, sizeof(typebuf), "AD-%s", dl->wantedtype_name);
- if(dl->wantedtype_name) free(dl->wantedtype_name);
- dl->wantedtype_name=xstrdup(typebuf);
- } else {
- output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "not present");
- }
-
- output_transaction_line(gs, dl->tracking_id, 0, "NAME", ans->rri_name);
-
- for(i=0; i<ans->rri_nrdatas; i++) {
- struct rdatainfo *ri = &ans->rri_rdatas[i];
- isc_region_t region;
- dns_rdata_t rd;
-
- isc_buffer_clear(gs->iscbuf);
- memset(&region, 0, sizeof(region));
- memset(&rd, 0, sizeof(rd));
-
- region.base = ri->rdi_data;
- region.length = ri->rdi_length;
-
- if(dl->wantedtype == dns_rdatatype_txt) {
- /* special treatment for TXT records */
- unsigned int len, rdatalen, totlen;
- unsigned char *txtp, *rdata;
-
- txtp = txtbuf;
- totlen = 0;
- rdatalen = ri->rdi_length;
- rdata = ri->rdi_data;
-
- while(rdatalen > 0) {
- len= (unsigned)rdata[0];
- memcpy(txtp, rdata+1, len);
- totlen += len;
- txtp += len;
- rdata += len+1;
- rdatalen -= len+1;
- }
- *txtp = '\0';
-
- output_transaction_line_limited(gs, dl->tracking_id, 0,
- dl->wantedtype_name,
- totlen, txtbuf);
-
- } else {
- dns_rdata_fromregion(&rd, dns_rdataclass_in,
- dl->wantedtype, &region);
-
- if(dns_rdata_totext(&rd, NULL, gs->iscbuf) != ISC_R_SUCCESS) {
-
- }
-
- output_transaction_line_limited(gs, dl->tracking_id, 0,
- dl->wantedtype_name,
- (int)isc_buffer_usedlength(gs->iscbuf),
- (char *)isc_buffer_base(gs->iscbuf));
- }
- }
-
- for(i=0; i<ans->rri_nsigs; i++) {
- struct rdatainfo *ri = &ans->rri_sigs[i];
- isc_region_t region;
- dns_rdata_t rd;
-
- isc_buffer_clear(gs->iscbuf);
- memset(&region, 0, sizeof(region));
- memset(&rd, 0, sizeof(rd));
-
- region.base = ri->rdi_data;
- region.length = ri->rdi_length;
-
- dns_rdata_fromregion(&rd, dns_rdataclass_in,
- dns_rdatatype_sig, &region);
- if(dns_rdata_totext(&rd, NULL, gs->iscbuf) != ISC_R_SUCCESS) {
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", "isc totext error");
- return;
- }
-
- output_transaction_line_limited(gs, dl->tracking_id, 0, "SIG",
- (int)isc_buffer_usedlength(gs->iscbuf),
- (char *)isc_buffer_base(gs->iscbuf));
- }
-}
-
-
-
-void lookup_step(dnskey_glob *gs,
- dnskey_lookup *dl,
- struct rrsetinfo *ans,
- int success)
-{
- /* char simplebuf[80]; */
- int nextstate;
-
- nextstate = dkl_done;
-
- if(dl == NULL)
- {
- return;
- }
-
- switch(dl->step)
- {
- case dkl_start:
- /* first request done, why are still in this state? */
- break;
-
- case dkl_first:
- /* okay, got the reply from the first step! */
- process_step_first(gs, dl, ans, success, 0);
- nextstate = dl->step;
- break;
-
- case dkl_cname:
- /*
- * we asked for a cname, and we have some result to deal
- * with here.
- */
- process_step_cname(gs, dl, ans, success);
- nextstate = dl->step;
- break;
-
- case dkl_second:
- /*
- * we had asked for something, for a cname, and we followed
- * it, and we'll see what we got back.
- */
- process_step_first(gs, dl, ans, success, 1);
- nextstate = dl->step;
- break;
-
- case dkl_done:
- /* this should not happen, really, just book keeping, so,
- * just free up the structure, and return.
- */
- nextstate = dl->step;
- return;
- }
-
-
- /* we have been through, made a state transition, if we are
- * done, then do that.
- */
- if(nextstate == dkl_done)
- {
- output_transaction_line(gs, dl->tracking_id, 0, "DONE", NULL);
- free_dl(gs, dl);
- dl=NULL;
- }
- return;
-}
-
-void process_dns_reply(dnskey_glob *gs)
-{
- dnskey_lookup *dl;
- struct lwres_async_state *plas;
- struct rrsetinfo *res;
- int success;
-
- plas = NULL;
-
- success = lwres_getrrsetbyname_read(&plas, gs->lwctx, &res);
-
- /* cast answer back to dnskey_lookup structure */
- dl = (dnskey_lookup *)plas;
-
- if(success == LWRES_R_RETRY) {
- /* XXX we got something from some other weird place!
- * transmit again, in the hope of getting the right answer
- */
- dl->retry_count--;
- if(dl->retry_count > 0) {
- lwres_getrrsetbyname_xmit(gs->lwctx, plas);
- } else {
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", "too many retries");
- free_dl(gs, dl);
- }
- return;
- }
-
- /* perform next step for this one */
- lookup_step(gs, dl, res, success);
-}
-
-/*
- * $Log: lookup.c,v $
- * Revision 1.1 2004/03/15 20:35:28 as
- * added files from freeswan-2.04-x509-1.5.3
- *
- * Revision 1.3 2003/09/18 02:17:39 mcr
- * if we have tried a CNAME lookup, then take a NODATA
- * reply as a no-name.
- *
- * Revision 1.2 2003/09/10 17:55:14 mcr
- * the CNAME message had the s removed, which changes test
- * results gratuitously.
- *
- * Revision 1.1 2003/09/03 01:13:24 mcr
- * first attempt at async capable lwdnsq.
- *
- *
- * Local variables:
- * c-file-style: "linux"
- * c-basic-offset: 2
- * End:
- *
- */