1609. [func] dig now has support to chase DNSSEC signature chains.

Requires -DDIG_SIGCHASE=1 to be set in STD_CDEFINES.
This commit is contained in:
Mark Andrews 2004-04-13 02:39:35 +00:00
parent ea17e96977
commit 1ae75c1024
9 changed files with 2564 additions and 67 deletions

View file

@ -1,3 +1,6 @@
1609. [func] dig now has support to chase DNSSEC signature chains.
Requires -DDIG_SIGCHASE=1 to be set in STD_CDEFINES.
1608. [func] dig and host now accept -4/-6 to select IP transport
to use when making queries.

5
README
View file

@ -237,7 +237,10 @@ Building
Possible settings:
Change the default syslog facility of named/lwresd.
e.g. -DISC_FACILITY=LOG_LOCAL0
-DISC_FACILITY=LOG_LOCAL0
Enable DNSSEC signature chasing support in dig.
-DDIG_SIGCHASE=1 (sets -DDIG_SIGCHASE_TD=1 and
-DDIG_SIGCHASE_BU=1)
To build shared libraries, specify "--with-libtool" on the
configure command line.

View file

@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.33 2004/03/05 04:57:29 marka Exp $
# $Id: Makefile.in,v 1.34 2004/04/13 02:39:33 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@ -27,6 +27,7 @@ CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} ${BIND9_INCLUDES} \
${ISC_INCLUDES} ${LWRES_INCLUDES}
CDEFINES = -DVERSION=\"${VERSION}\"
CWARNINGS =
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
@ -96,4 +97,6 @@ install:: dig@EXEEXT@ host@EXEEXT@ nslookup@EXEEXT@ installdirs
host@EXEEXT@ ${DESTDIR}${bindir}
${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \
nslookup@EXEEXT@ ${DESTDIR}${bindir}
for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man1; done
for m in ${MANPAGES}; do \
${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man1; \
done

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dig.c,v 1.187 2004/04/13 01:09:36 marka Exp $ */
/* $Id: dig.c,v 1.188 2004/04/13 02:39:34 marka Exp $ */
#include <config.h>
#include <stdlib.h>
@ -43,6 +43,15 @@
#include <dig/dig.h>
#ifdef DIG_SIGCHASE
#ifndef DIG_SIGCHASE_BU
#define DIG_SIGCHASE_BU 1
#endif
#ifndef DIG_SIGCHASE_TD
#define DIG_SIGCHASE_TD 1
#endif
#endif
extern ISC_LIST(dig_lookup_t) lookup_list;
extern dig_serverlist_t server_list;
extern ISC_LIST(dig_searchlist_t) search_list;
@ -69,6 +78,9 @@ extern isc_sockaddr_t bind_address;
extern char keynametext[MXNAME];
extern char keyfile[MXNAME];
extern char keysecret[MXNAME];
#ifdef DIG_SIGCHASE
extern char trustedkey[MXNAME];
#endif
extern dns_tsigkey_t *key;
extern isc_boolean_t validated;
extern isc_taskmgr_t *taskmgr;
@ -205,6 +217,13 @@ help(void) {
" +[no]identify (ID responders in short answers)\n"
" +[no]trace (Trace delegation down from root)\n"
" +[no]dnssec (Request DNSSEC records)\n"
#ifdef DIG_SIGCHASE
" +[no]sigchase (Chase DNSSEC signatures)\n"
" +trusted-key=#### (Trusted Key when chasing DNSSEC sigs)\n"
#if DIG_SIGCHASE_TD
" +[no]topdown (Do DNSSEC validation top down mode)\n"
#endif
#endif
" +[no]multiline (Print records in an expanded format)\n"
" global d-opts and servers (before host name) affect all queries.\n"
" local d-opts and servers (after host name) affect only that lookup.\n"
@ -350,6 +369,51 @@ short_answer(dns_message_t *msg, dns_messagetextflag_t flags,
return (ISC_R_SUCCESS);
}
#ifdef DIG_SIGCHASE
isc_result_t
printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset,
isc_buffer_t *target)
{
isc_result_t result;
dns_master_style_t *style = NULL;
unsigned int styleflags = 0;
if (rdataset == NULL || owner_name == NULL || target == NULL)
return(ISC_FALSE);
styleflags |= DNS_STYLEFLAG_REL_OWNER;
if (nottl)
styleflags |= DNS_STYLEFLAG_NO_TTL;
if (noclass)
styleflags |= DNS_STYLEFLAG_NO_CLASS;
if (multiline) {
styleflags |= DNS_STYLEFLAG_OMIT_OWNER;
styleflags |= DNS_STYLEFLAG_OMIT_CLASS;
styleflags |= DNS_STYLEFLAG_REL_DATA;
styleflags |= DNS_STYLEFLAG_OMIT_TTL;
styleflags |= DNS_STYLEFLAG_TTL;
styleflags |= DNS_STYLEFLAG_MULTILINE;
styleflags |= DNS_STYLEFLAG_COMMENT;
}
if (multiline || (nottl && noclass))
result = dns_master_stylecreate(&style, styleflags,
24, 24, 24, 32, 80, 8, mctx);
else if (nottl || noclass)
result = dns_master_stylecreate(&style, styleflags,
24, 24, 32, 40, 80, 8, mctx);
else
result = dns_master_stylecreate(&style, styleflags,
24, 32, 40, 48, 80, 8, mctx);
check_result(result, "dns_master_stylecreate");
result = dns_master_rdatasettotext(owner_name, rdataset, style, target);
if (style != NULL)
dns_master_styledestroy(&style, mctx);
return(result);
}
#endif
/*
* Callback from dighost.c to print the reply from a server
@ -450,8 +514,7 @@ printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
repopulate_buffer:
if (query->lookup->comments && headers && !short_form)
{
if (query->lookup->comments && headers && !short_form) {
result = dns_message_pseudosectiontotext(msg,
DNS_PSEUDOSECTION_OPT,
style, flags, buf);
@ -649,17 +712,20 @@ plus_option(char *option, isc_boolean_t is_batchfile,
char option_store[256];
char *cmd, *value, *ptr;
isc_boolean_t state = ISC_TRUE;
#ifdef DIG_SIGCHASE
size_t n;
#endif
strncpy(option_store, option, sizeof(option_store));
option_store[sizeof(option_store)-1]=0;
ptr = option_store;
cmd = next_token(&ptr,"=");
if (cmd == NULL) {
printf(";; Invalid option %s\n",option_store);
printf(";; Invalid option %s\n", option_store);
return;
}
value = ptr;
if (strncasecmp(cmd,"no",2)==0) {
if (strncasecmp(cmd, "no", 2)==0) {
cmd += 2;
state = ISC_FALSE;
}
@ -899,6 +965,14 @@ plus_option(char *option, isc_boolean_t is_batchfile,
lookup->stats = ISC_FALSE;
}
break;
#ifdef DIG_SIGCHASE
case 'i': /* sigchase */
FULLCHECK("sigchase");
lookup->sigchase = state;
if (lookup->sigchase)
lookup->dnssec = ISC_TRUE;
break;
#endif
case 't': /* stats */
FULLCHECK("stats");
lookup->stats = state;
@ -924,6 +998,12 @@ plus_option(char *option, isc_boolean_t is_batchfile,
if (timeout == 0)
timeout = 1;
break;
#if DIG_SIGCHASE_TD
case 'o': /* topdown */
FULLCHECK("topdown");
lookup->do_topdown = state;
break;
#endif
case 'r':
switch (cmd[2]) {
case 'a': /* trace */
@ -937,7 +1017,7 @@ plus_option(char *option, isc_boolean_t is_batchfile,
lookup->stats = ISC_FALSE;
lookup->section_additional = ISC_FALSE;
lookup->section_authority = ISC_TRUE;
lookup->section_question = ISC_FALSE;
lookup->section_question = ISC_FALSE;
}
break;
case 'i': /* tries */
@ -947,10 +1027,22 @@ plus_option(char *option, isc_boolean_t is_batchfile,
if (!state)
goto invalid_option;
lookup->retries = parse_uint(value, "tries",
MAXTRIES);
MAXTRIES);
if (lookup->retries == 0)
lookup->retries = 1;
break;
#ifdef DIG_SIGCHASE
case 'u': /* trusted-key */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
n = strlcpy(trustedkey, ptr,
sizeof(trustedkey));
if (n >= sizeof(trustedkey))
fatal("trusted key too large");
break;
#endif
default:
goto invalid_option;
}
@ -1049,8 +1141,9 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
case 'b':
hash = strchr(value, '#');
if (hash != NULL) {
srcport = (in_port_t) parse_uint(hash + 1,
"port number", MAXPORT);
srcport = (in_port_t)
parse_uint(hash + 1,
"port number", MAXPORT);
*hash = '\0';
} else
srcport = 0;
@ -1105,8 +1198,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
result = dns_rdatatype_fromtext(&rdtype,
(isc_textregion_t *)&tr);
if (result == ISC_R_SUCCESS &&
rdtype == dns_rdatatype_ixfr)
{
rdtype == dns_rdatatype_ixfr) {
result = DNS_R_UNKNOWN;
}
}
@ -1153,8 +1245,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
case 'x':
*lookup = clone_lookup(default_lookup, ISC_TRUE);
if (get_reverse(textname, sizeof(textname), value,
ip6_int, ISC_FALSE) == ISC_R_SUCCESS)
{
ip6_int, ISC_FALSE) == ISC_R_SUCCESS) {
strncpy((*lookup)->textname, textname,
sizeof((*lookup)->textname));
debug("looking up %s", (*lookup)->textname);
@ -1166,8 +1257,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
if (!(*lookup)->rdclassset)
(*lookup)->rdclass = dns_rdataclass_in;
(*lookup)->new_search = ISC_TRUE;
if (*lookup && *firstarg)
{
if (*lookup && *firstarg) {
printgreeting(argc, argv, *lookup);
*firstarg = ISC_FALSE;
}
@ -1333,8 +1423,7 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only,
result = dns_rdatatype_fromtext(&rdtype,
(isc_textregion_t *)&tr);
if (result == ISC_R_SUCCESS &&
rdtype == dns_rdatatype_ixfr)
{
rdtype == dns_rdatatype_ixfr) {
result = DNS_R_UNKNOWN;
fprintf(stderr, ";; Warning, "
"ixfr requires a "
@ -1548,6 +1637,9 @@ main(int argc, char **argv) {
fclose(batchfp);
batchname = NULL;
}
#ifdef DIG_SIGCHASE
clean_trustedkey();
#endif
cancel_all();
destroy_libs();
isc_app_finish();

View file

@ -16,7 +16,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: dig.docbook,v 1.18 2004/04/13 01:09:36 marka Exp $ -->
<!-- $Id: dig.docbook,v 1.19 2004/04/13 02:39:34 marka Exp $ -->
<refentry>
@ -483,29 +483,46 @@ Print records like the SOA records in a verbose multi-line
format with human-readable comments. The default is to print
each record on a single line, to facilitate machine parsing
of the <command>dig</command> output.
</para>
</listitem></varlistentry>
</para></listitem></varlistentry>
<varlistentry><term><option>+[no]fail</option></term>
<listitem><para>
Do not try the next server if you receive a SERVFAIL. The default is
to not try the next server which is the reverse of normal stub resolver
behaviour.
</para>
</para></listitem></varlistentry>
</listitem></varlistentry>
<varlistentry><term><option>+[no]besteffort</option></term>
<listitem><para>
Attempt to display the contents of messages which are malformed.
The default is to not display malformed answers.
</para>
</para></listitem></varlistentry>
</listitem></varlistentry>
<varlistentry><term><option>+[no]dnssec</option></term>
<listitem><para>
Requests DNSSEC records be sent by setting the DNSSEC OK bit (DO)
in the OPT record in the additional section of the query.
</para>
</para></listitem></varlistentry>
<varlistentry><term><option>+[no]sigchase</option></term>
<listitem><para>
Chase DNSSEC signature chains. Requires dig be compiled with
-DDIG_SIGCHASE.
</para></listitem></varlistentry>
<varlistentry><term><option>+trusted-key=####</option></term>
<listitem><para>
Specify a trusted key to be used with <option>+sigchase</option>.
Requires dig be compiled with -DDIG_SIGCHASE.
</para></listitem></varlistentry>
<varlistentry><term><option>+[no]topdown</option></term>
<listitem><para>
When chasing DNSSEC signature chains perform a top down validation.
Requires dig be compiled with -DDIG_SIGCHASE.
</para></listitem></varlistentry>
</variablelist>

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: host.c,v 1.95 2004/04/13 01:09:37 marka Exp $ */
/* $Id: host.c,v 1.96 2004/04/13 02:39:35 marka Exp $ */
#include <config.h>
#include <limits.h>
@ -209,8 +209,18 @@ say_message(dns_name_t *name, const char *msg, dns_rdata_t *rdata,
printf("\n");
isc_buffer_free(&b);
}
#ifdef _SIGCHASE_
/* Just for compatibility : not use in host program */
isc_result_t
printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset,
isc_buffer_t *target)
{
UNUSED(owner_name);
UNUSED(rdataset);
UNUSED(target);
return(ISC_FALSE);
}
#endif
static isc_result_t
printsection(dns_message_t *msg, dns_section_t sectionid,
const char *section_name, isc_boolean_t headers,
@ -698,8 +708,7 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
lookup->pending = ISC_FALSE;
if (get_reverse(store, sizeof(store), hostname,
lookup->ip6_int, ISC_TRUE) == ISC_R_SUCCESS)
{
lookup->ip6_int, ISC_TRUE) == ISC_R_SUCCESS) {
strncpy(lookup->textname, store, sizeof(lookup->textname));
lookup->textname[sizeof(lookup->textname)-1] = 0;
lookup->rdtype = dns_rdatatype_ptr;

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dig.h,v 1.82 2004/03/05 04:57:34 marka Exp $ */
/* $Id: dig.h,v 1.83 2004/04/13 02:39:35 marka Exp $ */
#ifndef DIG_H
#define DIG_H
@ -79,6 +79,9 @@ ISC_LANG_BEGINDECLS
typedef struct dig_lookup dig_lookup_t;
typedef struct dig_query dig_query_t;
typedef struct dig_server dig_server_t;
#ifdef _SIGCHASE_
typedef struct dig_message dig_message_t;
#endif
typedef ISC_LIST(dig_server_t) dig_serverlist_t;
typedef struct dig_searchlist dig_searchlist_t;
@ -110,10 +113,27 @@ struct dig_lookup {
new_search,
besteffort,
dnssec;
#ifdef _SIGCHASE_
isc_boolean_t sigchase;
#ifdef _SIGCHASE_TD_
isc_boolean_t do_topdown,
trace_root_sigchase,
rdtype_sigchaseset,
rdclass_sigchaseset;
/* Name we are going to validate RRset */
char textnamesigchase[MXNAME];
#endif
#endif
char textname[MXNAME]; /* Name we're going to be looking up */
char cmdline[MXNAME];
dns_rdatatype_t rdtype;
dns_rdatatype_t qrdtype;
#ifdef _SIGCHASE_TD_
dns_rdatatype_t rdtype_sigchase;
dns_rdatatype_t qrdtype_sigchase;
dns_rdataclass_t rdclass_sigchase;
#endif
dns_rdataclass_t rdclass;
isc_boolean_t rdtypeset;
isc_boolean_t rdclassset;
@ -183,7 +203,12 @@ struct dig_searchlist {
char origin[MXNAME];
ISC_LINK(dig_searchlist_t) link;
};
#ifdef _SIGCHASE_
struct dig_message {
dns_message_t *msg;
ISC_LINK(dig_message_t) link;
};
#endif
/*
* Routines in dighost.c.
*/
@ -255,9 +280,19 @@ destroy_libs(void);
void
set_search_domain(char *domain);
#ifdef _SIGCHASE_
void
clean_trustedkey(void);
#endif
/*
* Routines to be defined in dig.c, host.c, and nslookup.c.
*/
#ifdef _SIGCHASE_
isc_result_t
printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset,
isc_buffer_t *target);
#endif
isc_result_t
printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers);
@ -282,6 +317,14 @@ dighost_shutdown(void);
char *
next_token(char **stringp, const char *delim);
#ifdef _SIGCHASE_
/* Chasing functions */
dns_rdataset_t *
chase_scanname(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers);
void
chase_sig(dns_message_t *msg);
#endif
ISC_LANG_ENDDECLS
#endif

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: nslookup.c,v 1.101 2004/03/05 04:57:30 marka Exp $ */
/* $Id: nslookup.c,v 1.102 2004/04/13 02:39:35 marka Exp $ */
#include <config.h>
@ -189,7 +189,18 @@ printa(dns_rdata_t *rdata) {
printf("Address: %.*s\n", (int)isc_buffer_usedlength(&b),
(char *)isc_buffer_base(&b));
}
#ifdef _SIGCHASE_
/* Just for compatibility : not use in host program */
isc_result_t
printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset,
isc_buffer_t *target)
{
UNUSED(owner_name);
UNUSED(rdataset);
UNUSED(target);
return(ISC_FALSE);
}
#endif
static void
printrdata(dns_rdata_t *rdata) {
isc_result_t result;
@ -520,7 +531,8 @@ safecpy(char *dest, char *src, int size) {
}
static isc_result_t
parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max, const char *desc) {
parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
const char *desc) {
isc_uint32_t n;
isc_result_t result = isc_parse_uint32(&n, value, 10);
if (result == ISC_R_SUCCESS && n > max)
@ -663,8 +675,7 @@ addlookup(char *opt) {
}
lookup = make_empty_lookup();
if (get_reverse(store, sizeof(store), opt, lookup->ip6_int, ISC_TRUE)
== ISC_R_SUCCESS)
{
== ISC_R_SUCCESS) {
safecpy(lookup->textname, store, sizeof(lookup->textname));
lookup->rdtype = dns_rdatatype_ptr;
lookup->rdtypeset = ISC_TRUE;
@ -732,15 +743,13 @@ get_next_command(void) {
in_use = ISC_FALSE;
goto cleanup;
} else if (strcasecmp(ptr, "help") == 0 ||
strcasecmp(ptr, "?") == 0)
{
strcasecmp(ptr, "?") == 0) {
printf("The '%s' command is not yet implemented.\n", ptr);
goto cleanup;
} else if (strcasecmp(ptr, "finger") == 0 ||
strcasecmp(ptr, "root") == 0 ||
strcasecmp(ptr, "ls") == 0 ||
strcasecmp(ptr, "view") == 0)
{
strcasecmp(ptr, "view") == 0) {
printf("The '%s' command is not implemented.\n", ptr);
goto cleanup;
} else