diff options
author | erwin <erwin@FreeBSD.org> | 2013-08-06 06:22:54 +0000 |
---|---|---|
committer | erwin <erwin@FreeBSD.org> | 2013-08-06 06:22:54 +0000 |
commit | ef27886236495d424b7f096da332d093109780a6 (patch) | |
tree | b4ab3fc36f81b1377b903cb2fe0ca445c0304cbd /contrib/bind9/lib/dns | |
parent | c116c25dd59e2f090a93b32234e356ae28d96a02 (diff) | |
parent | 414d5ed7dd8cad7ef2738c53f9b9ecfe246ed91c (diff) | |
download | FreeBSD-src-ef27886236495d424b7f096da332d093109780a6.zip FreeBSD-src-ef27886236495d424b7f096da332d093109780a6.tar.gz |
Update Bind to 9.8.5-P2
New Features
Adds a new configuration option, "check-spf"; valid values are
"warn" (default) and "ignore". When set to "warn", checks SPF
and TXT records in spf format, warning if either resource record
type occurs without a corresponding record of the other resource
record type. [RT #33355]
Adds support for Uniform Resource Identifier (URI) resource
records. [RT #23386]
Adds support for the EUI48 and EUI64 RR types. [RT #33082]
Adds support for the RFC 6742 ILNP record types (NID, LP, L32,
and L64). [RT #31836]
Feature Changes
Changes timing of when slave zones send NOTIFY messages after
loading a new copy of the zone. They now send the NOTIFY before
writing the zone data to disk. This will result in quicker
propagation of updates in multi-level server structures. [RT #27242]
"named -V" can now report a source ID string. (This is will be
of most interest to developers and troubleshooters). The source
ID for ISC's production versions of BIND is defined in the "srcid"
file in the build tree and is normally set to the most recent
git hash. [RT #31494]
Response Policy Zone performance enhancements. New "response-policy"
option "min-ns-dots". "nsip" and "nsdname" now enabled by default
with RPZ. [RT #32251]
Approved by: delphij (mentor)
Sponsored by: DK Hostmaster A/S
Diffstat (limited to 'contrib/bind9/lib/dns')
84 files changed, 4266 insertions, 1241 deletions
diff --git a/contrib/bind9/lib/dns/Makefile.in b/contrib/bind9/lib/dns/Makefile.in index a01bb41..51d6066 100644 --- a/contrib/bind9/lib/dns/Makefile.in +++ b/contrib/bind9/lib/dns/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -46,8 +46,9 @@ LIBS = @LIBS@ # Alphabetically +OPENSSLGOSTLINKOBJS = opensslgost_link.@O@ OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - opensslecdsa_link.@O@ opensslgost_link.@O@ \ + opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ \ opensslrsa_link.@O@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \ @@ -76,8 +77,9 @@ DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} # Alphabetically +OPENSSLGOSTLINKSRCS = opensslgost_link.c OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ - opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c + opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \ diff --git a/contrib/bind9/lib/dns/acache.c b/contrib/bind9/lib/dns/acache.c index 2ad4981..863df35 100644 --- a/contrib/bind9/lib/dns/acache.c +++ b/contrib/bind9/lib/dns/acache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -27,6 +27,7 @@ #include <isc/random.h> #include <isc/refcount.h> #include <isc/rwlock.h> +#include <isc/serial.h> #include <isc/task.h> #include <isc/time.h> #include <isc/timer.h> @@ -72,10 +73,10 @@ * (XXX simply derived from definitions in cache.c There may be better * constants here.) */ -#define DNS_ACACHE_MINSIZE 2097152 /* Bytes. 2097152 = 2 MB */ -#define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */ +#define DNS_ACACHE_MINSIZE 2097152U /* Bytes. 2097152 = 2 MB */ +#define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */ -#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */ +#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */ #if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEATOMICSTORE) #define ACACHE_USE_RWLOCK 1 @@ -776,10 +777,14 @@ entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry, * use and the cleaning interval. */ if (cleaner->overmem) { - unsigned int passed = - now32 - entry->lastused; /* <= interval */ + unsigned int passed; isc_uint32_t val; + if (isc_serial_ge(now32, entry->lastused)) + passed = now32 - entry->lastused; /* <= interval */ + else + passed = 0; + if (passed > interval / 2) return (ISC_TRUE); isc_random_get(&val); @@ -825,8 +830,10 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { entry = cleaner->current_entry; isc_stdtime_convert32(cleaner->last_cleanup_time, &last32); - INSIST(now32 > last32); - interval = now32 - last32; + if (isc_serial_ge(now32, last32)) + interval = now32 - last32; + else + interval = 0; while (n_entries-- > 0) { isc_boolean_t is_stale = ISC_FALSE; @@ -861,7 +868,11 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { if (entry != NULL) { /* * If we are still in the overmem - * state, keep cleaning. + * state, keep cleaning. In case we + * exit from the loop immediately after + * this, reset next to the head entry + * as we'll expect it will be never + * NULL. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, @@ -870,6 +881,7 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { "acache cleaner: " "still overmem, " "reset and try again"); + next = entry; continue; } } @@ -888,7 +900,7 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { * be the starting point in the next clean-up, and reschedule another * batch. If it fails, just try to continue anyway. */ - INSIST(next != NULL && next != cleaner->current_entry); + INSIST(next != NULL); dns_acache_detachentry(&cleaner->current_entry); dns_acache_attachentry(next, &cleaner->current_entry); @@ -1649,12 +1661,17 @@ dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, return (result); } -void +isc_boolean_t dns_acache_cancelentry(dns_acacheentry_t *entry) { - dns_acache_t *acache = entry->acache; + dns_acache_t *acache; + isc_boolean_t callback_active; REQUIRE(DNS_ACACHEENTRY_VALID(entry)); - INSIST(DNS_ACACHE_VALID(acache)); + + acache = entry->acache; + callback_active = ISC_TF(entry->cbarg != NULL); + + INSIST(DNS_ACACHE_VALID(entry->acache)); LOCK(&acache->lock); ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); @@ -1674,6 +1691,8 @@ dns_acache_cancelentry(dns_acacheentry_t *entry) { ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); UNLOCK(&acache->lock); + + return (callback_active); } void @@ -1768,13 +1787,13 @@ dns_acache_setcachesize(dns_acache_t *acache, isc_uint32_t size) { REQUIRE(DNS_ACACHE_VALID(acache)); - if (size != 0 && size < DNS_ACACHE_MINSIZE) + if (size != 0U && size < DNS_ACACHE_MINSIZE) size = DNS_ACACHE_MINSIZE; hiwater = size - (size >> 3); lowater = size - (size >> 2); - if (size == 0 || hiwater == 0 || lowater == 0) + if (size == 0U || hiwater == 0U || lowater == 0U) isc_mem_setwater(acache->mctx, water, acache, 0, 0); else isc_mem_setwater(acache->mctx, water, acache, diff --git a/contrib/bind9/lib/dns/adb.c b/contrib/bind9/lib/dns/adb.c index 531d112..6aa5e5a 100644 --- a/contrib/bind9/lib/dns/adb.c +++ b/contrib/bind9/lib/dns/adb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -89,7 +89,7 @@ #define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */ -#define DNS_ADB_MINADBSIZE (1024*1024) /*%< 1 Megabyte */ +#define DNS_ADB_MINADBSIZE (1024U*1024U) /*%< 1 Megabyte */ typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t; typedef struct dns_adbnamehook dns_adbnamehook_t; @@ -518,7 +518,9 @@ grow_entries(isc_task_t *task, isc_event_t *ev) { isc_event_free(&ev); - isc_task_beginexclusive(task); + result = isc_task_beginexclusive(task); + if (result != ISC_R_SUCCESS) + goto check_exit; i = 0; while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i]) @@ -646,6 +648,7 @@ grow_entries(isc_task_t *task, isc_event_t *ev) { done: isc_task_endexclusive(task); + check_exit: LOCK(&adb->lock); if (dec_adb_irefcnt(adb)) check_exit(adb); @@ -670,7 +673,9 @@ grow_names(isc_task_t *task, isc_event_t *ev) { isc_event_free(&ev); - isc_task_beginexclusive(task); + result = isc_task_beginexclusive(task); + if (result != ISC_R_SUCCESS) + goto check_exit; i = 0; while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i]) @@ -794,6 +799,7 @@ grow_names(isc_task_t *task, isc_event_t *ev) { done: isc_task_endexclusive(task); + check_exit: LOCK(&adb->lock); if (dec_adb_irefcnt(adb)) check_exit(adb); @@ -1280,6 +1286,7 @@ clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) { if (addr_bucket != DNS_ADB_INVALIDBUCKET) UNLOCK(&adb->entrylocks[addr_bucket]); addr_bucket = entry->lock_bucket; + INSIST(addr_bucket != DNS_ADB_INVALIDBUCKET); LOCK(&adb->entrylocks[addr_bucket]); } @@ -2075,6 +2082,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname, while (namehook != NULL) { entry = namehook->entry; bucket = entry->lock_bucket; + INSIST(bucket != DNS_ADB_INVALIDBUCKET); LOCK(&adb->entrylocks[bucket]); if (!FIND_RETURNLAME(find) @@ -2105,6 +2113,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname, while (namehook != NULL) { entry = namehook->entry; bucket = entry->lock_bucket; + INSIST(bucket != DNS_ADB_INVALIDBUCKET); LOCK(&adb->entrylocks[bucket]); if (!FIND_RETURNLAME(find) @@ -2331,7 +2340,8 @@ destroy(dns_adb_t *adb) { adb->magic = 0; isc_task_detach(&adb->task); - isc_task_detach(&adb->excl); + if (adb->excl != NULL) + isc_task_detach(&adb->excl); isc_mempool_destroy(&adb->nmp); isc_mempool_destroy(&adb->nhmp); @@ -4126,13 +4136,13 @@ dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size) { INSIST(DNS_ADB_VALID(adb)); - if (size != 0 && size < DNS_ADB_MINADBSIZE) + if (size != 0U && size < DNS_ADB_MINADBSIZE) size = DNS_ADB_MINADBSIZE; hiwater = size - (size >> 3); /* Approximately 7/8ths. */ lowater = size - (size >> 2); /* Approximately 3/4ths. */ - if (size == 0 || hiwater == 0 || lowater == 0) + if (size == 0U || hiwater == 0U || lowater == 0U) isc_mem_setwater(adb->mctx, water, adb, 0, 0); else isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater); diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api index 325781a..5241a88 100644 --- a/contrib/bind9/lib/dns/api +++ b/contrib/bind9/lib/dns/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 -LIBINTERFACE = 89 +# 9.9-sub: 130-139 +LIBINTERFACE = 122 LIBREVISION = 1 -LIBAGE = 1 +LIBAGE = 0 diff --git a/contrib/bind9/lib/dns/cache.c b/contrib/bind9/lib/dns/cache.c index 56bff8d..bced80e 100644 --- a/contrib/bind9/lib/dns/cache.c +++ b/contrib/bind9/lib/dns/cache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -50,7 +50,7 @@ * DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize(). * See also DNS_CACHE_CLEANERINCREMENT */ -#define DNS_CACHE_MINSIZE 2097152 /*%< Bytes. 2097152 = 2 MB */ +#define DNS_CACHE_MINSIZE 2097152U /*%< Bytes. 2097152 = 2 MB */ /*! * Control incremental cleaning. * CLEANERINCREMENT is how many nodes are examined in one pass. @@ -1038,7 +1038,7 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) { * Impose a minimum cache size; pathological things happen if there * is too little room. */ - if (size != 0 && size < DNS_CACHE_MINSIZE) + if (size != 0U && size < DNS_CACHE_MINSIZE) size = DNS_CACHE_MINSIZE; LOCK(&cache->lock); @@ -1055,7 +1055,7 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) { * water(). */ - if (size == 0 || hiwater == 0 || lowater == 0) + if (size == 0U || hiwater == 0U || lowater == 0U) /* * Disable cache memory limiting. */ diff --git a/contrib/bind9/lib/dns/client.c b/contrib/bind9/lib/dns/client.c index 7b6d1640..c4780f7 100644 --- a/contrib/bind9/lib/dns/client.c +++ b/contrib/bind9/lib/dns/client.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -354,6 +354,12 @@ dns_client_create(dns_client_t **clientp, unsigned int options) { isc_taskmgr_t *taskmgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_timermgr_t *timermgr = NULL; +#if 0 + /* XXXMPA add debug logging support */ + isc_log_t *lctx = NULL; + isc_logconfig_t *logconfig = NULL; + unsigned int logdebuglevel = 0; +#endif result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) @@ -373,7 +379,18 @@ dns_client_create(dns_client_t **clientp, unsigned int options) { result = isc_timermgr_createinctx(mctx, actx, &timermgr); if (result != ISC_R_SUCCESS) goto cleanup; - +#if 0 + result = isc_log_create(mctx, &lctx, &logconfig); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_log_setcontext(lctx); + dns_log_init(lctx); + dns_log_setcontext(lctx); + result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_log_setdebuglevel(lctx, logdebuglevel); +#endif result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr, options, clientp); if (result != ISC_R_SUCCESS) @@ -485,6 +502,7 @@ dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, client->update_udpretries = DEF_UPDATE_UDPRETRIES; client->find_timeout = DEF_FIND_TIMEOUT; client->find_udpretries = DEF_FIND_UDPRETRIES; + client->attributes = 0; client->references = 1; client->magic = DNS_CLIENT_MAGIC; @@ -2000,8 +2018,9 @@ resolveaddr_done(isc_task_t *task, isc_event_t *event) { switch (family) { case AF_INET: dns_rdataset_current(rdataset, &rdata); - dns_rdata_tostruct(&rdata, &rdata_a, - NULL); + result = dns_rdata_tostruct(&rdata, &rdata_a, + NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_sockaddr_fromin(sa, &rdata_a.in_addr, 53); @@ -2009,8 +2028,9 @@ resolveaddr_done(isc_task_t *task, isc_event_t *event) { break; case AF_INET6: dns_rdataset_current(rdataset, &rdata); - dns_rdata_tostruct(&rdata, &rdata_aaaa, - NULL); + result = dns_rdata_tostruct(&rdata, &rdata_aaaa, + NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_sockaddr_fromin6(sa, &rdata_aaaa.in6_addr, 53); diff --git a/contrib/bind9/lib/dns/db.c b/contrib/bind9/lib/dns/db.c index 0cf2c27..77f82f1 100644 --- a/contrib/bind9/lib/dns/db.c +++ b/contrib/bind9/lib/dns/db.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -945,11 +945,12 @@ dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, (db->methods->resigned)(db, rdataset, version); } -void +isc_result_t dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) { if (db->methods->rpz_enabled != NULL) - (db->methods->rpz_enabled)(db, st); + return ((db->methods->rpz_enabled)(db, st)); + return (ISC_R_SUCCESS); } void diff --git a/contrib/bind9/lib/dns/dispatch.c b/contrib/bind9/lib/dns/dispatch.c index 775d4f4..9848ac2 100644 --- a/contrib/bind9/lib/dns/dispatch.c +++ b/contrib/bind9/lib/dns/dispatch.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -2756,7 +2756,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, * If no port is specified, we first try to pick up a random * port by ourselves. */ - if (isc_sockaddr_pf(&disp->local) == AF_INET) { + if (isc_sockaddr_pf(localaddr) == AF_INET) { nports = disp->mgr->nv4ports; ports = disp->mgr->v4ports; } else { @@ -2775,12 +2775,16 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, isc_sockaddr_setport(&localaddr_bound, prt); result = open_socket(sockmgr, &localaddr_bound, 0, &sock); - if (result == ISC_R_SUCCESS || - result != ISC_R_ADDRINUSE) { - disp->localport = prt; - *sockp = sock; - return (result); - } + /* + * Continue if the port choosen is already in use + * or the OS has reserved it. + */ + if (result == ISC_R_NOPERM || + result == ISC_R_ADDRINUSE) + continue; + disp->localport = prt; + *sockp = sock; + return (result); } /* @@ -2805,8 +2809,6 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, result = open_socket(sockmgr, localaddr, 0, &sock); if (result != ISC_R_SUCCESS) goto end; - else if (!anyport) - break; else if (portavailable(mgr, sock, NULL)) break; if (held[i] != NULL) diff --git a/contrib/bind9/lib/dns/dlz.c b/contrib/bind9/lib/dns/dlz.c index 8d1625a..19c600c 100644 --- a/contrib/bind9/lib/dns/dlz.c +++ b/contrib/bind9/lib/dns/dlz.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2005, 2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2005, 2007, 2009-2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -142,6 +142,7 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, { dns_dlzimplementation_t *impinfo; isc_result_t result; + dns_dlzdb_t *db = NULL; /* * initialize the dlz_implementations list, this is guaranteed @@ -180,30 +181,31 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, } /* Allocate memory to hold the DLZ database driver */ - (*dbp) = isc_mem_get(mctx, sizeof(dns_dlzdb_t)); - if ((*dbp) == NULL) { + db = isc_mem_get(mctx, sizeof(dns_dlzdb_t)); + if (db == NULL) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); return (ISC_R_NOMEMORY); } /* Make sure memory region is set to all 0's */ - memset((*dbp), 0, sizeof(dns_dlzdb_t)); + memset(db, 0, sizeof(dns_dlzdb_t)); - (*dbp)->implementation = impinfo; + db->implementation = impinfo; /* Create a new database using implementation 'drivername'. */ result = ((impinfo->methods->create)(mctx, dlzname, argc, argv, impinfo->driverarg, - &(*dbp)->dbdata)); + &db->dbdata)); /* mark the DLZ driver as valid */ if (result == ISC_R_SUCCESS) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); - (*dbp)->magic = DNS_DLZ_MAGIC; - isc_mem_attach(mctx, &(*dbp)->mctx); + db->magic = DNS_DLZ_MAGIC; + isc_mem_attach(mctx, &db->mctx); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "DLZ driver loaded successfully."); + *dbp = db; return (ISC_R_SUCCESS); } else { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, @@ -213,7 +215,7 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, /* impinfo->methods->create failed. */ RWUNLOCK(&dlz_implock, isc_rwlocktype_read); - isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t)); + isc_mem_put(mctx, db, sizeof(dns_dlzdb_t)); return (result); } @@ -543,7 +545,7 @@ dns_dlz_writeablezone(dns_view_t *view, const char *zone_name) { REQUIRE(dlzdatabase->configure_callback != NULL); - isc_buffer_init(&buffer, zone_name, strlen(zone_name)); + isc_buffer_constinit(&buffer, zone_name, strlen(zone_name)); isc_buffer_add(&buffer, strlen(zone_name)); dns_fixedname_init(&fixorigin); result = dns_name_fromtext(dns_fixedname_name(&fixorigin), diff --git a/contrib/bind9/lib/dns/dnssec.c b/contrib/bind9/lib/dns/dnssec.c index 3569ad7..587bd1c 100644 --- a/contrib/bind9/lib/dns/dnssec.c +++ b/contrib/bind9/lib/dns/dnssec.c @@ -275,7 +275,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, if (ret != ISC_R_SUCCESS) goto cleanup_databuf; - ret = dst_context_create(key, mctx, &ctx); + ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx); if (ret != ISC_R_SUCCESS) goto cleanup_databuf; @@ -352,7 +352,6 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, ret = ISC_R_NOSPACE; goto cleanup_array; } - memcpy(sig.signature, r.base, sig.siglen); ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass, sig.common.rdtype, &sig, buffer); @@ -462,7 +461,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, } again: - ret = dst_context_create(key, mctx, &ctx); + ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx); if (ret != ISC_R_SUCCESS) goto cleanup_struct; @@ -551,9 +550,9 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, if (ret == ISC_R_SUCCESS && downcase) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(&sig.signer, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, - "sucessfully validated after lower casing " + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, + DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), + "successfully validated after lower casing " "signer '%s'", namebuf); inc_stat(dns_dnssecstats_downcase); } else if (ret == ISC_R_SUCCESS) @@ -854,7 +853,7 @@ dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key) { isc_buffer_init(&databuf, data, sizeof(data)); - RETERR(dst_context_create(key, mctx, &ctx)); + RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx)); /* * Digest the fields of the SIG - we can cheat and use @@ -1004,7 +1003,7 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, goto failure; } - RETERR(dst_context_create(key, mctx, &ctx)); + RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx)); /* * Digest the SIG(0) record, except for the signature. diff --git a/contrib/bind9/lib/dns/dst_api.c b/contrib/bind9/lib/dns/dst_api.c index f5dd89a..53978bc 100644 --- a/contrib/bind9/lib/dns/dst_api.c +++ b/contrib/bind9/lib/dns/dst_api.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -276,6 +276,13 @@ dst_algorithm_supported(unsigned int alg) { isc_result_t dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) { + return (dst_context_create2(key, mctx, + DNS_LOGCATEGORY_GENERAL, dctxp)); +} + +isc_result_t +dst_context_create2(dst_key_t *key, isc_mem_t *mctx, + isc_logcategory_t *category, dst_context_t **dctxp) { dst_context_t *dctx; isc_result_t result; @@ -294,6 +301,7 @@ dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) { return (ISC_R_NOMEMORY); dctx->key = key; dctx->mctx = mctx; + dctx->category = category; result = key->func->createctx(key, dctx); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, dctx, sizeof(dst_context_t)); @@ -495,8 +503,7 @@ dst_key_fromnamedfile(const char *filename, const char *dirname, result = dst_key_read_public(newfilename, type, mctx, &pubkey); isc_mem_put(mctx, newfilename, newfilenamelen); newfilename = NULL; - if (result != ISC_R_SUCCESS) - return (result); + RETERR(result); if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC || (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { @@ -560,7 +567,8 @@ dst_key_fromnamedfile(const char *filename, const char *dirname, isc_mem_put(mctx, newfilename, newfilenamelen); if (lex != NULL) isc_lex_destroy(&lex); - dst_key_free(&key); + if (key != NULL) + dst_key_free(&key); return (result); } @@ -1190,7 +1198,7 @@ dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) { REQUIRE(length != NULL && *length == 0); REQUIRE(VALID_KEY(key)); - if (key->func->isprivate == NULL) + if (key->func->dump == NULL) return (ISC_R_NOTIMPLEMENTED); return (key->func->dump(key, mctx, buffer, length)); } @@ -1247,24 +1255,24 @@ get_key_struct(dns_name_t *name, unsigned int alg, return (NULL); memset(key, 0, sizeof(dst_key_t)); - key->magic = KEY_MAGIC; - - result = isc_refcount_init(&key->refs, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, key, sizeof(dst_key_t)); - return (NULL); - } key->key_name = isc_mem_get(mctx, sizeof(dns_name_t)); if (key->key_name == NULL) { - isc_refcount_destroy(&key->refs); isc_mem_put(mctx, key, sizeof(dst_key_t)); return (NULL); } + dns_name_init(key->key_name, NULL); result = dns_name_dup(name, mctx, key->key_name); if (result != ISC_R_SUCCESS) { - isc_refcount_destroy(&key->refs); + isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); + isc_mem_put(mctx, key, sizeof(dst_key_t)); + return (NULL); + } + + result = isc_refcount_init(&key->refs, 1); + if (result != ISC_R_SUCCESS) { + dns_name_free(key->key_name, mctx); isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); isc_mem_put(mctx, key, sizeof(dst_key_t)); return (NULL); @@ -1283,6 +1291,7 @@ get_key_struct(dns_name_t *name, unsigned int alg, key->times[i] = 0; key->timeset[i] = ISC_FALSE; } + key->magic = KEY_MAGIC; return (key); } diff --git a/contrib/bind9/lib/dns/dst_internal.h b/contrib/bind9/lib/dns/dst_internal.h index 2f4f946..ee824f4 100644 --- a/contrib/bind9/lib/dns/dst_internal.h +++ b/contrib/bind9/lib/dns/dst_internal.h @@ -137,6 +137,7 @@ struct dst_context { unsigned int magic; dst_key_t *key; isc_mem_t *mctx; + isc_logcategory_t *category; union { void *generic; dst_gssapi_signverifyctx_t *gssctx; diff --git a/contrib/bind9/lib/dns/dst_openssl.h b/contrib/bind9/lib/dns/dst_openssl.h index a30fd6a..e4d636e 100644 --- a/contrib/bind9/lib/dns/dst_openssl.h +++ b/contrib/bind9/lib/dns/dst_openssl.h @@ -21,6 +21,7 @@ #define DST_OPENSSL_H 1 #include <isc/lang.h> +#include <isc/log.h> #include <isc/result.h> #include <openssl/err.h> @@ -42,6 +43,10 @@ dst__openssl_toresult(isc_result_t fallback); isc_result_t dst__openssl_toresult2(const char *funcname, isc_result_t fallback); +isc_result_t +dst__openssl_toresult3(isc_logcategory_t *category, + const char *funcname, isc_result_t fallback); + #ifdef USE_ENGINE ENGINE * dst__openssl_getengine(const char *engine); diff --git a/contrib/bind9/lib/dns/ecdb.c b/contrib/bind9/lib/dns/ecdb.c index f1a833f..20da5b0 100644 --- a/contrib/bind9/lib/dns/ecdb.c +++ b/contrib/bind9/lib/dns/ecdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -80,8 +80,11 @@ typedef struct rdatasetheader { /* Copied from rbtdb.c */ #define RDATASET_ATTR_NXDOMAIN 0x0010 +#define RDATASET_ATTR_NEGATIVE 0x0100 #define NXDOMAIN(header) \ (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0) +#define NEGATIVE(header) \ + (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0) static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, @@ -406,6 +409,8 @@ bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node, rdataset->trust = header->trust; if (NXDOMAIN(header)) rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN; + if (NEGATIVE(header)) + rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE; rdataset->private1 = ecdb; rdataset->private2 = node; @@ -469,6 +474,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, header->attributes = 0; if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) header->attributes |= RDATASET_ATTR_NXDOMAIN; + if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) + header->attributes |= RDATASET_ATTR_NEGATIVE; ISC_LINK_INIT(header, link); ISC_LIST_APPEND(ecdbnode->rdatasets, header, link); diff --git a/contrib/bind9/lib/dns/gen.c b/contrib/bind9/lib/dns/gen.c index a0b4df3..6b533dd 100644 --- a/contrib/bind9/lib/dns/gen.c +++ b/contrib/bind9/lib/dns/gen.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,8 +15,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gen.c,v 1.85 2009/12/04 22:06:37 tbox Exp $ */ - /*! \file */ #ifdef WIN32 @@ -24,6 +22,10 @@ * Silence compiler warnings about using strcpy and friends. */ #define _CRT_SECURE_NO_DEPRECATE 1 +/* + * We use snprintf. + */ +#define snprintf _snprintf #endif #include <sys/types.h> @@ -41,7 +43,12 @@ #include "gen-unix.h" #endif -#define TYPECLASSLEN 21 +#define INSIST(cond) \ + if (!(cond)) { \ + fprintf(stderr, "%s:%d: INSIST(%s)\n", \ + __FILE__, __LINE__, #cond); \ + abort(); \ + } #define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks" #define FROMTEXTCLASS "rdclass" @@ -103,7 +110,7 @@ #define CHECKNAMESTYPE "rdata->type" #define CHECKNAMESDEF "result = ISC_TRUE" -const char copyright[] = +static const char copyright[] = "/*\n" " * Copyright (C) 2004%s Internet Systems Consortium, Inc. (\"ISC\")\n" " * Copyright (C) 1998-2003 Internet Software Consortium.\n" @@ -131,53 +138,59 @@ const char copyright[] = "/*! \\file */\n" "\n"; +#define STR_EXPAND(tok) #tok +#define STR(tok) STR_EXPAND(tok) + #define TYPENAMES 256 +#define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */ +#define TYPECLASSBUF (TYPECLASSLEN + 1) +#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d" +#define ATTRIBUTESIZE 256 +#define DIRNAMESIZE 256 -struct cc { +static struct cc { struct cc *next; int rdclass; - char classname[TYPECLASSLEN]; + char classname[TYPECLASSBUF]; } *classes; -struct tt { +static struct tt { struct tt *next; int rdclass; int type; - char classname[TYPECLASSLEN]; - char typename[TYPECLASSLEN]; - char dirname[256]; /* XXX Should be max path length */ + char classname[TYPECLASSBUF]; + char typename[TYPECLASSBUF]; + char dirname[DIRNAMESIZE]; /* XXX Should be max path length */ } *types; -struct ttnam { - char typename[TYPECLASSLEN]; - char macroname[TYPECLASSLEN]; - char attr[256]; +static struct ttnam { + char typename[TYPECLASSBUF]; + char macroname[TYPECLASSBUF]; + char attr[ATTRIBUTESIZE]; unsigned int sorted; int type; } typenames[TYPENAMES]; -int maxtype = -1; +static int maxtype = -1; -char * +static char * upper(char *); -char * +static char * funname(const char *, char *); -void +static void doswitch(const char *, const char *, const char *, const char *, const char *, const char *); -void -dodecl(char *, char *, char *); -void +static void add(int, const char *, int, const char *, const char *); -void +static void sd(int, const char *, const char *, char); -void +static void insert_into_typenames(int, const char *, const char *); /*% * If you use more than 10 of these in, say, a printf(), you'll have problems. */ -char * +static char * upper(char *s) { static int buf_to_use = 0; static char buf[10][256]; @@ -197,11 +210,12 @@ upper(char *s) { return (buf[buf_to_use]); } -char * +static char * funname(const char *s, char *buf) { char *b = buf; char c; + INSIST(strlen(s) < TYPECLASSBUF); while ((c = *s++)) { *b++ = (c == '-') ? '_' : c; } @@ -209,7 +223,7 @@ funname(const char *s, char *buf) { return (buf); } -void +static void doswitch(const char *name, const char *function, const char *args, const char *tsw, const char *csw, const char *res) { @@ -217,7 +231,7 @@ doswitch(const char *name, const char *function, const char *args, int first = 1; int lasttype = 0; int subswitch = 0; - char buf1[TYPECLASSLEN], buf2[TYPECLASSLEN]; + char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF]; const char *result = " result ="; if (res == NULL) @@ -280,26 +294,6 @@ doswitch(const char *name, const char *function, const char *args, } } -void -dodecl(char *type, char *function, char *args) { - struct tt *tt; - char buf1[TYPECLASSLEN], buf2[TYPECLASSLEN]; - - fputs("\n", stdout); - for (tt = types; tt; tt = tt->next) - if (tt->rdclass) - fprintf(stdout, - "static inline %s %s_%s_%s(%s);\n", - type, function, - funname(tt->classname, buf1), - funname(tt->typename, buf2), args); - else - fprintf(stdout, - "static inline %s %s_%s(%s);\n", - type, function, - funname(tt->typename, buf1), args); -} - static struct ttnam * find_typename(int type) { int i; @@ -312,12 +306,13 @@ find_typename(int type) { return (NULL); } -void +static void insert_into_typenames(int type, const char *typename, const char *attr) { struct ttnam *ttn = NULL; - int c, i; + int c, i, n; char tmp[256]; + INSIST(strlen(typename) < TYPECLASSBUF); for (i = 0; i < TYPENAMES; i++) { if (typenames[i].typename[0] != 0 && typenames[i].type == type && @@ -340,10 +335,10 @@ insert_into_typenames(int type, const char *typename, const char *attr) { typename); exit(1); } - strcpy(ttn->typename, typename); + strncpy(ttn->typename, typename, sizeof(ttn->typename)); ttn->type = type; - strcpy(ttn->macroname, ttn->typename); + strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname)); c = strlen(ttn->macroname); while (c > 0) { if (ttn->macroname[c - 1] == '-') @@ -352,7 +347,9 @@ insert_into_typenames(int type, const char *typename, const char *attr) { } if (attr == NULL) { - sprintf(tmp, "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); + n = snprintf(tmp, sizeof(tmp), + "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); + INSIST(n > 0 && (unsigned)n < sizeof(tmp)); attr = tmp; } @@ -367,13 +364,13 @@ insert_into_typenames(int type, const char *typename, const char *attr) { attr, typename); exit(1); } - strcpy(ttn->attr, attr); + strncpy(ttn->attr, attr, sizeof(ttn->attr)); ttn->sorted = 0; if (maxtype < type) maxtype = type; } -void +static void add(int rdclass, const char *classname, int type, const char *typename, const char *dirname) { @@ -382,6 +379,10 @@ add(int rdclass, const char *classname, int type, const char *typename, struct cc *newcc; struct cc *cc, *oldcc; + INSIST(strlen(typename) < TYPECLASSBUF); + INSIST(strlen(classname) < TYPECLASSBUF); + INSIST(strlen(dirname) < DIRNAMESIZE); + insert_into_typenames(type, typename, NULL); if (newtt == NULL) { @@ -392,11 +393,11 @@ add(int rdclass, const char *classname, int type, const char *typename, newtt->next = NULL; newtt->rdclass = rdclass; newtt->type = type; - strcpy(newtt->classname, classname); - strcpy(newtt->typename, typename); + strncpy(newtt->classname, classname, sizeof(newtt->classname)); + strncpy(newtt->typename, typename, sizeof(newtt->typename)); if (strncmp(dirname, "./", 2) == 0) dirname += 2; - strcpy(newtt->dirname, dirname); + strncpy(newtt->dirname, dirname, sizeof(newtt->dirname)); tt = types; oldtt = NULL; @@ -429,8 +430,12 @@ add(int rdclass, const char *classname, int type, const char *typename, return; newcc = (struct cc *)malloc(sizeof(*newcc)); + if (newcc == NULL) { + fprintf(stderr, "malloc() failed\n"); + exit(1); + } newcc->rdclass = rdclass; - strcpy(newcc->classname, classname); + strncpy(newcc->classname, classname, sizeof(newcc->classname)); cc = classes; oldcc = NULL; @@ -451,25 +456,25 @@ add(int rdclass, const char *classname, int type, const char *typename, classes = newcc; } -void +static void sd(int rdclass, const char *classname, const char *dirname, char filetype) { - char buf[sizeof("01234567890123456789_65535.h")]; - char fmt[sizeof("%20[-0-9a-z]_%d.h")]; - int type; - char typename[TYPECLASSLEN]; + char buf[TYPECLASSLEN + sizeof("_65535.h")]; + char typename[TYPECLASSBUF]; + int type, n; isc_dir_t dir; if (!start_directory(dirname, &dir)) return; - sprintf(fmt,"%s%c", "%20[-0-9a-z]_%d.", filetype); while (next_file(&dir)) { - if (sscanf(dir.filename, fmt, typename, &type) != 2) + if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2) continue; if ((type > 65535) || (type < 0)) continue; - sprintf(buf, "%s_%d.%c", typename, type, filetype); + n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename, + type, filetype); + INSIST(n > 0 && (unsigned)n < sizeof(buf)); if (strcmp(buf, dir.filename) != 0) continue; add(rdclass, classname, type, typename, dirname); @@ -496,10 +501,10 @@ HASH(char *string) { int main(int argc, char **argv) { - char buf[256]; /* XXX Should be max path length */ - char srcdir[256]; /* XXX Should be max path length */ + char buf[DIRNAMESIZE]; /* XXX Should be max path length */ + char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */ int rdclass; - char classname[TYPECLASSLEN]; + char classname[TYPECLASSBUF]; struct tt *tt; struct cc *cc; struct ttnam *ttn, *ttn2; @@ -513,8 +518,8 @@ main(int argc, char **argv) { int type_enum = 0; int structs = 0; int depend = 0; - int c, i, j; - char buf1[TYPECLASSLEN]; + int c, i, j, n; + char buf1[TYPECLASSBUF]; char filetype = 'c'; FILE *fd; char *prefix = NULL; @@ -561,7 +566,16 @@ main(int argc, char **argv) { filetype = 'h'; break; case 's': - sprintf(srcdir, "%s/", isc_commandline_argument); + if (strlen(isc_commandline_argument) > + DIRNAMESIZE - 2 * TYPECLASSLEN - + sizeof("/rdata/_65535_65535")) { + fprintf(stderr, "\"%s\" too long\n", + isc_commandline_argument); + exit(1); + } + n = snprintf(srcdir, sizeof(srcdir), "%s/", + isc_commandline_argument); + INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); break; case 'F': file = isc_commandline_argument; @@ -576,31 +590,37 @@ main(int argc, char **argv) { exit(1); } - sprintf(buf, "%srdata", srcdir); + n = snprintf(buf, sizeof(buf), "%srdata", srcdir); + INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); if (!start_directory(buf, &dir)) exit(1); while (next_file(&dir)) { - if (sscanf(dir.filename, "%10[0-9a-z]_%d", - classname, &rdclass) != 2) + if (sscanf(dir.filename, TYPECLASSFMT, classname, + &rdclass) != 2) continue; if ((rdclass > 65535) || (rdclass < 0)) continue; - sprintf(buf, "%srdata/%s_%d", srcdir, classname, rdclass); + n = snprintf(buf, sizeof(buf), "%srdata/%s_%d", + srcdir, classname, rdclass); + INSIST(n > 0 && (unsigned)n < sizeof(buf)); if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) continue; sd(rdclass, classname, buf, filetype); } end_directory(&dir); - sprintf(buf, "%srdata/generic", srcdir); + n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir); + INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); sd(0, "", buf, filetype); if (time(&now) != -1) { - if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) - sprintf(year, "-%d", tm->tm_year + 1900); - else + if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) { + n = snprintf(year, sizeof(year), "-%d", + tm->tm_year + 1900); + INSIST(n > 0 && (unsigned)n < sizeof(year)); + } else year[0] = 0; } else year[0] = 0; @@ -862,7 +882,7 @@ main(int argc, char **argv) { } } for (tt = types; tt != NULL; tt = tt->next) { - sprintf(buf, "%s/%s_%d.h", + snprintf(buf, sizeof(buf), "%s/%s_%d.h", tt->dirname, tt->typename, tt->type); if ((fd = fopen(buf,"r")) != NULL) { while (fgets(buf, sizeof(buf), fd) != NULL) diff --git a/contrib/bind9/lib/dns/gssapictx.c b/contrib/bind9/lib/dns/gssapictx.c index ee5be56..e4047d2 100644 --- a/contrib/bind9/lib/dns/gssapictx.c +++ b/contrib/bind9/lib/dns/gssapictx.c @@ -541,7 +541,7 @@ gss_err_message(isc_mem_t *mctx, isc_uint32_t major, isc_uint32_t minor, } estr = gss_error_tostring(major, minor, buf, sizeof(buf)); - if (estr) + if (estr != NULL) (*err_message) = isc_mem_strdup(mctx, estr); } #endif @@ -597,8 +597,12 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken, if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) { gss_err_message(mctx, gret, minor, err_message); - gss_log(3, "Failure initiating security context: %s", - *err_message); + if (err_message != NULL && *err_message != NULL) + gss_log(3, "Failure initiating security context: %s", + *err_message); + else + gss_log(3, "Failure initiating security context"); + result = ISC_R_FAILURE; goto out; } diff --git a/contrib/bind9/lib/dns/include/dns/acache.h b/contrib/bind9/lib/dns/include/dns/acache.h index 28990c2..c372ed9 100644 --- a/contrib/bind9/lib/dns/include/dns/acache.h +++ b/contrib/bind9/lib/dns/include/dns/acache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -25,7 +25,7 @@ /* * Acache - * + * * The Additional Cache Object * * This module manages internal caching entries that correspond to @@ -131,7 +131,7 @@ * - 76 bytes for each additional cache entry * - if the entry has a DNS name and associated RRset, * * 44 bytes + size of the name (1-255 bytes) - * * 52 bytes x number_of_RRs + * * 52 bytes x number_of_RRs * - 28 bytes for each DB related to this module * * Using the additional cache also requires extra memory consumption in @@ -387,7 +387,7 @@ dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, * ISC_R_NOTFOUND */ -void +isc_boolean_t dns_acache_cancelentry(dns_acacheentry_t *entry); /* * Cancel the use of the cache entry 'entry'. This function is supposed to @@ -398,6 +398,9 @@ dns_acache_cancelentry(dns_acacheentry_t *entry); * * Requires: * 'entry' is a valid additional cache entry. + * + * Returns: + * ISC_TRUE if the entry was active when canceled */ void @@ -415,7 +418,7 @@ dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp); * * *targetp is attached to 'source'. */ - + void dns_acache_detachentry(dns_acacheentry_t **entryp); /* @@ -429,7 +432,7 @@ dns_acache_detachentry(dns_acacheentry_t **entryp); * * *entryp is NULL. * - * If '*entryp' is the last reference to the entry, + * If '*entryp' is the last reference to the entry, * cache does not have an outstanding task, all resources used by the * entry (including the entry object itself) will be freed. */ diff --git a/contrib/bind9/lib/dns/include/dns/db.h b/contrib/bind9/lib/dns/include/dns/db.h index fe268f4..ef090a2 100644 --- a/contrib/bind9/lib/dns/include/dns/db.h +++ b/contrib/bind9/lib/dns/include/dns/db.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -171,7 +171,7 @@ typedef struct dns_dbmethods { dns_dbversion_t *version); isc_boolean_t (*isdnssec)(dns_db_t *db); dns_stats_t *(*getrrsetstats)(dns_db_t *db); - void (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st); + isc_result_t (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st); void (*rpz_findips)(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, dns_zone_t *zone, dns_db_t *db, @@ -1500,11 +1500,11 @@ dns_db_getrrsetstats(dns_db_t *db); * dns_rdatasetstats_create(); otherwise NULL. */ -void +isc_result_t dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st); /*%< - * See if a policy database has DNS_RPZ_TYPE_IP, DNS_RPZ_TYPE_NSIP, or - * DNS_RPZ_TYPE_NSDNAME records. + * Mark a database for response policy rewriting + * or find which RPZ data is available. */ void diff --git a/contrib/bind9/lib/dns/include/dns/message.h b/contrib/bind9/lib/dns/include/dns/message.h index 3bc734d..a6862fa 100644 --- a/contrib/bind9/lib/dns/include/dns/message.h +++ b/contrib/bind9/lib/dns/include/dns/message.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -251,6 +251,12 @@ struct dns_message { const void * order_arg; }; +struct dns_ednsopt { + isc_uint16_t code; + isc_uint16_t length; + unsigned char *value; +}; + /*** *** Functions ***/ @@ -1350,6 +1356,24 @@ dns_message_gettimeadjust(dns_message_t *msg); *\li msg be a valid message. */ +isc_result_t +dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt, + unsigned int version, isc_uint16_t udpsize, + unsigned int flags, dns_ednsopt_t *ednsopts, size_t count); +/*%< + * Built a opt record. + * + * Requires: + * \li msg be a valid message. + * \li opt to be a non NULL and *opt to be NULL. + * + * Returns: + * \li ISC_R_SUCCESS on success. + * \li ISC_R_NOMEMORY + * \li ISC_R_NOSPACE + * \li other. + */ + ISC_LANG_ENDDECLS #endif /* DNS_MESSAGE_H */ diff --git a/contrib/bind9/lib/dns/include/dns/name.h b/contrib/bind9/lib/dns/include/dns/name.h index bef8693..1a88e53 100644 --- a/contrib/bind9/lib/dns/include/dns/name.h +++ b/contrib/bind9/lib/dns/include/dns/name.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -1299,15 +1299,17 @@ ISC_LANG_ENDDECLS #define DNS_NAME_INIT(n, o) \ do { \ - (n)->magic = DNS_NAME_MAGIC; \ - (n)->ndata = NULL; \ - (n)->length = 0; \ - (n)->labels = 0; \ - (n)->attributes = 0; \ - (n)->offsets = (o); \ - (n)->buffer = NULL; \ - ISC_LINK_INIT((n), link); \ - ISC_LIST_INIT((n)->list); \ + dns_name_t *_n = (n); \ + /* memset(_n, 0, sizeof(*_n)); */ \ + _n->magic = DNS_NAME_MAGIC; \ + _n->ndata = NULL; \ + _n->length = 0; \ + _n->labels = 0; \ + _n->attributes = 0; \ + _n->offsets = (o); \ + _n->buffer = NULL; \ + ISC_LINK_INIT(_n, link); \ + ISC_LIST_INIT(_n->list); \ } while (0) #define DNS_NAME_RESET(n) \ diff --git a/contrib/bind9/lib/dns/include/dns/ncache.h b/contrib/bind9/lib/dns/include/dns/ncache.h index 8d89879..337e834 100644 --- a/contrib/bind9/lib/dns/include/dns/ncache.h +++ b/contrib/bind9/lib/dns/include/dns/ncache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -73,6 +73,11 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, * rdataset, and store it in 'cache' at 'node' with a TTL limited to * 'maxttl'. * + * \li dns_ncache_add produces a negative cache entry with a trust of no + * more than answer + * \li dns_ncache_addoptout produces a negative cache entry which will have + * a trust of secure if all the records that make up the entry are secure. + * * The 'covers' argument is the RR type whose nonexistence we are caching, * or dns_rdatatype_any when caching a NXDOMAIN response. * diff --git a/contrib/bind9/lib/dns/include/dns/nsec.h b/contrib/bind9/lib/dns/include/dns/nsec.h index a18e138..510d96b 100644 --- a/contrib/bind9/lib/dns/include/dns/nsec.h +++ b/contrib/bind9/lib/dns/include/dns/nsec.h @@ -75,6 +75,19 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, * 'answer' to be non NULL. */ +isc_result_t +dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name, + dns_name_t *nsecname, dns_rdataset_t *nsecset, + isc_boolean_t *exists, isc_boolean_t *data, + dns_name_t *wild, dns_nseclog_t log, void *arg); +/*% + * Return ISC_R_SUCCESS if we can determine that the name doesn't exist + * or we can determine whether there is data or not at the name. + * If the name does not exist return the wildcard name. + * + * Return ISC_R_IGNORE when the NSEC is not the appropriate one. + */ + ISC_LANG_ENDDECLS #endif /* DNS_NSEC_H */ diff --git a/contrib/bind9/lib/dns/include/dns/nsec3.h b/contrib/bind9/lib/dns/include/dns/nsec3.h index beb44f3..588dd05 100644 --- a/contrib/bind9/lib/dns/include/dns/nsec3.h +++ b/contrib/bind9/lib/dns/include/dns/nsec3.h @@ -247,6 +247,14 @@ dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, * Mark NSEC3PARAM for deletion. */ +isc_result_t +dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name, + dns_name_t *nsec3name, dns_rdataset_t *nsec3set, + dns_name_t *zonename, isc_boolean_t *exists, + isc_boolean_t *data, isc_boolean_t *optout, + isc_boolean_t *unknown, isc_boolean_t *setclosest, + isc_boolean_t *setnearest, dns_name_t *closest, + dns_name_t *nearest, dns_nseclog_t logit, void *arg); ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/rdata.h b/contrib/bind9/lib/dns/include/dns/rdata.h index c3e7db6..2a67dc9 100644 --- a/contrib/bind9/lib/dns/include/dns/rdata.h +++ b/contrib/bind9/lib/dns/include/dns/rdata.h @@ -176,6 +176,7 @@ struct dns_rdata { #define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE #define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX #define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL +#define DNS_RDATA_UNKNOWNESCAPE 0x80000000 /*** *** Initialization diff --git a/contrib/bind9/lib/dns/include/dns/result.h b/contrib/bind9/lib/dns/include/dns/result.h index 21388b2..9a7d2c2 100644 --- a/contrib/bind9/lib/dns/include/dns/result.h +++ b/contrib/bind9/lib/dns/include/dns/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -151,8 +151,10 @@ #define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105) #define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106) #define DNS_R_EXPIRED (ISC_RESULTCLASS_DNS + 107) +#define DNS_R_NOTDYNAMIC (ISC_RESULTCLASS_DNS + 108) +#define DNS_R_BADEUI (ISC_RESULTCLASS_DNS + 109) -#define DNS_R_NRESULTS 108 /*%< Number of results */ +#define DNS_R_NRESULTS 110 /*%< Number of results */ /* * DNS wire format rcodes. diff --git a/contrib/bind9/lib/dns/include/dns/rpz.h b/contrib/bind9/lib/dns/include/dns/rpz.h index 4227dd4..ceea26d 100644 --- a/contrib/bind9/lib/dns/include/dns/rpz.h +++ b/contrib/bind9/lib/dns/include/dns/rpz.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -27,10 +27,11 @@ ISC_LANG_BEGINDECLS -#define DNS_RPZ_IP_ZONE "rpz-ip" -#define DNS_RPZ_NSIP_ZONE "rpz-nsip" -#define DNS_RPZ_NSDNAME_ZONE "rpz-nsdname" -#define DNS_RPZ_PASSTHRU_ZONE "rpz-passthru" +#define DNS_RPZ_PREFIX "rpz-" +#define DNS_RPZ_IP_ZONE DNS_RPZ_PREFIX"ip" +#define DNS_RPZ_NSIP_ZONE DNS_RPZ_PREFIX"nsip" +#define DNS_RPZ_NSDNAME_ZONE DNS_RPZ_PREFIX"nsdname" +#define DNS_RPZ_PASSTHRU_ZONE DNS_RPZ_PREFIX"passthru" typedef isc_uint8_t dns_rpz_cidr_bits_t; @@ -75,6 +76,7 @@ struct dns_rpz_zone { dns_ttl_t max_policy_ttl; dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */ isc_boolean_t recursive_only; + isc_boolean_t defined; }; /* @@ -169,12 +171,6 @@ const char * dns_rpz_policy2str(dns_rpz_policy_t policy); void -dns_rpz_set_need(isc_boolean_t need); - -isc_boolean_t -dns_rpz_needed(void); - -void dns_rpz_cidr_free(dns_rpz_cidr_t **cidr); void @@ -184,7 +180,7 @@ isc_result_t dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, dns_rpz_cidr_t **rbtdb_cidr); void -dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st); +dns_rpz_enabled_get(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st); void dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name); diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h index 921c76aa..a031825 100644 --- a/contrib/bind9/lib/dns/include/dns/types.h +++ b/contrib/bind9/lib/dns/include/dns/types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -72,6 +72,7 @@ typedef ISC_LIST(dns_dns64_t) dns_dns64list_t; typedef struct dns_dnsseckey dns_dnsseckey_t; typedef ISC_LIST(dns_dnsseckey_t) dns_dnsseckeylist_t; typedef struct dns_dumpctx dns_dumpctx_t; +typedef struct dns_ednsopt dns_ednsopt_t; typedef struct dns_fetch dns_fetch_t; typedef struct dns_fixedname dns_fixedname_t; typedef struct dns_forwarders dns_forwarders_t; @@ -373,4 +374,7 @@ typedef isc_boolean_t (*dns_isselffunc_t)(dns_view_t *, dns_tsigkey_t *, isc_sockaddr_t *, isc_sockaddr_t *, dns_rdataclass_t, void *); +typedef void +(*dns_nseclog_t)(void *val, int , const char *, ...); + #endif /* DNS_TYPES_H */ diff --git a/contrib/bind9/lib/dns/include/dns/validator.h b/contrib/bind9/lib/dns/include/dns/validator.h index 7d6ea7a..b3cfe99 100644 --- a/contrib/bind9/lib/dns/include/dns/validator.h +++ b/contrib/bind9/lib/dns/include/dns/validator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -104,6 +104,10 @@ typedef struct dns_validatorevent { * Optout proof seen. */ isc_boolean_t optout; + /* + * Answer is secure. + */ + isc_boolean_t secure; } dns_validatorevent_t; #define DNS_VALIDATOR_NOQNAMEPROOF 0 diff --git a/contrib/bind9/lib/dns/include/dns/view.h b/contrib/bind9/lib/dns/include/dns/view.h index 4a04867..d999fa1 100644 --- a/contrib/bind9/lib/dns/include/dns/view.h +++ b/contrib/bind9/lib/dns/include/dns/view.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -164,6 +164,7 @@ struct dns_view { ISC_LIST(dns_rpz_zone_t) rpz_zones; isc_boolean_t rpz_recursive_only; isc_boolean_t rpz_break_dnssec; + unsigned int rpz_min_ns_labels; /* * Configurable data for server use only, diff --git a/contrib/bind9/lib/dns/include/dns/zone.h b/contrib/bind9/lib/dns/include/dns/zone.h index 9db825c..6b9911d 100644 --- a/contrib/bind9/lib/dns/include/dns/zone.h +++ b/contrib/bind9/lib/dns/include/dns/zone.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -34,6 +34,7 @@ #include <dns/masterdump.h> #include <dns/rdatastruct.h> +#include <dns/rpz.h> #include <dns/types.h> typedef enum { @@ -77,6 +78,7 @@ typedef enum { #define DNS_ZONEOPT_DNSKEYKSKONLY 0x10000000U /*%< dnssec-dnskey-kskonly */ #define DNS_ZONEOPT_CHECKDUPRR 0x20000000U /*%< check-dup-records */ #define DNS_ZONEOPT_CHECKDUPRRFAIL 0x40000000U /*%< fatal check-dup-records failures */ +#define DNS_ZONEOPT_CHECKSPF 0x80000000U /*%< check SPF records */ #ifndef NOMINUM_PUBLIC /* @@ -1898,6 +1900,15 @@ dns_zone_synckeyzone(dns_zone_t *zone); * maintenance timer. */ +isc_result_t +dns_zone_rpz_enable(dns_zone_t *zone); +/*% + * Set the response policy associated with a zone. + */ + +isc_boolean_t +dns_zone_get_rpz(dns_zone_t *zone); + ISC_LANG_ENDDECLS #endif /* DNS_ZONE_H */ diff --git a/contrib/bind9/lib/dns/include/dst/dst.h b/contrib/bind9/lib/dns/include/dst/dst.h index b0fa690..87d844b 100644 --- a/contrib/bind9/lib/dns/include/dst/dst.h +++ b/contrib/bind9/lib/dns/include/dst/dst.h @@ -26,6 +26,7 @@ #include <isc/stdtime.h> #include <dns/types.h> +#include <dns/log.h> #include <dns/name.h> #include <dns/secalg.h> @@ -169,6 +170,11 @@ dst_algorithm_supported(unsigned int alg); isc_result_t dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp); + +isc_result_t +dst_context_create2(dst_key_t *key, isc_mem_t *mctx, + isc_logcategory_t *category, dst_context_t **dctxp); + /*%< * Creates a context to be used for a sign or verify operation. * diff --git a/contrib/bind9/lib/dns/master.c b/contrib/bind9/lib/dns/master.c index 8304507..1b7460c 100644 --- a/contrib/bind9/lib/dns/master.c +++ b/contrib/bind9/lib/dns/master.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -156,6 +156,7 @@ struct dns_incctx { int glue_in_use; int current_in_use; int origin_in_use; + isc_boolean_t origin_changed; isc_boolean_t drop; unsigned int glue_line; unsigned int current_line; @@ -568,6 +569,7 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, goto cleanup_inc; lctx->keep_lex = ISC_FALSE; memset(specials, 0, sizeof(specials)); + specials[0] = 1; specials['('] = 1; specials[')'] = 1; specials['"'] = 1; @@ -770,7 +772,7 @@ static isc_result_t openfile_raw(dns_loadctx_t *lctx, const char *master_file) { isc_result_t result; - result = isc_stdio_open(master_file, "r", &lctx->f); + result = isc_stdio_open(master_file, "rb", &lctx->f); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_stdio_open() failed: %s", @@ -1402,6 +1404,7 @@ load_text(dns_loadctx_t *lctx) { ictx->origin_in_use = new_in_use; ictx->in_use[ictx->origin_in_use] = ISC_TRUE; ictx->origin = new_name; + ictx->origin_changed = ISC_TRUE; finish_origin = ISC_FALSE; EXPECTEOL; continue; @@ -1574,8 +1577,24 @@ load_text(dns_loadctx_t *lctx) { } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } + + if (ictx->origin_changed) { + char cbuf[DNS_NAME_FORMATSIZE]; + char obuf[DNS_NAME_FORMATSIZE]; + dns_name_format(ictx->current, cbuf, + sizeof(cbuf)); + dns_name_format(ictx->origin, obuf, + sizeof(obuf)); + (*callbacks->warn)(callbacks, + "%s:%lu: record with inherited " + "owner (%s) immediately after " + "$ORIGIN (%s)", source, line, + cbuf, obuf); + } } + ictx->origin_changed = ISC_FALSE; + if (dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) diff --git a/contrib/bind9/lib/dns/message.c b/contrib/bind9/lib/dns/message.c index 2b65f0e..d36edba 100644 --- a/contrib/bind9/lib/dns/message.c +++ b/contrib/bind9/lib/dns/message.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -1441,8 +1441,15 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, * the opcode is an update, or the type search is skipped. */ if (result == ISC_R_SUCCESS) { - if (dns_rdatatype_issingleton(rdtype)) - DO_FORMERR; + if (dns_rdatatype_issingleton(rdtype)) { + dns_rdata_t *first; + dns_rdatalist_fromrdataset(rdataset, + &rdatalist); + first = ISC_LIST_HEAD(rdatalist->rdata); + INSIST(first != NULL); + if (dns_rdata_compare(rdata, first) != 0) + DO_FORMERR; + } } if (result == ISC_R_NOTFOUND) { @@ -2112,6 +2119,30 @@ dns_message_renderend(dns_message_t *msg) { } /* + * If we're adding a OPT, TSIG or SIG(0) to a truncated message, + * clear all rdatasets from the message except for the question + * before adding the OPT, TSIG or SIG(0). If the question doesn't + * fit, don't include it. + */ + if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) && + (msg->flags & DNS_MESSAGEFLAG_TC) != 0) + { + isc_buffer_t *buf; + + msgresetnames(msg, DNS_SECTION_ANSWER); + buf = msg->buffer; + dns_message_renderreset(msg); + msg->buffer = buf; + isc_buffer_clear(msg->buffer); + isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN); + dns_compress_rollback(msg->cctx, 0); + result = dns_message_rendersection(msg, DNS_SECTION_QUESTION, + 0); + if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) + return (result); + } + + /* * If we've got an OPT record, render it. */ if (msg->opt != NULL) { @@ -2136,30 +2167,6 @@ dns_message_renderend(dns_message_t *msg) { } /* - * If we're adding a TSIG or SIG(0) to a truncated message, - * clear all rdatasets from the message except for the question - * before adding the TSIG or SIG(0). If the question doesn't fit, - * don't include it. - */ - if ((msg->tsigkey != NULL || msg->sig0key != NULL) && - (msg->flags & DNS_MESSAGEFLAG_TC) != 0) - { - isc_buffer_t *buf; - - msgresetnames(msg, DNS_SECTION_ANSWER); - buf = msg->buffer; - dns_message_renderreset(msg); - msg->buffer = buf; - isc_buffer_clear(msg->buffer); - isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN); - dns_compress_rollback(msg->cctx, 0); - result = dns_message_rendersection(msg, DNS_SECTION_QUESTION, - 0); - if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) - return (result); - } - - /* * If we're adding a TSIG record, generate and render it. */ if (msg->tsigkey != NULL) { @@ -2633,9 +2640,9 @@ dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) { return (ISC_R_SUCCESS); cleanup: + dns_rdataset_disassociate(opt); dns_message_puttemprdataset(msg, &opt); return (result); - } dns_rdataset_t * @@ -3449,3 +3456,95 @@ dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) { isc_buffer_putstr(target, opcodetext[opcode]); return (ISC_R_SUCCESS); } + +isc_result_t +dns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp, + unsigned int version, isc_uint16_t udpsize, + unsigned int flags, dns_ednsopt_t *ednsopts, size_t count) +{ + dns_rdataset_t *rdataset = NULL; + dns_rdatalist_t *rdatalist = NULL; + dns_rdata_t *rdata = NULL; + isc_result_t result; + size_t len = 0, i; + + REQUIRE(DNS_MESSAGE_VALID(message)); + REQUIRE(rdatasetp != NULL && *rdatasetp == NULL); + + result = dns_message_gettemprdatalist(message, &rdatalist); + if (result != ISC_R_SUCCESS) + return (result); + result = dns_message_gettemprdata(message, &rdata); + if (result != ISC_R_SUCCESS) + goto cleanup; + result = dns_message_gettemprdataset(message, &rdataset); + if (result != ISC_R_SUCCESS) + goto cleanup; + dns_rdataset_init(rdataset); + + rdatalist->type = dns_rdatatype_opt; + rdatalist->covers = 0; + + /* + * Set Maximum UDP buffer size. + */ + rdatalist->rdclass = udpsize; + + /* + * Set EXTENDED-RCODE and Z to 0. + */ + rdatalist->ttl = (version << 16); + rdatalist->ttl |= (flags & 0xffff); + + /* + * Set EDNS options if applicable + */ + if (count != 0U) { + isc_buffer_t *buf = NULL; + for (i = 0; i < count; i++) + len += ednsopts[i].length + 4; + + if (len > 0xffffU) { + result = ISC_R_NOSPACE; + goto cleanup; + } + + result = isc_buffer_allocate(message->mctx, &buf, len); + if (result != ISC_R_SUCCESS) + goto cleanup; + + for (i = 0; i < count; i++) { + isc_buffer_putuint16(buf, ednsopts[i].code); + isc_buffer_putuint16(buf, ednsopts[i].length); + isc_buffer_putmem(buf, ednsopts[i].value, + ednsopts[i].length); + } + rdata->data = isc_buffer_base(buf); + rdata->length = len; + dns_message_takebuffer(message, &buf); + } else { + rdata->data = NULL; + rdata->length = 0; + } + + rdata->rdclass = rdatalist->rdclass; + rdata->type = rdatalist->type; + rdata->flags = 0; + + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + result = dns_rdatalist_tordataset(rdatalist, rdataset); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + *rdatasetp = rdataset; + return (ISC_R_SUCCESS); + + cleanup: + if (rdata != NULL) + dns_message_puttemprdata(message, &rdata); + if (rdataset != NULL) + dns_message_puttemprdataset(message, &rdataset); + if (rdatalist != NULL) + dns_message_puttemprdatalist(message, &rdatalist); + return (result); +} diff --git a/contrib/bind9/lib/dns/name.c b/contrib/bind9/lib/dns/name.c index fab1f33..7fb21e1 100644 --- a/contrib/bind9/lib/dns/name.c +++ b/contrib/bind9/lib/dns/name.c @@ -584,11 +584,13 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, nlabels = 0; l1 = name1->labels; l2 = name2->labels; - ldiff = (int)l1 - (int)l2; - if (ldiff < 0) + if (l2 > l1) { l = l1; - else + ldiff = 0 - (l2 - l1); + } else { l = l2; + ldiff = l1 - l2; + } while (l > 0) { l--; @@ -841,6 +843,10 @@ dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) { REQUIRE(labels > 0); REQUIRE(dns_name_iswildcard(wname)); +#if defined(__clang__) && \ + ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) + memset(&tname, 0, sizeof(tname)); +#endif DNS_NAME_INIT(&tname, NULL); dns_name_getlabelsequence(wname, 1, labels - 1, &tname); if (dns_name_fullcompare(name, &tname, &order, &nlabels) == @@ -1427,6 +1433,7 @@ dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target) case 0x24: /* '$' */ if ((options & DNS_NAME_MASTERFILE) == 0) goto no_escape; + /* FALLTHROUGH */ case 0x22: /* '"' */ case 0x28: /* '(' */ case 0x29: /* ')' */ @@ -1934,6 +1941,10 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, * has one. */ if (name->offsets == NULL) { +#if defined(__clang__) && \ + ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) + memset(&clname, 0, sizeof(clname)); +#endif DNS_NAME_INIT(&clname, clo); dns_name_clone(name, &clname); name = &clname; @@ -2239,7 +2250,12 @@ dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) { REQUIRE(VALID_NAME(name)); REQUIRE(digest != NULL); +#if defined(__clang__) && \ + ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) + memset(&downname, 0, sizeof(downname)); +#endif DNS_NAME_INIT(&downname, NULL); + isc_buffer_init(&buffer, data, sizeof(data)); result = dns_name_downcase(name, &downname, &buffer); @@ -2404,7 +2420,7 @@ dns_name_fromstring2(dns_name_t *target, const char *src, REQUIRE(src != NULL); - isc_buffer_init(&buf, src, strlen(src)); + isc_buffer_constinit(&buf, src, strlen(src)); isc_buffer_add(&buf, strlen(src)); if (BINDABLE(target) && target->buffer != NULL) name = target; diff --git a/contrib/bind9/lib/dns/ncache.c b/contrib/bind9/lib/dns/ncache.c index c0e99d4..bcb3d05 100644 --- a/contrib/bind9/lib/dns/ncache.c +++ b/contrib/bind9/lib/dns/ncache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008, 2010-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2010-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -47,6 +47,12 @@ * */ +static isc_result_t +addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, + dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, + isc_boolean_t optout, isc_boolean_t secure, + dns_rdataset_t *addedrdataset); + static inline isc_result_t copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) { isc_result_t result; @@ -96,8 +102,8 @@ dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, dns_rdataset_t *addedrdataset) { - return (dns_ncache_addoptout(message, cache, node, covers, now, maxttl, - ISC_FALSE, addedrdataset)); + return (addoptout(message, cache, node, covers, now, maxttl, + ISC_FALSE, ISC_FALSE, addedrdataset)); } isc_result_t @@ -106,6 +112,16 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, dns_rdataset_t *addedrdataset) { + return (addoptout(message, cache, node, covers, now, maxttl, + optout, ISC_TRUE, addedrdataset)); +} + +static isc_result_t +addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, + dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, + isc_boolean_t optout, isc_boolean_t secure, + dns_rdataset_t *addedrdataset) +{ isc_result_t result; isc_buffer_t buffer; isc_region_t r; @@ -242,6 +258,8 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, dns_rdataset_init(&ncrdataset); RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset) == ISC_R_SUCCESS); + if (!secure && trust > dns_trust_answer) + trust = dns_trust_answer; ncrdataset.trust = trust; ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE; if (message->rcode == dns_rcode_nxdomain) diff --git a/contrib/bind9/lib/dns/nsec.c b/contrib/bind9/lib/dns/nsec.c index 72d1751..41b5dc3 100644 --- a/contrib/bind9/lib/dns/nsec.c +++ b/contrib/bind9/lib/dns/nsec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -21,6 +21,7 @@ #include <config.h> +#include <isc/log.h> #include <isc/string.h> #include <isc/util.h> @@ -275,3 +276,161 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, } return (result); } + +/*% + * Return ISC_R_SUCCESS if we can determine that the name doesn't exist + * or we can determine whether there is data or not at the name. + * If the name does not exist return the wildcard name. + * + * Return ISC_R_IGNORE when the NSEC is not the appropriate one. + */ +isc_result_t +dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name, + dns_name_t *nsecname, dns_rdataset_t *nsecset, + isc_boolean_t *exists, isc_boolean_t *data, + dns_name_t *wild, dns_nseclog_t logit, void *arg) +{ + int order; + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_result_t result; + dns_namereln_t relation; + unsigned int olabels, nlabels, labels; + dns_rdata_nsec_t nsec; + isc_boolean_t atparent; + isc_boolean_t ns; + isc_boolean_t soa; + + REQUIRE(exists != NULL); + REQUIRE(data != NULL); + REQUIRE(nsecset != NULL && + nsecset->type == dns_rdatatype_nsec); + + result = dns_rdataset_first(nsecset); + if (result != ISC_R_SUCCESS) { + (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC set"); + return (result); + } + dns_rdataset_current(nsecset, &rdata); + + (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC"); + relation = dns_name_fullcompare(name, nsecname, &order, &olabels); + + if (order < 0) { + /* + * The name is not within the NSEC range. + */ + (*logit)(arg, ISC_LOG_DEBUG(3), + "NSEC does not cover name, before NSEC"); + return (ISC_R_IGNORE); + } + + if (order == 0) { + /* + * The names are the same. If we are validating "." + * then atparent should not be set as there is no parent. + */ + atparent = (olabels != 1) && dns_rdatatype_atparent(type); + ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns); + soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa); + if (ns && !soa) { + if (!atparent) { + /* + * This NSEC record is from somewhere higher in + * the DNS, and at the parent of a delegation. + * It can not be legitimately used here. + */ + (*logit)(arg, ISC_LOG_DEBUG(3), + "ignoring parent nsec"); + return (ISC_R_IGNORE); + } + } else if (atparent && ns && soa) { + /* + * This NSEC record is from the child. + * It can not be legitimately used here. + */ + (*logit)(arg, ISC_LOG_DEBUG(3), + "ignoring child nsec"); + return (ISC_R_IGNORE); + } + if (type == dns_rdatatype_cname || type == dns_rdatatype_nxt || + type == dns_rdatatype_nsec || type == dns_rdatatype_key || + !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) { + *exists = ISC_TRUE; + *data = dns_nsec_typepresent(&rdata, type); + (*logit)(arg, ISC_LOG_DEBUG(3), + "nsec proves name exists (owner) data=%d", + *data); + return (ISC_R_SUCCESS); + } + (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists"); + return (ISC_R_IGNORE); + } + + if (relation == dns_namereln_subdomain && + dns_nsec_typepresent(&rdata, dns_rdatatype_ns) && + !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) + { + /* + * This NSEC record is from somewhere higher in + * the DNS, and at the parent of a delegation. + * It can not be legitimately used here. + */ + (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring parent nsec"); + return (ISC_R_IGNORE); + } + + result = dns_rdata_tostruct(&rdata, &nsec, NULL); + if (result != ISC_R_SUCCESS) + return (result); + relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels); + if (order == 0) { + dns_rdata_freestruct(&nsec); + (*logit)(arg, ISC_LOG_DEBUG(3), + "ignoring nsec matches next name"); + return (ISC_R_IGNORE); + } + + if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) { + /* + * The name is not within the NSEC range. + */ + dns_rdata_freestruct(&nsec); + (*logit)(arg, ISC_LOG_DEBUG(3), + "ignoring nsec because name is past end of range"); + return (ISC_R_IGNORE); + } + + if (order > 0 && relation == dns_namereln_subdomain) { + (*logit)(arg, ISC_LOG_DEBUG(3), + "nsec proves name exist (empty)"); + dns_rdata_freestruct(&nsec); + *exists = ISC_TRUE; + *data = ISC_FALSE; + return (ISC_R_SUCCESS); + } + if (wild != NULL) { + dns_name_t common; + dns_name_init(&common, NULL); + if (olabels > nlabels) { + labels = dns_name_countlabels(nsecname); + dns_name_getlabelsequence(nsecname, labels - olabels, + olabels, &common); + } else { + labels = dns_name_countlabels(&nsec.next); + dns_name_getlabelsequence(&nsec.next, labels - nlabels, + nlabels, &common); + } + result = dns_name_concatenate(dns_wildcardname, &common, + wild, NULL); + if (result != ISC_R_SUCCESS) { + dns_rdata_freestruct(&nsec); + (*logit)(arg, ISC_LOG_DEBUG(3), + "failure generating wildcard name"); + return (result); + } + } + dns_rdata_freestruct(&nsec); + (*logit)(arg, ISC_LOG_DEBUG(3), "nsec range ok"); + *exists = ISC_FALSE; + return (ISC_R_SUCCESS); +} diff --git a/contrib/bind9/lib/dns/nsec3.c b/contrib/bind9/lib/dns/nsec3.c index 123126d..7ec6b4c 100644 --- a/contrib/bind9/lib/dns/nsec3.c +++ b/contrib/bind9/lib/dns/nsec3.c @@ -22,6 +22,7 @@ #include <isc/buffer.h> #include <isc/hex.h> #include <isc/iterated_hash.h> +#include <isc/log.h> #include <isc/string.h> #include <isc/util.h> @@ -1132,7 +1133,11 @@ dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, INSIST(rdata.length <= sizeof(buf)); memcpy(buf, rdata.data, rdata.length); - if (buf[0] != 0 || + /* + * Private NSEC3 record length >= 6. + * <0(1), hash(1), flags(1), iterations(2), saltlen(1)> + */ + if (rdata.length < 6 || buf[0] != 0 || buf[2] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) { dns_rdata_reset(&rdata); continue; @@ -1832,3 +1837,285 @@ dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, dns_rdataset_disassociate(&rdataset); return (result); } + +isc_result_t +dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name, + dns_name_t *nsec3name, dns_rdataset_t *nsec3set, + dns_name_t *zonename, isc_boolean_t *exists, + isc_boolean_t *data, isc_boolean_t *optout, + isc_boolean_t *unknown, isc_boolean_t *setclosest, + isc_boolean_t *setnearest, dns_name_t *closest, + dns_name_t *nearest, dns_nseclog_t logit, void *arg) +{ + char namebuf[DNS_NAME_FORMATSIZE]; + dns_fixedname_t fzone; + dns_fixedname_t qfixed; + dns_label_t hashlabel; + dns_name_t *qname; + dns_name_t *zone; + dns_rdata_nsec3_t nsec3; + dns_rdata_t rdata = DNS_RDATA_INIT; + int order; + int scope; + isc_boolean_t atparent; + isc_boolean_t first; + isc_boolean_t ns; + isc_boolean_t soa; + isc_buffer_t buffer; + isc_result_t answer = ISC_R_IGNORE; + isc_result_t result; + unsigned char hash[NSEC3_MAX_HASH_LENGTH]; + unsigned char owner[NSEC3_MAX_HASH_LENGTH]; + unsigned int length; + unsigned int qlabels; + unsigned int zlabels; + + REQUIRE((exists == NULL && data == NULL) || + (exists != NULL && data != NULL)); + REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3); + REQUIRE((setclosest == NULL && closest == NULL) || + (setclosest != NULL && closest != NULL)); + REQUIRE((setnearest == NULL && nearest == NULL) || + (setnearest != NULL && nearest != NULL)); + + result = dns_rdataset_first(nsec3set); + if (result != ISC_R_SUCCESS) { + (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set"); + return (result); + } + + dns_rdataset_current(nsec3set, &rdata); + + result = dns_rdata_tostruct(&rdata, &nsec3, NULL); + if (result != ISC_R_SUCCESS) + return (result); + + (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3"); + + dns_fixedname_init(&fzone); + zone = dns_fixedname_name(&fzone); + zlabels = dns_name_countlabels(nsec3name); + + /* + * NSEC3 records must have two or more labels to be valid. + */ + if (zlabels < 2) + return (ISC_R_IGNORE); + + /* + * Strip off the NSEC3 hash to get the zone. + */ + zlabels--; + dns_name_split(nsec3name, zlabels, NULL, zone); + + /* + * If not below the zone name we can ignore this record. + */ + if (!dns_name_issubdomain(name, zone)) + return (ISC_R_IGNORE); + + /* + * Is this zone the same or deeper than the current zone? + */ + if (dns_name_countlabels(zonename) == 0 || + dns_name_issubdomain(zone, zonename)) + dns_name_copy(zone, zonename, NULL); + + if (!dns_name_equal(zone, zonename)) + return (ISC_R_IGNORE); + + /* + * Are we only looking for the most enclosing zone? + */ + if (exists == NULL || data == NULL) + return (ISC_R_SUCCESS); + + /* + * Only set unknown once we are sure that this NSEC3 is from + * the deepest covering zone. + */ + if (!dns_nsec3_supportedhash(nsec3.hash)) { + if (unknown != NULL) + *unknown = ISC_TRUE; + return (ISC_R_IGNORE); + } + + /* + * Recover the hash from the first label. + */ + dns_name_getlabel(nsec3name, 0, &hashlabel); + isc_region_consume(&hashlabel, 1); + isc_buffer_init(&buffer, owner, sizeof(owner)); + result = isc_base32hex_decoderegion(&hashlabel, &buffer); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * The hash lengths should match. If not ignore the record. + */ + if (isc_buffer_usedlength(&buffer) != nsec3.next_length) + return (ISC_R_IGNORE); + + /* + * Work out what this NSEC3 covers. + * Inside (<0) or outside (>=0). + */ + scope = memcmp(owner, nsec3.next, nsec3.next_length); + + /* + * Prepare to compute all the hashes. + */ + dns_fixedname_init(&qfixed); + qname = dns_fixedname_name(&qfixed); + dns_name_downcase(name, qname, NULL); + qlabels = dns_name_countlabels(qname); + first = ISC_TRUE; + + while (qlabels >= zlabels) { + length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations, + nsec3.salt, nsec3.salt_length, + qname->ndata, qname->length); + /* + * The computed hash length should match. + */ + if (length != nsec3.next_length) { + (*logit)(arg, ISC_LOG_DEBUG(3), + "ignoring NSEC bad length %u vs %u", + length, nsec3.next_length); + return (ISC_R_IGNORE); + } + + order = memcmp(hash, owner, length); + if (first && order == 0) { + /* + * The hashes are the same. + */ + atparent = dns_rdatatype_atparent(type); + ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns); + soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa); + if (ns && !soa) { + if (!atparent) { + /* + * This NSEC3 record is from somewhere + * higher in the DNS, and at the + * parent of a delegation. It can not + * be legitimately used here. + */ + (*logit)(arg, ISC_LOG_DEBUG(3), + "ignoring parent NSEC3"); + return (ISC_R_IGNORE); + } + } else if (atparent && ns && soa) { + /* + * This NSEC3 record is from the child. + * It can not be legitimately used here. + */ + (*logit)(arg, ISC_LOG_DEBUG(3), + "ignoring child NSEC3"); + return (ISC_R_IGNORE); + } + if (type == dns_rdatatype_cname || + type == dns_rdatatype_nxt || + type == dns_rdatatype_nsec || + type == dns_rdatatype_key || + !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) { + *exists = ISC_TRUE; + *data = dns_nsec3_typepresent(&rdata, type); + (*logit)(arg, ISC_LOG_DEBUG(3), + "NSEC3 proves name exists (owner) " + "data=%d", *data); + return (ISC_R_SUCCESS); + } + (*logit)(arg, ISC_LOG_DEBUG(3), + "NSEC3 proves CNAME exists"); + return (ISC_R_IGNORE); + } + + if (order == 0 && + dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) && + !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa)) + { + /* + * This NSEC3 record is from somewhere higher in + * the DNS, and at the parent of a delegation. + * It can not be legitimately used here. + */ + (*logit)(arg, ISC_LOG_DEBUG(3), + "ignoring parent NSEC3"); + return (ISC_R_IGNORE); + } + + /* + * Potential closest encloser. + */ + if (order == 0) { + if (closest != NULL && + (dns_name_countlabels(closest) == 0 || + dns_name_issubdomain(qname, closest)) && + !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) && + !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) && + (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) || + !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns))) + { + + dns_name_format(qname, namebuf, + sizeof(namebuf)); + (*logit)(arg, ISC_LOG_DEBUG(3), + "NSEC3 indicates potential closest " + "encloser: '%s'", namebuf); + dns_name_copy(qname, closest, NULL); + *setclosest = ISC_TRUE; + } + dns_name_format(qname, namebuf, sizeof(namebuf)); + (*logit)(arg, ISC_LOG_DEBUG(3), + "NSEC3 at super-domain %s", namebuf); + return (answer); + } + + /* + * Find if the name does not exist. + * + * We continue as we need to find the name closest to the + * closest encloser that doesn't exist. + * + * We also need to continue to ensure that we are not + * proving the non-existence of a record in a sub-zone. + * If that would be the case we will return ISC_R_IGNORE + * above. + */ + if ((scope < 0 && order > 0 && + memcmp(hash, nsec3.next, length) < 0) || + (scope >= 0 && (order > 0 || + memcmp(hash, nsec3.next, length) < 0))) + { + char namebuf[DNS_NAME_FORMATSIZE]; + + dns_name_format(qname, namebuf, sizeof(namebuf)); + (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves " + "name does not exist: '%s'", namebuf); + if (nearest != NULL && + (dns_name_countlabels(nearest) == 0 || + dns_name_issubdomain(nearest, qname))) { + dns_name_copy(qname, nearest, NULL); + *setnearest = ISC_TRUE; + } + + *exists = ISC_FALSE; + *data = ISC_FALSE; + if (optout != NULL) { + if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0) + (*logit)(arg, ISC_LOG_DEBUG(3), + "NSEC3 indicates optout"); + *optout = + ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT); + } + answer = ISC_R_SUCCESS; + } + + qlabels--; + if (qlabels > 0) + dns_name_split(qname, qlabels, NULL, qname); + first = ISC_FALSE; + } + return (answer); +} diff --git a/contrib/bind9/lib/dns/openssl_link.c b/contrib/bind9/lib/dns/openssl_link.c index d186761..56465aa 100644 --- a/contrib/bind9/lib/dns/openssl_link.c +++ b/contrib/bind9/lib/dns/openssl_link.c @@ -286,46 +286,78 @@ dst__openssl_destroy() { } } -isc_result_t -dst__openssl_toresult(isc_result_t fallback) { +static isc_result_t +toresult(isc_result_t fallback) { isc_result_t result = fallback; unsigned long err = ERR_get_error(); +#ifdef HAVE_OPENSSL_ECDSA + int lib = ERR_GET_LIB(err); +#endif + int reason = ERR_GET_REASON(err); - switch (ERR_GET_REASON(err)) { + switch (reason) { + /* + * ERR_* errors are globally unique; others + * are unique per sublibrary + */ case ERR_R_MALLOC_FAILURE: result = ISC_R_NOMEMORY; break; default: +#ifdef HAVE_OPENSSL_ECDSA + if (lib == ERR_R_ECDSA_LIB && + reason == ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) { + result = ISC_R_NOENTROPY; + break; + } +#endif break; } + + return (result); +} + +isc_result_t +dst__openssl_toresult(isc_result_t fallback) { + isc_result_t result; + + result = toresult(fallback); + ERR_clear_error(); return (result); } isc_result_t dst__openssl_toresult2(const char *funcname, isc_result_t fallback) { - isc_result_t result = fallback; - unsigned long err = ERR_peek_error(); + return (dst__openssl_toresult3(DNS_LOGCATEGORY_GENERAL, + funcname, fallback)); +} + +isc_result_t +dst__openssl_toresult3(isc_logcategory_t *category, + const char *funcname, isc_result_t fallback) { + isc_result_t result; + unsigned long err; const char *file, *data; int line, flags; char buf[256]; - switch (ERR_GET_REASON(err)) { - case ERR_R_MALLOC_FAILURE: - result = ISC_R_NOMEMORY; - goto done; - default: - break; - } - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + result = toresult(fallback); + + isc_log_write(dns_lctx, category, DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, - "%s failed", funcname); + "%s failed (%s)", funcname, + isc_result_totext(result)); + + if (result == ISC_R_NOMEMORY) + goto done; + for (;;) { err = ERR_get_error_line_data(&file, &line, &data, &flags); if (err == 0U) goto done; ERR_error_string_n(err, buf, sizeof(buf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + isc_log_write(dns_lctx, category, DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO, "%s:%s:%d:%s", buf, file, line, (flags & ERR_TXT_STRING) ? data : ""); diff --git a/contrib/bind9/lib/dns/openssldsa_link.c b/contrib/bind9/lib/dns/openssldsa_link.c index e2cf8cd..66d47bb 100644 --- a/contrib/bind9/lib/dns/openssldsa_link.c +++ b/contrib/bind9/lib/dns/openssldsa_link.c @@ -168,7 +168,8 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { EVP_PKEY_free(pkey); free(sigbuf); - return (dst__openssl_toresult2("EVP_SignFinal", + return (dst__openssl_toresult3(dctx->category, + "EVP_SignFinal", ISC_R_FAILURE)); } INSIST(EVP_PKEY_size(pkey) >= (int) siglen); @@ -182,25 +183,30 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { sb = sigbuf; if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { free(sigbuf); - return (dst__openssl_toresult2("d2i_DSA_SIG", ISC_R_FAILURE)); + return (dst__openssl_toresult3(dctx->category, + "d2i_DSA_SIG", + ISC_R_FAILURE)); } free(sigbuf); #elif 0 /* Only use EVP for the Digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { - return (dst__openssl_toresult2("EVP_DigestFinal_ex", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestFinal_ex", ISC_R_FAILURE)); } dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) - return (dst__openssl_toresult2("DSA_do_sign", + return (dst__openssl_toresult3(dctx->category, + "DSA_do_sign", DST_R_SIGNFAILURE)); #else isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) - return (dst__openssl_toresult2("DSA_do_sign", + return (dst__openssl_toresult3(dctx->category, + "DSA_do_sign", DST_R_SIGNFAILURE)); #endif *r.base++ = (key->key_size - 512)/64; @@ -286,7 +292,8 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); default: - return (dst__openssl_toresult2("DSA_do_verify", + return (dst__openssl_toresult3(dctx->category, + "DSA_do_verify", DST_R_VERIFYFAILURE)); } } diff --git a/contrib/bind9/lib/dns/opensslecdsa_link.c b/contrib/bind9/lib/dns/opensslecdsa_link.c index e6c9b67..1cf30f8 100644 --- a/contrib/bind9/lib/dns/opensslecdsa_link.c +++ b/contrib/bind9/lib/dns/opensslecdsa_link.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -73,7 +73,8 @@ opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); - return (dst__openssl_toresult2("EVP_DigestInit_ex", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestInit_ex", ISC_R_FAILURE)); } @@ -103,7 +104,8 @@ opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { dctx->key->key_alg == DST_ALG_ECDSA384); if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) - return (dst__openssl_toresult2("EVP_DigestUpdate", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestUpdate", ISC_R_FAILURE)); return (ISC_R_SUCCESS); @@ -147,12 +149,14 @@ opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { DST_RET(ISC_R_NOSPACE); if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen)) - DST_RET(dst__openssl_toresult2("EVP_DigestFinal", + DST_RET(dst__openssl_toresult3(dctx->category, + "EVP_DigestFinal", ISC_R_FAILURE)); ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey); if (ecdsasig == NULL) - DST_RET(dst__openssl_toresult2("ECDSA_do_sign", + DST_RET(dst__openssl_toresult3(dctx->category, + "ECDSA_do_sign", DST_R_SIGNFAILURE)); BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2); r.base += siglen / 2; @@ -196,14 +200,19 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { return (DST_R_VERIFYFAILURE); if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen)) - DST_RET (dst__openssl_toresult2("EVP_DigestFinal_ex", + DST_RET (dst__openssl_toresult3(dctx->category, + "EVP_DigestFinal_ex", ISC_R_FAILURE)); ecdsasig = ECDSA_SIG_new(); if (ecdsasig == NULL) DST_RET (ISC_R_NOMEMORY); + if (ecdsasig->r != NULL) + BN_free(ecdsasig->r); ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL); cp += siglen / 2; + if (ecdsasig->s != NULL) + BN_free(ecdsasig->s); ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL); /* cp += siglen / 2; */ @@ -216,7 +225,8 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { ret = dst__openssl_toresult(DST_R_VERIFYFAILURE); break; default: - ret = dst__openssl_toresult2("ECDSA_do_verify", + ret = dst__openssl_toresult3(dctx->category, + "ECDSA_do_verify", DST_R_VERIFYFAILURE); break; } diff --git a/contrib/bind9/lib/dns/opensslgost_link.c b/contrib/bind9/lib/dns/opensslgost_link.c index 8a55a6b..098e312 100644 --- a/contrib/bind9/lib/dns/opensslgost_link.c +++ b/contrib/bind9/lib/dns/opensslgost_link.c @@ -127,7 +127,8 @@ opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) { case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); default: - return (dst__openssl_toresult2("EVP_VerifyFinal", + return (dst__openssl_toresult3(dctx->category, + "EVP_VerifyFinal", DST_R_VERIFYFAILURE)); } } diff --git a/contrib/bind9/lib/dns/opensslrsa_link.c b/contrib/bind9/lib/dns/opensslrsa_link.c index 80c3f57..2430f24 100644 --- a/contrib/bind9/lib/dns/opensslrsa_link.c +++ b/contrib/bind9/lib/dns/opensslrsa_link.c @@ -156,7 +156,8 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); - return (dst__openssl_toresult2("EVP_DigestInit_ex", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestInit_ex", ISC_R_FAILURE)); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; @@ -305,7 +306,8 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) { #if USE_EVP if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { - return (dst__openssl_toresult2("EVP_DigestUpdate", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestUpdate", ISC_R_FAILURE)); } #else @@ -395,7 +397,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { return (ISC_R_NOSPACE); if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) { - return (dst__openssl_toresult2("EVP_SignFinal", + return (dst__openssl_toresult3(dctx->category, + "EVP_SignFinal", ISC_R_FAILURE)); } #else @@ -489,7 +492,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); #endif if (status == 0) - return (dst__openssl_toresult2("RSA_sign", + return (dst__openssl_toresult3(dctx->category, + "RSA_sign", DST_R_OPENSSLFAILURE)); #endif @@ -525,6 +529,16 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { #if USE_EVP status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); + switch (status) { + case 1: + return (ISC_R_SUCCESS); + case 0: + return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); + default: + return (dst__openssl_toresult3(dctx->category, + "EVP_VerifyFinal", + DST_R_VERIFYFAILURE)); + } #else switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: @@ -610,7 +624,8 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { original, rsa, RSA_PKCS1_PADDING); if (status <= 0) - return (dst__openssl_toresult2( + return (dst__openssl_toresult3( + dctx->category, "RSA_public_decrypt", DST_R_VERIFYFAILURE)); if (status != (int)(prefixlen + digestlen)) @@ -631,12 +646,10 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { status = RSA_verify(type, digest, digestlen, sig->base, RSA_size(rsa), rsa); #endif -#endif if (status != 1) - return (dst__openssl_toresult2("RSA_verify", - DST_R_VERIFYFAILURE)); - + return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); +#endif } static isc_boolean_t diff --git a/contrib/bind9/lib/dns/peer.c b/contrib/bind9/lib/dns/peer.c index c55d73d..ec9e08c 100644 --- a/contrib/bind9/lib/dns/peer.c +++ b/contrib/bind9/lib/dns/peer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -533,7 +533,7 @@ dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) { isc_result_t result; dns_fixedname_init(&fname); - isc_buffer_init(&b, keyval, strlen(keyval)); + isc_buffer_constinit(&b, keyval, strlen(keyval)); isc_buffer_add(&b, strlen(keyval)); result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname, 0, NULL); diff --git a/contrib/bind9/lib/dns/rbt.c b/contrib/bind9/lib/dns/rbt.c index 4e033d6..eb95d14 100644 --- a/contrib/bind9/lib/dns/rbt.c +++ b/contrib/bind9/lib/dns/rbt.c @@ -1537,6 +1537,8 @@ rehash(dns_rbt_t *rbt) { return; } + INSIST(rbt->hashsize > 0); + for (i = 0; i < rbt->hashsize; i++) rbt->hashtable[i] = NULL; @@ -1947,6 +1949,7 @@ dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) { COLOR(sibling) = COLOR(parent); MAKE_BLACK(parent); + INSIST(RIGHT(sibling) != NULL); MAKE_BLACK(RIGHT(sibling)); rotate_left(parent, rootp); child = *rootp; @@ -1984,6 +1987,7 @@ dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) { COLOR(sibling) = COLOR(parent); MAKE_BLACK(parent); + INSIST(LEFT(sibling) != NULL); MAKE_BLACK(LEFT(sibling)); rotate_right(parent, rootp); child = *rootp; diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c index ef721b8..f6f96ab 100644 --- a/contrib/bind9/lib/dns/rbtdb.c +++ b/contrib/bind9/lib/dns/rbtdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -1550,15 +1550,16 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "delete_nsecnode(): " + "delete_node(): " "dns_rbt_deletenode(nsecnode): %s", isc_result_totext(result)); } } - result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); #ifdef BIND9 - dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name); + if (rbtdb->rpz_cidr != NULL) + dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name); #endif + result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); break; case DNS_RBT_NSEC_NSEC: result = dns_rbt_deletenode(rbtdb->nsec, node, ISC_FALSE); @@ -1572,7 +1573,7 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "delete_nsecnode(): " + "delete_cnode(): " "dns_rbt_deletenode: %s", isc_result_totext(result)); } @@ -4547,19 +4548,28 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, } /* - * Mark a database for response policy rewriting. + * Mark a database for response policy rewriting + * or find which RPZ data is available. */ #ifdef BIND9 -static void -get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) -{ +static isc_result_t +rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) { dns_rbtdb_t *rbtdb; + isc_result_t result; + result = ISC_R_SUCCESS; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - dns_rpz_enabled(rbtdb->rpz_cidr, st); + if (st != NULL) { + dns_rpz_enabled_get(rbtdb->rpz_cidr, st); + } else { + result = dns_rpz_new_cidr(rbtdb->common.mctx, + &rbtdb->common.origin, + &rbtdb->rpz_cidr); + } RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); + return (result); } /* @@ -6224,6 +6234,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, * will do it on the LRU side, so memory * will not leak... for long. */ + INSIST(rbtdb->heaps != NULL); isc_heap_insert(rbtdb->heaps[idx], newheader); } else if (RESIGN(newheader)) resign_insert(rbtdb, idx, newheader); @@ -6357,7 +6368,8 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader, cleanup: dns_rdataset_disassociate(&neg); dns_rdataset_disassociate(&negsig); - free_noqname(mctx, &noqname); + if (noqname != NULL) + free_noqname(mctx, &noqname); return(result); } @@ -6407,7 +6419,8 @@ addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader, cleanup: dns_rdataset_disassociate(&neg); dns_rdataset_disassociate(&negsig); - free_noqname(mctx, &closest); + if (closest != NULL) + free_noqname(mctx, &closest); return(result); } @@ -6860,7 +6873,7 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep, noderesult = dns_rbt_addnode(rbtdb->tree, name, nodep); #ifdef BIND9 - if (noderesult == ISC_R_SUCCESS) + if (noderesult == ISC_R_SUCCESS && rbtdb->rpz_cidr != NULL) dns_rpz_cidr_addip(rbtdb->rpz_cidr, name); #endif @@ -7447,8 +7460,8 @@ static dns_dbmethods_t zone_methods = { isdnssec, NULL, #ifdef BIND9 - get_rpz_enabled, - rpz_findips + rpz_enabled, + rpz_findips, #else NULL, NULL @@ -7681,24 +7694,6 @@ dns_rbtdb_create return (result); } -#ifdef BIND9 - /* - * Get ready for response policy IP address searching if at least one - * zone has been configured as a response policy zone and this - * is not a cache zone. - * It would be better to know that this database is for a policy - * zone named for a view, but that would require knowledge from - * above such as an argv[] set from data in the zone. - */ - if (type == dns_dbtype_zone && !dns_name_equal(origin, dns_rootname)) { - result = dns_rpz_new_cidr(mctx, origin, &rbtdb->rpz_cidr); - if (result != ISC_R_SUCCESS) { - free_rbtdb(rbtdb, ISC_FALSE, NULL); - return (result); - } - } -#endif - /* * In order to set the node callback bit correctly in zone databases, * we need to know if the node has the origin name of the zone. @@ -7977,7 +7972,9 @@ rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { dns_dbnode_t *cloned_node = NULL; attachnode(db, node, &cloned_node); + INSIST(!ISC_LINK_LINKED(target, link)); *target = *source; + ISC_LINK_INIT(target, link); /* * Reset iterator state. @@ -8929,12 +8926,10 @@ acache_callback(dns_acacheentry_t *entry, void **arg) { if (acarray != NULL && acarray[count].entry == entry) { acarray[count].entry = NULL; INSIST(acarray[count].cbarg == cbarg); - isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t)); acarray[count].cbarg = NULL; - } else isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t)); - - dns_acache_detachentry(&entry); + dns_acache_detachentry(&entry); + } NODE_UNLOCK(nodelock, isc_rwlocktype_write); @@ -8958,9 +8953,10 @@ acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry, cbarg = *cbargp; - dns_acache_cancelentry(entry); - dns_db_detachnode(cbarg->db, &cbarg->node); - dns_db_detach(&cbarg->db); + if (dns_acache_cancelentry(entry)) { + dns_db_detachnode(cbarg->db, &cbarg->node); + dns_db_detach(&cbarg->db); + } isc_mem_put(mctx, cbarg, sizeof(acache_cbarg_t)); @@ -9027,6 +9023,7 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, acache_callback, newcbarg, &newentry); if (result != ISC_R_SUCCESS) goto fail; + /* Set cache data in the new entry. */ result = dns_acache_setentry(acache, newentry, zone, db, version, node, fname); diff --git a/contrib/bind9/lib/dns/rdata.c b/contrib/bind9/lib/dns/rdata.c index 60890e0..3865f42 100644 --- a/contrib/bind9/lib/dns/rdata.c +++ b/contrib/bind9/lib/dns/rdata.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,8 +15,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ - /*! \file */ #include <config.h> @@ -124,6 +122,15 @@ txt_fromtext(isc_textregion_t *source, isc_buffer_t *target); static isc_result_t txt_fromwire(isc_buffer_t *source, isc_buffer_t *target); +static isc_result_t +multitxt_totext(isc_region_t *source, isc_buffer_t *target); + +static isc_result_t +multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target); + +static isc_result_t +multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target); + static isc_boolean_t name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target); @@ -212,6 +219,70 @@ static isc_result_t unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target); +/*% INT16 Size */ +#define NS_INT16SZ 2 +/*% IPv6 Address Size */ +#define NS_LOCATORSZ 8 + +/*% + * convert presentation level address to network order binary form. + * \return + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * \note + * (1) does not touch `dst' unless it's returning 1. + */ +static inline int +locator_pton(const char *src, unsigned char *dst) { + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[NS_LOCATORSZ]; + unsigned char *tp = tmp, *endp; + const char *xdigits; + int ch, seen_xdigits; + unsigned int val; + + memset(tp, '\0', NS_LOCATORSZ); + endp = tp + NS_LOCATORSZ; + seen_xdigits = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + pch = strchr((xdigits = xdigits_l), ch); + if (pch == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (++seen_xdigits > 4) + return (0); + continue; + } + if (ch == ':') { + if (!seen_xdigits) + return (0); + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + seen_xdigits = 0; + val = 0; + continue; + } + return (0); + } + if (seen_xdigits) { + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, NS_LOCATORSZ); + return (1); +} + static inline int getquad(const void *src, struct in_addr *dst, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) @@ -559,9 +630,9 @@ unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type, if (type == 0 || dns_rdatatype_ismeta(type)) return (DNS_R_METATYPE); - result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - ISC_FALSE); - if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535U) + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 65535U) return (ISC_R_RANGE); result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong); if (result != ISC_R_SUCCESS) @@ -611,6 +682,7 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, void (*callback)(dns_rdatacallbacks_t *, const char *, ...); isc_result_t tresult; size_t length; + isc_boolean_t unknown; REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE); if (rdata != NULL) { @@ -638,13 +710,33 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, return (result); } - if (strcmp(DNS_AS_STR(token), "\\#") == 0) - result = unknown_fromtext(rdclass, type, lexer, mctx, target); - else { + unknown = ISC_FALSE; + if (token.type == isc_tokentype_string && + strcmp(DNS_AS_STR(token), "\\#") == 0) { + /* + * If this is a TXT record '\#' could be a escaped '#'. + * Look to see if the next token is a number and if so + * treat it as a unknown record format. + */ + if (type == dns_rdatatype_txt) { + result = isc_lex_getmastertoken(lexer, &token, + isc_tokentype_number, + ISC_FALSE); + if (result == ISC_R_SUCCESS) + isc_lex_ungettoken(lexer, &token); + } + + if (result == ISC_R_SUCCESS) { + unknown = ISC_TRUE; + result = unknown_fromtext(rdclass, type, lexer, + mctx, target); + } else + options |= DNS_RDATA_UNKNOWNESCAPE; + } else isc_lex_ungettoken(lexer, &token); + if (!unknown) FROMTEXTSWITCH - } /* * Consume to end of line / file. @@ -1174,6 +1266,157 @@ txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { return (ISC_R_SUCCESS); } +static isc_result_t +multitxt_totext(isc_region_t *source, isc_buffer_t *target) { + unsigned int tl; + unsigned int n0, n; + unsigned char *sp; + char *tp; + isc_region_t region; + + isc_buffer_availableregion(target, ®ion); + sp = source->base; + tp = (char *)region.base; + tl = region.length; + + if (tl < 1) + return (ISC_R_NOSPACE); + *tp++ = '"'; + tl--; + do { + n0 = n = *sp++; + + REQUIRE(n0 + 1 <= source->length); + + while (n--) { + if (*sp < 0x20 || *sp >= 0x7f) { + if (tl < 4) + return (ISC_R_NOSPACE); + *tp++ = 0x5c; + *tp++ = 0x30 + ((*sp / 100) % 10); + *tp++ = 0x30 + ((*sp / 10) % 10); + *tp++ = 0x30 + (*sp % 10); + sp++; + tl -= 4; + continue; + } + /* double quote, semi-colon, backslash */ + if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) { + if (tl < 2) + return (ISC_R_NOSPACE); + *tp++ = '\\'; + tl--; + } + if (tl < 1) + return (ISC_R_NOSPACE); + *tp++ = *sp++; + tl--; + } + isc_region_consume(source, n0 + 1); + } while (source->length != 0); + if (tl < 1) + return (ISC_R_NOSPACE); + *tp++ = '"'; + tl--; + isc_buffer_add(target, tp - (char *)region.base); + return (ISC_R_SUCCESS); +} + +static isc_result_t +multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { + isc_region_t tregion; + isc_boolean_t escape; + unsigned int n, nrem; + char *s; + unsigned char *t0, *t; + int d; + int c; + + s = source->base; + n = source->length; + escape = ISC_FALSE; + + do { + isc_buffer_availableregion(target, &tregion); + t0 = tregion.base; + nrem = tregion.length; + if (nrem < 1) + return (ISC_R_NOSPACE); + /* length byte */ + t = t0; + nrem--; + t++; + /* 255 byte character-string slice */ + if (nrem > 255) + nrem = 255; + while (n != 0) { + --n; + c = (*s++) & 0xff; + if (escape && (d = decvalue((char)c)) != -1) { + c = d; + if (n == 0) + return (DNS_R_SYNTAX); + n--; + if ((d = decvalue(*s++)) != -1) + c = c * 10 + d; + else + return (DNS_R_SYNTAX); + if (n == 0) + return (DNS_R_SYNTAX); + n--; + if ((d = decvalue(*s++)) != -1) + c = c * 10 + d; + else + return (DNS_R_SYNTAX); + if (c > 255) + return (DNS_R_SYNTAX); + } else if (!escape && c == '\\') { + escape = ISC_TRUE; + continue; + } + escape = ISC_FALSE; + *t++ = c; + nrem--; + if (nrem == 0) + break; + } + if (escape) + return (DNS_R_SYNTAX); + *t0 = t - t0 - 1; + isc_buffer_add(target, *t0 + 1); + } while (n != 0); + return (ISC_R_SUCCESS); +} + +static isc_result_t +multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { + unsigned int n; + isc_region_t sregion; + isc_region_t tregion; + + isc_buffer_activeregion(source, &sregion); + if (sregion.length == 0) + return(ISC_R_UNEXPECTEDEND); + n = 256U; + do { + if (n != 256U) + return (DNS_R_SYNTAX); + n = *sregion.base + 1; + if (n > sregion.length) + return (ISC_R_UNEXPECTEDEND); + + isc_buffer_availableregion(target, &tregion); + if (n > tregion.length) + return (ISC_R_NOSPACE); + + memcpy(tregion.base, sregion.base, n); + isc_buffer_forward(source, n); + isc_buffer_add(target, n); + isc_buffer_activeregion(source, &sregion); + } while (sregion.length != 0); + return (ISC_R_SUCCESS); +} + static isc_boolean_t name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) { int l1, l2; diff --git a/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c b/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c index 338c5dd..0046ed0 100644 --- a/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c +++ b/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c @@ -133,7 +133,7 @@ static inline isc_result_t totext_any_tsig(ARGS_TOTEXT) { isc_region_t sr; isc_region_t sigr; - char buf[sizeof("281474976710655 ")]; + char buf[sizeof(" 281474976710655 ")]; char *bufp; dns_name_t name; dns_name_t prefix; @@ -223,19 +223,14 @@ totext_any_tsig(ARGS_TOTEXT) { */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); - if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS) - RETERR(str_totext(" ", target)); - else { - sprintf(buf, "%u ", n); - RETERR(str_totext(buf, target)); - } + RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target)); /* * Other Size. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); - sprintf(buf, "%u ", n); + sprintf(buf, " %u ", n); RETERR(str_totext(buf, target)); /* diff --git a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c index 4dbcb1e..97f37f7 100644 --- a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c +++ b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2009, 2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -91,7 +91,7 @@ fromtext_dlv(ARGS_FROMTEXT) { length = -1; break; } - return (isc_hex_tobuffer(lexer, target, -1)); + return (isc_hex_tobuffer(lexer, target, length)); } static inline isc_result_t diff --git a/contrib/bind9/lib/dns/rdata/generic/eui48_108.c b/contrib/bind9/lib/dns/rdata/generic/eui48_108.c new file mode 100644 index 0000000..3e52fec --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/eui48_108.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef RDATA_GENERIC_EUI48_108_C +#define RDATA_GENERIC_EUI48_108_C + +#include <string.h> + +#define RRTYPE_EUI48_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_eui48(ARGS_FROMTEXT) { + isc_token_t token; + unsigned char eui48[6]; + unsigned int l0, l1, l2, l3, l4, l5; + int n; + + REQUIRE(type == 108); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + ISC_FALSE)); + n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x", + &l0, &l1, &l2, &l3, &l4, &l5); + if (n != 6 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U || + l4 > 255U || l5 > 255U) + return (DNS_R_BADEUI); + + eui48[0] = l0; + eui48[1] = l1; + eui48[2] = l2; + eui48[3] = l3; + eui48[4] = l4; + eui48[5] = l5; + return (mem_tobuffer(target, eui48, sizeof(eui48))); +} + +static inline isc_result_t +totext_eui48(ARGS_TOTEXT) { + char buf[sizeof("xx-xx-xx-xx-xx-xx")]; + + REQUIRE(rdata->type == 108); + REQUIRE(rdata->length == 6); + + UNUSED(tctx); + + (void)snprintf(buf, sizeof(buf), "%02x-%02x-%02x-%02x-%02x-%02x", + rdata->data[0], rdata->data[1], rdata->data[2], + rdata->data[3], rdata->data[4], rdata->data[5]); + return (str_totext(buf, target)); +} + +static inline isc_result_t +fromwire_eui48(ARGS_FROMWIRE) { + isc_region_t sregion; + + REQUIRE(type == 108); + + UNUSED(type); + UNUSED(options); + UNUSED(rdclass); + UNUSED(dctx); + + isc_buffer_activeregion(source, &sregion); + if (sregion.length != 6) + return (DNS_R_FORMERR); + isc_buffer_forward(source, sregion.length); + return (mem_tobuffer(target, sregion.base, sregion.length)); +} + +static inline isc_result_t +towire_eui48(ARGS_TOWIRE) { + + REQUIRE(rdata->type == 108); + REQUIRE(rdata->length == 6); + + UNUSED(cctx); + + return (mem_tobuffer(target, rdata->data, rdata->length)); +} + +static inline int +compare_eui48(ARGS_COMPARE) { + isc_region_t region1; + isc_region_t region2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 108); + REQUIRE(rdata1->length == 6); + REQUIRE(rdata2->length == 6); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +static inline isc_result_t +fromstruct_eui48(ARGS_FROMSTRUCT) { + dns_rdata_eui48_t *eui48 = source; + + REQUIRE(type == 108); + REQUIRE(source != NULL); + REQUIRE(eui48->common.rdtype == type); + REQUIRE(eui48->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + return (mem_tobuffer(target, eui48->eui48, sizeof(eui48->eui48))); +} + +static inline isc_result_t +tostruct_eui48(ARGS_TOSTRUCT) { + dns_rdata_eui48_t *eui48 = target; + + REQUIRE(rdata->type == 108); + REQUIRE(target != NULL); + REQUIRE(rdata->length == 6); + + UNUSED(mctx); + + eui48->common.rdclass = rdata->rdclass; + eui48->common.rdtype = rdata->type; + ISC_LINK_INIT(&eui48->common, link); + + memcpy(eui48->eui48, rdata->data, rdata->length); + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_eui48(ARGS_FREESTRUCT) { + dns_rdata_eui48_t *eui48 = source; + + REQUIRE(source != NULL); + REQUIRE(eui48->common.rdtype == 108); + + return; +} + +static inline isc_result_t +additionaldata_eui48(ARGS_ADDLDATA) { + + REQUIRE(rdata->type == 108); + REQUIRE(rdata->length == 6); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_eui48(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 108); + REQUIRE(rdata->length == 6); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_eui48(ARGS_CHECKOWNER) { + + REQUIRE(type == 108); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_eui48(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 108); + REQUIRE(rdata->length == 6); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +static inline int +casecompare_eui48(ARGS_COMPARE) { + return (compare_eui48(rdata1, rdata2)); +} + +#endif /* RDATA_GENERIC_EUI48_108_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/eui48_108.h b/contrib/bind9/lib/dns/rdata/generic/eui48_108.h new file mode 100644 index 0000000..508c61f --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/eui48_108.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* */ +#ifndef GENERIC_EUI48_108_H +#define GENERIC_EUI48_108_H 1 + +typedef struct dns_rdata_eui48 { + dns_rdatacommon_t common; + unsigned char eui48[6]; +} dns_rdata_eui48_t; + +#endif /* GENERIC_EUI48_10k_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/eui64_109.c b/contrib/bind9/lib/dns/rdata/generic/eui64_109.c new file mode 100644 index 0000000..245994f --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/eui64_109.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef RDATA_GENERIC_EUI64_109_C +#define RDATA_GENERIC_EUI64_109_C + +#include <string.h> + +#define RRTYPE_EUI64_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_eui64(ARGS_FROMTEXT) { + isc_token_t token; + unsigned char eui64[8]; + unsigned int l0, l1, l2, l3, l4, l5, l6, l7; + int n; + + REQUIRE(type == 109); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + ISC_FALSE)); + n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x", + &l0, &l1, &l2, &l3, &l4, &l5, &l6, &l7); + if (n != 8 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U || + l4 > 255U || l5 > 255U || l6 > 255U || l7 > 255U) + return (DNS_R_BADEUI); + + eui64[0] = l0; + eui64[1] = l1; + eui64[2] = l2; + eui64[3] = l3; + eui64[4] = l4; + eui64[5] = l5; + eui64[6] = l6; + eui64[7] = l7; + return (mem_tobuffer(target, eui64, sizeof(eui64))); +} + +static inline isc_result_t +totext_eui64(ARGS_TOTEXT) { + char buf[sizeof("xx-xx-xx-xx-xx-xx-xx-xx")]; + + REQUIRE(rdata->type == 109); + REQUIRE(rdata->length == 8); + + UNUSED(tctx); + + (void)snprintf(buf, sizeof(buf), + "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x", + rdata->data[0], rdata->data[1], + rdata->data[2], rdata->data[3], + rdata->data[4], rdata->data[5], + rdata->data[6], rdata->data[7]); + return (str_totext(buf, target)); +} + +static inline isc_result_t +fromwire_eui64(ARGS_FROMWIRE) { + isc_region_t sregion; + + REQUIRE(type == 109); + + UNUSED(type); + UNUSED(options); + UNUSED(rdclass); + UNUSED(dctx); + + isc_buffer_activeregion(source, &sregion); + if (sregion.length != 8) + return (DNS_R_FORMERR); + isc_buffer_forward(source, sregion.length); + return (mem_tobuffer(target, sregion.base, sregion.length)); +} + +static inline isc_result_t +towire_eui64(ARGS_TOWIRE) { + + REQUIRE(rdata->type == 109); + REQUIRE(rdata->length == 8); + + UNUSED(cctx); + + return (mem_tobuffer(target, rdata->data, rdata->length)); +} + +static inline int +compare_eui64(ARGS_COMPARE) { + isc_region_t region1; + isc_region_t region2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 109); + REQUIRE(rdata1->length == 8); + REQUIRE(rdata2->length == 8); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +static inline isc_result_t +fromstruct_eui64(ARGS_FROMSTRUCT) { + dns_rdata_eui64_t *eui64 = source; + + REQUIRE(type == 109); + REQUIRE(source != NULL); + REQUIRE(eui64->common.rdtype == type); + REQUIRE(eui64->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + return (mem_tobuffer(target, eui64->eui64, sizeof(eui64->eui64))); +} + +static inline isc_result_t +tostruct_eui64(ARGS_TOSTRUCT) { + dns_rdata_eui64_t *eui64 = target; + + REQUIRE(rdata->type == 109); + REQUIRE(target != NULL); + REQUIRE(rdata->length == 8); + + UNUSED(mctx); + + eui64->common.rdclass = rdata->rdclass; + eui64->common.rdtype = rdata->type; + ISC_LINK_INIT(&eui64->common, link); + + memcpy(eui64->eui64, rdata->data, rdata->length); + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_eui64(ARGS_FREESTRUCT) { + dns_rdata_eui64_t *eui64 = source; + + REQUIRE(source != NULL); + REQUIRE(eui64->common.rdtype == 109); + + return; +} + +static inline isc_result_t +additionaldata_eui64(ARGS_ADDLDATA) { + + REQUIRE(rdata->type == 109); + REQUIRE(rdata->length == 8); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_eui64(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 109); + REQUIRE(rdata->length == 8); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_eui64(ARGS_CHECKOWNER) { + + REQUIRE(type == 109); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_eui64(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 109); + REQUIRE(rdata->length == 8); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +static inline int +casecompare_eui64(ARGS_COMPARE) { + return (compare_eui64(rdata1, rdata2)); +} + +#endif /* RDATA_GENERIC_EUI64_109_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/eui64_109.h b/contrib/bind9/lib/dns/rdata/generic/eui64_109.h new file mode 100644 index 0000000..56996f8 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/eui64_109.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* */ +#ifndef GENERIC_EUI64_109_H +#define GENERIC_EUI64_109_H 1 + +typedef struct dns_rdata_eui64 { + dns_rdatacommon_t common; + unsigned char eui64[8]; +} dns_rdata_eui64_t; + +#endif /* GENERIC_EUI64_10k_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/l32_105.c b/contrib/bind9/lib/dns/rdata/generic/l32_105.c new file mode 100644 index 0000000..763ddb9 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/l32_105.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef RDATA_GENERIC_L32_105_C +#define RDATA_GENERIC_L32_105_C + +#include <string.h> + +#include <isc/net.h> + +#define RRTYPE_L32_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_l32(ARGS_FROMTEXT) { + isc_token_t token; + struct in_addr addr; + isc_region_t region; + + REQUIRE(type == 105); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffffU) + RETTOK(ISC_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + ISC_FALSE)); + + if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) + RETTOK(DNS_R_BADDOTTEDQUAD); + isc_buffer_availableregion(target, ®ion); + if (region.length < 4) + return (ISC_R_NOSPACE); + memcpy(region.base, &addr, 4); + isc_buffer_add(target, 4); + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +totext_l32(ARGS_TOTEXT) { + isc_region_t region; + char buf[sizeof("65000")]; + unsigned short num; + + REQUIRE(rdata->type == 105); + REQUIRE(rdata->length == 6); + + UNUSED(tctx); + + dns_rdata_toregion(rdata, ®ion); + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u", num); + RETERR(str_totext(buf, target)); + + RETERR(str_totext(" ", target)); + + return (inet_totext(AF_INET, ®ion, target)); +} + +static inline isc_result_t +fromwire_l32(ARGS_FROMWIRE) { + isc_region_t sregion; + + REQUIRE(type == 105); + + UNUSED(type); + UNUSED(options); + UNUSED(rdclass); + UNUSED(dctx); + + isc_buffer_activeregion(source, &sregion); + if (sregion.length != 6) + return (DNS_R_FORMERR); + isc_buffer_forward(source, sregion.length); + return (mem_tobuffer(target, sregion.base, sregion.length)); +} + +static inline isc_result_t +towire_l32(ARGS_TOWIRE) { + + REQUIRE(rdata->type == 105); + REQUIRE(rdata->length == 6); + + UNUSED(cctx); + + return (mem_tobuffer(target, rdata->data, rdata->length)); +} + +static inline int +compare_l32(ARGS_COMPARE) { + isc_region_t region1; + isc_region_t region2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 105); + REQUIRE(rdata1->length == 6); + REQUIRE(rdata2->length == 6); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +static inline isc_result_t +fromstruct_l32(ARGS_FROMSTRUCT) { + dns_rdata_l32_t *l32 = source; + isc_uint32_t n; + + REQUIRE(type == 105); + REQUIRE(source != NULL); + REQUIRE(l32->common.rdtype == type); + REQUIRE(l32->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + RETERR(uint16_tobuffer(l32->pref, target)); + n = ntohl(l32->l32.s_addr); + return (uint32_tobuffer(n, target)); +} + +static inline isc_result_t +tostruct_l32(ARGS_TOSTRUCT) { + isc_region_t region; + dns_rdata_l32_t *l32 = target; + isc_uint32_t n; + + REQUIRE(rdata->type == 105); + REQUIRE(target != NULL); + REQUIRE(rdata->length == 6); + + UNUSED(mctx); + + l32->common.rdclass = rdata->rdclass; + l32->common.rdtype = rdata->type; + ISC_LINK_INIT(&l32->common, link); + + dns_rdata_toregion(rdata, ®ion); + l32->pref = uint16_fromregion(®ion); + n = uint32_fromregion(®ion); + l32->l32.s_addr = htonl(n); + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_l32(ARGS_FREESTRUCT) { + dns_rdata_l32_t *l32 = source; + + REQUIRE(source != NULL); + REQUIRE(l32->common.rdtype == 105); + + return; +} + +static inline isc_result_t +additionaldata_l32(ARGS_ADDLDATA) { + + REQUIRE(rdata->type == 105); + REQUIRE(rdata->length == 6); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_l32(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 105); + REQUIRE(rdata->length == 6); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_l32(ARGS_CHECKOWNER) { + + REQUIRE(type == 105); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_l32(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 105); + REQUIRE(rdata->length == 6); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +static inline int +casecompare_l32(ARGS_COMPARE) { + return (compare_l32(rdata1, rdata2)); +} + +#endif /* RDATA_GENERIC_L32_105_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/l32_105.h b/contrib/bind9/lib/dns/rdata/generic/l32_105.h new file mode 100644 index 0000000..f95db22 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/l32_105.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* */ +#ifndef GENERIC_L32_105_H +#define GENERIC_L32_105_H 1 + +typedef struct dns_rdata_l32 { + dns_rdatacommon_t common; + isc_uint16_t pref; + struct in_addr l32; +} dns_rdata_l32_t; + +#endif /* GENERIC_L32_105_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/l64_106.c b/contrib/bind9/lib/dns/rdata/generic/l64_106.c new file mode 100644 index 0000000..ff20663 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/l64_106.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef RDATA_GENERIC_L64_106_C +#define RDATA_GENERIC_L64_106_C + +#include <string.h> + +#include <isc/net.h> + +#define RRTYPE_L64_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_l64(ARGS_FROMTEXT) { + isc_token_t token; + unsigned char locator[NS_LOCATORSZ]; + + REQUIRE(type == 106); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffffU) + RETTOK(ISC_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + ISC_FALSE)); + + if (locator_pton(DNS_AS_STR(token), locator) != 1) + RETTOK(DNS_R_SYNTAX); + return (mem_tobuffer(target, locator, NS_LOCATORSZ)); +} + +static inline isc_result_t +totext_l64(ARGS_TOTEXT) { + isc_region_t region; + char buf[sizeof("xxxx:xxxx:xxxx:xxxx")]; + unsigned short num; + + REQUIRE(rdata->type == 106); + REQUIRE(rdata->length == 10); + + UNUSED(tctx); + + dns_rdata_toregion(rdata, ®ion); + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u", num); + RETERR(str_totext(buf, target)); + + RETERR(str_totext(" ", target)); + + sprintf(buf, "%x:%x:%x:%x", + region.base[0]<<8 | region.base[1], + region.base[2]<<8 | region.base[3], + region.base[4]<<8 | region.base[5], + region.base[6]<<8 | region.base[7]); + return (str_totext(buf, target)); +} + +static inline isc_result_t +fromwire_l64(ARGS_FROMWIRE) { + isc_region_t sregion; + + REQUIRE(type == 106); + + UNUSED(type); + UNUSED(options); + UNUSED(rdclass); + UNUSED(dctx); + + isc_buffer_activeregion(source, &sregion); + if (sregion.length != 10) + return (DNS_R_FORMERR); + isc_buffer_forward(source, sregion.length); + return (mem_tobuffer(target, sregion.base, sregion.length)); +} + +static inline isc_result_t +towire_l64(ARGS_TOWIRE) { + + REQUIRE(rdata->type == 106); + REQUIRE(rdata->length == 10); + + UNUSED(cctx); + + return (mem_tobuffer(target, rdata->data, rdata->length)); +} + +static inline int +compare_l64(ARGS_COMPARE) { + isc_region_t region1; + isc_region_t region2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 106); + REQUIRE(rdata1->length == 10); + REQUIRE(rdata2->length == 10); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +static inline isc_result_t +fromstruct_l64(ARGS_FROMSTRUCT) { + dns_rdata_l64_t *l64 = source; + + REQUIRE(type == 106); + REQUIRE(source != NULL); + REQUIRE(l64->common.rdtype == type); + REQUIRE(l64->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + RETERR(uint16_tobuffer(l64->pref, target)); + return (mem_tobuffer(target, l64->l64, sizeof(l64->l64))); +} + +static inline isc_result_t +tostruct_l64(ARGS_TOSTRUCT) { + isc_region_t region; + dns_rdata_l64_t *l64 = target; + + REQUIRE(rdata->type == 106); + REQUIRE(target != NULL); + REQUIRE(rdata->length == 10); + + UNUSED(mctx); + + l64->common.rdclass = rdata->rdclass; + l64->common.rdtype = rdata->type; + ISC_LINK_INIT(&l64->common, link); + + dns_rdata_toregion(rdata, ®ion); + l64->pref = uint16_fromregion(®ion); + memcpy(l64->l64, region.base, region.length); + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_l64(ARGS_FREESTRUCT) { + dns_rdata_l64_t *l64 = source; + + REQUIRE(source != NULL); + REQUIRE(l64->common.rdtype == 106); + + return; +} + +static inline isc_result_t +additionaldata_l64(ARGS_ADDLDATA) { + + REQUIRE(rdata->type == 106); + REQUIRE(rdata->length == 10); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_l64(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 106); + REQUIRE(rdata->length == 10); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_l64(ARGS_CHECKOWNER) { + + REQUIRE(type == 106); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_l64(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 106); + REQUIRE(rdata->length == 10); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +static inline int +casecompare_l64(ARGS_COMPARE) { + return (compare_l64(rdata1, rdata2)); +} + +#endif /* RDATA_GENERIC_L64_106_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/l64_106.h b/contrib/bind9/lib/dns/rdata/generic/l64_106.h new file mode 100644 index 0000000..8f93fc5 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/l64_106.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* */ +#ifndef GENERIC_L64_106_H +#define GENERIC_L64_106_H 1 + +typedef struct dns_rdata_l64 { + dns_rdatacommon_t common; + isc_uint16_t pref; + unsigned char l64[8]; +} dns_rdata_l64_t; + +#endif /* GENERIC_L64_106_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/lp_107.c b/contrib/bind9/lib/dns/rdata/generic/lp_107.c new file mode 100644 index 0000000..732ef7f --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/lp_107.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef RDATA_GENERIC_LP_107_C +#define RDATA_GENERIC_LP_107_C + +#include <string.h> + +#include <isc/net.h> + +#define RRTYPE_LP_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_lp(ARGS_FROMTEXT) { + isc_token_t token; + dns_name_t name; + isc_buffer_t buffer; + + REQUIRE(type == 107); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(callbacks); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffffU) + RETTOK(ISC_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + ISC_FALSE)); + + dns_name_init(&name, NULL); + buffer_fromregion(&buffer, &token.value.as_region); + origin = (origin != NULL) ? origin : dns_rootname; + return (dns_name_fromtext(&name, &buffer, origin, options, target)); +} + +static inline isc_result_t +totext_lp(ARGS_TOTEXT) { + isc_region_t region; + dns_name_t name; + dns_name_t prefix; + isc_boolean_t sub; + char buf[sizeof("64000")]; + unsigned short num; + + REQUIRE(rdata->type == 107); + REQUIRE(rdata->length != 0); + + dns_name_init(&name, NULL); + dns_name_init(&prefix, NULL); + + dns_rdata_toregion(rdata, ®ion); + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u", num); + RETERR(str_totext(buf, target)); + + RETERR(str_totext(" ", target)); + + dns_name_fromregion(&name, ®ion); + sub = name_prefix(&name, tctx->origin, &prefix); + return (dns_name_totext(&prefix, sub, target)); +} + +static inline isc_result_t +fromwire_lp(ARGS_FROMWIRE) { + dns_name_t name; + isc_region_t sregion; + + REQUIRE(type == 107); + + UNUSED(type); + UNUSED(rdclass); + + dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); + + dns_name_init(&name, NULL); + + isc_buffer_activeregion(source, &sregion); + if (sregion.length < 2) + return (ISC_R_UNEXPECTEDEND); + RETERR(mem_tobuffer(target, sregion.base, 2)); + isc_buffer_forward(source, 2); + return (dns_name_fromwire(&name, source, dctx, options, target)); +} + +static inline isc_result_t +towire_lp(ARGS_TOWIRE) { + + REQUIRE(rdata->type == 107); + REQUIRE(rdata->length != 0); + + UNUSED(cctx); + + return (mem_tobuffer(target, rdata->data, rdata->length)); +} + +static inline int +compare_lp(ARGS_COMPARE) { + isc_region_t region1; + isc_region_t region2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 107); + REQUIRE(rdata1->length != 0); + REQUIRE(rdata2->length != 0); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + + return (isc_region_compare(®ion1, ®ion2)); +} + +static inline isc_result_t +fromstruct_lp(ARGS_FROMSTRUCT) { + dns_rdata_lp_t *lp = source; + isc_region_t region; + + REQUIRE(type == 107); + REQUIRE(source != NULL); + REQUIRE(lp->common.rdtype == type); + REQUIRE(lp->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + RETERR(uint16_tobuffer(lp->pref, target)); + dns_name_toregion(&lp->lp, ®ion); + return (isc_buffer_copyregion(target, ®ion)); +} + +static inline isc_result_t +tostruct_lp(ARGS_TOSTRUCT) { + isc_region_t region; + dns_rdata_lp_t *lp = target; + dns_name_t name; + + REQUIRE(rdata->type == 107); + REQUIRE(target != NULL); + REQUIRE(rdata->length != 0); + + lp->common.rdclass = rdata->rdclass; + lp->common.rdtype = rdata->type; + ISC_LINK_INIT(&lp->common, link); + + dns_name_init(&name, NULL); + dns_rdata_toregion(rdata, ®ion); + lp->pref = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + dns_name_fromregion(&name, ®ion); + dns_name_init(&lp->lp, NULL); + RETERR(name_duporclone(&name, mctx, &lp->lp)); + lp->mctx = mctx; + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_lp(ARGS_FREESTRUCT) { + dns_rdata_lp_t *lp = source; + + REQUIRE(source != NULL); + REQUIRE(lp->common.rdtype == 107); + + if (lp->mctx == NULL) + return; + + dns_name_free(&lp->lp, lp->mctx); + lp->mctx = NULL; +} + +static inline isc_result_t +additionaldata_lp(ARGS_ADDLDATA) { + dns_name_t name; + dns_offsets_t offsets; + isc_region_t region; + isc_result_t result; + + REQUIRE(rdata->type == 107); + + dns_name_init(&name, offsets); + dns_rdata_toregion(rdata, ®ion); + isc_region_consume(®ion, 2); + dns_name_fromregion(&name, ®ion); + + result = (add)(arg, &name, dns_rdatatype_l32); + if (result != ISC_R_SUCCESS) + return (result); + return ((add)(arg, &name, dns_rdatatype_l64)); +} + +static inline isc_result_t +digest_lp(ARGS_DIGEST) { + isc_region_t region; + + REQUIRE(rdata->type == 107); + + dns_rdata_toregion(rdata, ®ion); + return ((digest)(arg, ®ion)); +} + +static inline isc_boolean_t +checkowner_lp(ARGS_CHECKOWNER) { + + REQUIRE(type == 107); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(name); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_lp(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 107); + + UNUSED(bad); + UNUSED(owner); + + return (ISC_TRUE); +} + +static inline int +casecompare_lp(ARGS_COMPARE) { + dns_name_t name1; + dns_name_t name2; + isc_region_t region1; + isc_region_t region2; + int order; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 107); + REQUIRE(rdata1->length != 0); + REQUIRE(rdata2->length != 0); + + order = memcmp(rdata1->data, rdata2->data, 2); + if (order != 0) + return (order < 0 ? -1 : 1); + + dns_name_init(&name1, NULL); + dns_name_init(&name2, NULL); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + + isc_region_consume(®ion1, 2); + isc_region_consume(®ion2, 2); + + dns_name_fromregion(&name1, ®ion1); + dns_name_fromregion(&name2, ®ion2); + + return (dns_name_rdatacompare(&name1, &name2)); +} + +#endif /* RDATA_GENERIC_LP_107_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/lp_107.h b/contrib/bind9/lib/dns/rdata/generic/lp_107.h new file mode 100644 index 0000000..cbfee8a --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/lp_107.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* */ +#ifndef GENERIC_LP_107_H +#define GENERIC_LP_107_H 1 + +typedef struct dns_rdata_lp { + dns_rdatacommon_t common; + isc_mem_t *mctx; + isc_uint16_t pref; + dns_name_t lp; +} dns_rdata_lp_t; + +#endif /* GENERIC_LP_107_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/mx_15.c b/contrib/bind9/lib/dns/rdata/generic/mx_15.c index fd09e92..77eee15 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mx_15.c +++ b/contrib/bind9/lib/dns/rdata/generic/mx_15.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -57,7 +57,6 @@ fromtext_mx(ARGS_FROMTEXT) { UNUSED(type); UNUSED(rdclass); - UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); diff --git a/contrib/bind9/lib/dns/rdata/generic/nid_104.c b/contrib/bind9/lib/dns/rdata/generic/nid_104.c new file mode 100644 index 0000000..c96b0bf --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/nid_104.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef RDATA_GENERIC_NID_104_C +#define RDATA_GENERIC_NID_104_C + +#include <string.h> + +#include <isc/net.h> + +#define RRTYPE_NID_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_nid(ARGS_FROMTEXT) { + isc_token_t token; + unsigned char locator[NS_LOCATORSZ]; + + REQUIRE(type == 104); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffffU) + RETTOK(ISC_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + ISC_FALSE)); + + if (locator_pton(DNS_AS_STR(token), locator) != 1) + RETTOK(DNS_R_SYNTAX); + return (mem_tobuffer(target, locator, NS_LOCATORSZ)); +} + +static inline isc_result_t +totext_nid(ARGS_TOTEXT) { + isc_region_t region; + char buf[sizeof("xxxx:xxxx:xxxx:xxxx")]; + unsigned short num; + + REQUIRE(rdata->type == 104); + REQUIRE(rdata->length != 0); + + UNUSED(tctx); + + dns_rdata_toregion(rdata, ®ion); + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u", num); + RETERR(str_totext(buf, target)); + + RETERR(str_totext(" ", target)); + + sprintf(buf, "%x:%x:%x:%x", + region.base[0]<<8 | region.base[1], + region.base[2]<<8 | region.base[3], + region.base[4]<<8 | region.base[5], + region.base[6]<<8 | region.base[7]); + return (str_totext(buf, target)); +} + +static inline isc_result_t +fromwire_nid(ARGS_FROMWIRE) { + isc_region_t sregion; + + REQUIRE(type == 104); + + UNUSED(type); + UNUSED(options); + UNUSED(rdclass); + UNUSED(dctx); + + isc_buffer_activeregion(source, &sregion); + if (sregion.length != 10) + return (DNS_R_FORMERR); + isc_buffer_forward(source, sregion.length); + return (mem_tobuffer(target, sregion.base, sregion.length)); +} + +static inline isc_result_t +towire_nid(ARGS_TOWIRE) { + + REQUIRE(rdata->type == 104); + REQUIRE(rdata->length == 10); + + UNUSED(cctx); + + return (mem_tobuffer(target, rdata->data, rdata->length)); +} + +static inline int +compare_nid(ARGS_COMPARE) { + isc_region_t region1; + isc_region_t region2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 104); + REQUIRE(rdata1->length == 10); + REQUIRE(rdata2->length == 10); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +static inline isc_result_t +fromstruct_nid(ARGS_FROMSTRUCT) { + dns_rdata_nid_t *nid = source; + + REQUIRE(type == 104); + REQUIRE(source != NULL); + REQUIRE(nid->common.rdtype == type); + REQUIRE(nid->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + RETERR(uint16_tobuffer(nid->pref, target)); + return (mem_tobuffer(target, nid->nid, sizeof(nid->nid))); +} + +static inline isc_result_t +tostruct_nid(ARGS_TOSTRUCT) { + isc_region_t region; + dns_rdata_nid_t *nid = target; + + REQUIRE(rdata->type == 104); + REQUIRE(target != NULL); + REQUIRE(rdata->length == 10); + + UNUSED(mctx); + + nid->common.rdclass = rdata->rdclass; + nid->common.rdtype = rdata->type; + ISC_LINK_INIT(&nid->common, link); + + dns_rdata_toregion(rdata, ®ion); + nid->pref = uint16_fromregion(®ion); + memcpy(nid->nid, region.base, region.length); + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_nid(ARGS_FREESTRUCT) { + dns_rdata_nid_t *nid = source; + + REQUIRE(source != NULL); + REQUIRE(nid->common.rdtype == 104); + + return; +} + +static inline isc_result_t +additionaldata_nid(ARGS_ADDLDATA) { + + REQUIRE(rdata->type == 104); + REQUIRE(rdata->length == 10); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_nid(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 104); + REQUIRE(rdata->length == 10); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_nid(ARGS_CHECKOWNER) { + + REQUIRE(type == 104); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_nid(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 104); + REQUIRE(rdata->length == 10); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +static inline int +casecompare_nid(ARGS_COMPARE) { + return (compare_nid(rdata1, rdata2)); +} + +#endif /* RDATA_GENERIC_NID_104_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/nid_104.h b/contrib/bind9/lib/dns/rdata/generic/nid_104.h new file mode 100644 index 0000000..64a3ba4 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/nid_104.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* */ +#ifndef GENERIC_NID_104_H +#define GENERIC_NID_104_H 1 + +typedef struct dns_rdata_nid { + dns_rdatacommon_t common; + isc_uint16_t pref; + unsigned char nid[8]; +} dns_rdata_nid_t; + +#endif /* GENERIC_NID_104_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c b/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c index c94c75c..03d5127 100644 --- a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c +++ b/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -53,7 +53,6 @@ fromtext_sshfp(ARGS_FROMTEXT) { if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); - type = (isc_uint16_t) token.value.as_ulong; /* * Digest. diff --git a/contrib/bind9/lib/dns/rdata/generic/txt_16.c b/contrib/bind9/lib/dns/rdata/generic/txt_16.c index c49864e..e1bce6a 100644 --- a/contrib/bind9/lib/dns/rdata/generic/txt_16.c +++ b/contrib/bind9/lib/dns/rdata/generic/txt_16.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007-2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -38,6 +38,13 @@ fromtext_txt(ARGS_FROMTEXT) { UNUSED(callbacks); strings = 0; + if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) { + isc_textregion_t r; + DE_CONST("#", r.base); + r.length = 1; + RETERR(txt_fromtext(&r, target)); + strings++; + } for (;;) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, diff --git a/contrib/bind9/lib/dns/rdata/generic/uri_256.c b/contrib/bind9/lib/dns/rdata/generic/uri_256.c new file mode 100644 index 0000000..aa5b194 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/uri_256.c @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: uri_256.c,v 1.2 2011/03/03 14:10:27 fdupont Exp $ */ + +#ifndef GENERIC_URI_256_C +#define GENERIC_URI_256_C 1 + +#define RRTYPE_URI_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_uri(ARGS_FROMTEXT) { + isc_token_t token; + + REQUIRE(type == 256); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + /* + * Priority + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffffU) + RETTOK(ISC_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + /* + * Weight + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffffU) + RETTOK(ISC_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + /* + * Target URI + */ + RETERR(isc_lex_getmastertoken(lexer, &token, + isc_tokentype_qstring, ISC_FALSE)); + if (token.type != isc_tokentype_qstring) + RETTOK(DNS_R_SYNTAX); + RETTOK(multitxt_fromtext(&token.value.as_textregion, target)); + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +totext_uri(ARGS_TOTEXT) { + isc_region_t region; + unsigned short priority, weight; + char buf[sizeof("65000 ")]; + + UNUSED(tctx); + + REQUIRE(rdata->type == 256); + REQUIRE(rdata->length != 0); + + dns_rdata_toregion(rdata, ®ion); + + /* + * Priority + */ + priority = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u ", priority); + RETERR(str_totext(buf, target)); + + /* + * Weight + */ + weight = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u ", weight); + RETERR(str_totext(buf, target)); + + /* + * Target URI + */ + RETERR(multitxt_totext(®ion, target)); + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +fromwire_uri(ARGS_FROMWIRE) { + isc_region_t region; + + REQUIRE(type == 256); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(dctx); + UNUSED(options); + + /* + * Priority, weight + */ + isc_buffer_activeregion(source, ®ion); + if (region.length < 4) + return (ISC_R_UNEXPECTEDEND); + RETERR(mem_tobuffer(target, region.base, 4)); + isc_buffer_forward(source, 4); + + /* + * Target URI + */ + RETERR(multitxt_fromwire(source, target)); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +towire_uri(ARGS_TOWIRE) { + isc_region_t region; + + REQUIRE(rdata->type == 256); + REQUIRE(rdata->length != 0); + + UNUSED(cctx); + + dns_rdata_toregion(rdata, ®ion); + return (mem_tobuffer(target, region.base, region.length)); +} + +static inline int +compare_uri(ARGS_COMPARE) { + isc_region_t r1; + isc_region_t r2; + int order; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 256); + REQUIRE(rdata1->length != 0); + REQUIRE(rdata2->length != 0); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + + /* + * Priority + */ + order = memcmp(r1.base, r2.base, 2); + if (order != 0) + return (order < 0 ? -1 : 1); + isc_region_consume(&r1, 2); + isc_region_consume(&r2, 2); + + /* + * Weight + */ + order = memcmp(r1.base, r2.base, 2); + if (order != 0) + return (order < 0 ? -1 : 1); + isc_region_consume(&r1, 2); + isc_region_consume(&r2, 2); + + return (isc_region_compare(&r1, &r2)); +} + +static inline isc_result_t +fromstruct_uri(ARGS_FROMSTRUCT) { + dns_rdata_uri_t *uri = source; + isc_region_t region; + isc_uint8_t len; + + REQUIRE(type == 256); + REQUIRE(source != NULL); + REQUIRE(uri->common.rdtype == type); + REQUIRE(uri->common.rdclass == rdclass); + REQUIRE(uri->target != NULL && uri->tgt_len != 0); + + UNUSED(type); + UNUSED(rdclass); + + /* + * Priority + */ + RETERR(uint16_tobuffer(uri->priority, target)); + + /* + * Weight + */ + RETERR(uint16_tobuffer(uri->weight, target)); + + /* + * Target URI + */ + len = 255U; + region.base = uri->target; + region.length = uri->tgt_len; + while (region.length > 0) { + REQUIRE(len == 255U); + len = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + if (region.length < len) + return (ISC_R_UNEXPECTEDEND); + isc_region_consume(®ion, len); + } + + return (mem_tobuffer(target, uri->target, uri->tgt_len)); +} + +static inline isc_result_t +tostruct_uri(ARGS_TOSTRUCT) { + dns_rdata_uri_t *uri = target; + isc_region_t sr; + + REQUIRE(rdata->type == 256); + REQUIRE(target != NULL); + REQUIRE(rdata->length != 0); + + uri->common.rdclass = rdata->rdclass; + uri->common.rdtype = rdata->type; + ISC_LINK_INIT(&uri->common, link); + + dns_rdata_toregion(rdata, &sr); + + /* + * Priority + */ + if (sr.length < 2) + return (ISC_R_UNEXPECTEDEND); + uri->priority = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + + /* + * Weight + */ + if (sr.length < 2) + return (ISC_R_UNEXPECTEDEND); + uri->weight = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + + /* + * Target URI + */ + uri->tgt_len = sr.length; + uri->target = mem_maybedup(mctx, sr.base, sr.length); + if (uri->target == NULL) + return (ISC_R_NOMEMORY); + + uri->mctx = mctx; + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_uri(ARGS_FREESTRUCT) { + dns_rdata_uri_t *uri = (dns_rdata_uri_t *) source; + + REQUIRE(source != NULL); + REQUIRE(uri->common.rdtype == 256); + + if (uri->mctx == NULL) + return; + + if (uri->target != NULL) + isc_mem_free(uri->mctx, uri->target); + uri->mctx = NULL; +} + +static inline isc_result_t +additionaldata_uri(ARGS_ADDLDATA) { + REQUIRE(rdata->type == 256); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_uri(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 256); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_uri(ARGS_CHECKOWNER) { + + REQUIRE(type == 256); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_uri(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 256); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +static inline int +casecompare_uri(ARGS_COMPARE) { + return (compare_uri(rdata1, rdata2)); +} + +#endif /* GENERIC_URI_256_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/uri_256.h b/contrib/bind9/lib/dns/rdata/generic/uri_256.h new file mode 100644 index 0000000..5061c03 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/uri_256.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef GENERIC_URI_256_H +#define GENERIC_URI_256_H 1 + +/* $Id: uri_256.h,v 1.2 2011/03/03 14:10:27 fdupont Exp $ */ + +typedef struct dns_rdata_uri { + dns_rdatacommon_t common; + isc_mem_t * mctx; + isc_uint16_t priority; + isc_uint16_t weight; + unsigned char * target; + isc_uint16_t tgt_len; +} dns_rdata_uri_t; + +#endif /* GENERIC_URI_256_H */ diff --git a/contrib/bind9/lib/dns/rdata/in_1/naptr_35.c b/contrib/bind9/lib/dns/rdata/in_1/naptr_35.c index 71ba31e..e5df80b 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/naptr_35.c +++ b/contrib/bind9/lib/dns/rdata/in_1/naptr_35.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -25,9 +25,8 @@ #define RDATA_IN_1_NAPTR_35_C #define RRTYPE_NAPTR_ATTRIBUTES (0) -#ifdef HAVE_REGEX_H -#include <regex.h> -#endif + +#include <isc/regex.h> /* * Check the wire format of the Regexp field. @@ -35,18 +34,15 @@ */ static inline isc_result_t txt_valid_regex(const unsigned char *txt) { -#ifdef HAVE_REGEX_H - regex_t preg; - unsigned int regflags = REG_EXTENDED; unsigned int nsub = 0; char regex[256]; char *cp; -#endif isc_boolean_t flags = ISC_FALSE; isc_boolean_t replace = ISC_FALSE; unsigned char c; unsigned char delim; unsigned int len; + int n; len = *txt++; if (len == 0U) @@ -65,11 +61,7 @@ txt_valid_regex(const unsigned char *txt) { return (DNS_R_SYNTAX); } -#ifdef HAVE_REGEX_H - memset(&preg, 0, sizeof(preg)); cp = regex; -#endif - while (len-- > 0) { c = *txt++; if (c == 0) @@ -88,18 +80,13 @@ txt_valid_regex(const unsigned char *txt) { if (flags) { switch (c) { case 'i': -#ifdef HAVE_REGEX_H - regflags |= REG_ICASE; -#endif continue; default: return (DNS_R_SYNTAX); } } -#ifdef HAVE_REGEX_H if (!replace) *cp++ = c; -#endif if (c == '\\') { if (len == 0) return (DNS_R_SYNTAX); @@ -110,7 +97,6 @@ txt_valid_regex(const unsigned char *txt) { if (replace) switch (c) { case '0': return (DNS_R_SYNTAX); -#ifdef HAVE_REGEX_H case '1': if (nsub < 1) nsub = 1; break; case '2': if (nsub < 2) nsub = 2; break; case '3': if (nsub < 3) nsub = 3; break; @@ -120,30 +106,17 @@ txt_valid_regex(const unsigned char *txt) { case '7': if (nsub < 7) nsub = 7; break; case '8': if (nsub < 8) nsub = 8; break; case '9': if (nsub < 9) nsub = 9; break; -#endif } -#ifdef HAVE_REGEX_H if (!replace) *cp++ = c; -#endif } } if (!flags) return (DNS_R_SYNTAX); -#ifdef HAVE_REGEX_H *cp = '\0'; - if (regcomp(&preg, regex, regflags)) - return (DNS_R_SYNTAX); - /* - * Check that substitutions in the replacement string are consistant - * with the regular expression. - */ - if (preg.re_nsub < nsub) { - regfree(&preg); + n = isc_regex_validate(regex); + if (n < 0 || nsub > (unsigned int)n) return (DNS_R_SYNTAX); - } - regfree(&preg); -#endif return (ISC_R_SUCCESS); } diff --git a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c b/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c index d762fe1..66129fe 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c +++ b/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -53,7 +53,6 @@ fromtext_in_nsap(ARGS_FROMTEXT) { RETTOK(DNS_R_SYNTAX); isc_textregion_consume(sr, 2); digits = 0; - n = 0; while (sr->length > 0) { if (sr->base[0] == '.') { isc_textregion_consume(sr, 1); diff --git a/contrib/bind9/lib/dns/request.c b/contrib/bind9/lib/dns/request.c index 58c0103..1316e69 100644 --- a/contrib/bind9/lib/dns/request.c +++ b/contrib/bind9/lib/dns/request.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -894,13 +894,15 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, REQUIRE(action != NULL); REQUIRE(requestp != NULL && *requestp == NULL); REQUIRE(timeout > 0); - if (srcaddr != NULL) - REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr)); mctx = requestmgr->mctx; req_log(ISC_LOG_DEBUG(3), "dns_request_createvia"); + if (srcaddr != NULL && + isc_sockaddr_pf(srcaddr) != isc_sockaddr_pf(destaddr)) + return (ISC_R_FAMILYMISMATCH); + if (isblackholed(requestmgr->dispatchmgr, destaddr)) return (DNS_R_BLACKHOLED); diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c index 503f1d2..e21d97e 100644 --- a/contrib/bind9/lib/dns/resolver.c +++ b/contrib/bind9/lib/dns/resolver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -21,6 +21,7 @@ #include <config.h> +#include <isc/log.h> #include <isc/platform.h> #include <isc/print.h> #include <isc/string.h> @@ -42,6 +43,8 @@ #include <dns/log.h> #include <dns/message.h> #include <dns/ncache.h> +#include <dns/nsec.h> +#include <dns/nsec3.h> #include <dns/opcode.h> #include <dns/peer.h> #include <dns/rbt.h> @@ -75,7 +78,7 @@ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ - "fctx %p(%s'): %s", fctx, fctx->info, (m)) + "fctx %p(%s): %s", fctx, fctx->info, (m)) #define FCTXTRACE2(m1, m2) \ isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ @@ -130,6 +133,7 @@ * Maximum EDNS0 input packet size. */ #define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */ +#define EDNSOPTS 2 /*% * This defines the maximum number of timeouts we will permit before we @@ -468,12 +472,16 @@ static isc_result_t ncache_adderesult(dns_message_t *message, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, + isc_boolean_t secure, dns_rdataset_t *ardataset, isc_result_t *eresultp); static void validated(isc_task_t *task, isc_event_t *event); static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked); static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, badnstype_t badtype); +static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name, + dns_rdatatype_t type, + dns_name_t **noqname); /*% * Increment resolver-related statistics counters. @@ -1270,67 +1278,15 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) { static inline isc_result_t fctx_addopt(dns_message_t *message, unsigned int version, - isc_uint16_t udpsize, isc_boolean_t request_nsid) + isc_uint16_t udpsize, dns_ednsopt_t *ednsopts, size_t count) { - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; + dns_rdataset_t *rdataset = NULL; isc_result_t result; - rdatalist = NULL; - result = dns_message_gettemprdatalist(message, &rdatalist); - if (result != ISC_R_SUCCESS) - return (result); - rdata = NULL; - result = dns_message_gettemprdata(message, &rdata); - if (result != ISC_R_SUCCESS) - return (result); - rdataset = NULL; - result = dns_message_gettemprdataset(message, &rdataset); + result = dns_message_buildopt(message, &rdataset, version, udpsize, + DNS_MESSAGEEXTFLAG_DO, ednsopts, count); if (result != ISC_R_SUCCESS) return (result); - dns_rdataset_init(rdataset); - - rdatalist->type = dns_rdatatype_opt; - rdatalist->covers = 0; - - /* - * Set Maximum UDP buffer size. - */ - rdatalist->rdclass = udpsize; - - /* - * Set EXTENDED-RCODE and Z to 0, DO to 1. - */ - rdatalist->ttl = (version << 16); - rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO; - - /* - * Set EDNS options if applicable - */ - if (request_nsid) { - /* Send empty NSID option (RFC5001) */ - unsigned char data[4]; - isc_buffer_t buf; - - isc_buffer_init(&buf, data, sizeof(data)); - isc_buffer_putuint16(&buf, DNS_OPT_NSID); - isc_buffer_putuint16(&buf, 0); - rdata->data = data; - rdata->length = sizeof(data); - } else { - rdata->data = NULL; - rdata->length = 0; - } - - rdata->rdclass = rdatalist->rdclass; - rdata->type = rdatalist->type; - rdata->flags = 0; - - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS); - return (dns_message_setopt(message, rdataset)); } @@ -1710,6 +1666,8 @@ resquery_send(resquery_t *query) { isc_boolean_t cleanup_cctx = ISC_FALSE; isc_boolean_t secure_domain; isc_boolean_t connecting = ISC_FALSE; + dns_ednsopt_t ednsopts[EDNSOPTS]; + unsigned ednsopt = 0; fctx = query->fctx; QTRACE("send"); @@ -1892,8 +1850,15 @@ resquery_send(resquery_t *query) { /* request NSID for current view or peer? */ if (peer != NULL) (void) dns_peer_getrequestnsid(peer, &reqnsid); + if (reqnsid) { + INSIST(ednsopt < EDNSOPTS); + ednsopts[ednsopt].code = DNS_OPT_NSID; + ednsopts[ednsopt].length = 0; + ednsopts[ednsopt].value = NULL; + ednsopt++; + } result = fctx_addopt(fctx->qmessage, version, - udpsize, reqnsid); + udpsize, ednsopts, ednsopt); if (reqnsid && result == ISC_R_SUCCESS) { query->options |= DNS_FETCHOPT_WANTNSID; } else if (result != ISC_R_SUCCESS) { @@ -2478,7 +2443,7 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, isc_result_t result; res = fctx->res; - unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0); + unshared = ISC_TF((fctx->options & DNS_FETCHOPT_UNSHARED) != 0); /* * If this name is a subdomain of the query domain, tell * the ADB to start looking using zone/hint data. This keeps us @@ -4227,7 +4192,7 @@ validated(isc_task_t *task, isc_event_t *event) { result = ncache_adderesult(fctx->rmessage, fctx->cache, node, covers, now, ttl, vevent->optout, - ardataset, &eresult); + vevent->secure, ardataset, &eresult); if (result != ISC_R_SUCCESS) goto noanswer_response; goto answer_response; @@ -4237,7 +4202,6 @@ validated(isc_task_t *task, isc_event_t *event) { FCTXTRACE("validation OK"); if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) { - result = dns_rdataset_addnoqname(vevent->rdataset, vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]); RUNTIME_CHECK(result == ISC_R_SUCCESS); @@ -4248,6 +4212,18 @@ validated(isc_task_t *task, isc_event_t *event) { vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]); RUNTIME_CHECK(result == ISC_R_SUCCESS); } + } else if (vevent->rdataset->trust == dns_trust_answer && + vevent->rdataset->type != dns_rdatatype_rrsig) + { + isc_result_t tresult; + dns_name_t *noqname = NULL; + tresult = findnoqname(fctx, vevent->name, + vevent->rdataset->type, &noqname); + if (tresult == ISC_R_SUCCESS && noqname != NULL) { + tresult = dns_rdataset_addnoqname(vevent->rdataset, + noqname); + RUNTIME_CHECK(tresult == ISC_R_SUCCESS); + } } /* @@ -4367,6 +4343,14 @@ validated(isc_task_t *task, isc_event_t *event) { fctx->attributes |= FCTX_ATTR_HAVEANSWER; if (hevent != NULL) { + /* + * Negative results must be indicated in event->result. + */ + if (dns_rdataset_isassociated(hevent->rdataset) && + NEGATIVE(hevent->rdataset)) { + INSIST(eresult == DNS_R_NCACHENXDOMAIN || + eresult == DNS_R_NCACHENXRRSET); + } hevent->result = eresult; RUNTIME_CHECK(dns_name_copy(vevent->name, dns_fixedname_name(&hevent->foundname), NULL) @@ -4388,6 +4372,149 @@ validated(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); } +static void +fctx_log(void *arg, int level, const char *fmt, ...) { + char msgbuf[2048]; + va_list args; + fetchctx_t *fctx = arg; + + va_start(args, fmt); + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + va_end(args); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, + DNS_LOGMODULE_RESOLVER, level, + "fctx %p(%s): %s", fctx, fctx->info, msgbuf); +} + +static inline isc_result_t +findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type, + dns_name_t **noqnamep) +{ + dns_rdataset_t *nrdataset, *next, *sigrdataset; + dns_rdata_rrsig_t rrsig; + isc_result_t result; + unsigned int labels; + dns_section_t section; + dns_name_t *zonename; + dns_fixedname_t fzonename; + dns_name_t *closest; + dns_fixedname_t fclosest; + dns_name_t *nearest; + dns_fixedname_t fnearest; + dns_rdatatype_t found = dns_rdatatype_none; + dns_name_t *noqname = NULL; + + FCTXTRACE("findnoqname"); + + REQUIRE(noqnamep != NULL && *noqnamep == NULL); + + /* + * Find the SIG for this rdataset, if we have it. + */ + for (sigrdataset = ISC_LIST_HEAD(name->list); + sigrdataset != NULL; + sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { + if (sigrdataset->type == dns_rdatatype_rrsig && + sigrdataset->covers == type) + break; + } + + if (sigrdataset == NULL) + return (ISC_R_NOTFOUND); + + labels = dns_name_countlabels(name); + + for (result = dns_rdataset_first(sigrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(sigrdataset)) { + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdataset_current(sigrdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &rrsig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + /* Wildcard has rrsig.labels < labels - 1. */ + if (rrsig.labels + 1U >= labels) + continue; + break; + } + + if (result == ISC_R_NOMORE) + return (ISC_R_NOTFOUND); + if (result != ISC_R_SUCCESS) + return (result); + + dns_fixedname_init(&fzonename); + zonename = dns_fixedname_name(&fzonename); + dns_fixedname_init(&fclosest); + closest = dns_fixedname_name(&fclosest); + dns_fixedname_init(&fnearest); + nearest = dns_fixedname_name(&fnearest); + +#define NXND(x) ((x) == ISC_R_SUCCESS) + + section = DNS_SECTION_AUTHORITY; + for (result = dns_message_firstname(fctx->rmessage, section); + result == ISC_R_SUCCESS; + result = dns_message_nextname(fctx->rmessage, section)) { + dns_name_t *nsec = NULL; + dns_message_currentname(fctx->rmessage, section, &nsec); + for (nrdataset = ISC_LIST_HEAD(nsec->list); + nrdataset != NULL; nrdataset = next) { + isc_boolean_t data = ISC_FALSE, exists = ISC_FALSE; + isc_boolean_t optout = ISC_FALSE, unknown = ISC_FALSE; + isc_boolean_t setclosest = ISC_FALSE; + isc_boolean_t setnearest = ISC_FALSE; + + next = ISC_LIST_NEXT(nrdataset, link); + if (nrdataset->type != dns_rdatatype_nsec && + nrdataset->type != dns_rdatatype_nsec3) + continue; + + if (nrdataset->type == dns_rdatatype_nsec && + NXND(dns_nsec_noexistnodata(type, name, nsec, + nrdataset, &exists, + &data, NULL, fctx_log, + fctx))) + { + if (!exists) { + noqname = nsec; + found = dns_rdatatype_nsec; + } + } + + if (nrdataset->type == dns_rdatatype_nsec3 && + NXND(dns_nsec3_noexistnodata(type, name, nsec, + nrdataset, zonename, + &exists, &data, + &optout, &unknown, + &setclosest, + &setnearest, + closest, nearest, + fctx_log, fctx))) + { + if (!exists && setnearest) { + noqname = nsec; + found = dns_rdatatype_nsec3; + } + } + } + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + if (noqname != NULL) { + for (sigrdataset = ISC_LIST_HEAD(noqname->list); + sigrdataset != NULL; + sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { + if (sigrdataset->type == dns_rdatatype_rrsig && + sigrdataset->covers == found) + break; + } + if (sigrdataset != NULL) + *noqnamep = noqname; + } + return (result); +} + static inline isc_result_t cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) @@ -4521,6 +4648,17 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, rdataset->ttl = res->view->maxcachettl; /* + * Find the SIG for this rdataset, if we have it. + */ + for (sigrdataset = ISC_LIST_HEAD(name->list); + sigrdataset != NULL; + sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { + if (sigrdataset->type == dns_rdatatype_rrsig && + sigrdataset->covers == rdataset->type) + break; + } + + /* * If this RRset is in a secure domain, is in bailiwick, * and is not glue, attempt DNSSEC validation. (We do not * attempt to validate glue or out-of-bailiwick data--even @@ -4540,16 +4678,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, */ if (rdataset->type == dns_rdatatype_rrsig) continue; - /* - * Find the SIG for this rdataset, if we have it. - */ - for (sigrdataset = ISC_LIST_HEAD(name->list); - sigrdataset != NULL; - sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { - if (sigrdataset->type == dns_rdatatype_rrsig && - sigrdataset->covers == rdataset->type) - break; - } + if (sigrdataset == NULL) { if (!ANSWER(rdataset) && need_validation) { /* @@ -4583,6 +4712,22 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, if (sigrdataset != NULL) sigrdataset->trust = trust; if (!need_validation || !ANSWER(rdataset)) { + if (ANSWER(rdataset) && + rdataset->type != dns_rdatatype_rrsig) { + isc_result_t tresult; + dns_name_t *noqname = NULL; + tresult = findnoqname(fctx, name, + rdataset->type, + &noqname); + if (tresult == ISC_R_SUCCESS && + noqname != NULL) { + tresult = + dns_rdataset_addnoqname( + rdataset, noqname); + RUNTIME_CHECK(tresult == + ISC_R_SUCCESS); + } + } addedrdataset = ardataset; result = dns_db_addrdataset(fctx->cache, node, NULL, now, rdataset, @@ -4710,6 +4855,21 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, options = DNS_DBADD_FORCE; } else options = 0; + + if (ANSWER(rdataset) && + rdataset->type != dns_rdatatype_rrsig) { + isc_result_t tresult; + dns_name_t *noqname = NULL; + tresult = findnoqname(fctx, name, + rdataset->type, &noqname); + if (tresult == ISC_R_SUCCESS && + noqname != NULL) { + tresult = dns_rdataset_addnoqname( + rdataset, noqname); + RUNTIME_CHECK(tresult == ISC_R_SUCCESS); + } + } + /* * Now we can add the rdataset. */ @@ -4718,6 +4878,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, rdataset, options, addedrdataset); + if (result == DNS_R_UNCHANGED) { if (ANSWER(rdataset) && ardataset != NULL && @@ -4813,8 +4974,8 @@ cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) static isc_result_t ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, - isc_boolean_t optout, dns_rdataset_t *ardataset, - isc_result_t *eresultp) + isc_boolean_t optout, isc_boolean_t secure, + dns_rdataset_t *ardataset, isc_result_t *eresultp) { isc_result_t result; dns_rdataset_t rdataset; @@ -4823,8 +4984,12 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdataset_init(&rdataset); ardataset = &rdataset; } - result = dns_ncache_addoptout(message, cache, node, covers, now, - maxttl, optout, ardataset); + if (secure) + result = dns_ncache_addoptout(message, cache, node, covers, + now, maxttl, optout, ardataset); + else + result = dns_ncache_add(message, cache, node, covers, now, + maxttl, ardataset); if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) { /* * If the cache now contains a negative entry and we @@ -4991,7 +5156,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, result = ncache_adderesult(fctx->rmessage, fctx->cache, node, covers, now, ttl, ISC_FALSE, - ardataset, &eresult); + ISC_FALSE, ardataset, &eresult); if (result != ISC_R_SUCCESS) goto unlock; @@ -5387,10 +5552,10 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, { isc_result_t result; dns_message_t *message; - dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name; + dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name, *save_name; dns_rdataset_t *rdataset, *ns_rdataset; isc_boolean_t aa, negative_response; - dns_rdatatype_t type; + dns_rdatatype_t type, save_type; dns_section_t section; FCTXTRACE("noanswer_response"); @@ -5457,6 +5622,8 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, ns_rdataset = NULL; soa_name = NULL; ds_name = NULL; + save_name = NULL; + save_type = dns_rdatatype_none; result = dns_message_firstname(message, section); while (result == ISC_R_SUCCESS) { name = NULL; @@ -5655,6 +5822,9 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, dns_trust_additional; } } + } else { + save_name = name; + save_type = ISC_LIST_HEAD(name->list)->type; } result = dns_message_nextname(message, section); if (result == ISC_R_NOMORE) @@ -5690,7 +5860,27 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, /* * The responder is insane. */ - log_formerr(fctx, "invalid response"); + if (save_name == NULL) { + log_formerr(fctx, "invalid response"); + return (DNS_R_FORMERR); + } + if (!dns_name_issubdomain(save_name, &fctx->domain)) { + char nbuf[DNS_NAME_FORMATSIZE]; + char dbuf[DNS_NAME_FORMATSIZE]; + char tbuf[DNS_RDATATYPE_FORMATSIZE]; + + dns_rdatatype_format(save_type, tbuf, + sizeof(tbuf)); + dns_name_format(save_name, nbuf, sizeof(nbuf)); + dns_name_format(&fctx->domain, dbuf, + sizeof(dbuf)); + + log_formerr(fctx, "Name %s (%s) not subdomain" + " of zone %s -- invalid response", + nbuf, tbuf, dbuf); + } else { + log_formerr(fctx, "invalid response"); + } return (DNS_R_FORMERR); } } @@ -5899,12 +6089,12 @@ answer_response(fetchctx_t *fctx) { * but we found a CNAME. * * Getting a CNAME response for some - * query types is an error. + * query types is an error, see + * RFC 4035, Section 2.5. */ if (type == dns_rdatatype_rrsig || - type == dns_rdatatype_dnskey || - type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3) { + type == dns_rdatatype_key || + type == dns_rdatatype_nsec) { char buf[DNS_RDATATYPE_FORMATSIZE]; dns_rdatatype_format(fctx->type, buf, sizeof(buf)); @@ -6449,44 +6639,24 @@ checknames(dns_message_t *message) { /* * Log server NSID at log level 'level' */ -static isc_result_t -log_nsid(dns_rdataset_t *opt, resquery_t *query, int level, isc_mem_t *mctx) +static void +log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, + int level, isc_mem_t *mctx) { static const char hex[17] = "0123456789abcdef"; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - isc_uint16_t optcode, nsid_len, buflen, i; - isc_result_t result; - isc_buffer_t nsidbuf; - dns_rdata_t rdata; + isc_uint16_t buflen, i; unsigned char *p, *buf, *nsid; - /* Extract rdata from OPT rdataset */ - result = dns_rdataset_first(opt); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - dns_rdata_init(&rdata); - dns_rdataset_current(opt, &rdata); - if (rdata.length < 4) - return (ISC_R_FAILURE); - - /* Check for NSID */ - isc_buffer_init(&nsidbuf, rdata.data, rdata.length); - isc_buffer_add(&nsidbuf, rdata.length); - optcode = isc_buffer_getuint16(&nsidbuf); - nsid_len = isc_buffer_getuint16(&nsidbuf); - if (optcode != DNS_OPT_NSID || nsid_len == 0) - return (ISC_R_FAILURE); - /* Allocate buffer for storing hex version of the NSID */ buflen = nsid_len * 2 + 1; buf = isc_mem_get(mctx, buflen); if (buf == NULL) - return (ISC_R_NOSPACE); + return; /* Convert to hex */ p = buf; - nsid = rdata.data + 4; + nsid = isc_buffer_current(opt); for (i = 0; i < nsid_len; i++) { *p++ = hex[(nsid[0] >> 4) & 0xf]; *p++ = hex[nsid[0] & 0xf]; @@ -6502,7 +6672,7 @@ log_nsid(dns_rdataset_t *opt, resquery_t *query, int level, isc_mem_t *mctx) /* Clean up */ isc_mem_put(mctx, buf, buflen); - return (ISC_R_SUCCESS); + return; } static void @@ -6576,6 +6746,41 @@ betterreferral(fetchctx_t *fctx) { } static void +process_opt(resquery_t *query, dns_rdataset_t *opt) { + dns_rdata_t rdata; + isc_buffer_t optbuf; + isc_result_t result; + isc_uint16_t optcode; + isc_uint16_t optlen; + + result = dns_rdataset_first(opt); + if (result == ISC_R_SUCCESS) { + dns_rdata_init(&rdata); + dns_rdataset_current(opt, &rdata); + isc_buffer_init(&optbuf, rdata.data, rdata.length); + isc_buffer_add(&optbuf, rdata.length); + while (isc_buffer_remaininglength(&optbuf) >= 4) { + optcode = isc_buffer_getuint16(&optbuf); + optlen = isc_buffer_getuint16(&optbuf); + INSIST(optlen <= isc_buffer_remaininglength(&optbuf)); + switch (optcode) { + case DNS_OPT_NSID: + if (query->options & DNS_FETCHOPT_WANTNSID) + log_nsid(&optbuf, optlen, query, + ISC_LOG_INFO, + query->fctx->res->mctx); + isc_buffer_forward(&optbuf, optlen); + break; + default: + isc_buffer_forward(&optbuf, optlen); + break; + } + } + INSIST(isc_buffer_remaininglength(&optbuf) == 0U); + } +} + +static void resquery_response(isc_task_t *task, isc_event_t *event) { isc_result_t result = ISC_R_SUCCESS; resquery_t *query = event->ev_arg; @@ -6650,13 +6855,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; - /* - * Remember that they don't like EDNS0. - */ - dns_adb_changeflags(fctx->adb, - query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); + add_bad_edns(fctx, &query->addrinfo->sockaddr); } else { /* * There's no hope for this query. @@ -6723,14 +6922,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) { */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; - /* - * Remember that they don't like EDNS0. - */ - dns_adb_changeflags( - fctx->adb, - query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); + add_bad_edns(fctx, + &query->addrinfo->sockaddr); inc_stats(fctx->res, dns_resstatscounter_edns0fail); } else { @@ -6754,13 +6947,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; - /* - * Remember that they don't like EDNS0. - */ - dns_adb_changeflags(fctx->adb, - query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); + add_bad_edns(fctx, &query->addrinfo->sockaddr); inc_stats(fctx->res, dns_resstatscounter_edns0fail); } else { @@ -6783,12 +6970,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) { log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx); /* - * Did we request NSID? If so, and if the response contains - * NSID data, log it at INFO level. + * Process receive opt record. */ opt = dns_message_getopt(message); - if (opt != NULL && (query->options & DNS_FETCHOPT_WANTNSID) != 0) - log_nsid(opt, query, ISC_LOG_INFO, fctx->res->mctx); + if (opt != NULL) + process_opt(query, opt); /* * If the message is signed, check the signature. If not, this diff --git a/contrib/bind9/lib/dns/result.c b/contrib/bind9/lib/dns/result.c index 0546d0f..3987953 100644 --- a/contrib/bind9/lib/dns/result.c +++ b/contrib/bind9/lib/dns/result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -160,7 +160,9 @@ static const char *text[DNS_R_NRESULTS] = { "not master", /*%< 105 DNS_R_NOTMASTER */ "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */ - "expired", /*%< 106 DNS_R_EXPIRED */ + "expired", /*%< 107 DNS_R_EXPIRED */ + "not dynamic", /*%< 108 DNS_R_NOTDYNAMIC */ + "bad EUI" /*%< 109 DNS_R_BADEUI */ }; static const char *rcode_text[DNS_R_NRCODERESULTS] = { @@ -264,6 +266,7 @@ dns_result_torcode(isc_result_t result) { case DNS_R_TOOMANYHOPS: case DNS_R_TSIGERRORSET: case DNS_R_UNKNOWN: + case DNS_R_NAMETOOLONG: rcode = dns_rcode_formerr; break; case DNS_R_DISALLOWED: diff --git a/contrib/bind9/lib/dns/rootns.c b/contrib/bind9/lib/dns/rootns.c index 9b25369..3502022 100644 --- a/contrib/bind9/lib/dns/rootns.c +++ b/contrib/bind9/lib/dns/rootns.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -63,7 +63,8 @@ static char root_ns[] = "A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:BA3E::2:30\n" "B.ROOT-SERVERS.NET. 3600000 IN A 192.228.79.201\n" "C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12\n" -"D.ROOT-SERVERS.NET. 3600000 IN A 128.8.10.90\n" +"D.ROOT-SERVERS.NET. 3600000 IN A 199.7.91.13\n" +"D.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2d::d\n" "E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10\n" "F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241\n" "F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2F::F\n" diff --git a/contrib/bind9/lib/dns/rpz.c b/contrib/bind9/lib/dns/rpz.c index 7865859..2d689e7 100644 --- a/contrib/bind9/lib/dns/rpz.c +++ b/contrib/bind9/lib/dns/rpz.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,6 +16,7 @@ /* $Id$ */ + /*! \file */ #include <config.h> @@ -123,8 +124,6 @@ struct dns_rpz_cidr { dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */ }; -static isc_boolean_t have_rpz_zones = ISC_FALSE; - const char * dns_rpz_type2str(dns_rpz_type_t type) { switch (type) { @@ -191,6 +190,7 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) { break; default: str = ""; + POST(str); INSIST(0); } return (str); @@ -266,21 +266,6 @@ dns_rpz_view_destroy(dns_view_t *view) { } /* - * Note that we have at least one response policy zone. - * It would be better for something to tell the rbtdb code that the - * zone is in at least one view's list of policy zones. - */ -void -dns_rpz_set_need(isc_boolean_t need) { - have_rpz_zones = need; -} - -isc_boolean_t -dns_rpz_needed(void) { - return (have_rpz_zones); -} - -/* * Start a new radix tree for a response policy zone. */ isc_result_t @@ -292,12 +277,6 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, REQUIRE(rbtdb_cidr != NULL && *rbtdb_cidr == NULL); - /* - * Only if there is at least one response policy zone. - */ - if (!have_rpz_zones) - return (ISC_R_SUCCESS); - cidr = isc_mem_get(mctx, sizeof(*cidr)); if (cidr == NULL) return (ISC_R_NOMEMORY); @@ -339,7 +318,7 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, * See if a policy zone has IP, NSIP, or NSDNAME rules or records. */ void -dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) { +dns_rpz_enabled_get(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) { if (cidr == NULL) return; if (cidr->root != NULL && @@ -432,6 +411,9 @@ static void badname(int level, dns_name_t *name, const char *str1, const char *str2) { char printname[DNS_NAME_FORMATSIZE]; + /* + * bin/tests/system/rpz/tests.sh looks for "invalid rpz". + */ if (level < DNS_RPZ_DEBUG_QUIET && isc_log_wouldlog(dns_lctx, level)) { dns_name_format(name, printname, sizeof(printname)); @@ -508,7 +490,7 @@ ip2name(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip, while (i < DNS_RPZ_CIDR_WORDS * 2 && w[i] == 0) ++i; } - if (len > (int)sizeof(str)) + if (len >= (int)sizeof(str)) return (ISC_R_FAILURE); } } @@ -956,8 +938,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { dns_rpz_cidr_bits_t tgt_prefix; dns_rpz_type_t type; - if (cidr == NULL) - return; + REQUIRE(cidr != NULL); /* * No worries if the new name is not an IP address. @@ -985,6 +966,9 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { { char printname[DNS_NAME_FORMATSIZE]; + /* + * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". + */ dns_name_format(name, printname, sizeof(printname)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, diff --git a/contrib/bind9/lib/dns/sdb.c b/contrib/bind9/lib/dns/sdb.c index 8092c5a..526ce87 100644 --- a/contrib/bind9/lib/dns/sdb.c +++ b/contrib/bind9/lib/dns/sdb.c @@ -382,7 +382,7 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, datalen = strlen(data); size = initial_size(datalen); do { - isc_buffer_init(&b, data, datalen); + isc_buffer_constinit(&b, data, datalen); isc_buffer_add(&b, datalen); result = isc_lex_openbuffer(lex, &b); if (result != ISC_R_SUCCESS) @@ -448,7 +448,7 @@ getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) { origin = &sdb->common.origin; else origin = dns_rootname; - isc_buffer_init(&b, name, strlen(name)); + isc_buffer_constinit(&b, name, strlen(name)); isc_buffer_add(&b, strlen(name)); result = dns_name_fromtext(newname, &b, origin, 0, NULL); diff --git a/contrib/bind9/lib/dns/sdlz.c b/contrib/bind9/lib/dns/sdlz.c index 870e981..6e518d1 100644 --- a/contrib/bind9/lib/dns/sdlz.c +++ b/contrib/bind9/lib/dns/sdlz.c @@ -1817,7 +1817,7 @@ dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, size = initial_size(data); do { - isc_buffer_init(&b, data, strlen(data)); + isc_buffer_constinit(&b, data, strlen(data)); isc_buffer_add(&b, strlen(data)); result = isc_lex_openbuffer(lex, &b); @@ -1883,7 +1883,7 @@ dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name, origin = &sdlz->common.origin; else origin = dns_rootname; - isc_buffer_init(&b, name, strlen(name)); + isc_buffer_constinit(&b, name, strlen(name)); isc_buffer_add(&b, strlen(name)); result = dns_name_fromtext(newname, &b, origin, 0, NULL); diff --git a/contrib/bind9/lib/dns/spnego.c b/contrib/bind9/lib/dns/spnego.c index 0486a72..0c1c858 100644 --- a/contrib/bind9/lib/dns/spnego.c +++ b/contrib/bind9/lib/dns/spnego.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2006-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -630,8 +630,10 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status, sizeof(mechbuf), &init_token.mechTypes.val[i], &mech_len); - if (ret) + if (ret) { + free_NegTokenInit(&init_token); return (GSS_S_DEFECTIVE_TOKEN); + } if (mech_len == GSS_KRB5_MECH->length && memcmp(GSS_KRB5_MECH->elements, mechbuf + sizeof(mechbuf) - mech_len, @@ -650,8 +652,10 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status, } } - if (!found) + if (!found) { + free_NegTokenInit(&init_token); return (send_reject(minor_status, output_token)); + } if (i == 0 && init_token.mechToken != NULL) { ibuf.length = init_token.mechToken->length; @@ -669,12 +673,14 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status, time_rec, delegated_cred_handle); if (GSS_ERROR(major_status)) { + free_NegTokenInit(&init_token); send_reject(&minor_status2, output_token); return (major_status); } ot = &obuf; } ret = send_accept(&minor_status2, output_token, ot, pref); + free_NegTokenInit(&init_token); if (ot != NULL && ot->length != 0U) gss_release_buffer(&minor_status2, ot); @@ -846,10 +852,13 @@ der_get_octet_string(const unsigned char *p, size_t len, octet_string *data, size_t *size) { data->length = len; - data->data = malloc(len); - if (data->data == NULL && data->length != 0U) - return (ENOMEM); - memcpy(data->data, p, len); + if (len != 0U) { + data->data = malloc(len); + if (data->data == NULL) + return (ENOMEM); + memcpy(data->data, p, len); + } else + data->data = NULL; if (size) *size = len; return (0); @@ -862,6 +871,8 @@ der_get_oid(const unsigned char *p, size_t len, int n; size_t oldlen = len; + data->components = NULL; + data->length = 0; if (len < 1U) return (ASN1_OVERRUN); @@ -997,6 +1008,9 @@ decode_octet_string(const unsigned char *p, size_t len, int e; size_t slen; + k->data = NULL; + k->length = 0; + e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_OctetString, &l); if (e) return (e); @@ -1547,6 +1561,11 @@ spnego_initial(OM_uint32 *minor_status, buf_size = 1024; buf = malloc(buf_size); + if (buf == NULL) { + *minor_status = ENOMEM; + ret = GSS_S_FAILURE; + goto end; + } do { ret = encode_NegTokenInit(buf + buf_size - 1, @@ -1685,6 +1704,7 @@ spnego_reply(OM_uint32 *minor_status, ret = decode_NegTokenResp(buf + taglen, len, &resp, NULL); if (ret) { + free_NegTokenResp(&resp); *minor_status = ENOMEM; return (GSS_S_FAILURE); } diff --git a/contrib/bind9/lib/dns/spnego_asn1.c b/contrib/bind9/lib/dns/spnego_asn1.c index 75c2304..b506054 100644 --- a/contrib/bind9/lib/dns/spnego_asn1.c +++ b/contrib/bind9/lib/dns/spnego_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2006, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -53,10 +53,10 @@ typedef struct oid { (R) = ENOMEM; \ } else { \ (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \ - (S), (L)); \ + (S), (L)); \ if((R) != 0) { \ - free((B)); \ - (B) = NULL; \ + free((B)); \ + (B) = NULL; \ } \ } \ } while (0) @@ -171,33 +171,31 @@ static void free_NegTokenResp(NegTokenResp *); /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l +#define BACK if (e) return e; p -= l; len -= l; ret += l; POST(p); POST(len); POST(ret) static int encode_MechType(unsigned char *p, size_t len, const MechType * data, size_t * size) { size_t ret = 0; size_t l; - int i, e; + int e; - i = 0; e = encode_oid(p, len, data, &l); BACK; *size = ret; return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l +#define FORW if(e) goto fail; p += l; len -= l; ret += l; POST(p); POST(len); POST(ret) static int decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size) { - size_t ret = 0, reallen; + size_t ret = 0; size_t l; int e; memset(data, 0, sizeof(*data)); - reallen = 0; e = decode_oid(p, len, data, &l); FORW; if (size) @@ -223,8 +221,6 @@ free_MechType(MechType * data) /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l - static int encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size) { @@ -232,7 +228,6 @@ encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, siz size_t l; int i, e; - i = 0; for (i = (data)->len - 1; i >= 0; --i) { int oldret = ret; ret = 0; @@ -246,8 +241,6 @@ encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, siz return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l - static int decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size) { @@ -269,8 +262,14 @@ decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, siz (data)->len = 0; (data)->val = NULL; while (ret < origlen) { + void *old = (data)->val; (data)->len++; (data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len); + if ((data)->val == NULL) { + (data)->val = old; + (data)->len--; + return ENOMEM; + } e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l); FORW; len = origlen - ret; @@ -305,16 +304,13 @@ free_MechTypeList(MechTypeList * data) /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l - static int encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size) { size_t ret = 0; size_t l; - int i, e; + int e; - i = 0; { unsigned char c = 0; *p-- = c; @@ -355,8 +351,6 @@ encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, siz return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l - static int decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size) { @@ -381,8 +375,6 @@ decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, siz data->anonFlag = (*p >> 3) & 1; data->confFlag = (*p >> 2) & 1; data->integFlag = (*p >> 1) & 1; - p += reallen; - len -= reallen; ret += reallen; if (size) *size = ret; @@ -418,16 +410,13 @@ free_ContextFlags(ContextFlags * data) /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l - static int encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size) { size_t ret = 0; size_t l; - int i, e; + int e; - i = 0; if ((data)->mechListMIC) { int oldret = ret; ret = 0; @@ -469,8 +458,6 @@ encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, siz return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l - static int decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size) { @@ -646,16 +633,13 @@ free_NegTokenInit(NegTokenInit * data) /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l - static int encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size) { size_t ret = 0; size_t l; - int i, e; + int e; - i = 0; if ((data)->mechListMIC) { int oldret = ret; ret = 0; @@ -698,8 +682,6 @@ encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, siz return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l - static int decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size) { diff --git a/contrib/bind9/lib/dns/ssu.c b/contrib/bind9/lib/dns/ssu.c index 83aa679..49a777a 100644 --- a/contrib/bind9/lib/dns/ssu.c +++ b/contrib/bind9/lib/dns/ssu.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2010, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -82,7 +82,8 @@ dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) { return (result); } table->references = 1; - table->mctx = mctx; + table->mctx = NULL; + isc_mem_attach(mctx, &table->mctx); ISC_LIST_INIT(table->rules); table->magic = SSUTABLEMAGIC; *tablep = table; @@ -115,7 +116,7 @@ destroy(dns_ssutable_t *table) { } DESTROYLOCK(&table->lock); table->magic = 0; - isc_mem_put(mctx, table, sizeof(dns_ssutable_t)); + isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t)); } void diff --git a/contrib/bind9/lib/dns/ssu_external.c b/contrib/bind9/lib/dns/ssu_external.c index 65ba1b5..43d231d 100644 --- a/contrib/bind9/lib/dns/ssu_external.c +++ b/contrib/bind9/lib/dns/ssu_external.c @@ -79,7 +79,7 @@ ux_socket_connect(const char *path) { memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, path, sizeof(addr.sun_path)); + strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { diff --git a/contrib/bind9/lib/dns/tkey.c b/contrib/bind9/lib/dns/tkey.c index 0112f7e..161c188 100644 --- a/contrib/bind9/lib/dns/tkey.c +++ b/contrib/bind9/lib/dns/tkey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -991,8 +991,13 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name, ISC_LIST_INIT(namelist); RETERR(add_rdata_to_list(msg, &keyname, rdata, 0, &namelist)); - dns_message_addname(msg, ISC_LIST_HEAD(namelist), - DNS_SECTION_ADDITIONAL); + name = ISC_LIST_HEAD(namelist); + while (name != NULL) { + dns_name_t *next = ISC_LIST_NEXT(name, link); + ISC_LIST_UNLINK(namelist, name, link); + dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL); + name = next; + } return (ISC_R_SUCCESS); diff --git a/contrib/bind9/lib/dns/tsig.c b/contrib/bind9/lib/dns/tsig.c index 76c239b..c7768f4 100644 --- a/contrib/bind9/lib/dns/tsig.c +++ b/contrib/bind9/lib/dns/tsig.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -239,7 +239,9 @@ adjust_lru(dns_tsigkey_t *tkey) { * We may have been removed from the LRU list between * removing the read lock and aquiring the write lock. */ - if (ISC_LINK_LINKED(tkey, link)) { + if (ISC_LINK_LINKED(tkey, link) && + tkey->ring->lru.tail != tkey) + { ISC_LIST_UNLINK(tkey->ring->lru, tkey, link); ISC_LIST_APPEND(tkey->ring->lru, tkey, link); } @@ -625,8 +627,7 @@ restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) { } static void -dump_key(dns_tsigkey_t *tkey, FILE *fp) -{ +dump_key(dns_tsigkey_t *tkey, FILE *fp) { char *buffer = NULL; int length = 0; char namestr[DNS_NAME_FORMATSIZE]; @@ -634,6 +635,9 @@ dump_key(dns_tsigkey_t *tkey, FILE *fp) char algorithmstr[DNS_NAME_FORMATSIZE]; isc_result_t result; + REQUIRE(tkey != NULL); + REQUIRE(fp != NULL); + dns_name_format(&tkey->name, namestr, sizeof(namestr)); dns_name_format(tkey->creator, creatorstr, sizeof(creatorstr)); dns_name_format(tkey->algorithm, algorithmstr, sizeof(algorithmstr)); @@ -942,7 +946,8 @@ dns_tsig_sign(dns_message_t *msg) { isc_buffer_t headerbuf; isc_uint16_t digestbits; - ret = dst_context_create(key->key, mctx, &ctx); + ret = dst_context_create2(key->key, mctx, + DNS_LOGCATEGORY_DNSSEC, &ctx); if (ret != ISC_R_SUCCESS) return (ret); @@ -973,6 +978,13 @@ dns_tsig_sign(dns_message_t *msg) { if (ret != ISC_R_SUCCESS) goto cleanup_context; } +#if defined(__clang__) && \ + ( __clang_major__ < 3 || \ + (__clang_major__ == 3 && __clang_minor__ < 2) || \ + (__clang_major__ == 4 && __clang_minor__ < 2)) + /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */ + else memset(&querytsig, 0, sizeof(querytsig)); +#endif /* * Digest the header. @@ -1228,6 +1240,13 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, if (ret != ISC_R_SUCCESS) return (ret); } +#if defined(__clang__) && \ + ( __clang_major__ < 3 || \ + (__clang_major__ == 3 && __clang_minor__ < 2) || \ + (__clang_major__ == 4 && __clang_minor__ < 2)) + /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */ + else memset(&querytsig, 0, sizeof(querytsig)); +#endif /* * Do the key name and algorithm match that of the query? @@ -1326,7 +1345,8 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, sig_r.base = tsig.signature; sig_r.length = tsig.siglen; - ret = dst_context_create(key, mctx, &ctx); + ret = dst_context_create2(key, mctx, + DNS_LOGCATEGORY_DNSSEC, &ctx); if (ret != ISC_R_SUCCESS) return (ret); @@ -1557,7 +1577,9 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) { key = tsigkey->key; if (msg->tsigctx == NULL) { - ret = dst_context_create(key, mctx, &msg->tsigctx); + ret = dst_context_create2(key, mctx, + DNS_LOGCATEGORY_DNSSEC, + &msg->tsigctx); if (ret != ISC_R_SUCCESS) goto cleanup_querystruct; @@ -1746,11 +1768,15 @@ static void free_tsignode(void *node, void *_unused) { dns_tsigkey_t *key; - UNUSED(_unused); - REQUIRE(node != NULL); + UNUSED(_unused); + key = node; + if (key->generated) { + if (ISC_LINK_LINKED(key, link)) + ISC_LIST_UNLINK(key->ring->lru, key, link); + } dns_tsigkey_detach(&key); } diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c index 674675f..3d7518a 100644 --- a/contrib/bind9/lib/dns/validator.c +++ b/contrib/bind9/lib/dns/validator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -157,7 +157,7 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category, ISC_FORMAT_PRINTF(5, 0); static void -validator_log(dns_validator_t *val, int level, const char *fmt, ...) +validator_log(void *val, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); static void @@ -195,6 +195,7 @@ marksecure(dns_validatorevent_t *event) { dns_rdataset_settrust(event->rdataset, dns_trust_secure); if (event->sigrdataset != NULL) dns_rdataset_settrust(event->sigrdataset, dns_trust_secure); + event->secure = ISC_TRUE; } static void @@ -403,6 +404,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { isc_result_t result; isc_result_t eresult; isc_result_t saved_result; + dns_fetch_t *fetch; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); @@ -419,12 +421,13 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); - dns_resolver_destroyfetch(&val->fetch); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator"); LOCK(&val->lock); + fetch = val->fetch; + val->fetch = NULL; if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == ISC_R_SUCCESS) { @@ -464,6 +467,8 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { } want_destroy = exit_check(val); UNLOCK(&val->lock); + if (fetch != NULL) + dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } @@ -481,6 +486,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) { isc_boolean_t want_destroy; isc_result_t result; isc_result_t eresult; + dns_fetch_t *fetch; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); @@ -497,12 +503,13 @@ dsfetched(isc_task_t *task, isc_event_t *event) { if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); - dns_resolver_destroyfetch(&val->fetch); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched"); LOCK(&val->lock); + fetch = val->fetch; + val->fetch = NULL; if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == ISC_R_SUCCESS) { @@ -536,6 +543,8 @@ dsfetched(isc_task_t *task, isc_event_t *event) { } want_destroy = exit_check(val); UNLOCK(&val->lock); + if (fetch != NULL) + dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } @@ -559,6 +568,7 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { isc_boolean_t want_destroy; isc_result_t result; isc_result_t eresult; + dns_fetch_t *fetch; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); @@ -573,13 +583,14 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { dns_db_detach(&devent->db); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); - dns_resolver_destroyfetch(&val->fetch); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s", dns_result_totext(eresult)); LOCK(&val->lock); + fetch = val->fetch; + val->fetch = NULL; if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == DNS_R_CNAME || @@ -632,6 +643,8 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); want_destroy = exit_check(val); UNLOCK(&val->lock); + if (fetch != NULL) + dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } @@ -839,452 +852,6 @@ cnamevalidated(isc_task_t *task, isc_event_t *event) { } /*% - * Return ISC_R_SUCCESS if we can determine that the name doesn't exist - * or we can determine whether there is data or not at the name. - * If the name does not exist return the wildcard name. - * - * Return ISC_R_IGNORE when the NSEC is not the appropriate one. - */ -static isc_result_t -nsecnoexistnodata(dns_validator_t *val, dns_name_t *name, dns_name_t *nsecname, - dns_rdataset_t *nsecset, isc_boolean_t *exists, - isc_boolean_t *data, dns_name_t *wild) -{ - int order; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - dns_namereln_t relation; - unsigned int olabels, nlabels, labels; - dns_rdata_nsec_t nsec; - isc_boolean_t atparent; - isc_boolean_t ns; - isc_boolean_t soa; - - REQUIRE(exists != NULL); - REQUIRE(data != NULL); - REQUIRE(nsecset != NULL && - nsecset->type == dns_rdatatype_nsec); - - result = dns_rdataset_first(nsecset); - if (result != ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), - "failure processing NSEC set"); - return (result); - } - dns_rdataset_current(nsecset, &rdata); - - validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant nsec"); - relation = dns_name_fullcompare(name, nsecname, &order, &olabels); - - if (order < 0) { - /* - * The name is not within the NSEC range. - */ - validator_log(val, ISC_LOG_DEBUG(3), - "NSEC does not cover name, before NSEC"); - return (ISC_R_IGNORE); - } - - if (order == 0) { - /* - * The names are the same. If we are validating "." - * then atparent should not be set as there is no parent. - */ - atparent = (olabels != 1) && - dns_rdatatype_atparent(val->event->type); - ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns); - soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa); - if (ns && !soa) { - if (!atparent) { - /* - * This NSEC record is from somewhere higher in - * the DNS, and at the parent of a delegation. - * It can not be legitimately used here. - */ - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring parent nsec"); - return (ISC_R_IGNORE); - } - } else if (atparent && ns && soa) { - /* - * This NSEC record is from the child. - * It can not be legitimately used here. - */ - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring child nsec"); - return (ISC_R_IGNORE); - } - if (val->event->type == dns_rdatatype_cname || - val->event->type == dns_rdatatype_nxt || - val->event->type == dns_rdatatype_nsec || - val->event->type == dns_rdatatype_key || - !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) { - *exists = ISC_TRUE; - *data = dns_nsec_typepresent(&rdata, val->event->type); - validator_log(val, ISC_LOG_DEBUG(3), - "nsec proves name exists (owner) data=%d", - *data); - return (ISC_R_SUCCESS); - } - validator_log(val, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists"); - return (ISC_R_IGNORE); - } - - if (relation == dns_namereln_subdomain && - dns_nsec_typepresent(&rdata, dns_rdatatype_ns) && - !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) - { - /* - * This NSEC record is from somewhere higher in - * the DNS, and at the parent of a delegation. - * It can not be legitimately used here. - */ - validator_log(val, ISC_LOG_DEBUG(3), "ignoring parent nsec"); - return (ISC_R_IGNORE); - } - - result = dns_rdata_tostruct(&rdata, &nsec, NULL); - if (result != ISC_R_SUCCESS) - return (result); - relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels); - if (order == 0) { - dns_rdata_freestruct(&nsec); - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring nsec matches next name"); - return (ISC_R_IGNORE); - } - - if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) { - /* - * The name is not within the NSEC range. - */ - dns_rdata_freestruct(&nsec); - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring nsec because name is past end of range"); - return (ISC_R_IGNORE); - } - - if (order > 0 && relation == dns_namereln_subdomain) { - validator_log(val, ISC_LOG_DEBUG(3), - "nsec proves name exist (empty)"); - dns_rdata_freestruct(&nsec); - *exists = ISC_TRUE; - *data = ISC_FALSE; - return (ISC_R_SUCCESS); - } - if (wild != NULL) { - dns_name_t common; - dns_name_init(&common, NULL); - if (olabels > nlabels) { - labels = dns_name_countlabels(nsecname); - dns_name_getlabelsequence(nsecname, labels - olabels, - olabels, &common); - } else { - labels = dns_name_countlabels(&nsec.next); - dns_name_getlabelsequence(&nsec.next, labels - nlabels, - nlabels, &common); - } - result = dns_name_concatenate(dns_wildcardname, &common, - wild, NULL); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&nsec); - validator_log(val, ISC_LOG_DEBUG(3), - "failure generating wildcard name"); - return (result); - } - } - dns_rdata_freestruct(&nsec); - validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok"); - *exists = ISC_FALSE; - return (ISC_R_SUCCESS); -} - -static isc_result_t -nsec3noexistnodata(dns_validator_t *val, dns_name_t* name, - dns_name_t *nsec3name, dns_rdataset_t *nsec3set, - dns_name_t *zonename, isc_boolean_t *exists, - isc_boolean_t *data, isc_boolean_t *optout, - isc_boolean_t *unknown, isc_boolean_t *setclosest, - isc_boolean_t *setnearest, dns_name_t *closest, - dns_name_t *nearest) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fzone; - dns_fixedname_t qfixed; - dns_label_t hashlabel; - dns_name_t *qname; - dns_name_t *zone; - dns_rdata_nsec3_t nsec3; - dns_rdata_t rdata = DNS_RDATA_INIT; - int order; - int scope; - isc_boolean_t atparent; - isc_boolean_t first; - isc_boolean_t ns; - isc_boolean_t soa; - isc_buffer_t buffer; - isc_result_t answer = ISC_R_IGNORE; - isc_result_t result; - unsigned char hash[NSEC3_MAX_HASH_LENGTH]; - unsigned char owner[NSEC3_MAX_HASH_LENGTH]; - unsigned int length; - unsigned int qlabels; - unsigned int zlabels; - - REQUIRE((exists == NULL && data == NULL) || - (exists != NULL && data != NULL)); - REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3); - REQUIRE((setclosest == NULL && closest == NULL) || - (setclosest != NULL && closest != NULL)); - REQUIRE((setnearest == NULL && nearest == NULL) || - (setnearest != NULL && nearest != NULL)); - - result = dns_rdataset_first(nsec3set); - if (result != ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), - "failure processing NSEC3 set"); - return (result); - } - - dns_rdataset_current(nsec3set, &rdata); - - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant NSEC3"); - - dns_fixedname_init(&fzone); - zone = dns_fixedname_name(&fzone); - zlabels = dns_name_countlabels(nsec3name); - - /* - * NSEC3 records must have two or more labels to be valid. - */ - if (zlabels < 2) - return (ISC_R_IGNORE); - - /* - * Strip off the NSEC3 hash to get the zone. - */ - zlabels--; - dns_name_split(nsec3name, zlabels, NULL, zone); - - /* - * If not below the zone name we can ignore this record. - */ - if (!dns_name_issubdomain(name, zone)) - return (ISC_R_IGNORE); - - /* - * Is this zone the same or deeper than the current zone? - */ - if (dns_name_countlabels(zonename) == 0 || - dns_name_issubdomain(zone, zonename)) - dns_name_copy(zone, zonename, NULL); - - if (!dns_name_equal(zone, zonename)) - return (ISC_R_IGNORE); - - /* - * Are we only looking for the most enclosing zone? - */ - if (exists == NULL || data == NULL) - return (ISC_R_SUCCESS); - - /* - * Only set unknown once we are sure that this NSEC3 is from - * the deepest covering zone. - */ - if (!dns_nsec3_supportedhash(nsec3.hash)) { - if (unknown != NULL) - *unknown = ISC_TRUE; - return (ISC_R_IGNORE); - } - - /* - * Recover the hash from the first label. - */ - dns_name_getlabel(nsec3name, 0, &hashlabel); - isc_region_consume(&hashlabel, 1); - isc_buffer_init(&buffer, owner, sizeof(owner)); - result = isc_base32hex_decoderegion(&hashlabel, &buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * The hash lengths should match. If not ignore the record. - */ - if (isc_buffer_usedlength(&buffer) != nsec3.next_length) - return (ISC_R_IGNORE); - - /* - * Work out what this NSEC3 covers. - * Inside (<0) or outside (>=0). - */ - scope = memcmp(owner, nsec3.next, nsec3.next_length); - - /* - * Prepare to compute all the hashes. - */ - dns_fixedname_init(&qfixed); - qname = dns_fixedname_name(&qfixed); - dns_name_downcase(name, qname, NULL); - qlabels = dns_name_countlabels(qname); - first = ISC_TRUE; - - while (qlabels >= zlabels) { - length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations, - nsec3.salt, nsec3.salt_length, - qname->ndata, qname->length); - /* - * The computed hash length should match. - */ - if (length != nsec3.next_length) { - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring NSEC bad length %u vs %u", - length, nsec3.next_length); - return (ISC_R_IGNORE); - } - - order = memcmp(hash, owner, length); - if (first && order == 0) { - /* - * The hashes are the same. - */ - atparent = dns_rdatatype_atparent(val->event->type); - ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns); - soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa); - if (ns && !soa) { - if (!atparent) { - /* - * This NSEC3 record is from somewhere - * higher in the DNS, and at the - * parent of a delegation. It can not - * be legitimately used here. - */ - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring parent NSEC3"); - return (ISC_R_IGNORE); - } - } else if (atparent && ns && soa) { - /* - * This NSEC3 record is from the child. - * It can not be legitimately used here. - */ - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring child NSEC3"); - return (ISC_R_IGNORE); - } - if (val->event->type == dns_rdatatype_cname || - val->event->type == dns_rdatatype_nxt || - val->event->type == dns_rdatatype_nsec || - val->event->type == dns_rdatatype_key || - !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) { - *exists = ISC_TRUE; - *data = dns_nsec3_typepresent(&rdata, - val->event->type); - validator_log(val, ISC_LOG_DEBUG(3), - "NSEC3 proves name exists (owner) " - "data=%d", *data); - return (ISC_R_SUCCESS); - } - validator_log(val, ISC_LOG_DEBUG(3), - "NSEC3 proves CNAME exists"); - return (ISC_R_IGNORE); - } - - if (order == 0 && - dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) && - !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa)) - { - /* - * This NSEC3 record is from somewhere higher in - * the DNS, and at the parent of a delegation. - * It can not be legitimately used here. - */ - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring parent NSEC3"); - return (ISC_R_IGNORE); - } - - /* - * Potential closest encloser. - */ - if (order == 0) { - if (closest != NULL && - (dns_name_countlabels(closest) == 0 || - dns_name_issubdomain(qname, closest)) && - !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) && - !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) && - (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) || - !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns))) - { - - dns_name_format(qname, namebuf, - sizeof(namebuf)); - validator_log(val, ISC_LOG_DEBUG(3), - "NSEC3 indicates potential " - "closest encloser: '%s'", - namebuf); - dns_name_copy(qname, closest, NULL); - *setclosest = ISC_TRUE; - } - dns_name_format(qname, namebuf, sizeof(namebuf)); - validator_log(val, ISC_LOG_DEBUG(3), - "NSEC3 at super-domain %s", namebuf); - return (answer); - } - - /* - * Find if the name does not exist. - * - * We continue as we need to find the name closest to the - * closest encloser that doesn't exist. - * - * We also need to continue to ensure that we are not - * proving the non-existence of a record in a sub-zone. - * If that would be the case we will return ISC_R_IGNORE - * above. - */ - if ((scope < 0 && order > 0 && - memcmp(hash, nsec3.next, length) < 0) || - (scope >= 0 && (order > 0 || - memcmp(hash, nsec3.next, length) < 0))) - { - char namebuf[DNS_NAME_FORMATSIZE]; - - dns_name_format(qname, namebuf, sizeof(namebuf)); - validator_log(val, ISC_LOG_DEBUG(3), "NSEC3 proves " - "name does not exist: '%s'", namebuf); - if (nearest != NULL && - (dns_name_countlabels(nearest) == 0 || - dns_name_issubdomain(nearest, qname))) { - dns_name_copy(qname, nearest, NULL); - *setnearest = ISC_TRUE; - } - - *exists = ISC_FALSE; - *data = ISC_FALSE; - if (optout != NULL) { - if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0) - validator_log(val, ISC_LOG_DEBUG(3), - "NSEC3 indicates optout"); - *optout = - ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT); - } - answer = ISC_R_SUCCESS; - } - - qlabels--; - if (qlabels > 0) - dns_name_split(qname, qlabels, NULL, qname); - first = ISC_FALSE; - } - return (answer); -} - -/*% * Callback for when NSEC records have been validated. * * Looks for NOQNAME, NODATA and OPTOUT proofs. @@ -1339,8 +906,9 @@ authvalidated(isc_task_t *task, isc_event_t *event) { rdataset->trust == dns_trust_secure && (NEEDNODATA(val) || NEEDNOQNAME(val)) && !FOUNDNODATA(val) && !FOUNDNOQNAME(val) && - nsecnoexistnodata(val, val->event->name, devent->name, - rdataset, &exists, &data, wild) + dns_nsec_noexistnodata(val->event->type, val->event->name, + devent->name, rdataset, &exists, + &data, wild, validator_log, val) == ISC_R_SUCCESS) { if (exists && !data) { @@ -1413,9 +981,6 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); - if (val->view->zonetable == NULL) - return (ISC_R_CANCELED); - if (isc_time_now(&now) == ISC_R_SUCCESS && dns_resolver_getbadcache(val->view->resolver, name, type, &now)) { @@ -1859,6 +1424,10 @@ isselfsigned(dns_validator_t *val) { name = val->event->name; mctx = val->view->mctx; + if (rdataset->type == dns_rdatatype_cname || + rdataset->type == dns_rdatatype_dname) + return (answer); + INSIST(rdataset->type == dns_rdatatype_dnskey); for (result = dns_rdataset_first(rdataset); @@ -2831,8 +2400,9 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename) if (rdataset->type == dns_rdatatype_nsec && (NEEDNODATA(val) || NEEDNOWILDCARD(val)) && !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) && - nsecnoexistnodata(val, wild, name, rdataset, - &exists, &data, NULL) + dns_nsec_noexistnodata(val->event->type, wild, name, + rdataset, &exists, &data, NULL, + validator_log, val) == ISC_R_SUCCESS) { dns_name_t **proofs = val->event->proofs; @@ -2855,10 +2425,11 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename) if (rdataset->type == dns_rdatatype_nsec3 && (NEEDNODATA(val) || NEEDNOWILDCARD(val)) && !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) && - nsec3noexistnodata(val, wild, name, rdataset, - zonename, &exists, &data, - NULL, NULL, NULL, NULL, NULL, - NULL) == ISC_R_SUCCESS) + dns_nsec3_noexistnodata(val->event->type, wild, name, + rdataset, zonename, &exists, &data, + NULL, NULL, NULL, NULL, NULL, NULL, + validator_log, val) + == ISC_R_SUCCESS) { dns_name_t **proofs = val->event->proofs; if (exists && !data) @@ -2920,11 +2491,12 @@ findnsec3proofs(dns_validator_t *val) { rdataset->trust != dns_trust_secure) continue; - result = nsec3noexistnodata(val, val->event->name, - name, rdataset, - zonename, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL); + result = dns_nsec3_noexistnodata(val->event->type, + val->event->name, name, + rdataset, zonename, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, validator_log, + val); if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) { if (dns_rdataset_isassociated(&trdataset)) dns_rdataset_disassociate(&trdataset); @@ -2972,16 +2544,19 @@ findnsec3proofs(dns_validator_t *val) { setclosest = setnearest = ISC_FALSE; optout = ISC_FALSE; unknown = ISC_FALSE; - (void)nsec3noexistnodata(val, val->event->name, name, rdataset, - zonename, &exists, &data, &optout, - &unknown, setclosestp, &setnearest, - closestp, nearest); - if (setclosest) - proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name; + result = dns_nsec3_noexistnodata(val->event->type, + val->event->name, + name, rdataset, zonename, + &exists, &data, &optout, + &unknown, setclosestp, + &setnearest, closestp, + nearest, validator_log, val); if (unknown) val->attributes |= VALATTR_FOUNDUNKNOWN; if (result != ISC_R_SUCCESS) continue; + if (setclosest) + proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name; if (exists && !data && NEEDNODATA(val)) { val->attributes |= VALATTR_FOUNDNODATA; proofs[DNS_VALIDATOR_NODATAPROOF] = name; @@ -3272,6 +2847,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { "nonexistence proof(s) found"); if (val->event->message == NULL) marksecure(val->event); + else + val->event->secure = ISC_TRUE; return (ISC_R_SUCCESS); } @@ -3374,6 +2951,7 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { isc_boolean_t want_destroy; isc_result_t eresult; isc_result_t result; + dns_fetch_t *fetch; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); @@ -3389,13 +2967,14 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); - dns_resolver_destroyfetch(&val->fetch); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s", dns_result_totext(eresult)); LOCK(&val->lock); + fetch = val->fetch; + val->fetch = NULL; if (eresult == ISC_R_SUCCESS) { dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf, sizeof(namebuf)); @@ -3448,6 +3027,8 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { } want_destroy = exit_check(val); UNLOCK(&val->lock); + if (fetch != NULL) + dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } @@ -4155,6 +3736,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, event->message = message; memset(event->proofs, 0, sizeof(event->proofs)); event->optout = ISC_FALSE; + event->secure = ISC_FALSE; result = isc_mutex_init(&val->lock); if (result != ISC_R_SUCCESS) goto cleanup_event; @@ -4230,6 +3812,8 @@ dns_validator_send(dns_validator_t *validator) { void dns_validator_cancel(dns_validator_t *validator) { + dns_fetch_t *fetch = NULL; + REQUIRE(VALID_VALIDATOR(validator)); LOCK(&validator->lock); @@ -4239,8 +3823,8 @@ dns_validator_cancel(dns_validator_t *validator) { if ((validator->attributes & VALATTR_CANCELED) == 0) { validator->attributes |= VALATTR_CANCELED; if (validator->event != NULL) { - if (validator->fetch != NULL) - dns_resolver_cancelfetch(validator->fetch); + fetch = validator->fetch; + validator->fetch = NULL; if (validator->subvalidator != NULL) dns_validator_cancel(validator->subvalidator); @@ -4251,6 +3835,12 @@ dns_validator_cancel(dns_validator_t *validator) { } } UNLOCK(&validator->lock); + + /* Need to cancel and destroy the fetch outside validator lock */ + if (fetch != NULL) { + dns_resolver_cancelfetch(fetch); + dns_resolver_destroyfetch(&fetch); + } } static void @@ -4339,7 +3929,7 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category, } static void -validator_log(dns_validator_t *val, int level, const char *fmt, ...) { +validator_log(void *val, int level, const char *fmt, ...) { va_list ap; if (! isc_log_wouldlog(dns_lctx, level)) diff --git a/contrib/bind9/lib/dns/view.c b/contrib/bind9/lib/dns/view.c index 6750058..5b6ad65 100644 --- a/contrib/bind9/lib/dns/view.c +++ b/contrib/bind9/lib/dns/view.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -86,6 +86,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view = isc_mem_get(mctx, sizeof(*view)); if (view == NULL) return (ISC_R_NOMEMORY); + + view->mctx = NULL; + isc_mem_attach(mctx, &view->mctx); view->name = isc_mem_strdup(mctx, name); if (view->name == NULL) { result = ISC_R_NOMEMORY; @@ -95,8 +98,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, if (result != ISC_R_SUCCESS) goto cleanup_name; -#ifdef BIND9 view->zonetable = NULL; +#ifdef BIND9 result = dns_zt_create(mctx, rdclass, &view->zonetable); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, @@ -125,7 +128,6 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->resolver = NULL; view->adb = NULL; view->requestmgr = NULL; - view->mctx = mctx; view->rdclass = rdclass; view->frozen = ISC_FALSE; view->task = NULL; @@ -225,6 +227,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL, DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown, view, NULL, NULL, NULL); + view->viewlist = NULL; view->magic = DNS_VIEW_MAGIC; *viewp = view; @@ -260,7 +263,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_mem_free(mctx, view->name); cleanup_view: - isc_mem_put(mctx, view, sizeof(*view)); + isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); return (result); } @@ -439,7 +442,7 @@ destroy(dns_view_t *view) { DESTROYLOCK(&view->lock); isc_refcount_destroy(&view->references); isc_mem_free(view->mctx, view->name); - isc_mem_put(view->mctx, view, sizeof(*view)); + isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); } /* @@ -482,6 +485,10 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { view->flush = ISC_TRUE; isc_refcount_decrement(&view->references, &refs); if (refs == 0) { +#ifdef BIND9 + dns_zone_t *mkzone = NULL; +#endif + LOCK(&view->lock); if (!RESSHUTDOWN(view)) dns_resolver_shutdown(view->resolver); @@ -497,13 +504,20 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { else dns_zt_detach(&view->zonetable); if (view->managed_keys != NULL) { + mkzone = view->managed_keys; + view->managed_keys = NULL; if (view->flush) - dns_zone_flush(view->managed_keys); - dns_zone_detach(&view->managed_keys); + dns_zone_flush(mkzone); } #endif done = all_done(view); UNLOCK(&view->lock); + +#ifdef BIND9 + /* Need to detach zones outside view lock */ + if (mkzone != NULL) + dns_zone_detach(&mkzone); +#endif } *viewp = NULL; @@ -855,11 +869,14 @@ dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { REQUIRE(DNS_VIEW_VALID(view)); - result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); - if (result == DNS_R_PARTIALMATCH) { - dns_zone_detach(zonep); + if (view->zonetable != NULL) { + result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); + if (result == DNS_R_PARTIALMATCH) { + dns_zone_detach(zonep); + result = ISC_R_NOTFOUND; + } + } else result = ISC_R_NOTFOUND; - } return (result); } @@ -892,6 +909,7 @@ dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, #ifndef BIND9 UNUSED(use_hints); UNUSED(use_static_stub); + UNUSED(zone); #endif /* @@ -916,11 +934,11 @@ dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, /* * Find a database to answer the query. */ - zone = NULL; db = NULL; node = NULL; is_staticstub_zone = ISC_FALSE; #ifdef BIND9 + zone = NULL; result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub && !use_static_stub) { @@ -1168,11 +1186,14 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, dns_rdataset_t zrdataset, zsigrdataset; dns_fixedname_t zfixedname; +#ifndef BIND9 + UNUSED(zone); +#endif + REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->frozen); db = NULL; - zone = NULL; use_zone = ISC_FALSE; try_hints = ISC_FALSE; zfname = NULL; @@ -1188,6 +1209,7 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, * Find the right database. */ #ifdef BIND9 + zone = NULL; result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) result = dns_zone_getdb(zone, &db); diff --git a/contrib/bind9/lib/dns/xfrin.c b/contrib/bind9/lib/dns/xfrin.c index eae39d9..3026af9 100644 --- a/contrib/bind9/lib/dns/xfrin.c +++ b/contrib/bind9/lib/dns/xfrin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -591,6 +591,7 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl, case XFRST_AXFR_END: case XFRST_IXFR_END: FAIL(DNS_R_EXTRADATA); + /* NOTREACHED */ default: INSIST(0); break; @@ -781,7 +782,8 @@ xfrin_create(isc_mem_t *mctx, xfr = isc_mem_get(mctx, sizeof(*xfr)); if (xfr == NULL) return (ISC_R_NOMEMORY); - xfr->mctx = mctx; + xfr->mctx = NULL; + isc_mem_attach(mctx, &xfr->mctx); xfr->refcount = 0; xfr->zone = NULL; dns_zone_iattach(zone, &xfr->zone); @@ -876,7 +878,7 @@ xfrin_create(isc_mem_t *mctx, dns_db_detach(&xfr->db); isc_task_detach(&xfr->task); dns_zone_idetach(&xfr->zone); - isc_mem_put(mctx, xfr, sizeof(*xfr)); + isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); return (result); } @@ -1491,7 +1493,7 @@ maybe_free(dns_xfrin_ctx_t *xfr) { if (xfr->zone != NULL) dns_zone_idetach(&xfr->zone); - isc_mem_put(xfr->mctx, xfr, sizeof(*xfr)); + isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); } /* diff --git a/contrib/bind9/lib/dns/zone.c b/contrib/bind9/lib/dns/zone.c index 22db239..c212bf6 100644 --- a/contrib/bind9/lib/dns/zone.c +++ b/contrib/bind9/lib/dns/zone.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -335,9 +335,9 @@ struct dns_zone { isc_boolean_t added; /*% - * whether a rpz radix was needed when last loaded + * whether this is a response policy zone */ - isc_boolean_t rpz_zone; + isc_boolean_t is_rpz; /*% * Outstanding forwarded UPDATE requests. @@ -345,6 +345,18 @@ struct dns_zone { dns_forwardlist_t forwards; }; +typedef struct { + dns_diff_t *diff; + isc_boolean_t offline; +} zonediff_t; + +#define zonediff_init(z, d) \ + do { \ + zonediff_t *_z = (z); \ + (_z)->diff = (d); \ + (_z)->offline = ISC_FALSE; \ + } while (0) + #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) #define DNS_ZONE_SETFLAG(z,f) do { \ INSIST(LOCKED_ZONE(z)); \ @@ -855,7 +867,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->nodes = 100; zone->privatetype = (dns_rdatatype_t)0xffffU; zone->added = ISC_FALSE; - zone->rpz_zone = ISC_FALSE; + zone->is_rpz = ISC_FALSE; ISC_LIST_INIT(zone->forwards); zone->magic = ZONE_MAGIC; @@ -1042,6 +1054,7 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { isc_result_t dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { isc_result_t result; + unsigned int soacount; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(serialp != NULL); @@ -1049,8 +1062,11 @@ dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { - result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp, - NULL, NULL, NULL, NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, &soacount, + serialp, NULL, NULL, NULL, NULL, + NULL); + if (result == ISC_R_SUCCESS && soacount == 0) + result = ISC_R_FAILURE; } else result = DNS_R_NOTLOADED; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); @@ -1390,6 +1406,30 @@ zone_isdynamic(dns_zone_t *zone) { !dns_acl_isnone(zone->update_acl)))); } +/* + * Set the response policy index and information for a zone. + */ +isc_result_t +dns_zone_rpz_enable(dns_zone_t *zone) { + /* + * Only RBTDB zones can be used for response policy zones, + * because only they have the code to load the create the summary data. + * Only zones that are loaded instead of mmap()ed create the + * summary data and so can be policy zones. + */ + if (strcmp(zone->db_argv[0], "rbt") != 0 && + strcmp(zone->db_argv[0], "rbt64") != 0) + return (ISC_R_NOTIMPLEMENTED); + + zone->is_rpz = ISC_TRUE; + + return (ISC_R_SUCCESS); +} + +isc_boolean_t +dns_zone_get_rpz(dns_zone_t *zone) { + return (zone->is_rpz); +} static isc_result_t zone_load(dns_zone_t *zone, unsigned int flags) { @@ -1459,8 +1499,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { * "rndc reconfig", we are done. */ if (!isc_time_isepoch(&zone->loadtime) && - (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 && - zone->rpz_zone == dns_rpz_needed()) { + (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { result = ISC_R_SUCCESS; goto cleanup; } @@ -1469,8 +1508,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { if (result == ISC_R_SUCCESS) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && - isc_time_compare(&filetime, &zone->loadtime) <= 0 && - zone->rpz_zone == dns_rpz_needed()) { + isc_time_compare(&filetime, &zone->loadtime) <= 0) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "skipping load: master file " "older than last load"); @@ -1478,7 +1516,6 @@ zone_load(dns_zone_t *zone, unsigned int flags) { goto cleanup; } loadtime = filetime; - zone->rpz_zone = dns_rpz_needed(); } } @@ -1704,8 +1741,15 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { isc_result_t tresult; unsigned int options; - options = get_master_options(zone); +#ifdef BIND9 + if (zone->is_rpz) { + result = dns_db_rpz_enabled(db, NULL); + if (result != ISC_R_SUCCESS) + return (result); + } +#endif + options = get_master_options(zone); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) options |= DNS_MASTER_MANYERRORS; @@ -2174,6 +2218,34 @@ zone_check_dup(dns_zone_t *zone, dns_db_t *db) { } static isc_boolean_t +isspf(const dns_rdata_t *rdata) { + char buf[1024]; + const unsigned char *data = rdata->data; + unsigned int rdl = rdata->length, i = 0, tl, len; + + while (rdl > 0U) { + len = tl = *data; + ++data; + --rdl; + INSIST(tl <= rdl); + if (len > sizeof(buf) - i - 1) + len = sizeof(buf) - i - 1; + memcpy(buf + i, data, len); + i += len; + data += tl; + rdl -= tl; + } + + if (i < 6U) + return(ISC_FALSE); + + buf[i] = 0; + if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) + return (ISC_TRUE); + return (ISC_FALSE); +} + +static isc_boolean_t integrity_checks(dns_zone_t *zone, dns_db_t *db) { dns_dbiterator_t *dbiterator = NULL; dns_dbnode_t *node = NULL; @@ -2187,7 +2259,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { dns_name_t *name; dns_name_t *bottom; isc_result_t result; - isc_boolean_t ok = ISC_TRUE; + isc_boolean_t ok = ISC_TRUE, have_spf, have_txt; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); @@ -2265,7 +2337,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) - goto next; + goto checkspf; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); @@ -2278,6 +2350,50 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { } dns_rdataset_disassociate(&rdataset); + checkspf: + /* + * Check if there is a type TXT spf record without a type SPF + * RRset being present. + */ + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) + goto next; + if (zone->rdclass != dns_rdataclass_in) + goto next; + have_spf = have_txt = ISC_FALSE; + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, + 0, 0, &rdataset, NULL); + if (result == ISC_R_SUCCESS) { + dns_rdataset_disassociate(&rdataset); + have_spf = ISC_TRUE; + } + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, + 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + goto notxt; + result = dns_rdataset_first(&rdataset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rdataset, &rdata); + have_txt = isspf(&rdata); + dns_rdata_reset(&rdata); + if (have_txt) + break; + result = dns_rdataset_next(&rdataset); + } + dns_rdataset_disassociate(&rdataset); + + notxt: + if (have_spf != have_txt) { + char namebuf[DNS_NAME_FORMATSIZE]; + const char *found = have_txt ? "TXT" : "SPF"; + const char *need = have_txt ? "SPF" : "TXT"; + + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s " + "record but no SPF/%s record found, add " + "matching type %s record", namebuf, found, + need, need); + } + next: dns_db_detachnode(db, &node); result = dns_dbiterator_next(dbiterator); @@ -2788,6 +2904,8 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, dst_key_name(key), 0, &rdata)); *changed = ISC_TRUE; + /* Refresh new keys from the zone apex as soon as possible. */ + set_refreshkeytimer(zone, &keydata, now); skip: result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); @@ -2797,10 +2915,6 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, } } - /* Refresh new keys from the zone apex as soon as possible. */ - if (*changed) - set_refreshkeytimer(zone, &keydata, now); - if (keynode != NULL) dns_keytable_detachkeynode(keytable, &keynode); *keynodep = NULL; @@ -2942,7 +3056,8 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { dns_rdataset_current(rdataset, &rdata); /* Convert rdata to keydata. */ - dns_rdata_tostruct(&rdata, &keydata, NULL); + result = dns_rdata_tostruct(&rdata, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Set the key refresh timer. */ set_refreshkeytimer(zone, &keydata, now); @@ -3285,6 +3400,13 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) { } failure: + if (result != ISC_R_SUCCESS && + !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { + dns_zone_log(zone, ISC_LOG_ERROR, + "unable to synchronize managed keys: %s", + dns_result_totext(result)); + isc_time_settoepoch(&zone->refreshkeytime); + } if (keynode != NULL) dns_keytable_detachkeynode(sr, &keynode); if (sr != NULL) @@ -3462,14 +3584,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, } if (zone->db != NULL) { + unsigned int oldsoacount; + /* * This is checked in zone_replacedb() for slave zones * as they don't reload from disk. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, - &oldserial, NULL, NULL, NULL, - NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, + &oldsoacount, &oldserial, + NULL, NULL, NULL, NULL, + NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; @@ -3877,6 +4003,19 @@ zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, *expire = soa.expire; if (minimum != NULL) *minimum = soa.minimum; + } else { + if (soacount != NULL) + *soacount = 0; + if (serial != NULL) + *serial = 0; + if (refresh != NULL) + *refresh = 0; + if (retry != NULL) + *retry = 0; + if (expire != NULL) + *expire = 0; + if (minimum != NULL) + *minimum = 0; } result = ISC_R_SUCCESS; @@ -4543,20 +4682,21 @@ find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, } static isc_result_t -offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name, - dns_ttl_t ttl, dns_rdata_t *rdata) +offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff, + dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { isc_result_t result; if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) return (ISC_R_SUCCESS); - result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, ttl, rdata); if (result != ISC_R_SUCCESS) return (result); rdata->flags |= DNS_RDATA_OFFLINE; - result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, name, ttl, rdata); + zonediff->offline = ISC_TRUE; return (result); } @@ -4631,7 +4771,7 @@ delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) { */ static isc_result_t del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, + dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys, unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental) { isc_result_t result; @@ -4677,7 +4817,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, if (type != dns_rdatatype_dnskey) { if (delsig_ok(&rrsig, keys, nkeys)) { - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); if (incremental) @@ -4695,8 +4835,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * for the private part. */ if (incremental) { - result = offline(db, ver, diff, name, - rdataset.ttl, &rdata); + result = offline(db, ver, zonediff, + name, rdataset.ttl, + &rdata); changed = ISC_TRUE; if (result != ISC_R_SUCCESS) break; @@ -4756,11 +4897,12 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, warn = maybe; if (warn == 0 || warn > timeexpire) warn = timeexpire; - result = offline(db, ver, diff, name, - rdataset.ttl, &rdata); + result = offline(db, ver, zonediff, + name, rdataset.ttl, + &rdata); break; } - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); @@ -4773,7 +4915,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * delete the RRSIG. */ if (!found) - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); if (result != ISC_R_SUCCESS) @@ -4903,9 +5045,11 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, static void zone_resigninc(dns_zone_t *zone) { + const char *me = "zone_resigninc"; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; - dns_diff_t sig_diff; + dns_diff_t _sig_diff; + zonediff_t zonediff; dns_fixedname_t fixed; dns_name_t *name; dns_rdataset_t rdataset; @@ -4919,10 +5063,13 @@ zone_resigninc(dns_zone_t *zone) { unsigned int nkeys = 0; unsigned int resign; + ENTER; + dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); - dns_diff_init(zone->mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + dns_diff_init(zone->mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; + zonediff_init(&zonediff, &_sig_diff); /* * Updates are disabled. Pause for 5 minutes. @@ -4992,7 +5139,7 @@ zone_resigninc(dns_zone_t *zone) { resign > stop) break; - result = del_sigs(zone, db, version, name, covers, &sig_diff, + result = del_sigs(zone, db, version, name, covers, &zonediff, zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -5001,7 +5148,7 @@ zone_resigninc(dns_zone_t *zone) { break; } - result = add_sigs(db, version, name, covers, &sig_diff, + result = add_sigs(db, version, name, covers, zonediff.diff, zone_keys, nkeys, zone->mctx, inception, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { @@ -5026,7 +5173,7 @@ zone_resigninc(dns_zone_t *zone) { goto failure; result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, now, ISC_TRUE); + &zonediff, zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:del_sigs -> %s", @@ -5037,11 +5184,17 @@ zone_resigninc(dns_zone_t *zone) { /* * Did we change anything in the zone? */ - if (ISC_LIST_EMPTY(sig_diff.tuples)) + if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { + /* + * Commit the changes if any key has been marked as offline. + */ + if (zonediff.offline) + dns_db_closeversion(db, &version, ISC_TRUE); goto failure; + } /* Increment SOA serial if we have made changes */ - result = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:increment_soa_serial -> %s", @@ -5054,8 +5207,8 @@ zone_resigninc(dns_zone_t *zone) { * termination is sensible. */ result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + zonediff.diff, zone_keys, nkeys, zone->mctx, + inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:add_sigs -> %s", @@ -5064,13 +5217,13 @@ zone_resigninc(dns_zone_t *zone) { } /* Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_resigninc")); + CHECK(zone_journal(zone, zonediff.diff, "zone_resigninc")); /* Everything has succeeded. Commit the changes. */ dns_db_closeversion(db, &version, ISC_TRUE); failure: - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); if (version != NULL) { @@ -5740,7 +5893,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone, isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now, isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, - dns_diff_t *sig_diff) + zonediff_t *zonediff) { dns_difftuple_t *tuple; isc_result_t result; @@ -5749,7 +5902,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, tuple != NULL; tuple = ISC_LIST_HEAD(diff->tuples)) { result = del_sigs(zone, db, version, &tuple->name, - tuple->rdata.type, sig_diff, + tuple->rdata.type, zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -5758,7 +5911,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, return (result); } result = add_sigs(db, version, &tuple->name, - tuple->rdata.type, sig_diff, + tuple->rdata.type, zonediff->diff, zone_keys, nkeys, zone->mctx, inception, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { @@ -5775,7 +5928,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, !dns_name_equal(&tuple->name, &next->name))) next = ISC_LIST_NEXT(next, link); ISC_LIST_UNLINK(diff->tuples, tuple, link); - dns_diff_appendminimal(sig_diff, &tuple); + dns_diff_appendminimal(zonediff->diff, &tuple); INSIST(tuple == NULL); tuple = next; } while (tuple != NULL); @@ -5789,13 +5942,15 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, */ static void zone_nsec3chain(dns_zone_t *zone) { + const char *me = "zone_nsec3chain"; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; - dns_diff_t sig_diff; + dns_diff_t _sig_diff; dns_diff_t nsec_diff; dns_diff_t nsec3_diff; dns_diff_t param_diff; + zonediff_t zonediff; dns_fixedname_t fixed; dns_fixedname_t nextfixed; dns_name_t *name, *nextname; @@ -5821,6 +5976,8 @@ zone_nsec3chain(dns_zone_t *zone) { isc_boolean_t updatensec = ISC_FALSE; dns_rdatatype_t privatetype = zone->privatetype; + ENTER; + dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); @@ -5829,8 +5986,9 @@ zone_nsec3chain(dns_zone_t *zone) { dns_diff_init(zone->mctx, ¶m_diff); dns_diff_init(zone->mctx, &nsec3_diff); dns_diff_init(zone->mctx, &nsec_diff); - dns_diff_init(zone->mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + dns_diff_init(zone->mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; + zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); /* @@ -6028,6 +6186,7 @@ zone_nsec3chain(dns_zone_t *zone) { result = dns_dbiterator_next(nsec3chain->dbiterator); if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { + dns_dbiterator_pause(nsec3chain->dbiterator); CHECK(fixup_nsec3param(db, version, nsec3chain, ISC_FALSE, privatetype, ¶m_diff)); @@ -6325,6 +6484,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (rebuild_nsec) { if (nsec3chain != NULL) dns_dbiterator_pause(nsec3chain->dbiterator); + result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_TRUE, &nsec_diff); @@ -6336,7 +6496,11 @@ zone_nsec3chain(dns_zone_t *zone) { goto failure; } } + if (rebuild_nsec3) { + if (nsec3chain != NULL) + dns_dbiterator_pause(nsec3chain->dbiterator); + result = dns_nsec3_addnsec3s(db, version, dns_db_origin(db), zone->minimum, ISC_FALSE, @@ -6351,12 +6515,17 @@ zone_nsec3chain(dns_zone_t *zone) { } } + if (nsec3chain != NULL) + dns_dbiterator_pause(nsec3chain->dbiterator); + /* * Add / update signatures for the NSEC3 records. */ + if (nsec3chain != NULL) + dns_dbiterator_pause(nsec3chain->dbiterator); result = update_sigs(&nsec3_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); @@ -6369,7 +6538,7 @@ zone_nsec3chain(dns_zone_t *zone) { */ result = update_sigs(¶m_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); @@ -6377,8 +6546,6 @@ zone_nsec3chain(dns_zone_t *zone) { } if (updatensec) { - if (nsec3chain != NULL) - dns_dbiterator_pause(nsec3chain->dbiterator); result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_FALSE, &nsec_diff); if (result != ISC_R_SUCCESS) { @@ -6391,7 +6558,7 @@ zone_nsec3chain(dns_zone_t *zone) { result = update_sigs(&nsec_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); @@ -6402,18 +6569,23 @@ zone_nsec3chain(dns_zone_t *zone) { * If we made no effective changes to the zone then we can just * cleanup otherwise we need to increment the serial. */ - if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) + if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { + /* + * No need to call dns_db_closeversion() here as it is + * called with commit = ISC_TRUE below. + */ goto done; + } result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, now, ISC_FALSE); + &zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "del_sigs -> %s", dns_result_totext(result)); goto failure; } - result = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "increment_soa_serial -> %s", @@ -6422,8 +6594,8 @@ zone_nsec3chain(dns_zone_t *zone) { } result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + zonediff.diff, zone_keys, nkeys, zone->mctx, + inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "add_sigs -> %s", dns_result_totext(result)); @@ -6431,7 +6603,7 @@ zone_nsec3chain(dns_zone_t *zone) { } /* Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_nsec3chain")); + CHECK(zone_journal(zone, zonediff.diff, "zone_nsec3chain")); LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); @@ -6451,6 +6623,7 @@ zone_nsec3chain(dns_zone_t *zone) { /* * Everything has succeeded. Commit the changes. + * Unconditionally commit as zonediff.offline not checked above. */ dns_db_closeversion(db, &version, ISC_TRUE); @@ -6520,7 +6693,7 @@ zone_nsec3chain(dns_zone_t *zone) { dns_diff_clear(¶m_diff); dns_diff_clear(&nsec3_diff); dns_diff_clear(&nsec_diff); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); if (iterator != NULL) dns_rdatasetiter_destroy(&iterator); @@ -6622,11 +6795,13 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, */ static void zone_sign(dns_zone_t *zone) { + const char *me = "zone_sign"; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; - dns_diff_t sig_diff; + dns_diff_t _sig_diff; dns_diff_t post_diff; + zonediff_t zonediff; dns_fixedname_t fixed; dns_fixedname_t nextfixed; dns_name_t *name, *nextname; @@ -6648,14 +6823,17 @@ zone_sign(dns_zone_t *zone) { unsigned int nkeys = 0; isc_uint32_t nodes; + ENTER; + dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); dns_fixedname_init(&nextfixed); nextname = dns_fixedname_name(&nextfixed); - dns_diff_init(zone->mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + dns_diff_init(zone->mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; dns_diff_init(zone->mctx, &post_diff); + zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); /* @@ -6769,7 +6947,7 @@ zone_sign(dns_zone_t *zone) { dns_dbiterator_pause(signing->dbiterator); CHECK(del_sig(db, version, name, node, nkeys, signing->algorithm, signing->keyid, - &sig_diff)); + zonediff.diff)); } /* @@ -6864,7 +7042,7 @@ zone_sign(dns_zone_t *zone) { build_nsec, zone_keys[i], inception, expire, zone->minimum, is_ksk, ISC_TF(both && keyset_kskonly), - &delegation, &sig_diff, + &delegation, zonediff.diff, &signatures, zone->mctx)); /* * If we are adding we are done. Look for other keys @@ -6946,7 +7124,7 @@ zone_sign(dns_zone_t *zone) { if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { result = update_sigs(&post_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" "update_sigs -> %s", @@ -6958,7 +7136,9 @@ zone_sign(dns_zone_t *zone) { /* * Have we changed anything? */ - if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) { + if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { + if (zonediff.offline) + commit = ISC_TRUE; result = ISC_R_SUCCESS; goto pauseall; } @@ -6966,7 +7146,7 @@ zone_sign(dns_zone_t *zone) { commit = ISC_TRUE; result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, now, ISC_FALSE); + &zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s", @@ -6974,7 +7154,7 @@ zone_sign(dns_zone_t *zone) { goto failure; } - result = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:increment_soa_serial -> %s", @@ -6987,8 +7167,8 @@ zone_sign(dns_zone_t *zone) { * termination is sensible. */ result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + zonediff.diff, zone_keys, nkeys, zone->mctx, + inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s", @@ -6999,7 +7179,7 @@ zone_sign(dns_zone_t *zone) { /* * Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_sign")); + CHECK(zone_journal(zone, zonediff.diff, "zone_sign")); pauseall: /* @@ -7059,7 +7239,7 @@ zone_sign(dns_zone_t *zone) { signing = ISC_LIST_NEXT(signing, link)) dns_dbiterator_pause(signing->dbiterator); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); @@ -7090,19 +7270,22 @@ normalize_key(dns_rdata_t *rr, dns_rdata_t *target, dns_rdata_dnskey_t dnskey; dns_rdata_keydata_t keydata; isc_buffer_t buf; + isc_result_t result; dns_rdata_reset(target); isc_buffer_init(&buf, data, size); switch (rr->type) { case dns_rdatatype_dnskey: - dns_rdata_tostruct(rr, &dnskey, NULL); + result = dns_rdata_tostruct(rr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); dnskey.flags &= ~DNS_KEYFLAG_REVOKE; dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, &dnskey, &buf); break; case dns_rdatatype_keydata: - dns_rdata_tostruct(rr, &keydata, NULL); + result = dns_rdata_tostruct(rr, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_keydata_todnskey(&keydata, &dnskey, NULL); dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, &dnskey, &buf); @@ -7509,7 +7692,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { result = dns_rdataset_next(&kfetch->keydataset)) { dns_rdata_reset(&keydatarr); dns_rdataset_current(&kfetch->keydataset, &keydatarr); - dns_rdata_tostruct(&keydatarr, &keydata, NULL); + result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* * If any keydata record has a nonzero add holddown, then @@ -7599,7 +7783,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { dns_rdata_reset(&dnskeyrr); dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr); - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Skip ZSK's */ if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK)) @@ -7610,7 +7795,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { if (matchkey(&kfetch->keydataset, &dnskeyrr)) { dns_rdata_reset(&keydatarr); dns_rdataset_current(&kfetch->keydataset, &keydatarr); - dns_rdata_tostruct(&keydatarr, &keydata, NULL); + result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (revoked && revocable(kfetch, &keydata)) { if (keydata.addhd > now) { @@ -7710,7 +7896,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { &keydatarr)); } else if (newkey) { /* Convert DNSKEY to KEYDATA */ - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, NULL); keydata.addhd = initializing ? now : now + MONTH; @@ -7729,7 +7916,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { if (trustkey) { /* Trust this key. */ - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); trust_key(zone, keyname, &dnskey, mctx); } @@ -8020,6 +8208,14 @@ zone_maintenance(dns_zone_t *zone) { } /* + * Slaves send notifies before backing up to disk, masters after. + */ + if (zone->type == dns_zone_slave && + DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && + isc_time_compare(&now, &zone->notifytime) >= 0) + zone_notify(zone, &now); + + /* * Do we need to consolidate the backing store? */ switch (zone->type) { @@ -8049,14 +8245,28 @@ zone_maintenance(dns_zone_t *zone) { } /* + * Master/redirect zones send notifies now, if needed + */ + switch (zone->type) { + case dns_zone_master: + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && + isc_time_compare(&now, &zone->notifytime) >= 0) + zone_notify(zone, &now); + default: + break; + } + + /* * Do we need to refresh keys? */ switch (zone->type) { case dns_zone_key: - if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 && - DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && - !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) - zone_refreshkeys(zone); + if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) { + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && + !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { + zone_refreshkeys(zone); + } + } break; case dns_zone_master: if (!isc_time_isepoch(&zone->refreshkeytime) && @@ -8070,12 +8280,6 @@ zone_maintenance(dns_zone_t *zone) { case dns_zone_master: case dns_zone_slave: /* - * Do we need to send out notify messages? - */ - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && - isc_time_compare(&now, &zone->notifytime) >= 0) - zone_notify(zone, &now); - /* * Do we need to sign/resign some RRsets? */ if (!isc_time_isepoch(&zone->signingtime) && @@ -8088,7 +8292,7 @@ zone_maintenance(dns_zone_t *zone) { isc_time_compare(&now, &zone->nsec3chaintime) >= 0) zone_nsec3chain(zone); /* - * Do we need to issue a key expiry warning. + * Do we need to issue a key expiry warning? */ if (!isc_time_isepoch(&zone->keywarntime) && isc_time_compare(&now, &zone->keywarntime) >= 0) @@ -8237,6 +8441,7 @@ dns_zone_dump(dns_zone_t *zone) { static void zone_needdump(dns_zone_t *zone, unsigned int delay) { + const char me[] = "zone_needdump"; isc_time_t dumptime; isc_time_t now; @@ -8246,6 +8451,7 @@ zone_needdump(dns_zone_t *zone, unsigned int delay) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); + ENTER; /* * Do we have a place to dump to and are we loaded? @@ -8898,9 +9104,9 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { dns_message_destroy(&message); cleanup: UNLOCK_ZONE(notify->zone); + isc_event_free(&event); if (result != ISC_R_SUCCESS) notify_destroy(notify, ISC_FALSE); - isc_event_free(&event); } static void @@ -9247,7 +9453,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { isc_time_t now; isc_boolean_t exiting = ISC_FALSE; isc_interval_t i; - unsigned int j; + unsigned int j, soacount; stub = revent->ev_arg; INSIST(DNS_STUB_VALID(stub)); @@ -9390,9 +9596,9 @@ stub_callback(isc_task_t *task, isc_event_t *event) { ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db == NULL) zone_attachdb(zone, stub->db); - result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh, - &retry, &expire, NULL, NULL); - if (result == ISC_R_SUCCESS) { + result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, + &refresh, &retry, &expire, NULL, NULL); + if (result == ISC_R_SUCCESS && soacount > 0U) { zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, zone->minretry, zone->maxretry); @@ -9728,10 +9934,12 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { serial = soa.serial; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { - result = zone_get_from_db(zone, zone->db, NULL, NULL, + unsigned int soacount; + result = zone_get_from_db(zone, zone->db, NULL, &soacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial, oldserial); } else @@ -10953,6 +11161,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, result = dns_rdataset_first(rdataset); if (result == ISC_R_SUCCESS) { isc_uint32_t serial = 0, oldserial; + unsigned int soacount; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); @@ -10962,10 +11171,11 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, * The following should safely be performed without DB * lock and succeed in this context. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, - &oldserial, NULL, NULL, NULL, - NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, + &soacount, &oldserial, NULL, + NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if (isc_serial_le(serial, oldserial)) { dns_zone_log(zone, ISC_LOG_INFO, @@ -11652,6 +11862,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { isc_uint32_t serial, oldserial; + unsigned int soacount; dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); @@ -11666,10 +11877,11 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { /* * This is checked in zone_postload() for master zones. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, + result = zone_get_from_db(zone, zone->db, NULL, &soacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if (zone->type == dns_zone_slave && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; @@ -11916,6 +12128,8 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { * won't hurt with an AXFR. */ if (zone->masterfile != NULL || zone->journal != NULL) { + unsigned int delay = DNS_DUMP_DELAY; + result = ISC_R_FAILURE; if (zone->journal != NULL) result = isc_file_settime(zone->journal, &now); @@ -11923,14 +12137,16 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { zone->masterfile != NULL) result = isc_file_settime(zone->masterfile, &now); - /* Someone removed the file from underneath us! */ - if (result == ISC_R_FILENOTFOUND && - zone->masterfile != NULL) { - unsigned int delay = DNS_DUMP_DELAY; - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY)) - delay = 0; + + if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || + result == ISC_R_FILENOTFOUND) + delay = 0; + + if ((result == ISC_R_SUCCESS || + result == ISC_R_FILENOTFOUND) && + zone->masterfile != NULL) zone_needdump(zone, delay); - } else if (result != ISC_R_SUCCESS) + else if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "transfer: could not set file " "modification time of '%s': %s", @@ -13323,6 +13539,8 @@ dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { + if (zmgr->unreachable[i].expire == 0) + break; result = isc_rwlock_tryupgrade(&zmgr->urlock); if (result == ISC_R_SUCCESS) { locktype = isc_rwlocktype_write; @@ -13994,7 +14212,7 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, static isc_result_t sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff, dns_diff_t *sig_diff) + dns_diff_t *diff, zonediff_t *zonediff) { isc_result_t result; isc_stdtime_t now, inception, soaexpire; @@ -14034,7 +14252,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, if (tuple == NULL) { result = del_sigs(zone, db, ver, &zone->origin, - dns_rdatatype_dnskey, sig_diff, + dns_rdatatype_dnskey, zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -14043,7 +14261,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, goto failure; } result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey, - sig_diff, zone_keys, nkeys, zone->mctx, + zonediff->diff, zone_keys, nkeys, zone->mctx, inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { @@ -14056,7 +14274,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, result = update_sigs(diff, db, ver, zone_keys, nkeys, zone, inception, soaexpire, now, check_ksk, - keyset_kskonly, sig_diff); + keyset_kskonly, zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -14209,7 +14427,8 @@ zone_rekey(dns_zone_t *zone) { dns_rdataset_t soaset, soasigs, keyset, keysigs; dns_dnsseckeylist_t dnskeys, keys, rmkeys; dns_dnsseckey_t *key; - dns_diff_t diff, sig_diff; + dns_diff_t diff, _sig_diff; + zonediff_t zonediff; isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE; isc_boolean_t newalg = ISC_FALSE; isc_boolean_t fullsign; @@ -14233,8 +14452,9 @@ zone_rekey(dns_zone_t *zone) { dir = dns_zone_getkeydirectory(zone); mctx = zone->mctx; dns_diff_init(mctx, &diff); - dns_diff_init(mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + dns_diff_init(mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; + zonediff_init(&zonediff, &_sig_diff); CHECK(dns_zone_getdb(zone, &db)); CHECK(dns_db_newversion(db, &ver)); @@ -14334,8 +14554,8 @@ zone_rekey(dns_zone_t *zone) { ISC_TF(newalg || fullsign))); CHECK(increment_soa_serial(db, ver, &diff, mctx)); CHECK(add_chains(zone, db, ver, &diff)); - CHECK(sign_apex(zone, db, ver, &diff, &sig_diff)); - CHECK(zone_journal(zone, &sig_diff, "zone_rekey")); + CHECK(sign_apex(zone, db, ver, &diff, &zonediff)); + CHECK(zone_journal(zone, zonediff.diff, "zone_rekey")); commit = ISC_TRUE; } } @@ -14425,7 +14645,7 @@ zone_rekey(dns_zone_t *zone) { * Cause the zone to add/delete NSEC3 chains for the * deferred NSEC3PARAM changes. */ - for (tuple = ISC_LIST_HEAD(sig_diff.tuples); + for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; @@ -14500,7 +14720,7 @@ zone_rekey(dns_zone_t *zone) { failure: dns_diff_clear(&diff); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); clear_keylist(&dnskeys, mctx); clear_keylist(&keys, mctx); |