diff --git a/CHANGES b/CHANGES index f10bdedfab..782d57bfed 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2679. [func] dig -k can now accept TSIG keys in named.conf + format. [RT #20031] + 2678. [func] Treat DS queries as if "minimal-response yes;" was set. [RT #20258] @@ -12,7 +15,7 @@ signing but is still published. - The "unpublished" date (-U) is deprecated in favor of "deleted" (-D). - [rt20247] + [RT #20247] 2676. [bug] --with-export-installdir should have been --with-export-includedir. [RT #20252] diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in index 3cb1bd1fb4..6021a5f96c 100644 --- a/bin/dig/Makefile.in +++ b/bin/dig/Makefile.in @@ -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.44 2009/09/02 23:48:01 tbox Exp $ +# $Id: Makefile.in,v 1.45 2009/09/15 03:13:43 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} ${BIND9_INCLUDES} \ - ${ISC_INCLUDES} ${LWRES_INCLUDES} + ${ISC_INCLUDES} ${LWRES_INCLUDES} ${ISCCFG_INCLUDES} CDEFINES = -DBIND9 -DVERSION=\"${VERSION}\" CWARNINGS = @@ -45,8 +45,8 @@ LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} \ ${LWRESDEPLIBS} -LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} \ - ${ISCCFGLIBS} @IDNLIBS@ @LIBS@ +LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ + ${ISCLIBS} @IDNLIBS@ @LIBS@ NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCNOSYMLIBS} \ ${ISCCFGLIBS} @IDNLIBS@ @LIBS@ diff --git a/bin/dig/dig.c b/bin/dig/dig.c index ad9269f51f..56165b771e 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dig.c,v 1.229 2009/05/06 10:16:32 fdupont Exp $ */ +/* $Id: dig.c,v 1.230 2009/09/15 03:13:43 each Exp $ */ /*! \file */ @@ -671,19 +671,6 @@ printgreeting(int argc, char **argv, dig_lookup_t *lookup) { } } -static isc_uint32_t -parse_uint(char *arg, const char *desc, isc_uint32_t max) { - isc_result_t result; - isc_uint32_t tmp; - - result = isc_parse_uint32(&tmp, arg, 10); - if (result == ISC_R_SUCCESS && tmp > max) - result = ISC_R_RANGE; - if (result != ISC_R_SUCCESS) - fatal("%s '%s': %s", desc, arg, isc_result_totext(result)); - return (tmp); -} - /*% * We're not using isc_commandline_parse() here since the command line * syntax of dig is quite a bit different from that which can be described @@ -695,8 +682,10 @@ static void plus_option(char *option, isc_boolean_t is_batchfile, dig_lookup_t *lookup) { + isc_result_t result; char option_store[256]; char *cmd, *value, *ptr; + isc_uint32_t num; isc_boolean_t state = ISC_TRUE; #ifdef DIG_SIGCHASE size_t n; @@ -785,8 +774,11 @@ plus_option(char *option, isc_boolean_t is_batchfile, goto need_value; if (!state) goto invalid_option; - lookup->udpsize = (isc_uint16_t) parse_uint(value, - "buffer size", COMMSIZE); + result = parse_uint(&num, value, COMMSIZE, + "buffer size"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse buffer size"); + lookup->udpsize = num; break; default: goto invalid_option; @@ -851,7 +843,10 @@ plus_option(char *option, isc_boolean_t is_batchfile, } if (value == NULL) goto need_value; - lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255); + result = parse_uint(&num, value, 255, "edns"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse edns"); + lookup->edns = num; break; case 'f': /* fail */ FULLCHECK("fail"); @@ -881,7 +876,10 @@ plus_option(char *option, isc_boolean_t is_batchfile, goto need_value; if (!state) goto invalid_option; - ndots = parse_uint(value, "ndots", MAXNDOTS); + result = parse_uint(&num, value, MAXNDOTS, "ndots"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse ndots"); + ndots = num; break; case 's': switch (cmd[2]) { @@ -946,8 +944,10 @@ plus_option(char *option, isc_boolean_t is_batchfile, goto need_value; if (!state) goto invalid_option; - lookup->retries = parse_uint(value, "retries", - MAXTRIES - 1); + result = parse_uint(&lookup->retries, value, + MAXTRIES - 1, "retries"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse retries"); lookup->retries++; break; default: @@ -1023,7 +1023,10 @@ plus_option(char *option, isc_boolean_t is_batchfile, goto need_value; if (!state) goto invalid_option; - timeout = parse_uint(value, "timeout", MAXTIMEOUT); + result = parse_uint(&timeout, value, MAXTIMEOUT, + "timeout"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse timeout"); if (timeout == 0) timeout = 1; break; @@ -1056,8 +1059,10 @@ plus_option(char *option, isc_boolean_t is_batchfile, goto need_value; if (!state) goto invalid_option; - lookup->retries = parse_uint(value, "tries", - MAXTRIES); + result = parse_uint(&lookup->retries, value, + MAXTRIES, "tries"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse tries"); if (lookup->retries == 0) lookup->retries = 1; break; @@ -1123,6 +1128,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, struct in6_addr in6; in_port_t srcport; char *hash, *cmd; + isc_uint32_t num; while (strpbrk(option, single_dash_opts) == &option[0]) { /* @@ -1197,9 +1203,11 @@ 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); + result = parse_uint(&num, hash + 1, MAXPORT, + "port number"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse port number"); + srcport = num; *hash = '\0'; } else srcport = 0; @@ -1243,7 +1251,10 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, keyfile[sizeof(keyfile)-1]=0; return (value_from_next); case 'p': - port = (in_port_t) parse_uint(value, "port number", MAXPORT); + result = parse_uint(&num, value, MAXPORT, "port number"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse port number"); + port = num; return (value_from_next); case 'q': if (!config_only) { @@ -1286,11 +1297,14 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, "extra type option\n"); } if (rdtype == dns_rdatatype_ixfr) { + isc_uint32_t serial; (*lookup)->rdtype = dns_rdatatype_ixfr; (*lookup)->rdtypeset = ISC_TRUE; - (*lookup)->ixfr_serial = - parse_uint(&value[5], "serial number", - MAXSERIAL); + result = parse_uint(&serial, &value[5], + MAXSERIAL, "serial number"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse serial number"); + (*lookup)->ixfr_serial = serial; (*lookup)->section_question = plusquest; (*lookup)->comments = pluscomm; (*lookup)->tcp_mode = ISC_TRUE; @@ -1318,65 +1332,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, usage(); ptr3 = next_token(&value,":"); /* secret or NULL */ if (ptr3 != NULL) { - if (strcasecmp(ptr, "hmac-md5") == 0) { - hmacname = DNS_TSIG_HMACMD5_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-md5-", 9) == 0) { - hmacname = DNS_TSIG_HMACMD5_NAME; - digestbits = parse_uint(&ptr[9], - "digest-bits [0..128]", - 128); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha1") == 0) { - hmacname = DNS_TSIG_HMACSHA1_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha1-", 10) == 0) { - hmacname = DNS_TSIG_HMACSHA1_NAME; - digestbits = parse_uint(&ptr[10], - "digest-bits [0..160]", - 160); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha224") == 0) { - hmacname = DNS_TSIG_HMACSHA224_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha224-", 12) == 0) { - hmacname = DNS_TSIG_HMACSHA224_NAME; - digestbits = parse_uint(&ptr[12], - "digest-bits [0..224]", - 224); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha256") == 0) { - hmacname = DNS_TSIG_HMACSHA256_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha256-", 12) == 0) { - hmacname = DNS_TSIG_HMACSHA256_NAME; - digestbits = parse_uint(&ptr[12], - "digest-bits [0..256]", - 256); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha384") == 0) { - hmacname = DNS_TSIG_HMACSHA384_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha384-", 12) == 0) { - hmacname = DNS_TSIG_HMACSHA384_NAME; - digestbits = parse_uint(&ptr[12], - "digest-bits [0..384]", - 384); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha512") == 0) { - hmacname = DNS_TSIG_HMACSHA512_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha512-", 12) == 0) { - hmacname = DNS_TSIG_HMACSHA512_NAME; - digestbits = parse_uint(&ptr[12], - "digest-bits [0..512]", - 512); - digestbits = (digestbits + 7) & ~0x7U; - } else { - fprintf(stderr, ";; Warning, ignoring " - "invalid TSIG algorithm %s\n", ptr); - return (value_from_next); - } + parse_hmac(ptr); ptr = ptr2; ptr2 = ptr3; } else { @@ -1624,13 +1580,18 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, "extra type option\n"); } if (rdtype == dns_rdatatype_ixfr) { + isc_uint32_t serial; lookup->rdtype = dns_rdatatype_ixfr; lookup->rdtypeset = ISC_TRUE; - lookup->ixfr_serial = - parse_uint(&rv[0][5], - "serial number", - MAXSERIAL); + result = parse_uint(&serial, + &rv[0][5], + MAXSERIAL, + "serial number"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse " + "serial number"); + lookup->ixfr_serial = serial; lookup->section_question = plusquest; lookup->comments = pluscomm; diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index f1fa25ef7b..4b6764dda9 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.324 2009/09/01 00:22:24 jinmei Exp $ */ +/* $Id: dighost.c,v 1.325 2009/09/15 03:13:43 each Exp $ */ /*! \file * \note @@ -53,6 +53,7 @@ #include #endif #include +#include #include #include #include @@ -71,10 +72,12 @@ #include #include #include +#include #include #ifdef DIG_SIGCHASE #include #endif +#include #include #include #include @@ -84,6 +87,8 @@ #include #include +#include + #include #include @@ -121,6 +126,7 @@ in_port_t port = 53; unsigned int timeout = 0; unsigned int extrabytes; isc_mem_t *mctx = NULL; +isc_log_t *lctx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_task_t *global_task = NULL; isc_timermgr_t *timermgr = NULL; @@ -940,15 +946,164 @@ setup_text_key(void) { isc_buffer_free(&namebuf); } +isc_result_t +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) + result = ISC_R_RANGE; + if (result != ISC_R_SUCCESS) { + printf("invalid %s '%s': %s\n", desc, + value, isc_result_totext(result)); + return (result); + } + *uip = n; + return (ISC_R_SUCCESS); +} + +static isc_uint32_t +parse_bits(char *arg, const char *desc, isc_uint32_t max) { + isc_result_t result; + isc_uint32_t tmp; + + result = parse_uint(&tmp, arg, max, desc); + if (result != ISC_R_SUCCESS) + fatal("couldn't parse digest bits"); + tmp = (tmp + 7) & ~0x7U; + return (tmp); +} + + +/* + * Parse HMAC algorithm specification + */ +void +parse_hmac(const char *hmac) { + char buf[20]; + int len; + + REQUIRE(hmac != NULL); + + len = strlen(hmac); + if (len >= (int) sizeof(buf)) + fatal("unknown key type '%.*s'", len, hmac); + strncpy(buf, hmac, sizeof(buf)); + + digestbits = 0; + + if (strcasecmp(buf, "hmac-md5") == 0) { + hmacname = DNS_TSIG_HMACMD5_NAME; + } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) { + hmacname = DNS_TSIG_HMACMD5_NAME; + digestbits = parse_bits(&buf[9], "digest-bits [0..128]", 128); + } else if (strcasecmp(buf, "hmac-sha1") == 0) { + hmacname = DNS_TSIG_HMACSHA1_NAME; + digestbits = 0; + } else if (strncasecmp(buf, "hmac-sha1-", 10) == 0) { + hmacname = DNS_TSIG_HMACSHA1_NAME; + digestbits = parse_bits(&buf[10], "digest-bits [0..160]", 160); + } else if (strcasecmp(buf, "hmac-sha224") == 0) { + hmacname = DNS_TSIG_HMACSHA224_NAME; + } else if (strncasecmp(buf, "hmac-sha224-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA224_NAME; + digestbits = parse_bits(&buf[12], "digest-bits [0..224]", 224); + } else if (strcasecmp(buf, "hmac-sha256") == 0) { + hmacname = DNS_TSIG_HMACSHA256_NAME; + } else if (strncasecmp(buf, "hmac-sha256-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA256_NAME; + digestbits = parse_bits(&buf[12], "digest-bits [0..256]", 256); + } else if (strcasecmp(buf, "hmac-sha384") == 0) { + hmacname = DNS_TSIG_HMACSHA384_NAME; + } else if (strncasecmp(buf, "hmac-sha384-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA384_NAME; + digestbits = parse_bits(&buf[12], "digest-bits [0..384]", 384); + } else if (strcasecmp(buf, "hmac-sha512") == 0) { + hmacname = DNS_TSIG_HMACSHA512_NAME; + } else if (strncasecmp(buf, "hmac-sha512-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA512_NAME; + digestbits = parse_bits(&buf[12], "digest-bits [0..512]", 512); + } else { + fprintf(stderr, ";; Warning, ignoring " + "invalid TSIG algorithm %s\n", buf); + } +} + +/* + * Get a key from a named.conf format keyfile + */ +static isc_result_t +read_confkey(void) { + isc_log_t *lctx = NULL; + cfg_parser_t *pctx = NULL; + cfg_obj_t *file = NULL; + const cfg_obj_t *key = NULL; + const cfg_obj_t *secretobj = NULL; + const cfg_obj_t *algorithmobj = NULL; + const char *keyname; + const char *secretstr; + const char *algorithm; + isc_result_t result; + + if (! isc_file_exists(keyfile)) + return (ISC_R_FILENOTFOUND); + + result = cfg_parser_create(mctx, lctx, &pctx); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey, + &file); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = cfg_map_get(file, "key", &key); + if (result != ISC_R_SUCCESS) + goto cleanup; + + (void) cfg_map_get(key, "secret", &secretobj); + (void) cfg_map_get(key, "algorithm", &algorithmobj); + if (secretobj == NULL || algorithmobj == NULL) + fatal("key must have algorithm and secret"); + + keyname = cfg_obj_asstring(cfg_map_getname(key)); + secretstr = cfg_obj_asstring(secretobj); + algorithm = cfg_obj_asstring(algorithmobj); + + strncpy(keynametext, keyname, sizeof(keynametext)); + strncpy(keysecret, secretstr, sizeof(keysecret)); + parse_hmac(algorithm); + setup_text_key(); + + cleanup: + if (pctx != NULL) { + if (file != NULL) + cfg_obj_destroy(pctx, &file); + cfg_parser_destroy(&pctx); + } + + return (result); +} + static void setup_file_key(void) { isc_result_t result; dst_key_t *dstkey = NULL; debug("setup_file_key()"); + + /* Try reading the key from a K* pair */ result = dst_key_fromnamedfile(keyfile, NULL, DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx, &dstkey); + + /* If that didn't work, try reading it as a session.key keyfile */ + if (result != ISC_R_SUCCESS) { + result = read_confkey(); + if (result == ISC_R_SUCCESS) + return; + } + if (result != ISC_R_SUCCESS) { fprintf(stderr, "Couldn't read key from %s: %s\n", keyfile, isc_result_totext(result)); @@ -1137,6 +1292,7 @@ set_search_domain(char *domain) { void setup_libs(void) { isc_result_t result; + isc_logconfig_t *logconfig = NULL; debug("setup_libs()"); @@ -1153,6 +1309,18 @@ setup_libs(void) { result = isc_mem_create(0, 0, &mctx); check_result(result, "isc_mem_create"); + result = isc_log_create(mctx, &lctx, &logconfig); + check_result(result, "isc_log_create"); + + isc_log_setcontext(lctx); + dns_log_init(lctx); + dns_log_setcontext(lctx); + + result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL); + check_result(result, "isc_log_usechannel"); + + isc_log_setdebuglevel(lctx, 0); + result = isc_taskmgr_create(mctx, 1, 0, &taskmgr); check_result(result, "isc_taskmgr_create"); @@ -3557,9 +3725,11 @@ destroy_libs(void) { free_name(&chase_signame, mctx); #endif - debug("Destroy memory"); - #endif + debug("Removing log context"); + isc_log_destroy(&lctx); + + debug("Destroy memory"); if (memdebugging != 0) isc_mem_stats(mctx, stderr); if (mctx != NULL) diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index bf8a06cabc..8d319fbb11 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dig.h,v 1.108 2008/12/16 02:57:24 jinmei Exp $ */ +/* $Id: dig.h,v 1.109 2009/09/15 03:13:44 each Exp $ */ #ifndef DIG_H #define DIG_H @@ -325,6 +325,13 @@ setup_libs(void); void setup_system(void); +isc_result_t +parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max, + const char *desc); + +void +parse_hmac(const char *hmacstr); + dig_lookup_t * requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers); diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c index 9340eb3f0d..22614b415f 100644 --- a/bin/dig/nslookup.c +++ b/bin/dig/nslookup.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nslookup.c,v 1.122 2009/05/06 23:47:50 tbox Exp $ */ +/* $Id: nslookup.c,v 1.123 2009/09/15 03:13:43 each Exp $ */ #include @@ -540,22 +540,6 @@ safecpy(char *dest, char *src, int size) { dest[size-1] = 0; } -static isc_result_t -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) - result = ISC_R_RANGE; - if (result != ISC_R_SUCCESS) { - printf("invalid %s '%s': %s\n", desc, - value, isc_result_totext(result)); - return result; - } - *uip = n; - return (ISC_R_SUCCESS); -} - static void set_port(const char *value) { isc_uint32_t n;