mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 08:05:21 +00:00
2890. [bug] Handle the introduction of new trusted-keys and
DS, DLV RRsets better. [RT #21097]
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
|||||||
|
2890. [bug] Handle the introduction of new trusted-keys and
|
||||||
|
DS, DLV RRsets better. [RT #21097]
|
||||||
|
|
||||||
2889. [bug] Elements of the grammar where not properly reported.
|
2889. [bug] Elements of the grammar where not properly reported.
|
||||||
[RT #21046]
|
[RT #21046]
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: ncache.h,v 1.27 2009/12/30 23:49:14 tbox Exp $ */
|
/* $Id: ncache.h,v 1.28 2010/05/14 00:13:43 marka Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_NCACHE_H
|
#ifndef DNS_NCACHE_H
|
||||||
#define DNS_NCACHE_H 1
|
#define DNS_NCACHE_H 1
|
||||||
@@ -161,6 +161,13 @@ dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
|
||||||
|
dns_rdatatype_t covers, dns_rdataset_t *rdataset);
|
||||||
|
/*%<
|
||||||
|
* Similar to dns_ncache_getrdataset() but get the rrsig that matches.
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
|
dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
|
||||||
dns_rdataset_t *rdataset);
|
dns_rdataset_t *rdataset);
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: types.h,v 1.139 2009/12/30 08:02:23 jinmei Exp $ */
|
/* $Id: types.h,v 1.140 2010/05/14 00:13:43 marka Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_TYPES_H
|
#ifndef DNS_TYPES_H
|
||||||
#define DNS_TYPES_H 1
|
#define DNS_TYPES_H 1
|
||||||
@@ -321,6 +321,7 @@ enum {
|
|||||||
#define DNS_TRUST_ADDITIONAL(x) ((x) == dns_trust_additional || \
|
#define DNS_TRUST_ADDITIONAL(x) ((x) == dns_trust_additional || \
|
||||||
(x) == dns_trust_pending_additional)
|
(x) == dns_trust_pending_additional)
|
||||||
#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue)
|
#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue)
|
||||||
|
#define DNS_TRUST_ANSWER(x) ((x) == dns_trust_answer)
|
||||||
|
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
|
142
lib/dns/ncache.c
142
lib/dns/ncache.c
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: ncache.c,v 1.45 2010/02/25 05:08:01 tbox Exp $ */
|
/* $Id: ncache.c,v 1.46 2010/05/14 00:13:43 marka Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
*
|
*
|
||||||
* owner name
|
* owner name
|
||||||
* type
|
* type
|
||||||
|
* trust
|
||||||
* rdata count
|
* rdata count
|
||||||
* rdata length These two occur 'rdata count'
|
* rdata length These two occur 'rdata count'
|
||||||
* rdata times.
|
* rdata times.
|
||||||
@@ -189,6 +190,8 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
|
|||||||
return (ISC_R_NOSPACE);
|
return (ISC_R_NOSPACE);
|
||||||
isc_buffer_putuint16(&buffer,
|
isc_buffer_putuint16(&buffer,
|
||||||
rdataset->type);
|
rdataset->type);
|
||||||
|
isc_buffer_putuint8(&buffer,
|
||||||
|
rdataset->trust);
|
||||||
/*
|
/*
|
||||||
* Copy the rdataset into the buffer.
|
* Copy the rdataset into the buffer.
|
||||||
*/
|
*/
|
||||||
@@ -335,8 +338,9 @@ dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
|
|||||||
isc_buffer_forward(&source, name.length);
|
isc_buffer_forward(&source, name.length);
|
||||||
remaining.length -= name.length;
|
remaining.length -= name.length;
|
||||||
|
|
||||||
INSIST(remaining.length >= 4);
|
INSIST(remaining.length >= 5);
|
||||||
type = isc_buffer_getuint16(&source);
|
type = isc_buffer_getuint16(&source);
|
||||||
|
isc_buffer_forward(&source, 1);
|
||||||
rcount = isc_buffer_getuint16(&source);
|
rcount = isc_buffer_getuint16(&source);
|
||||||
|
|
||||||
for (i = 0; i < rcount; i++) {
|
for (i = 0; i < rcount; i++) {
|
||||||
@@ -506,6 +510,13 @@ rdataset_count(dns_rdataset_t *rdataset) {
|
|||||||
return (count);
|
return (count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
|
||||||
|
unsigned char *raw = rdataset->private3;
|
||||||
|
|
||||||
|
raw[-1] = trust;
|
||||||
|
}
|
||||||
|
|
||||||
static dns_rdatasetmethods_t rdataset_methods = {
|
static dns_rdatasetmethods_t rdataset_methods = {
|
||||||
rdataset_disassociate,
|
rdataset_disassociate,
|
||||||
rdataset_first,
|
rdataset_first,
|
||||||
@@ -520,7 +531,7 @@ static dns_rdatasetmethods_t rdataset_methods = {
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
rdataset_settrust,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -534,6 +545,8 @@ dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
|
|||||||
isc_buffer_t source;
|
isc_buffer_t source;
|
||||||
dns_name_t tname;
|
dns_name_t tname;
|
||||||
dns_rdatatype_t ttype;
|
dns_rdatatype_t ttype;
|
||||||
|
dns_trust_t trust = dns_trust_none;
|
||||||
|
dns_rdataset_t clone;
|
||||||
|
|
||||||
REQUIRE(ncacherdataset != NULL);
|
REQUIRE(ncacherdataset != NULL);
|
||||||
REQUIRE(ncacherdataset->type == 0);
|
REQUIRE(ncacherdataset->type == 0);
|
||||||
@@ -541,9 +554,11 @@ dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
|
|||||||
REQUIRE(!dns_rdataset_isassociated(rdataset));
|
REQUIRE(!dns_rdataset_isassociated(rdataset));
|
||||||
REQUIRE(type != dns_rdatatype_rrsig);
|
REQUIRE(type != dns_rdatatype_rrsig);
|
||||||
|
|
||||||
result = dns_rdataset_first(ncacherdataset);
|
dns_rdataset_init(&clone);
|
||||||
|
dns_rdataset_clone(ncacherdataset, &clone);
|
||||||
|
result = dns_rdataset_first(&clone);
|
||||||
while (result == ISC_R_SUCCESS) {
|
while (result == ISC_R_SUCCESS) {
|
||||||
dns_rdataset_current(ncacherdataset, &rdata);
|
dns_rdataset_current(&clone, &rdata);
|
||||||
isc_buffer_init(&source, rdata.data, rdata.length);
|
isc_buffer_init(&source, rdata.data, rdata.length);
|
||||||
isc_buffer_add(&source, rdata.length);
|
isc_buffer_add(&source, rdata.length);
|
||||||
dns_name_init(&tname, NULL);
|
dns_name_init(&tname, NULL);
|
||||||
@@ -553,16 +568,19 @@ dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
|
|||||||
isc_buffer_forward(&source, tname.length);
|
isc_buffer_forward(&source, tname.length);
|
||||||
remaining.length -= tname.length;
|
remaining.length -= tname.length;
|
||||||
|
|
||||||
INSIST(remaining.length >= 4);
|
INSIST(remaining.length >= 3);
|
||||||
ttype = isc_buffer_getuint16(&source);
|
ttype = isc_buffer_getuint16(&source);
|
||||||
|
|
||||||
if (ttype == type && dns_name_equal(&tname, name)) {
|
if (ttype == type && dns_name_equal(&tname, name)) {
|
||||||
|
trust = isc_buffer_getuint8(&source);
|
||||||
|
INSIST(trust <= dns_trust_ultimate);
|
||||||
isc_buffer_remainingregion(&source, &remaining);
|
isc_buffer_remainingregion(&source, &remaining);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result = dns_rdataset_next(ncacherdataset);
|
result = dns_rdataset_next(&clone);
|
||||||
dns_rdata_reset(&rdata);
|
dns_rdata_reset(&rdata);
|
||||||
}
|
}
|
||||||
|
dns_rdataset_disassociate(&clone);
|
||||||
if (result == ISC_R_NOMORE)
|
if (result == ISC_R_NOMORE)
|
||||||
return (ISC_R_NOTFOUND);
|
return (ISC_R_NOTFOUND);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
@@ -575,7 +593,108 @@ dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
|
|||||||
rdataset->type = type;
|
rdataset->type = type;
|
||||||
rdataset->covers = 0;
|
rdataset->covers = 0;
|
||||||
rdataset->ttl = ncacherdataset->ttl;
|
rdataset->ttl = ncacherdataset->ttl;
|
||||||
rdataset->trust = ncacherdataset->trust;
|
rdataset->trust = trust;
|
||||||
|
rdataset->private1 = NULL;
|
||||||
|
rdataset->private2 = NULL;
|
||||||
|
|
||||||
|
rdataset->private3 = remaining.base;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset iterator state.
|
||||||
|
*/
|
||||||
|
rdataset->privateuint4 = 0;
|
||||||
|
rdataset->private5 = NULL;
|
||||||
|
rdataset->private6 = NULL;
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
|
||||||
|
dns_rdatatype_t covers, dns_rdataset_t *rdataset)
|
||||||
|
{
|
||||||
|
dns_name_t tname;
|
||||||
|
dns_rdata_rrsig_t rrsig;
|
||||||
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
|
dns_rdataset_t clone;
|
||||||
|
dns_rdatatype_t type;
|
||||||
|
dns_trust_t trust = dns_trust_none;
|
||||||
|
isc_buffer_t source;
|
||||||
|
isc_region_t remaining, sigregion;
|
||||||
|
isc_result_t result;
|
||||||
|
unsigned char *raw;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
REQUIRE(ncacherdataset != NULL);
|
||||||
|
REQUIRE(ncacherdataset->type == 0);
|
||||||
|
REQUIRE(name != NULL);
|
||||||
|
REQUIRE(!dns_rdataset_isassociated(rdataset));
|
||||||
|
|
||||||
|
dns_rdataset_init(&clone);
|
||||||
|
dns_rdataset_clone(ncacherdataset, &clone);
|
||||||
|
result = dns_rdataset_first(&clone);
|
||||||
|
while (result == ISC_R_SUCCESS) {
|
||||||
|
dns_rdataset_current(&clone, &rdata);
|
||||||
|
isc_buffer_init(&source, rdata.data, rdata.length);
|
||||||
|
isc_buffer_add(&source, rdata.length);
|
||||||
|
dns_name_init(&tname, NULL);
|
||||||
|
isc_buffer_remainingregion(&source, &remaining);
|
||||||
|
dns_name_fromregion(&tname, &remaining);
|
||||||
|
INSIST(remaining.length >= tname.length);
|
||||||
|
isc_buffer_forward(&source, tname.length);
|
||||||
|
remaining.length -= tname.length;
|
||||||
|
remaining.base += tname.length;
|
||||||
|
|
||||||
|
INSIST(remaining.length >= 2);
|
||||||
|
type = isc_buffer_getuint16(&source);
|
||||||
|
remaining.length -= 2;
|
||||||
|
remaining.base += 2;
|
||||||
|
|
||||||
|
if (type != dns_rdatatype_rrsig ||
|
||||||
|
!dns_name_equal(&tname, name)) {
|
||||||
|
result = dns_rdataset_next(&clone);
|
||||||
|
dns_rdata_reset(&rdata);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
INSIST(remaining.length >= 1);
|
||||||
|
trust = isc_buffer_getuint8(&source);
|
||||||
|
INSIST(trust <= dns_trust_ultimate);
|
||||||
|
remaining.length -= 1;
|
||||||
|
remaining.base += 1;
|
||||||
|
|
||||||
|
raw = remaining.base;
|
||||||
|
count = raw[0] * 256 + raw[1];
|
||||||
|
INSIST(count > 0);
|
||||||
|
raw += 2;
|
||||||
|
sigregion.length = raw[0] * 256 + raw[1];
|
||||||
|
raw += 2;
|
||||||
|
sigregion.base = raw;
|
||||||
|
dns_rdata_reset(&rdata);
|
||||||
|
dns_rdata_fromregion(&rdata, rdataset->rdclass,
|
||||||
|
dns_rdatatype_rrsig, &sigregion);
|
||||||
|
(void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
|
||||||
|
if (rrsig.covered == covers) {
|
||||||
|
isc_buffer_remainingregion(&source, &remaining);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = dns_rdataset_next(&clone);
|
||||||
|
dns_rdata_reset(&rdata);
|
||||||
|
}
|
||||||
|
dns_rdataset_disassociate(&clone);
|
||||||
|
if (result == ISC_R_NOMORE)
|
||||||
|
return (ISC_R_NOTFOUND);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
|
||||||
|
INSIST(remaining.length != 0);
|
||||||
|
|
||||||
|
rdataset->methods = &rdataset_methods;
|
||||||
|
rdataset->rdclass = ncacherdataset->rdclass;
|
||||||
|
rdataset->type = dns_rdatatype_rrsig;
|
||||||
|
rdataset->covers = covers;
|
||||||
|
rdataset->ttl = ncacherdataset->ttl;
|
||||||
|
rdataset->trust = trust;
|
||||||
rdataset->private1 = NULL;
|
rdataset->private1 = NULL;
|
||||||
rdataset->private2 = NULL;
|
rdataset->private2 = NULL;
|
||||||
|
|
||||||
@@ -595,6 +714,7 @@ dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
|
|||||||
dns_rdataset_t *rdataset)
|
dns_rdataset_t *rdataset)
|
||||||
{
|
{
|
||||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
|
dns_trust_t trust;
|
||||||
isc_region_t remaining, sigregion;
|
isc_region_t remaining, sigregion;
|
||||||
isc_buffer_t source;
|
isc_buffer_t source;
|
||||||
dns_name_t tname;
|
dns_name_t tname;
|
||||||
@@ -619,8 +739,10 @@ dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
|
|||||||
isc_buffer_forward(&source, found->length);
|
isc_buffer_forward(&source, found->length);
|
||||||
remaining.length -= found->length;
|
remaining.length -= found->length;
|
||||||
|
|
||||||
INSIST(remaining.length >= 4);
|
INSIST(remaining.length >= 5);
|
||||||
type = isc_buffer_getuint16(&source);
|
type = isc_buffer_getuint16(&source);
|
||||||
|
trust = isc_buffer_getuint8(&source);
|
||||||
|
INSIST(trust <= dns_trust_ultimate);
|
||||||
isc_buffer_remainingregion(&source, &remaining);
|
isc_buffer_remainingregion(&source, &remaining);
|
||||||
|
|
||||||
rdataset->methods = &rdataset_methods;
|
rdataset->methods = &rdataset_methods;
|
||||||
@@ -645,7 +767,7 @@ dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
|
|||||||
} else
|
} else
|
||||||
rdataset->covers = 0;
|
rdataset->covers = 0;
|
||||||
rdataset->ttl = ncacherdataset->ttl;
|
rdataset->ttl = ncacherdataset->ttl;
|
||||||
rdataset->trust = ncacherdataset->trust;
|
rdataset->trust = trust;
|
||||||
rdataset->private1 = NULL;
|
rdataset->private1 = NULL;
|
||||||
rdataset->private2 = NULL;
|
rdataset->private2 = NULL;
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: validator.c,v 1.190 2010/04/21 05:45:47 marka Exp $ */
|
/* $Id: validator.c,v 1.191 2010/05/14 00:13:43 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -120,6 +120,11 @@
|
|||||||
#define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
|
#define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
|
||||||
#define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
|
#define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
|
||||||
#define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
|
#define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
|
||||||
|
#define FOUNDNODATA(val) ((val->attributes & VALATTR_FOUNDNODATA) != 0)
|
||||||
|
#define FOUNDNOQNAME(val) ((val->attributes & VALATTR_FOUNDNOQNAME) != 0)
|
||||||
|
#define FOUNDNOWILDCARD(val) ((val->attributes & VALATTR_FOUNDNOWILDCARD) != 0)
|
||||||
|
#define FOUNDCLOSEST(val) ((val->attributes & VALATTR_FOUNDCLOSEST) != 0)
|
||||||
|
#define FOUNDOPTOUT(val) ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
|
||||||
|
|
||||||
#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
|
#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
|
||||||
#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
|
#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
|
||||||
@@ -174,8 +179,8 @@ startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure);
|
|||||||
* Mark the RRsets as a answer.
|
* Mark the RRsets as a answer.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
markanswer(dns_validator_t *val) {
|
markanswer(dns_validator_t *val, const char *where) {
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");
|
validator_log(val, ISC_LOG_DEBUG(3), "marking as answer (%s)", where);
|
||||||
if (val->event->rdataset != NULL)
|
if (val->event->rdataset != NULL)
|
||||||
dns_rdataset_settrust(val->event->rdataset, dns_trust_answer);
|
dns_rdataset_settrust(val->event->rdataset, dns_trust_answer);
|
||||||
if (val->event->sigrdataset != NULL)
|
if (val->event->sigrdataset != NULL)
|
||||||
@@ -186,6 +191,7 @@ markanswer(dns_validator_t *val) {
|
|||||||
static inline void
|
static inline void
|
||||||
marksecure(dns_validatorevent_t *event) {
|
marksecure(dns_validatorevent_t *event) {
|
||||||
dns_rdataset_settrust(event->rdataset, dns_trust_secure);
|
dns_rdataset_settrust(event->rdataset, dns_trust_secure);
|
||||||
|
if (event->sigrdataset != NULL)
|
||||||
dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
|
dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,7 +570,7 @@ dsfetched2(isc_task_t *task, isc_event_t *event) {
|
|||||||
" and this is a delegation");
|
" and this is a delegation");
|
||||||
validator_done(val, DNS_R_MUSTBESECURE);
|
validator_done(val, DNS_R_MUSTBESECURE);
|
||||||
} else if (val->view->dlv == NULL || DLVTRIED(val)) {
|
} else if (val->view->dlv == NULL || DLVTRIED(val)) {
|
||||||
markanswer(val);
|
markanswer(val, "dsfetched2");
|
||||||
validator_done(val, ISC_R_SUCCESS);
|
validator_done(val, ISC_R_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
result = startfinddlvsep(val, tname);
|
result = startfinddlvsep(val, tname);
|
||||||
@@ -690,11 +696,32 @@ dsvalidated(isc_task_t *task, isc_event_t *event) {
|
|||||||
if (CANCELED(val)) {
|
if (CANCELED(val)) {
|
||||||
validator_done(val, ISC_R_CANCELED);
|
validator_done(val, ISC_R_CANCELED);
|
||||||
} else if (eresult == ISC_R_SUCCESS) {
|
} else if (eresult == ISC_R_SUCCESS) {
|
||||||
|
isc_boolean_t have_dsset;
|
||||||
|
dns_name_t *name;
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"dsset with trust %d", val->frdataset.trust);
|
"%s with trust %d",
|
||||||
if ((val->attributes & VALATTR_INSECURITY) != 0)
|
val->frdataset.type == dns_rdatatype_ds ?
|
||||||
result = proveunsecure(val, ISC_TRUE, ISC_TRUE);
|
"dsset" : "ds non-existance",
|
||||||
else
|
val->frdataset.trust);
|
||||||
|
have_dsset = ISC_TF(val->frdataset.type == dns_rdatatype_ds);
|
||||||
|
name = dns_fixedname_name(&val->fname);
|
||||||
|
if ((val->attributes & VALATTR_INSECURITY) != 0 &&
|
||||||
|
val->frdataset.covers == dns_rdatatype_ds &&
|
||||||
|
val->frdataset.type == 0 &&
|
||||||
|
isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) {
|
||||||
|
if (val->mustbesecure) {
|
||||||
|
validator_log(val, ISC_LOG_WARNING,
|
||||||
|
"must be secure failure, no DS "
|
||||||
|
"and this is a delegation");
|
||||||
|
result = DNS_R_MUSTBESECURE;
|
||||||
|
} else if (val->view->dlv == NULL || DLVTRIED(val)) {
|
||||||
|
markanswer(val, "dsvalidated");
|
||||||
|
result = ISC_R_SUCCESS;;
|
||||||
|
} else
|
||||||
|
result = startfinddlvsep(val, name);
|
||||||
|
} else if ((val->attributes & VALATTR_INSECURITY) != 0) {
|
||||||
|
result = proveunsecure(val, have_dsset, ISC_TRUE);
|
||||||
|
} else
|
||||||
result = validatezonekey(val);
|
result = validatezonekey(val);
|
||||||
if (result != DNS_R_WAIT)
|
if (result != DNS_R_WAIT)
|
||||||
validator_done(val, result);
|
validator_done(val, result);
|
||||||
@@ -1139,29 +1166,7 @@ nsec3noexistnodata(dns_validator_t *val, dns_name_t* name,
|
|||||||
dns_name_copy(qname, nearest, NULL);
|
dns_name_copy(qname, nearest, NULL);
|
||||||
*setnearest = ISC_TRUE;
|
*setnearest = ISC_TRUE;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* The closest encloser may be the zone name.
|
|
||||||
*/
|
|
||||||
if (closest != NULL &&
|
|
||||||
dns_name_countlabels(closest) == 0 &&
|
|
||||||
!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)))
|
|
||||||
{
|
|
||||||
char namebuf[DNS_NAME_FORMATSIZE];
|
|
||||||
|
|
||||||
dns_name_format(zone, namebuf,
|
|
||||||
sizeof(namebuf));
|
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
|
||||||
"NSEC3 potential closest "
|
|
||||||
"encloser from zone name: '%s'",
|
|
||||||
namebuf);
|
|
||||||
dns_name_copy(zone, closest, NULL);
|
|
||||||
*setclosest = ISC_TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*exists = ISC_FALSE;
|
*exists = ISC_FALSE;
|
||||||
*data = ISC_FALSE;
|
*data = ISC_FALSE;
|
||||||
if (optout != NULL) {
|
if (optout != NULL) {
|
||||||
@@ -1237,10 +1242,8 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
if (rdataset->type == dns_rdatatype_nsec &&
|
if (rdataset->type == dns_rdatatype_nsec &&
|
||||||
rdataset->trust == dns_trust_secure &&
|
rdataset->trust == dns_trust_secure &&
|
||||||
((val->attributes & VALATTR_NEEDNODATA) != 0 ||
|
(NEEDNODATA(val) || NEEDNOQNAME(val)) &&
|
||||||
(val->attributes & VALATTR_NEEDNOQNAME) != 0) &&
|
!FOUNDNODATA(val) && !FOUNDNOQNAME(val) &&
|
||||||
(val->attributes & VALATTR_FOUNDNODATA) == 0 &&
|
|
||||||
(val->attributes & VALATTR_FOUNDNOQNAME) == 0 &&
|
|
||||||
nsecnoexistnodata(val, val->event->name, devent->name,
|
nsecnoexistnodata(val, val->event->name, devent->name,
|
||||||
rdataset, &exists, &data, wild)
|
rdataset, &exists, &data, wild)
|
||||||
== ISC_R_SUCCESS)
|
== ISC_R_SUCCESS)
|
||||||
@@ -1650,11 +1653,14 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
|
|||||||
* We have an rrset for the given keyname.
|
* We have an rrset for the given keyname.
|
||||||
*/
|
*/
|
||||||
val->keyset = &val->frdataset;
|
val->keyset = &val->frdataset;
|
||||||
if (DNS_TRUST_PENDING(val->frdataset.trust) &&
|
if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
|
||||||
|
DNS_TRUST_ANSWER(val->frdataset.trust)) &&
|
||||||
dns_rdataset_isassociated(&val->fsigrdataset))
|
dns_rdataset_isassociated(&val->fsigrdataset))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We know the key but haven't validated it yet.
|
* We know the key but haven't validated it yet or
|
||||||
|
* we have a key of trust answer but a DS/DLV
|
||||||
|
* record for the zone may have been added.
|
||||||
*/
|
*/
|
||||||
result = create_validator(val, &siginfo->signer,
|
result = create_validator(val, &siginfo->signer,
|
||||||
dns_rdatatype_dnskey,
|
dns_rdatatype_dnskey,
|
||||||
@@ -1899,7 +1905,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
|
|||||||
" data as insecure also.");
|
" data as insecure also.");
|
||||||
return (DNS_R_MUSTBESECURE);
|
return (DNS_R_MUSTBESECURE);
|
||||||
}
|
}
|
||||||
markanswer(val);
|
markanswer(val, "validate");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1958,7 +1964,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val->key = NULL;
|
val->key = NULL;
|
||||||
if ((val->attributes & VALATTR_NEEDNOQNAME) != 0) {
|
if (NEEDNOQNAME(val)) {
|
||||||
if (val->event->message == NULL) {
|
if (val->event->message == NULL) {
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"no message available for noqname proof");
|
"no message available for noqname proof");
|
||||||
@@ -2157,7 +2163,7 @@ dlv_validatezonekey(dns_validator_t *val) {
|
|||||||
}
|
}
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"no supported algorithm/digest (dlv)");
|
"no supported algorithm/digest (dlv)");
|
||||||
markanswer(val);
|
markanswer(val, "dlv_validatezonekey (2)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
} else
|
} else
|
||||||
return (DNS_R_NOVALIDSIG);
|
return (DNS_R_NOVALIDSIG);
|
||||||
@@ -2212,7 +2218,11 @@ validatezonekey(dns_validator_t *val) {
|
|||||||
result = dns_rdataset_next(val->event->sigrdataset))
|
result = dns_rdataset_next(val->event->sigrdataset))
|
||||||
{
|
{
|
||||||
dns_keynode_t *keynode = NULL;
|
dns_keynode_t *keynode = NULL;
|
||||||
|
dns_fixedname_t fixed;
|
||||||
|
dns_name_t *found;
|
||||||
|
|
||||||
|
dns_fixedname_init(&fixed);
|
||||||
|
found = dns_fixedname_name(&fixed);
|
||||||
dns_rdata_reset(&sigrdata);
|
dns_rdata_reset(&sigrdata);
|
||||||
dns_rdataset_current(val->event->sigrdataset,
|
dns_rdataset_current(val->event->sigrdataset,
|
||||||
&sigrdata);
|
&sigrdata);
|
||||||
@@ -2227,6 +2237,23 @@ validatezonekey(dns_validator_t *val) {
|
|||||||
sig.algorithm,
|
sig.algorithm,
|
||||||
sig.keyid,
|
sig.keyid,
|
||||||
&keynode);
|
&keynode);
|
||||||
|
if (result == ISC_R_NOTFOUND &&
|
||||||
|
dns_keytable_finddeepestmatch(val->keytable,
|
||||||
|
val->event->name, found) != ISC_R_SUCCESS) {
|
||||||
|
if (val->mustbesecure) {
|
||||||
|
validator_log(val, ISC_LOG_WARNING,
|
||||||
|
"must be secure failure, "
|
||||||
|
"not beneath secure root");
|
||||||
|
return (DNS_R_MUSTBESECURE);
|
||||||
|
} else
|
||||||
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
|
"not beneath secure root");
|
||||||
|
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
||||||
|
markanswer(val, "validatezonekey (1)");
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
return (startfinddlvsep(val, dns_rootname));
|
||||||
|
}
|
||||||
if (result == DNS_R_PARTIALMATCH ||
|
if (result == DNS_R_PARTIALMATCH ||
|
||||||
result == ISC_R_SUCCESS)
|
result == ISC_R_SUCCESS)
|
||||||
atsep = ISC_TRUE;
|
atsep = ISC_TRUE;
|
||||||
@@ -2308,7 +2335,8 @@ validatezonekey(dns_validator_t *val) {
|
|||||||
* We have DS records.
|
* We have DS records.
|
||||||
*/
|
*/
|
||||||
val->dsset = &val->frdataset;
|
val->dsset = &val->frdataset;
|
||||||
if (DNS_TRUST_PENDING(val->frdataset.trust) &&
|
if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
|
||||||
|
DNS_TRUST_ANSWER(val->frdataset.trust)) &&
|
||||||
dns_rdataset_isassociated(&val->fsigrdataset))
|
dns_rdataset_isassociated(&val->fsigrdataset))
|
||||||
{
|
{
|
||||||
result = create_validator(val,
|
result = create_validator(val,
|
||||||
@@ -2372,7 +2400,7 @@ validatezonekey(dns_validator_t *val) {
|
|||||||
" insecure DS");
|
" insecure DS");
|
||||||
return (DNS_R_MUSTBESECURE);
|
return (DNS_R_MUSTBESECURE);
|
||||||
}
|
}
|
||||||
markanswer(val);
|
markanswer(val, "validatezonekey (2)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2519,7 +2547,7 @@ validatezonekey(dns_validator_t *val) {
|
|||||||
}
|
}
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"no supported algorithm/digest (DS)");
|
"no supported algorithm/digest (DS)");
|
||||||
markanswer(val);
|
markanswer(val, "validatezonekey (3)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
validator_log(val, ISC_LOG_INFO,
|
validator_log(val, ISC_LOG_INFO,
|
||||||
@@ -2548,6 +2576,80 @@ start_positive_validation(dns_validator_t *val) {
|
|||||||
return (validatezonekey(val));
|
return (validatezonekey(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* val_rdataset_first and val_rdataset_next provide iteration methods
|
||||||
|
* that hide whether we are iterating across a message or a negative
|
||||||
|
* cache rdataset.
|
||||||
|
*/
|
||||||
|
static isc_result_t
|
||||||
|
val_rdataset_first(dns_validator_t *val, dns_name_t **namep,
|
||||||
|
dns_rdataset_t **rdatasetp)
|
||||||
|
{
|
||||||
|
dns_message_t *message = val->event->message;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
REQUIRE(rdatasetp != NULL);
|
||||||
|
REQUIRE(namep != NULL);
|
||||||
|
if (message == NULL) {
|
||||||
|
REQUIRE(*rdatasetp != NULL);
|
||||||
|
REQUIRE(*namep != NULL);
|
||||||
|
} else {
|
||||||
|
REQUIRE(*rdatasetp == NULL);
|
||||||
|
REQUIRE(*namep == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message != NULL) {
|
||||||
|
result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
dns_message_currentname(message, DNS_SECTION_AUTHORITY, namep);
|
||||||
|
*rdatasetp = ISC_LIST_HEAD((*namep)->list);
|
||||||
|
INSIST(*rdatasetp != NULL);
|
||||||
|
} else {
|
||||||
|
result = dns_rdataset_first(val->event->rdataset);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
dns_ncache_current(val->event->rdataset, *namep,
|
||||||
|
*rdatasetp);
|
||||||
|
}
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
val_rdataset_next(dns_validator_t *val, dns_name_t **namep,
|
||||||
|
dns_rdataset_t **rdatasetp)
|
||||||
|
{
|
||||||
|
dns_message_t *message = val->event->message;
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
REQUIRE(rdatasetp != NULL && *rdatasetp != NULL);
|
||||||
|
REQUIRE(namep != NULL && *namep != NULL);
|
||||||
|
|
||||||
|
if (message != NULL) {
|
||||||
|
dns_rdataset_t *rdataset = *rdatasetp;
|
||||||
|
rdataset = ISC_LIST_NEXT(rdataset, link);
|
||||||
|
if (rdataset == NULL) {
|
||||||
|
*namep = NULL;
|
||||||
|
result = dns_message_nextname(message,
|
||||||
|
DNS_SECTION_AUTHORITY);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
dns_message_currentname(message,
|
||||||
|
DNS_SECTION_AUTHORITY,
|
||||||
|
namep);
|
||||||
|
rdataset = ISC_LIST_HEAD((*namep)->list);
|
||||||
|
INSIST(rdataset != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*rdatasetp = rdataset;
|
||||||
|
} else {
|
||||||
|
dns_rdataset_disassociate(*rdatasetp);
|
||||||
|
result = dns_rdataset_next(val->event->rdataset);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
dns_ncache_current(val->event->rdataset, *namep,
|
||||||
|
*rdatasetp);
|
||||||
|
}
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Look for NODATA at the wildcard and NOWILDCARD proofs in the
|
* Look for NODATA at the wildcard and NOWILDCARD proofs in the
|
||||||
* previously validated NSEC records. As these proofs are mutually
|
* previously validated NSEC records. As these proofs are mutually
|
||||||
@@ -2559,12 +2661,14 @@ start_positive_validation(dns_validator_t *val) {
|
|||||||
static isc_result_t
|
static isc_result_t
|
||||||
checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
|
checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
|
||||||
{
|
{
|
||||||
dns_name_t *name, *wild;
|
dns_name_t *name, *wild, tname;
|
||||||
dns_message_t *message = val->event->message;
|
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_boolean_t exists, data;
|
isc_boolean_t exists, data;
|
||||||
char namebuf[DNS_NAME_FORMATSIZE];
|
char namebuf[DNS_NAME_FORMATSIZE];
|
||||||
|
dns_rdataset_t *rdataset, trdataset;
|
||||||
|
|
||||||
|
dns_name_init(&tname, NULL);
|
||||||
|
dns_rdataset_init(&trdataset);
|
||||||
wild = dns_fixedname_name(&val->wild);
|
wild = dns_fixedname_name(&val->wild);
|
||||||
|
|
||||||
if (dns_name_countlabels(wild) == 0) {
|
if (dns_name_countlabels(wild) == 0) {
|
||||||
@@ -2576,41 +2680,25 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
|
|||||||
dns_name_format(wild, namebuf, sizeof(namebuf));
|
dns_name_format(wild, namebuf, sizeof(namebuf));
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf);
|
validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf);
|
||||||
|
|
||||||
for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
|
if (val->event->message == NULL) {
|
||||||
result == ISC_R_SUCCESS;
|
name = &tname;
|
||||||
result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
|
rdataset = &trdataset;
|
||||||
{
|
} else {
|
||||||
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
|
|
||||||
|
|
||||||
name = NULL;
|
name = NULL;
|
||||||
dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
|
rdataset = NULL;
|
||||||
|
|
||||||
for (rdataset = ISC_LIST_HEAD(name->list);
|
|
||||||
rdataset != NULL;
|
|
||||||
rdataset = ISC_LIST_NEXT(rdataset, link))
|
|
||||||
{
|
|
||||||
if (rdataset->type != type)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
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)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (rdataset->trust != dns_trust_secure)
|
for (result = val_rdataset_first(val, &name, &rdataset);
|
||||||
|
result == ISC_R_SUCCESS;
|
||||||
|
result = val_rdataset_next(val, &name, &rdataset))
|
||||||
|
{
|
||||||
|
if (rdataset->type != type ||
|
||||||
|
rdataset->trust != dns_trust_secure)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (rdataset->type == dns_rdatatype_nsec &&
|
if (rdataset->type == dns_rdatatype_nsec &&
|
||||||
((val->attributes & VALATTR_NEEDNODATA) != 0 ||
|
(NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
|
||||||
(val->attributes & VALATTR_NEEDNOWILDCARD) != 0) &&
|
!FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
|
||||||
(val->attributes & VALATTR_FOUNDNODATA) == 0 &&
|
|
||||||
(val->attributes & VALATTR_FOUNDNOWILDCARD) == 0 &&
|
|
||||||
nsecnoexistnodata(val, wild, name, rdataset,
|
nsecnoexistnodata(val, wild, name, rdataset,
|
||||||
&exists, &data, NULL)
|
&exists, &data, NULL)
|
||||||
== ISC_R_SUCCESS)
|
== ISC_R_SUCCESS)
|
||||||
@@ -2627,14 +2715,14 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
|
|||||||
if (!exists && NEEDNOQNAME(val))
|
if (!exists && NEEDNOQNAME(val))
|
||||||
proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
|
proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
|
||||||
name;
|
name;
|
||||||
|
if (dns_rdataset_isassociated(&trdataset))
|
||||||
|
dns_rdataset_disassociate(&trdataset);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rdataset->type == dns_rdatatype_nsec3 &&
|
if (rdataset->type == dns_rdatatype_nsec3 &&
|
||||||
((val->attributes & VALATTR_NEEDNODATA) != 0 ||
|
(NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
|
||||||
(val->attributes & VALATTR_NEEDNOWILDCARD) != 0) &&
|
!FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
|
||||||
(val->attributes & VALATTR_FOUNDNODATA) == 0 &&
|
|
||||||
(val->attributes & VALATTR_FOUNDNOWILDCARD) == 0 &&
|
|
||||||
nsec3noexistnodata(val, wild, name, rdataset,
|
nsec3noexistnodata(val, wild, name, rdataset,
|
||||||
zonename, &exists, &data,
|
zonename, &exists, &data,
|
||||||
NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL,
|
||||||
@@ -2652,27 +2740,31 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
|
|||||||
if (!exists && NEEDNOQNAME(val))
|
if (!exists && NEEDNOQNAME(val))
|
||||||
proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
|
proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
|
||||||
name;
|
name;
|
||||||
|
if (dns_rdataset_isassociated(&trdataset))
|
||||||
|
dns_rdataset_disassociate(&trdataset);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (result == ISC_R_NOMORE)
|
if (result == ISC_R_NOMORE)
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
|
if (dns_rdataset_isassociated(&trdataset))
|
||||||
|
dns_rdataset_disassociate(&trdataset);
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
findnsec3proofs(dns_validator_t *val) {
|
findnsec3proofs(dns_validator_t *val) {
|
||||||
dns_name_t *name;
|
dns_name_t *name, tname;
|
||||||
dns_message_t *message = val->event->message;
|
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_boolean_t exists, data, optout, unknown;
|
isc_boolean_t exists, data, optout, unknown;
|
||||||
isc_boolean_t setclosest, setnearest;
|
isc_boolean_t setclosest, setnearest;
|
||||||
dns_fixedname_t fclosest, fnearest, fzonename;
|
dns_fixedname_t fclosest, fnearest, fzonename;
|
||||||
dns_name_t *closest, *nearest, *zonename;
|
dns_name_t *closest, *nearest, *zonename;
|
||||||
dns_name_t **proofs = val->event->proofs;
|
dns_name_t **proofs = val->event->proofs;
|
||||||
|
dns_rdataset_t *rdataset, trdataset;
|
||||||
|
|
||||||
|
dns_name_init(&tname, NULL);
|
||||||
|
dns_rdataset_init(&trdataset);
|
||||||
dns_fixedname_init(&fclosest);
|
dns_fixedname_init(&fclosest);
|
||||||
dns_fixedname_init(&fnearest);
|
dns_fixedname_init(&fnearest);
|
||||||
dns_fixedname_init(&fzonename);
|
dns_fixedname_init(&fzonename);
|
||||||
@@ -2680,34 +2772,20 @@ findnsec3proofs(dns_validator_t *val) {
|
|||||||
nearest = dns_fixedname_name(&fnearest);
|
nearest = dns_fixedname_name(&fnearest);
|
||||||
zonename = dns_fixedname_name(&fzonename);
|
zonename = dns_fixedname_name(&fzonename);
|
||||||
|
|
||||||
for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
|
if (val->event->message == NULL) {
|
||||||
result == ISC_R_SUCCESS;
|
name = &tname;
|
||||||
result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
|
rdataset = &trdataset;
|
||||||
{
|
} else {
|
||||||
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
|
|
||||||
|
|
||||||
name = NULL;
|
name = NULL;
|
||||||
dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
|
rdataset = NULL;
|
||||||
|
|
||||||
for (rdataset = ISC_LIST_HEAD(name->list);
|
|
||||||
rdataset != NULL;
|
|
||||||
rdataset = ISC_LIST_NEXT(rdataset, link))
|
|
||||||
{
|
|
||||||
if (rdataset->type != dns_rdatatype_nsec3)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (sigrdataset = ISC_LIST_HEAD(name->list);
|
|
||||||
sigrdataset != NULL;
|
|
||||||
sigrdataset = ISC_LIST_NEXT(sigrdataset, link))
|
|
||||||
{
|
|
||||||
if (sigrdataset->type == dns_rdatatype_rrsig &&
|
|
||||||
sigrdataset->covers == dns_rdatatype_nsec3)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (sigrdataset == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (rdataset->trust != dns_trust_secure)
|
for (result = val_rdataset_first(val, &name, &rdataset);
|
||||||
|
result == ISC_R_SUCCESS;
|
||||||
|
result = val_rdataset_next(val, &name, &rdataset))
|
||||||
|
{
|
||||||
|
if (rdataset->type != dns_rdatatype_nsec3 ||
|
||||||
|
rdataset->trust != dns_trust_secure)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result = nsec3noexistnodata(val, val->event->name,
|
result = nsec3noexistnodata(val, val->event->name,
|
||||||
@@ -2715,7 +2793,9 @@ findnsec3proofs(dns_validator_t *val) {
|
|||||||
zonename, NULL, NULL, NULL,
|
zonename, NULL, NULL, NULL,
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS)
|
if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) {
|
||||||
|
if (dns_rdataset_isassociated(&trdataset))
|
||||||
|
dns_rdataset_disassociate(&trdataset);
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2725,34 +2805,12 @@ findnsec3proofs(dns_validator_t *val) {
|
|||||||
if (dns_name_countlabels(zonename) == 0)
|
if (dns_name_countlabels(zonename) == 0)
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
|
for (result = val_rdataset_first(val, &name, &rdataset);
|
||||||
result == ISC_R_SUCCESS;
|
result == ISC_R_SUCCESS;
|
||||||
result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
|
result = val_rdataset_next(val, &name, &rdataset))
|
||||||
{
|
{
|
||||||
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
|
if (rdataset->type != dns_rdatatype_nsec3 ||
|
||||||
|
rdataset->trust != dns_trust_secure)
|
||||||
name = NULL;
|
|
||||||
dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
|
|
||||||
|
|
||||||
for (rdataset = ISC_LIST_HEAD(name->list);
|
|
||||||
rdataset != NULL;
|
|
||||||
rdataset = ISC_LIST_NEXT(rdataset, link))
|
|
||||||
{
|
|
||||||
if (rdataset->type != dns_rdatatype_nsec3)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (sigrdataset = ISC_LIST_HEAD(name->list);
|
|
||||||
sigrdataset != NULL;
|
|
||||||
sigrdataset = ISC_LIST_NEXT(sigrdataset, link))
|
|
||||||
{
|
|
||||||
if (sigrdataset->type == dns_rdatatype_rrsig &&
|
|
||||||
sigrdataset->covers == dns_rdatatype_nsec3)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (sigrdataset == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (rdataset->trust != dns_trust_secure)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2762,11 +2820,9 @@ findnsec3proofs(dns_validator_t *val) {
|
|||||||
setclosest = setnearest = ISC_FALSE;
|
setclosest = setnearest = ISC_FALSE;
|
||||||
optout = ISC_FALSE;
|
optout = ISC_FALSE;
|
||||||
unknown = ISC_FALSE;
|
unknown = ISC_FALSE;
|
||||||
result = nsec3noexistnodata(val, val->event->name,
|
(void)nsec3noexistnodata(val, val->event->name, name, rdataset,
|
||||||
name, rdataset,
|
zonename, &exists, &data, &optout,
|
||||||
zonename, &exists,
|
&unknown, &setclosest, &setnearest,
|
||||||
&data, &optout, &unknown,
|
|
||||||
&setclosest, &setnearest,
|
|
||||||
closest, nearest);
|
closest, nearest);
|
||||||
if (setclosest)
|
if (setclosest)
|
||||||
proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
|
proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
|
||||||
@@ -2785,8 +2841,7 @@ findnsec3proofs(dns_validator_t *val) {
|
|||||||
val->attributes |= VALATTR_FOUNDOPTOUT;
|
val->attributes |= VALATTR_FOUNDOPTOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (result == ISC_R_NOMORE)
|
||||||
if (result != ISC_R_NOMORE)
|
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2813,11 +2868,8 @@ findnsec3proofs(dns_validator_t *val) {
|
|||||||
/*
|
/*
|
||||||
* Do we need to check for the wildcard?
|
* Do we need to check for the wildcard?
|
||||||
*/
|
*/
|
||||||
if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0 &&
|
if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
|
||||||
(val->attributes & VALATTR_FOUNDCLOSEST) != 0 &&
|
((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
|
||||||
(((val->attributes & VALATTR_NEEDNODATA) != 0 &&
|
|
||||||
(val->attributes & VALATTR_FOUNDNODATA) == 0) ||
|
|
||||||
(val->attributes & VALATTR_NEEDNOWILDCARD) != 0)) {
|
|
||||||
result = checkwildcard(val, dns_rdatatype_nsec3, zonename);
|
result = checkwildcard(val, dns_rdatatype_nsec3, zonename);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
@@ -2826,29 +2878,20 @@ findnsec3proofs(dns_validator_t *val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Prove a negative answer is good or that there is a NOQNAME when the
|
* Validate the authority section records.
|
||||||
* answer is from a wildcard.
|
|
||||||
*
|
|
||||||
* Loop through the authority section looking for NODATA, NOWILDCARD
|
|
||||||
* and NOQNAME proofs in the NSEC records by calling authvalidated().
|
|
||||||
*
|
|
||||||
* If the required proofs are found we are done.
|
|
||||||
*
|
|
||||||
* If the proofs are not found attempt to prove this is a unsecure
|
|
||||||
* response.
|
|
||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
validate_authority(dns_validator_t *val, isc_boolean_t resume) {
|
||||||
dns_name_t *name;
|
dns_name_t *name;
|
||||||
dns_message_t *message = val->event->message;
|
dns_message_t *message = val->event->message;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
if (!resume)
|
if (!resume) {
|
||||||
result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
|
result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
|
||||||
else {
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
} else
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;
|
for (;
|
||||||
result == ISC_R_SUCCESS;
|
result == ISC_R_SUCCESS;
|
||||||
@@ -2911,16 +2954,123 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
|||||||
result = create_validator(val, name, rdataset->type,
|
result = create_validator(val, name, rdataset->type,
|
||||||
rdataset, sigrdataset,
|
rdataset, sigrdataset,
|
||||||
authvalidated,
|
authvalidated,
|
||||||
"nsecvalidate");
|
"validate_authority");
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
val->authcount++;
|
val->authcount++;
|
||||||
return (DNS_R_WAIT);
|
return (DNS_R_WAIT);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result == ISC_R_NOMORE)
|
if (result == ISC_R_NOMORE)
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Validate the ncache elements.
|
||||||
|
*/
|
||||||
|
static isc_result_t
|
||||||
|
validate_ncache(dns_validator_t *val, isc_boolean_t resume) {
|
||||||
|
dns_name_t *name;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
if (!resume) {
|
||||||
|
result = dns_rdataset_first(val->event->rdataset);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
} else
|
||||||
|
result = dns_rdataset_next(val->event->rdataset);
|
||||||
|
|
||||||
|
for (;
|
||||||
|
result == ISC_R_SUCCESS;
|
||||||
|
result = dns_rdataset_next(val->event->rdataset))
|
||||||
|
{
|
||||||
|
dns_rdataset_t *rdataset, *sigrdataset = NULL;
|
||||||
|
|
||||||
|
if (dns_rdataset_isassociated(&val->frdataset))
|
||||||
|
dns_rdataset_disassociate(&val->frdataset);
|
||||||
|
if (dns_rdataset_isassociated(&val->fsigrdataset))
|
||||||
|
dns_rdataset_disassociate(&val->fsigrdataset);
|
||||||
|
|
||||||
|
dns_fixedname_init(&val->fname);
|
||||||
|
name = dns_fixedname_name(&val->fname);
|
||||||
|
rdataset = &val->frdataset;
|
||||||
|
dns_ncache_current(val->event->rdataset, name, rdataset);
|
||||||
|
|
||||||
|
if (val->frdataset.type == dns_rdatatype_rrsig)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
result = dns_ncache_getsigrdataset(val->event->rdataset, name,
|
||||||
|
rdataset->type,
|
||||||
|
&val->fsigrdataset);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
sigrdataset = &val->fsigrdataset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a signed zone is missing the zone key, bad
|
||||||
|
* things could happen. A query for data in the zone
|
||||||
|
* would lead to a query for the zone key, which
|
||||||
|
* would return a negative answer, which would contain
|
||||||
|
* an SOA and an NSEC signed by the missing key, which
|
||||||
|
* would trigger another query for the DNSKEY (since
|
||||||
|
* the first one is still in progress), and go into an
|
||||||
|
* infinite loop. Avoid that.
|
||||||
|
*/
|
||||||
|
if (val->event->type == dns_rdatatype_dnskey &&
|
||||||
|
dns_name_equal(name, val->event->name))
|
||||||
|
{
|
||||||
|
dns_rdata_t nsec = DNS_RDATA_INIT;
|
||||||
|
|
||||||
|
if (rdataset->type != dns_rdatatype_nsec)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
result = dns_rdataset_first(rdataset);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
dns_rdataset_current(rdataset, &nsec);
|
||||||
|
if (dns_nsec_typepresent(&nsec,
|
||||||
|
dns_rdatatype_soa))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
val->currentset = rdataset;
|
||||||
|
result = create_validator(val, name, rdataset->type,
|
||||||
|
rdataset, sigrdataset,
|
||||||
|
authvalidated,
|
||||||
|
"validate_ncache");
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
val->authcount++;
|
||||||
|
return (DNS_R_WAIT);
|
||||||
|
}
|
||||||
|
if (result == ISC_R_NOMORE)
|
||||||
|
result = ISC_R_SUCCESS;
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Prove a negative answer is good or that there is a NOQNAME when the
|
||||||
|
* answer is from a wildcard.
|
||||||
|
*
|
||||||
|
* Loop through the authority section looking for NODATA, NOWILDCARD
|
||||||
|
* and NOQNAME proofs in the NSEC records by calling authvalidated().
|
||||||
|
*
|
||||||
|
* If the required proofs are found we are done.
|
||||||
|
*
|
||||||
|
* If the proofs are not found attempt to prove this is a unsecure
|
||||||
|
* response.
|
||||||
|
*/
|
||||||
|
static isc_result_t
|
||||||
|
nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
if (resume)
|
||||||
|
validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
|
||||||
|
|
||||||
|
if (val->event->message == NULL)
|
||||||
|
result = validate_ncache(val, resume);
|
||||||
|
else
|
||||||
|
result = validate_authority(val, resume);
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
|
|
||||||
@@ -2928,29 +3078,26 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
|||||||
* Do we only need to check for NOQNAME? To get here we must have
|
* Do we only need to check for NOQNAME? To get here we must have
|
||||||
* had a secure wildcard answer.
|
* had a secure wildcard answer.
|
||||||
*/
|
*/
|
||||||
if ((val->attributes & VALATTR_NEEDNODATA) == 0 &&
|
if (!NEEDNODATA(val) && !NEEDNOWILDCARD(val) && NEEDNOQNAME(val)) {
|
||||||
(val->attributes & VALATTR_NEEDNOWILDCARD) == 0 &&
|
if (!FOUNDNOQNAME(val))
|
||||||
(val->attributes & VALATTR_NEEDNOQNAME) != 0) {
|
|
||||||
if ((val->attributes & VALATTR_FOUNDNOQNAME) == 0)
|
|
||||||
findnsec3proofs(val);
|
findnsec3proofs(val);
|
||||||
if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0 &&
|
if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val)) {
|
||||||
(val->attributes & VALATTR_FOUNDCLOSEST) != 0) {
|
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"marking as secure, noqname proof found");
|
"marking as secure, noqname proof found");
|
||||||
marksecure(val->event);
|
marksecure(val->event);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
} else if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0 &&
|
} else if (FOUNDOPTOUT(val) &&
|
||||||
dns_name_countlabels(dns_fixedname_name(&val->wild))
|
dns_name_countlabels(dns_fixedname_name(&val->wild))
|
||||||
!= 0) {
|
!= 0) {
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"optout proof found");
|
"optout proof found");
|
||||||
val->event->optout = ISC_TRUE;
|
val->event->optout = ISC_TRUE;
|
||||||
markanswer(val);
|
markanswer(val, "nsecvalidate (1)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
} else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) {
|
} else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) {
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"unknown NSEC3 hash algorithm found");
|
"unknown NSEC3 hash algorithm found");
|
||||||
markanswer(val);
|
markanswer(val, "nsecvalidate (2)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
@@ -2958,35 +3105,29 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
|||||||
return (DNS_R_NOVALIDNSEC);
|
return (DNS_R_NOVALIDNSEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((val->attributes & VALATTR_FOUNDNOQNAME) == 0 &&
|
if (!FOUNDNOQNAME(val) && !FOUNDNODATA(val))
|
||||||
(val->attributes & VALATTR_FOUNDNODATA) == 0)
|
|
||||||
findnsec3proofs(val);
|
findnsec3proofs(val);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do we need to check for the wildcard?
|
* Do we need to check for the wildcard?
|
||||||
*/
|
*/
|
||||||
if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0 &&
|
if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
|
||||||
(val->attributes & VALATTR_FOUNDCLOSEST) != 0 &&
|
((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
|
||||||
(((val->attributes & VALATTR_NEEDNODATA) != 0 &&
|
|
||||||
(val->attributes & VALATTR_FOUNDNODATA) == 0) ||
|
|
||||||
(val->attributes & VALATTR_NEEDNOWILDCARD) != 0)) {
|
|
||||||
result = checkwildcard(val, dns_rdatatype_nsec, NULL);
|
result = checkwildcard(val, dns_rdatatype_nsec, NULL);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((val->attributes & VALATTR_NEEDNODATA) != 0 &&
|
if ((NEEDNODATA(val) && (FOUNDNODATA(val) || FOUNDOPTOUT(val))) ||
|
||||||
((val->attributes & VALATTR_FOUNDNODATA) != 0 ||
|
(NEEDNOQNAME(val) && FOUNDNOQNAME(val) &&
|
||||||
(val->attributes & VALATTR_FOUNDOPTOUT) != 0)) ||
|
NEEDNOWILDCARD(val) && FOUNDNOWILDCARD(val) &&
|
||||||
((val->attributes & VALATTR_NEEDNOQNAME) != 0 &&
|
FOUNDCLOSEST(val))) {
|
||||||
(val->attributes & VALATTR_FOUNDNOQNAME) != 0 &&
|
|
||||||
(val->attributes & VALATTR_NEEDNOWILDCARD) != 0 &&
|
|
||||||
(val->attributes & VALATTR_FOUNDNOWILDCARD) != 0 &&
|
|
||||||
(val->attributes & VALATTR_FOUNDCLOSEST) != 0)) {
|
|
||||||
if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
|
if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
|
||||||
val->event->optout = ISC_TRUE;
|
val->event->optout = ISC_TRUE;
|
||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"nonexistence proof(s) found");
|
"nonexistence proof(s) found");
|
||||||
|
if (val->event->message == NULL)
|
||||||
|
marksecure(val->event);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3054,7 +3195,7 @@ dlvvalidated(isc_task_t *task, isc_event_t *event) {
|
|||||||
if (dlv_algorithm_supported(val))
|
if (dlv_algorithm_supported(val))
|
||||||
dlv_validator_start(val);
|
dlv_validator_start(val);
|
||||||
else {
|
else {
|
||||||
markanswer(val);
|
markanswer(val, "dlvvalidated");
|
||||||
validator_done(val, ISC_R_SUCCESS);
|
validator_done(val, ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -3123,7 +3264,7 @@ dlvfetched(isc_task_t *task, isc_event_t *event) {
|
|||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"DLV %s found with no supported algorithms",
|
"DLV %s found with no supported algorithms",
|
||||||
namebuf);
|
namebuf);
|
||||||
markanswer(val);
|
markanswer(val, "dlvfetched (1)");
|
||||||
validator_done(val, ISC_R_SUCCESS);
|
validator_done(val, ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
} else if (eresult == DNS_R_NXRRSET ||
|
} else if (eresult == DNS_R_NXRRSET ||
|
||||||
@@ -3142,12 +3283,12 @@ dlvfetched(isc_task_t *task, isc_event_t *event) {
|
|||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"DLV %s found with no supported "
|
"DLV %s found with no supported "
|
||||||
"algorithms", namebuf);
|
"algorithms", namebuf);
|
||||||
markanswer(val);
|
markanswer(val, "dlvfetched (2)");
|
||||||
validator_done(val, ISC_R_SUCCESS);
|
validator_done(val, ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
} else if (result == ISC_R_NOTFOUND) {
|
} else if (result == ISC_R_NOTFOUND) {
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
|
validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
|
||||||
markanswer(val);
|
markanswer(val, "dlvfetched (3)");
|
||||||
validator_done(val, ISC_R_SUCCESS);
|
validator_done(val, ISC_R_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
|
validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
|
||||||
@@ -3198,7 +3339,7 @@ startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
|
|||||||
result = finddlvsep(val, ISC_FALSE);
|
result = finddlvsep(val, ISC_FALSE);
|
||||||
if (result == ISC_R_NOTFOUND) {
|
if (result == ISC_R_NOTFOUND) {
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
|
validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
|
||||||
markanswer(val);
|
markanswer(val, "startfinddlvsep (1)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
@@ -3215,7 +3356,7 @@ startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
|
|||||||
}
|
}
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported "
|
validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported "
|
||||||
"algorithms", namebuf);
|
"algorithms", namebuf);
|
||||||
markanswer(val);
|
markanswer(val, "startfinddlvsep (2)");
|
||||||
validator_done(val, ISC_R_SUCCESS);
|
validator_done(val, ISC_R_SUCCESS);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -3412,7 +3553,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
|
|||||||
validator_log(val, ISC_LOG_DEBUG(3),
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
"not beneath secure root");
|
"not beneath secure root");
|
||||||
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
||||||
markanswer(val);
|
markanswer(val, "proveunsecure (1)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
return (startfinddlvsep(val, dns_rootname));
|
return (startfinddlvsep(val, dns_rootname));
|
||||||
@@ -3451,7 +3592,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
|
|||||||
"no supported algorithm/digest (%s/DS)",
|
"no supported algorithm/digest (%s/DS)",
|
||||||
namebuf);
|
namebuf);
|
||||||
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
||||||
markanswer(val);
|
markanswer(val, "proveunsecure (2)");
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -3481,16 +3622,21 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
|
|||||||
namebuf);
|
namebuf);
|
||||||
|
|
||||||
result = view_find(val, tname, dns_rdatatype_ds);
|
result = view_find(val, tname, dns_rdatatype_ds);
|
||||||
|
|
||||||
if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
|
if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
|
||||||
/*
|
/*
|
||||||
* There is no DS. If this is a delegation,
|
* There is no DS. If this is a delegation,
|
||||||
* we may be done.
|
* we may be done.
|
||||||
*/
|
*/
|
||||||
if (DNS_TRUST_PENDING(val->frdataset.trust)) {
|
/*
|
||||||
result = create_fetch(val, tname,
|
* If we have "trust == answer" then this namespace
|
||||||
|
* has switched from insecure to should be secure.
|
||||||
|
*/
|
||||||
|
if (DNS_TRUST_PENDING(val->frdataset.trust) ||
|
||||||
|
DNS_TRUST_ANSWER(val->frdataset.trust)) {
|
||||||
|
result = create_validator(val, tname,
|
||||||
dns_rdatatype_ds,
|
dns_rdatatype_ds,
|
||||||
dsfetched2,
|
&val->frdataset,
|
||||||
|
NULL, dsvalidated,
|
||||||
"proveunsecure");
|
"proveunsecure");
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -3514,7 +3660,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
|
|||||||
return (DNS_R_MUSTBESECURE);
|
return (DNS_R_MUSTBESECURE);
|
||||||
}
|
}
|
||||||
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
||||||
markanswer(val);
|
markanswer(val, "proveunsecure (3)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
return (startfinddlvsep(val, tname));
|
return (startfinddlvsep(val, tname));
|
||||||
@@ -3541,7 +3687,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
|
|||||||
return (DNS_R_MUSTBESECURE);
|
return (DNS_R_MUSTBESECURE);
|
||||||
}
|
}
|
||||||
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
if (val->view->dlv == NULL || DLVTRIED(val)) {
|
||||||
markanswer(val);
|
markanswer(val, "proveunsecure (4)");
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
return (startfinddlvsep(val, tname));
|
return (startfinddlvsep(val, tname));
|
||||||
@@ -3569,7 +3715,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
|
|||||||
}
|
}
|
||||||
if (val->view->dlv == NULL ||
|
if (val->view->dlv == NULL ||
|
||||||
DLVTRIED(val)) {
|
DLVTRIED(val)) {
|
||||||
markanswer(val);
|
markanswer(val,
|
||||||
|
"proveunsecure (5)");
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -3585,6 +3732,9 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
|
|||||||
result = DNS_R_NOVALIDSIG;
|
result = DNS_R_NOVALIDSIG;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Validate / re-validate answer.
|
||||||
|
*/
|
||||||
result = create_validator(val, tname, dns_rdatatype_ds,
|
result = create_validator(val, tname, dns_rdatatype_ds,
|
||||||
&val->frdataset,
|
&val->frdataset,
|
||||||
&val->fsigrdataset,
|
&val->fsigrdataset,
|
||||||
@@ -3634,13 +3784,6 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if ((val->attributes & VALATTR_NEEDOPTOUT) == 0 &&
|
|
||||||
val->event->message != NULL) {
|
|
||||||
val->attributes |= VALATTR_NEEDOPTOUT;
|
|
||||||
return (nsecvalidate(val, ISC_FALSE));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/* Couldn't complete insecurity proof */
|
/* Couldn't complete insecurity proof */
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
|
validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
|
||||||
return (DNS_R_NOTINSECURE);
|
return (DNS_R_NOTINSECURE);
|
||||||
@@ -3736,7 +3879,8 @@ validator_start(isc_task_t *task, isc_event_t *event) {
|
|||||||
if (result == DNS_R_NOTINSECURE)
|
if (result == DNS_R_NOTINSECURE)
|
||||||
result = saved_result;
|
result = saved_result;
|
||||||
}
|
}
|
||||||
} else if (val->event->rdataset != NULL) {
|
} else if (val->event->rdataset != NULL &&
|
||||||
|
val->event->rdataset->type != 0) {
|
||||||
/*
|
/*
|
||||||
* This is either an unsecure subdomain or a response from
|
* This is either an unsecure subdomain or a response from
|
||||||
* a broken server.
|
* a broken server.
|
||||||
@@ -3766,6 +3910,21 @@ validator_start(isc_task_t *task, isc_event_t *event) {
|
|||||||
} else
|
} else
|
||||||
val->attributes |= VALATTR_NEEDNODATA;
|
val->attributes |= VALATTR_NEEDNODATA;
|
||||||
result = nsecvalidate(val, ISC_FALSE);
|
result = nsecvalidate(val, ISC_FALSE);
|
||||||
|
} else if (val->event->rdataset != NULL &&
|
||||||
|
val->event->rdataset->type == 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is a nonexistence validation.
|
||||||
|
*/
|
||||||
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
|
"attempting negative response validation");
|
||||||
|
|
||||||
|
if (val->event->rdataset->covers == dns_rdatatype_any) {
|
||||||
|
val->attributes |= VALATTR_NEEDNOQNAME;
|
||||||
|
val->attributes |= VALATTR_NEEDNOWILDCARD;
|
||||||
|
} else
|
||||||
|
val->attributes |= VALATTR_NEEDNODATA;
|
||||||
|
result = nsecvalidate(val, ISC_FALSE);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* This shouldn't happen.
|
* This shouldn't happen.
|
||||||
|
Reference in New Issue
Block a user