3571e53040
patches for easier mirroring, to eliminate a special copy, to make www.freebsd.org/security a full copy of security.freebsd.org and be eventually be the same. For now files are just sitting there. The symlinks are missing. Discussed on: www (repository location) Discussed with: simon (so)
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)
|
|
@@ -3070,7 +3070,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
|
|
@@ -3584,7 +3584,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)
|
|
@@ -3847,6 +3847,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.
|
|
@@ -3883,12 +3884,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
|
|
@@ -4236,7 +4259,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)
|
|
@@ -1140,7 +1140,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))
|
|
{
|
|
/*
|
|
@@ -1155,7 +1155,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.
|
|
@@ -1763,7 +1763,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,
|
|
@@ -1776,7 +1776,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.
|
|
*/
|
|
@@ -2586,7 +2586,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;
|
|
@@ -3335,6 +3337,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *
|
|
unsigned int options;
|
|
isc_boolean_t empty_wild;
|
|
dns_rdataset_t *noqname;
|
|
+ dns_rdataset_t tmprdataset;
|
|
+ unsigned int dboptions;
|
|
|
|
CTRACE("query_find");
|
|
|
|
@@ -3544,9 +3548,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");
|