I'm very pleased to announce the release of our new website and documentation using the new toolchain with Hugo and AsciiDoctor. To get more information about the new toolchain please read the FreeBSD Documentation Project Primer[1], Hugo docs[2] and AsciiDoctor docs[3]. Acknowledgment: Benedict Reuschling <bcr@> Glen Barber <gjb@> Hiroki Sato <hrs@> Li-Wen Hsu <lwhsu@> Sean Chittenden <seanc@> The FreeBSD Foundation [1] https://docs.FreeBSD.org/en/books/fdp-primer/ [2] https://gohugo.io/documentation/ [3] https://docs.asciidoctor.org/home/ Approved by: doceng, core
336 lines
12 KiB
Diff
336 lines
12 KiB
Diff
Index: contrib/bind9/lib/dns/rbtdb.c
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/rbtdb.c (revision 200669)
|
|
+++ contrib/bind9/lib/dns/rbtdb.c (working copy)
|
|
@@ -3072,7 +3072,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_na
|
|
}
|
|
|
|
if (dname_header != NULL &&
|
|
- (dname_header->trust != dns_trust_pending ||
|
|
+ (!DNS_TRUST_PENDING(dname_header->trust) ||
|
|
(search->options & DNS_DBFIND_PENDINGOK) != 0)) {
|
|
/*
|
|
* We increment the reference count on node to ensure that
|
|
@@ -3586,7 +3586,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbv
|
|
if (found == NULL ||
|
|
(found->trust == dns_trust_glue &&
|
|
((options & DNS_DBFIND_GLUEOK) == 0)) ||
|
|
- (found->trust == dns_trust_pending &&
|
|
+ (DNS_TRUST_PENDING(found->trust) &&
|
|
((options & DNS_DBFIND_PENDINGOK) == 0))) {
|
|
/*
|
|
* If there is an NS rdataset at this node, then this is the
|
|
Index: contrib/bind9/lib/dns/include/dns/types.h
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/include/dns/types.h (revision 200669)
|
|
+++ contrib/bind9/lib/dns/include/dns/types.h (working copy)
|
|
@@ -241,40 +241,52 @@ enum {
|
|
dns_trust_none = 0,
|
|
#define dns_trust_none ((dns_trust_t)dns_trust_none)
|
|
|
|
- /*% Subject to DNSSEC validation but has not yet been validated */
|
|
- dns_trust_pending = 1,
|
|
-#define dns_trust_pending ((dns_trust_t)dns_trust_pending)
|
|
-
|
|
+ /*%
|
|
+ * Subject to DNSSEC validation but has not yet been validated
|
|
+ * dns_trust_pending_additional (from the additional section).
|
|
+ */
|
|
+ dns_trust_pending_additional = 1,
|
|
+#define dns_trust_pending_additional \
|
|
+ ((dns_trust_t)dns_trust_pending_additional)
|
|
+
|
|
+ dns_trust_pending_answer = 2,
|
|
+#define dns_trust_pending_answer ((dns_trust_t)dns_trust_pending_answer)
|
|
+
|
|
/*% Received in the additional section of a response. */
|
|
- dns_trust_additional = 2,
|
|
+ dns_trust_additional = 3,
|
|
#define dns_trust_additional ((dns_trust_t)dns_trust_additional)
|
|
-
|
|
- /* Received in a referral response. */
|
|
- dns_trust_glue = 3,
|
|
+
|
|
+ /* Received in a referral response. */
|
|
+ dns_trust_glue = 4,
|
|
#define dns_trust_glue ((dns_trust_t)dns_trust_glue)
|
|
-
|
|
- /* Answser from a non-authoritative server */
|
|
- dns_trust_answer = 4,
|
|
+
|
|
+ /* Answer from a non-authoritative server */
|
|
+ dns_trust_answer = 5,
|
|
#define dns_trust_answer ((dns_trust_t)dns_trust_answer)
|
|
-
|
|
+
|
|
/* Received in the authority section as part of an
|
|
authoritative response */
|
|
- dns_trust_authauthority = 5,
|
|
+ dns_trust_authauthority = 6,
|
|
#define dns_trust_authauthority ((dns_trust_t)dns_trust_authauthority)
|
|
|
|
- /* Answser from an authoritative server */
|
|
- dns_trust_authanswer = 6,
|
|
+ /* Answer from an authoritative server */
|
|
+ dns_trust_authanswer = 7,
|
|
#define dns_trust_authanswer ((dns_trust_t)dns_trust_authanswer)
|
|
-
|
|
- /* Successfully DNSSEC validated */
|
|
- dns_trust_secure = 7,
|
|
+
|
|
+ /* Successfully DNSSEC validated */
|
|
+ dns_trust_secure = 8,
|
|
#define dns_trust_secure ((dns_trust_t)dns_trust_secure)
|
|
|
|
/* This server is authoritative */
|
|
- dns_trust_ultimate = 8
|
|
+ dns_trust_ultimate = 9
|
|
#define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate)
|
|
};
|
|
|
|
+#define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \
|
|
+ (x) == dns_trust_pending_additional)
|
|
+#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue)
|
|
+
|
|
+
|
|
/*%
|
|
* Name checking severites.
|
|
*/
|
|
Index: contrib/bind9/lib/dns/resolver.c
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/resolver.c (revision 200669)
|
|
+++ contrib/bind9/lib/dns/resolver.c (working copy)
|
|
@@ -3887,6 +3887,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns
|
|
* for it, unless it is glue.
|
|
*/
|
|
if (secure_domain && rdataset->trust != dns_trust_glue) {
|
|
+ dns_trust_t trust;
|
|
/*
|
|
* RRSIGs are validated as part of validating the
|
|
* type they cover.
|
|
@@ -3923,12 +3924,34 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns
|
|
}
|
|
|
|
/*
|
|
+ * Reject out of bailiwick additional records
|
|
+ * without RRSIGs as they can't possibly validate
|
|
+ * as "secure" and as we will never never want to
|
|
+ * store these as "answers" after validation.
|
|
+ */
|
|
+ if (rdataset->trust == dns_trust_additional &&
|
|
+ sigrdataset == NULL && EXTERNAL(rdataset))
|
|
+ continue;
|
|
+
|
|
+ /*
|
|
+ * XXXMPA: If we store as "answer" after validating
|
|
+ * then we need to do bailiwick processing and
|
|
+ * also need to track whether RRsets are in or
|
|
+ * out of bailiwick. This will require a another
|
|
+ * pending trust level.
|
|
+ *
|
|
* Cache this rdataset/sigrdataset pair as
|
|
- * pending data.
|
|
+ * pending data. Track whether it was additional
|
|
+ * or not.
|
|
*/
|
|
- rdataset->trust = dns_trust_pending;
|
|
+ if (rdataset->trust == dns_trust_additional)
|
|
+ trust = dns_trust_pending_additional;
|
|
+ else
|
|
+ trust = dns_trust_pending_answer;
|
|
+
|
|
+ rdataset->trust = trust;
|
|
if (sigrdataset != NULL)
|
|
- sigrdataset->trust = dns_trust_pending;
|
|
+ sigrdataset->trust = trust;
|
|
if (!need_validation)
|
|
addedrdataset = ardataset;
|
|
else
|
|
@@ -4276,7 +4299,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t
|
|
for (trdataset = ISC_LIST_HEAD(tname->list);
|
|
trdataset != NULL;
|
|
trdataset = ISC_LIST_NEXT(trdataset, link))
|
|
- trdataset->trust = dns_trust_pending;
|
|
+ trdataset->trust = dns_trust_pending_answer;
|
|
result = dns_message_nextname(fctx->rmessage,
|
|
DNS_SECTION_AUTHORITY);
|
|
}
|
|
Index: contrib/bind9/lib/dns/masterdump.c
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/masterdump.c (revision 200669)
|
|
+++ contrib/bind9/lib/dns/masterdump.c (working copy)
|
|
@@ -774,7 +774,8 @@ dump_order_compare(const void *a, const void *b) {
|
|
|
|
static const char *trustnames[] = {
|
|
"none",
|
|
- "pending",
|
|
+ "pending-additional",
|
|
+ "pending-answer",
|
|
"additional",
|
|
"glue",
|
|
"answer",
|
|
Index: contrib/bind9/lib/dns/validator.c
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/validator.c (revision 200669)
|
|
+++ contrib/bind9/lib/dns/validator.c (working copy)
|
|
@@ -1174,7 +1174,7 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *s
|
|
* We have an rrset for the given keyname.
|
|
*/
|
|
val->keyset = &val->frdataset;
|
|
- if (val->frdataset.trust == dns_trust_pending &&
|
|
+ if (DNS_TRUST_PENDING(val->frdataset.trust) &&
|
|
dns_rdataset_isassociated(&val->fsigrdataset))
|
|
{
|
|
/*
|
|
@@ -1189,7 +1189,7 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *s
|
|
if (result != ISC_R_SUCCESS)
|
|
return (result);
|
|
return (DNS_R_WAIT);
|
|
- } else if (val->frdataset.trust == dns_trust_pending) {
|
|
+ } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
|
|
/*
|
|
* Having a pending key with no signature means that
|
|
* something is broken.
|
|
@@ -1805,7 +1805,7 @@ validatezonekey(dns_validator_t *val) {
|
|
* We have DS records.
|
|
*/
|
|
val->dsset = &val->frdataset;
|
|
- if (val->frdataset.trust == dns_trust_pending &&
|
|
+ if (DNS_TRUST_PENDING(val->frdataset.trust) &&
|
|
dns_rdataset_isassociated(&val->fsigrdataset))
|
|
{
|
|
result = create_validator(val,
|
|
@@ -1818,7 +1818,7 @@ validatezonekey(dns_validator_t *val) {
|
|
if (result != ISC_R_SUCCESS)
|
|
return (result);
|
|
return (DNS_R_WAIT);
|
|
- } else if (val->frdataset.trust == dns_trust_pending) {
|
|
+ } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
|
|
/*
|
|
* There should never be an unsigned DS.
|
|
*/
|
|
@@ -2667,7 +2667,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t
|
|
* There is no DS. If this is a delegation,
|
|
* we maybe done.
|
|
*/
|
|
- if (val->frdataset.trust == dns_trust_pending) {
|
|
+ if (DNS_TRUST_PENDING(val->frdataset.trust)) {
|
|
result = create_fetch(val, tname,
|
|
dns_rdatatype_ds,
|
|
dsfetched2,
|
|
Index: contrib/bind9/bin/named/query.c
|
|
===================================================================
|
|
--- contrib/bind9/bin/named/query.c (revision 200669)
|
|
+++ contrib/bind9/bin/named/query.c (working copy)
|
|
@@ -109,6 +109,8 @@
|
|
#define DNS_GETDB_NOLOG 0x02U
|
|
#define DNS_GETDB_PARTIAL 0x04U
|
|
|
|
+#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0)
|
|
+
|
|
typedef struct client_additionalctx {
|
|
ns_client_t *client;
|
|
dns_rdataset_t *rdataset;
|
|
@@ -1721,8 +1723,8 @@ query_addadditional2(void *arg, dns_name_t *name,
|
|
*/
|
|
if (result == ISC_R_SUCCESS &&
|
|
additionaltype == dns_rdatasetadditional_fromcache &&
|
|
- (rdataset->trust == dns_trust_pending ||
|
|
- rdataset->trust == dns_trust_glue) &&
|
|
+ (DNS_TRUST_PENDING(rdataset->trust) ||
|
|
+ DNS_TRUST_GLUE(rdataset->trust)) &&
|
|
!validate(client, db, fname, rdataset, sigrdataset)) {
|
|
dns_rdataset_disassociate(rdataset);
|
|
if (dns_rdataset_isassociated(sigrdataset))
|
|
@@ -1761,8 +1763,8 @@ query_addadditional2(void *arg, dns_name_t *name,
|
|
*/
|
|
if (result == ISC_R_SUCCESS &&
|
|
additionaltype == dns_rdatasetadditional_fromcache &&
|
|
- (rdataset->trust == dns_trust_pending ||
|
|
- rdataset->trust == dns_trust_glue) &&
|
|
+ (DNS_TRUST_PENDING(rdataset->trust) ||
|
|
+ DNS_TRUST_GLUE(rdataset->trust)) &&
|
|
!validate(client, db, fname, rdataset, sigrdataset)) {
|
|
dns_rdataset_disassociate(rdataset);
|
|
if (dns_rdataset_isassociated(sigrdataset))
|
|
@@ -2547,14 +2549,14 @@ query_addbestns(ns_client_t *client) {
|
|
/*
|
|
* Attempt to validate RRsets that are pending or that are glue.
|
|
*/
|
|
- if ((rdataset->trust == dns_trust_pending ||
|
|
- (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending))
|
|
+ if ((DNS_TRUST_PENDING(rdataset->trust) ||
|
|
+ (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust)))
|
|
&& !validate(client, db, fname, rdataset, sigrdataset) &&
|
|
- (client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0)
|
|
+ !PENDINGOK(client->query.dboptions))
|
|
goto cleanup;
|
|
|
|
- if ((rdataset->trust == dns_trust_glue ||
|
|
- (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue)) &&
|
|
+ if ((DNS_TRUST_GLUE(rdataset->trust) ||
|
|
+ (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) &&
|
|
!validate(client, db, fname, rdataset, sigrdataset) &&
|
|
SECURE(client) && WANTDNSSEC(client))
|
|
goto cleanup;
|
|
@@ -3344,6 +3346,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *
|
|
isc_boolean_t empty_wild;
|
|
dns_rdataset_t *noqname;
|
|
isc_boolean_t resuming;
|
|
+ dns_rdataset_t tmprdataset;
|
|
+ unsigned int dboptions;
|
|
|
|
CTRACE("query_find");
|
|
|
|
@@ -3555,9 +3559,49 @@ query_find(ns_client_t *client, dns_fetchevent_t *
|
|
/*
|
|
* Now look for an answer in the database.
|
|
*/
|
|
+ dboptions = client->query.dboptions;
|
|
+ if (sigrdataset == NULL && client->view->enablednssec) {
|
|
+ /*
|
|
+ * If the client doesn't want DNSSEC we still want to
|
|
+ * look for any data pending validation to save a remote
|
|
+ * lookup if possible.
|
|
+ */
|
|
+ dns_rdataset_init(&tmprdataset);
|
|
+ sigrdataset = &tmprdataset;
|
|
+ dboptions |= DNS_DBFIND_PENDINGOK;
|
|
+ }
|
|
+ refind:
|
|
result = dns_db_find(db, client->query.qname, version, type,
|
|
- client->query.dboptions, client->now,
|
|
- &node, fname, rdataset, sigrdataset);
|
|
+ dboptions, client->now, &node, fname,
|
|
+ rdataset, sigrdataset);
|
|
+ /*
|
|
+ * If we have found pending data try to validate it.
|
|
+ * If the data does not validate as secure and we can't
|
|
+ * use the unvalidated data requery the database with
|
|
+ * pending disabled to prevent infinite looping.
|
|
+ */
|
|
+ if (result != ISC_R_SUCCESS || !DNS_TRUST_PENDING(rdataset->trust))
|
|
+ goto validation_done;
|
|
+ if (validate(client, db, fname, rdataset, sigrdataset))
|
|
+ goto validation_done;
|
|
+ if (rdataset->trust != dns_trust_pending_answer ||
|
|
+ !PENDINGOK(client->query.dboptions)) {
|
|
+ dns_rdataset_disassociate(rdataset);
|
|
+ if (sigrdataset != NULL &&
|
|
+ dns_rdataset_isassociated(sigrdataset))
|
|
+ dns_rdataset_disassociate(sigrdataset);
|
|
+ if (sigrdataset == &tmprdataset)
|
|
+ sigrdataset = NULL;
|
|
+ dns_db_detachnode(db, &node);
|
|
+ dboptions &= ~DNS_DBFIND_PENDINGOK;
|
|
+ goto refind;
|
|
+ }
|
|
+ validation_done:
|
|
+ if (sigrdataset == &tmprdataset) {
|
|
+ if (dns_rdataset_isassociated(sigrdataset))
|
|
+ dns_rdataset_disassociate(sigrdataset);
|
|
+ sigrdataset = NULL;
|
|
+ }
|
|
|
|
resume:
|
|
CTRACE("query_find: resume");
|