diff options
Diffstat (limited to 'programs/lwdnsq/lookup.c')
-rw-r--r-- | programs/lwdnsq/lookup.c | 632 |
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(®ion, 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, ®ion); - - /* 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(®ion, 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, ®ion); - - 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(®ion, 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, ®ion); - 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: - * - */ |