diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2020-02-04 19:27:46 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2020-02-04 19:27:46 +0000 |
commit | 640b974af1fb1db5b5d6858fc48c88713056d2b8 (patch) | |
tree | b89da3d10deaec4b8604eae083117bbbc051e738 /usr.sbin | |
parent | bcb96830a4cca42e038e6d45a8183b4bf6fc829d (diff) |
We are not going to generate nsec or nsec3 RRsets.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bind/lib/dns/Makefile.inc | 4 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/include/dns/nsec.h | 115 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/include/dns/nsec3.h | 165 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/nsec.c | 292 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/nsec3.c | 526 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/rdatalist.c | 5 |
6 files changed, 3 insertions, 1104 deletions
diff --git a/usr.sbin/bind/lib/dns/Makefile.inc b/usr.sbin/bind/lib/dns/Makefile.inc index 7f99a97ab25..2b7938d4379 100644 --- a/usr.sbin/bind/lib/dns/Makefile.inc +++ b/usr.sbin/bind/lib/dns/Makefile.inc @@ -1,11 +1,11 @@ -# $OpenBSD: Makefile.inc,v 1.3 2020/02/04 19:24:07 florian Exp $ +# $OpenBSD: Makefile.inc,v 1.4 2020/02/04 19:27:45 florian Exp $ .PATH: ${.CURDIR}/lib/dns SRCS+= byaddr.c callbacks.c compress.c dns_log.c dns_result.c dns_time.c SRCS+= ds.c dst_api.c dst_parse.c dst_result.c masterdump.c SRCS+= hmac_link.c key.c keydata.c lib.c name.c openssl_link.c message.c -SRCS+= ncache.c nsec.c nsec3.c +SRCS+= ncache.c SRCS+= rcode.c rdata.c rdatalist.c SRCS+= rdataset.c soa.c tsig.c ttl.c diff --git a/usr.sbin/bind/lib/dns/include/dns/nsec.h b/usr.sbin/bind/lib/dns/include/dns/nsec.h deleted file mode 100644 index 72d41f75a0b..00000000000 --- a/usr.sbin/bind/lib/dns/include/dns/nsec.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 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: nsec.h,v 1.3 2019/12/17 01:46:32 sthen Exp $ */ - -#ifndef DNS_NSEC_H -#define DNS_NSEC_H 1 - -/*! \file dns/nsec.h */ - -#include <isc/lang.h> - -#include <dns/types.h> -#include <dns/name.h> - -#define DNS_NSEC_BUFFERSIZE (DNS_NAME_MAXWIRE + 8192 + 512) - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *target, - unsigned char *buffer, dns_rdata_t *rdata); -/*%< - * Build the rdata of a NSEC record. - * - * Requires: - *\li buffer Points to a temporary buffer of at least - * DNS_NSEC_BUFFERSIZE bytes. - *\li rdata Points to an initialized dns_rdata_t. - * - * Ensures: - * \li *rdata Contains a valid NSEC rdata. The 'data' member refers - * to 'buffer'. - */ - -isc_result_t -dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, - dns_name_t *target, dns_ttl_t ttl); -/*%< - * Build a NSEC record and add it to a database. - */ - -isc_boolean_t -dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type); -/*%< - * Determine if a type is marked as present in an NSEC record. - * - * Requires: - *\li 'nsec' points to a valid rdataset of type NSEC - */ - -isc_result_t -dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, - isc_boolean_t *answer); -/* - * Report whether the DNSKEY RRset has a NSEC only algorithm. Unknown - * algorithms are assumed to support NSEC3. If DNSKEY is not found, - * *answer is set to ISC_FALSE, and ISC_R_NOTFOUND is returned. - * - * Requires: - * 'answer' to be non NULL. - */ - -unsigned int -dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, - unsigned int max_type); -/*%< - * Convert a raw bitmap into a compressed windowed bit map. 'map' and 'raw' - * may overlap. - * - * Returns the length of the compressed windowed bit map. - */ - -void -dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit); -/*%< - * Set type bit in raw 'array' to 'bit'. - */ - -isc_boolean_t -dns_nsec_isset(const unsigned char *array, unsigned int type); -/*%< - * Test if the corresponding 'type' bit is set in 'array'. - */ - -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/usr.sbin/bind/lib/dns/include/dns/nsec3.h b/usr.sbin/bind/lib/dns/include/dns/nsec3.h deleted file mode 100644 index 4424cf6b0fe..00000000000 --- a/usr.sbin/bind/lib/dns/include/dns/nsec3.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 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: nsec3.h,v 1.5 2020/01/28 17:17:05 florian Exp $ */ - -#ifndef DNS_NSEC3_H -#define DNS_NSEC3_H 1 - -#include <isc/lang.h> -#include <isc/iterated_hash.h> - - - -#include <dns/name.h> -#include "rdatastruct.h" -#include <dns/types.h> - -#define DNS_NSEC3_SALTSIZE 255 - -/* - * hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max) - * hash length = 1, hash = 255 (max), bitmap = 8192 + 512 (max) - */ -#define DNS_NSEC3_BUFFERSIZE (6 + 255 + 255 + 8192 + 512) -/* - * hash = 1, flags = 1, iterations = 2, salt length = 1, salt = 255 (max) - */ -#define DNS_NSEC3PARAM_BUFFERSIZE (5 + 255) - -/* - * Test "unknown" algorithm. Is mapped to dns_hash_sha1. - */ -#define DNS_NSEC3_UNKNOWNALG ((dns_hash_t)245U) - -ISC_LANG_BEGINDECLS - -isc_boolean_t -dns_nsec3_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type); -/*%< - * Determine if a type is marked as present in an NSEC3 record. - * - * Requires: - * 'nsec' points to a valid rdataset of type NSEC3 - */ - -isc_result_t -dns_nsec3_hashname(dns_fixedname_t *result, - unsigned char rethash[NSEC3_MAX_HASH_LENGTH], - size_t *hash_length, dns_name_t *name, dns_name_t *origin, - dns_hash_t hashalg, unsigned int iterations, - const unsigned char *salt, size_t saltlength); -/*%< - * Make a hashed domain name from an unhashed one. If rethash is not NULL - * the raw hash is stored there. - */ - -unsigned int -dns_nsec3_hashlength(dns_hash_t hash); -/*%< - * Return the length of the hash produced by the specified algorithm - * or zero when unknown. - */ - -isc_boolean_t -dns_nsec3_supportedhash(dns_hash_t hash); -/*%< - * Return whether we support this hash algorithm or not. - */ - - -isc_result_t -dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version, - isc_boolean_t complete, isc_boolean_t *answer); - -isc_result_t -dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version, - isc_boolean_t complete, dns_rdatatype_t private, - isc_boolean_t *answer); -/*%< - * Check if there are any complete/to be built NSEC3 chains. - * If 'complete' is ISC_TRUE only complete chains will be recognized. - * - * dns_nsec3_activex() is similar to dns_nsec3_active() but 'private' - * specifies the type of the private rdataset to be checked in addition to - * the nsec3param rdataset at the zone apex. - * - * Requires: - * 'db' to be valid. - * 'version' to be valid or NULL. - * 'answer' to be non NULL. - */ - -isc_result_t -dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, - unsigned int *iterationsp); -/*%< - * Find the maximum permissible number of iterations allowed based on - * the key strength. - * - * Requires: - * 'db' to be valid. - * 'version' to be valid or NULL. - * 'mctx' to be valid. - * 'iterationsp' to be non NULL. - */ - -isc_boolean_t -dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target, - unsigned char *buf, size_t buflen); -/*%< - * Convert a private rdata to a nsec3param rdata. - * - * Return ISC_TRUE if 'src' could be successfully converted. - * - * 'buf' should be at least DNS_NSEC3PARAM_BUFFERSIZE in size. - */ - -void -dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target, - dns_rdatatype_t privatetype, - unsigned char *buf, size_t buflen); -/*%< - * Convert a nsec3param rdata to a private rdata. - * - * 'buf' should be at least src->length + 1 in size. - */ - -isc_result_t -dns_nsec3param_salttotext(dns_rdata_nsec3param_t *nsec3param, char *dst, - size_t dstlen); -/*%< - * Convert the salt of given NSEC3PARAM RDATA into hex-encoded, NULL-terminated - * text stored at "dst". - * - * Requires: - * - *\li "dst" to have enough space (as indicated by "dstlen") to hold the - * resulting text and its NULL-terminating byte. - */ - -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 - -#endif /* DNS_NSEC3_H */ diff --git a/usr.sbin/bind/lib/dns/nsec.c b/usr.sbin/bind/lib/dns/nsec.c deleted file mode 100644 index cb14733c620..00000000000 --- a/usr.sbin/bind/lib/dns/nsec.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 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: nsec.c,v 1.8 2020/01/28 17:17:05 florian Exp $ */ - -/*! \file */ - - - -#include <isc/log.h> -#include <string.h> -#include <isc/util.h> - - -#include <dns/nsec.h> -#include <dns/rdata.h> -#include <dns/rdatalist.h> -#include <dns/rdataset.h> - -#include "rdatastruct.h" -#include <dns/result.h> - -#include <dst/dst.h> - -#define RETERR(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - -void -dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit) { - unsigned int shift, mask; - - shift = 7 - (type % 8); - mask = 1 << shift; - - if (bit != 0) - array[type / 8] |= mask; - else - array[type / 8] &= (~mask & 0xFF); -} - -isc_boolean_t -dns_nsec_isset(const unsigned char *array, unsigned int type) { - unsigned int byte, shift, mask; - - byte = array[type / 8]; - shift = 7 - (type % 8); - mask = 1 << shift; - - return (ISC_TF(byte & mask)); -} - -unsigned int -dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, - unsigned int max_type) -{ - unsigned char *start = map; - unsigned int window; - int octet; - - if (raw == NULL) - return (0); - - for (window = 0; window < 256; window++) { - if (window * 256 > max_type) - break; - for (octet = 31; octet >= 0; octet--) - if (*(raw + octet) != 0) - break; - if (octet < 0) { - raw += 32; - continue; - } - *map++ = window; - *map++ = octet + 1; - /* - * Note: potential overlapping move. - */ - memmove(map, raw, octet + 1); - map += octet + 1; - raw += 32; - } - return (unsigned int)(map - start); -} - -isc_boolean_t -dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) { - dns_rdata_nsec_t nsecstruct; - isc_result_t result; - isc_boolean_t present; - unsigned int i, len, window; - - REQUIRE(nsec != NULL); - REQUIRE(nsec->type == dns_rdatatype_nsec); - - /* This should never fail */ - result = dns_rdata_tostruct(nsec, &nsecstruct); - INSIST(result == ISC_R_SUCCESS); - - present = ISC_FALSE; - for (i = 0; i < nsecstruct.len; i += len) { - INSIST(i + 2 <= nsecstruct.len); - window = nsecstruct.typebits[i]; - len = nsecstruct.typebits[i + 1]; - INSIST(len > 0 && len <= 32); - i += 2; - INSIST(i + len <= nsecstruct.len); - if (window * 256 > type) - break; - if ((window + 1) * 256 <= type) - continue; - if (type < (window * 256) + len * 8) - present = ISC_TF(dns_nsec_isset(&nsecstruct.typebits[i], - type % 256)); - break; - } - dns_rdata_freestruct(&nsecstruct); - return (present); -} - -/*% - * 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); - 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/usr.sbin/bind/lib/dns/nsec3.c b/usr.sbin/bind/lib/dns/nsec3.c deleted file mode 100644 index ecb537219bc..00000000000 --- a/usr.sbin/bind/lib/dns/nsec3.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (C) 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: nsec3.c,v 1.8 2020/01/28 17:17:05 florian Exp $ */ - - - -#include <isc/base32.h> -#include <isc/buffer.h> -#include <isc/hex.h> -#include <isc/iterated_hash.h> -#include <isc/log.h> -#include <string.h> -#include <isc/util.h> -#include <isc/safe.h> - -#include <dst/dst.h> - - - -#include <dns/compress.h> - - -#include <dns/fixedname.h> -#include <dns/nsec.h> -#include <dns/nsec3.h> -#include <dns/rdata.h> -#include <dns/rdatalist.h> -#include <dns/rdataset.h> - -#include "rdatastruct.h" -#include <dns/result.h> - -#define CHECK(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - -#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0) -#define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0) -#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0) -#define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) - -isc_boolean_t -dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) { - dns_rdata_nsec3_t nsec3; - isc_result_t result; - isc_boolean_t present; - unsigned int i, len, window; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_nsec3); - - /* This should never fail */ - result = dns_rdata_tostruct(rdata, &nsec3); - INSIST(result == ISC_R_SUCCESS); - - present = ISC_FALSE; - for (i = 0; i < nsec3.len; i += len) { - INSIST(i + 2 <= nsec3.len); - window = nsec3.typebits[i]; - len = nsec3.typebits[i + 1]; - INSIST(len > 0 && len <= 32); - i += 2; - INSIST(i + len <= nsec3.len); - if (window * 256 > type) - break; - if ((window + 1) * 256 <= type) - continue; - if (type < (window * 256) + len * 8) - present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i], - type % 256)); - break; - } - dns_rdata_freestruct(&nsec3); - return (present); -} - -isc_result_t -dns_nsec3_hashname(dns_fixedname_t *result, - unsigned char rethash[NSEC3_MAX_HASH_LENGTH], - size_t *hash_length, dns_name_t *name, dns_name_t *origin, - dns_hash_t hashalg, unsigned int iterations, - const unsigned char *salt, size_t saltlength) -{ - unsigned char hash[NSEC3_MAX_HASH_LENGTH]; - unsigned char nametext[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fixed; - dns_name_t *downcased; - isc_buffer_t namebuffer; - isc_region_t region; - size_t len; - - if (rethash == NULL) - rethash = hash; - - memset(rethash, 0, NSEC3_MAX_HASH_LENGTH); - - dns_fixedname_init(&fixed); - downcased = dns_fixedname_name(&fixed); - dns_name_downcase(name, downcased, NULL); - - /* hash the node name */ - len = isc_iterated_hash(rethash, hashalg, iterations, - salt, (int)saltlength, - downcased->ndata, downcased->length); - if (len == 0U) - return (DNS_R_BADALG); - - if (hash_length != NULL) - *hash_length = len; - - /* convert the hash to base32hex non-padded */ - region.base = rethash; - region.length = (unsigned int)len; - isc_buffer_init(&namebuffer, nametext, sizeof nametext); - isc_base32hexnp_totext(®ion, 1, "", &namebuffer); - - /* convert the hex to a domain name */ - dns_fixedname_init(result); - return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer, - origin, 0, NULL)); -} - -unsigned int -dns_nsec3_hashlength(dns_hash_t hash) { - - switch (hash) { - case dns_hash_sha1: - return(ISC_SHA1_DIGESTLENGTH); - } - return (0); -} - -isc_boolean_t -dns_nsec3_supportedhash(dns_hash_t hash) { - switch (hash) { - case dns_hash_sha1: - return (ISC_TRUE); - } - return (ISC_FALSE); -} - -isc_boolean_t -dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target, - unsigned char *buf, size_t buflen) -{ - dns_decompress_t dctx; - isc_result_t result; - isc_buffer_t buf1; - isc_buffer_t buf2; - - /* - * Algorithm 0 (reserved by RFC 4034) is used to identify - * NSEC3PARAM records from DNSKEY pointers. - */ - if (src->length < 1 || src->data[0] != 0) - return (ISC_FALSE); - - isc_buffer_init(&buf1, src->data + 1, src->length - 1); - isc_buffer_add(&buf1, src->length - 1); - isc_buffer_setactive(&buf1, src->length - 1); - isc_buffer_init(&buf2, buf, (unsigned int)buflen); - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); - result = dns_rdata_fromwire(target, src->rdclass, - dns_rdatatype_nsec3param, - &buf1, &dctx, 0, &buf2); - dns_decompress_invalidate(&dctx); - - return (ISC_TF(result == ISC_R_SUCCESS)); -} - -void -dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target, - dns_rdatatype_t privatetype, - unsigned char *buf, size_t buflen) -{ - REQUIRE(buflen >= src->length + 1); - - REQUIRE(DNS_RDATA_INITIALIZED(target)); - - memmove(buf + 1, src->data, src->length); - buf[0] = 0; - target->data = buf; - target->length = src->length + 1; - target->type = privatetype; - target->rdclass = src->rdclass; - target->flags = 0; - ISC_LINK_INIT(target, link); -} - - -isc_result_t -dns_nsec3param_salttotext(dns_rdata_nsec3param_t *nsec3param, char *dst, - size_t dstlen) -{ - isc_result_t result; - isc_region_t r; - isc_buffer_t b; - - REQUIRE(nsec3param != NULL); - REQUIRE(dst != NULL); - - if (nsec3param->salt_length == 0) { - if (dstlen < 2U) { - return (ISC_R_NOSPACE); - } - strlcpy(dst, "-", dstlen); - return (ISC_R_SUCCESS); - } - - r.base = nsec3param->salt; - r.length = nsec3param->salt_length; - isc_buffer_init(&b, dst, (unsigned int)dstlen); - - result = isc_hex_totext(&r, 2, "", &b); - if (result != ISC_R_SUCCESS) { - return (result); - } - - if (isc_buffer_availablelength(&b) < 1) { - return (ISC_R_NOSPACE); - } - isc_buffer_putuint8(&b, 0); - - return (ISC_R_SUCCESS); -} - - - -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); - 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 = isc_safe_memcompare(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 = isc_safe_memcompare(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))) - { - 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"); - else - (*logit)(arg, ISC_LOG_DEBUG(3), - "NSEC3 indicates secure range"); - *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/usr.sbin/bind/lib/dns/rdatalist.c b/usr.sbin/bind/lib/dns/rdatalist.c index b29b795a92f..490735ac64f 100644 --- a/usr.sbin/bind/lib/dns/rdatalist.c +++ b/usr.sbin/bind/lib/dns/rdatalist.c @@ -14,18 +14,15 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatalist.c,v 1.7 2020/01/22 13:02:09 florian Exp $ */ +/* $Id: rdatalist.c,v 1.8 2020/02/04 19:27:45 florian Exp $ */ /*! \file */ - - #include <stddef.h> #include <isc/util.h> #include <dns/name.h> -#include <dns/nsec3.h> #include <dns/rdata.h> #include <dns/rdatalist.h> #include <dns/rdataset.h> |