summaryrefslogtreecommitdiff
path: root/lib/dns
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns')
-rw-r--r--lib/dns/api2
-rw-r--r--lib/dns/include/dns/db.h24
-rw-r--r--lib/dns/rbtdb.c40
-rw-r--r--lib/dns/validator.c58
4 files changed, 91 insertions, 33 deletions
diff --git a/lib/dns/api b/lib/dns/api
index 251eda6f4d415..02321262cdeda 100644
--- a/lib/dns/api
+++ b/lib/dns/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 39
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 1
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index 6086bff5f703f..32b4d3f754128 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.h,v 1.76.18.14 2009/01/19 00:36:28 marka Exp $ */
+/* $Id: db.h,v 1.76.18.16 2010/11/17 23:45:12 tbox Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -184,13 +184,15 @@ struct dns_db {
/*%
* Options that can be specified for dns_db_find().
*/
-#define DNS_DBFIND_GLUEOK 0x01
-#define DNS_DBFIND_VALIDATEGLUE 0x02
-#define DNS_DBFIND_NOWILD 0x04
-#define DNS_DBFIND_PENDINGOK 0x08
-#define DNS_DBFIND_NOEXACT 0x10
-#define DNS_DBFIND_FORCENSEC 0x20
-#define DNS_DBFIND_COVERINGNSEC 0x40
+#define DNS_DBFIND_GLUEOK 0x0001
+#define DNS_DBFIND_VALIDATEGLUE 0x0002
+#define DNS_DBFIND_NOWILD 0x0004
+#define DNS_DBFIND_PENDINGOK 0x0008
+#define DNS_DBFIND_NOEXACT 0x0010
+#define DNS_DBFIND_FORCENSEC 0x0020
+#define DNS_DBFIND_COVERINGNSEC 0x0040
+#define DNS_DBFIND_FORCENSEC3 0x0080
+#define DNS_DBFIND_ADDITIONALOK 0x0100
/*@}*/
/*@{*/
@@ -649,6 +651,10 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* For cache databases, glue is any rdataset with a trust of
* dns_trust_glue.
*
+ * \li If 'options' does not have #DNS_DBFIND_ADDITIONALOK set, then no
+ * additional records will be returned. Only caches can have
+ * rdataset with trust dns_trust_additional.
+ *
* \li If 'options' does not have #DNS_DBFIND_PENDINGOK set, then no
* pending data will be returned. This option is only meaningful for
* cache databases.
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index fb561db3cf9dd..0aafb9ffb14f3 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.196.18.61 2010/02/26 23:46:36 tbox Exp $ */
+/* $Id: rbtdb.c,v 1.196.18.64 2010/11/17 10:21:01 marka Exp $ */
/*! \file */
@@ -3594,6 +3594,8 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* If we didn't find what we were looking for...
*/
if (found == NULL ||
+ (found->trust == dns_trust_additional &&
+ ((options & DNS_DBFIND_ADDITIONALOK) == 0)) ||
(found->trust == dns_trust_glue &&
((options & DNS_DBFIND_GLUEOK) == 0)) ||
(DNS_TRUST_PENDING(found->trust) &&
@@ -4406,14 +4408,14 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
dns_rdataset_t *addedrdataset, isc_stdtime_t now)
{
rbtdb_changed_t *changed = NULL;
- rdatasetheader_t *topheader, *topheader_prev, *header;
+ rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader;
unsigned char *merged;
isc_result_t result;
isc_boolean_t header_nx;
isc_boolean_t newheader_nx;
isc_boolean_t merge;
dns_rdatatype_t rdtype, covers;
- rbtdb_rdatatype_t negtype;
+ rbtdb_rdatatype_t negtype, sigtype;
dns_trust_t trust;
/*
@@ -4450,7 +4452,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
newheader_nx = NONEXISTENT(newheader) ? ISC_TRUE : ISC_FALSE;
topheader_prev = NULL;
-
+ sigheader = NULL;
negtype = 0;
if (rbtversion == NULL && !newheader_nx) {
rdtype = RBTDB_RDATATYPE_BASE(newheader->type);
@@ -4459,26 +4461,35 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* We're adding a negative cache entry.
*/
covers = RBTDB_RDATATYPE_EXT(newheader->type);
- if (covers == dns_rdatatype_any) {
+ sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig,
+ covers);
+
+ for (topheader = rbtnode->data;
+ topheader != NULL;
+ topheader = topheader->next) {
/*
- * We're adding an negative cache entry
+ * If we're adding an negative cache entry
* which covers all types (NXDOMAIN,
* NODATA(QTYPE=ANY)).
*
* We make all other data stale so that the
* only rdataset that can be found at this
* node is the negative cache entry.
+ *
+ * Otherwise look for any RRSIGs of the
+ * given type so they can be marked stale
+ * later.
*/
- for (topheader = rbtnode->data;
- topheader != NULL;
- topheader = topheader->next) {
+ if (covers == dns_rdatatype_any) {
topheader->ttl = 0;
topheader->attributes |=
RDATASET_ATTR_STALE;
- }
- rbtnode->dirty = 1;
- goto find_header;
+ rbtnode->dirty = 1;
+ } else if (topheader->type == sigtype)
+ sigheader = topheader;
}
+ if (covers == dns_rdatatype_any)
+ goto find_header;
negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
} else {
/*
@@ -4700,6 +4711,11 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
if (rbtversion == NULL) {
header->ttl = 0;
header->attributes |= RDATASET_ATTR_STALE;
+ if (sigheader != NULL) {
+ sigheader->ttl = 0;
+ sigheader->attributes |=
+ RDATASET_ATTR_STALE;
+ }
}
}
} else {
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 6a1d0c9a04b44..bea5301773c28 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.119.18.59 2010/09/02 07:21:53 marka Exp $ */
+/* $Id: validator.c,v 1.119.18.60 2010/11/16 04:17:44 marka Exp $ */
/*! \file */
@@ -304,6 +304,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
+ isc_result_t saved_result;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@@ -340,6 +341,17 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
val->keyset = &val->frdataset;
}
result = validate(val, ISC_TRUE);
+ if (result == DNS_R_NOVALIDSIG &&
+ (val->attributes & VALATTR_TRIEDVERIFY) == 0)
+ {
+ saved_result = result;
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "falling back to insecurity proof");
+ val->attributes |= VALATTR_INSECURITY;
+ result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+ if (result == DNS_R_NOTINSECURE)
+ result = saved_result;
+ }
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
@@ -530,6 +542,7 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
+ isc_result_t saved_result;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
@@ -556,6 +569,17 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
if (val->frdataset.trust >= dns_trust_secure)
(void) get_dst_key(val, val->siginfo, &val->frdataset);
result = validate(val, ISC_TRUE);
+ if (result == DNS_R_NOVALIDSIG &&
+ (val->attributes & VALATTR_TRIEDVERIFY) == 0)
+ {
+ saved_result = result;
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "falling back to insecurity proof");
+ val->attributes |= VALATTR_INSECURITY;
+ result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+ if (result == DNS_R_NOTINSECURE)
+ result = saved_result;
+ }
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
@@ -1480,9 +1504,11 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
* was known and "sufficiently good".
*/
if (!dns_resolver_algorithm_supported(val->view->resolver,
- event->name,
- val->siginfo->algorithm))
+ event->name,
+ val->siginfo->algorithm)) {
+ resume = ISC_FALSE;
continue;
+ }
if (!resume) {
result = get_key(val, val->siginfo);
@@ -1493,16 +1519,12 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
}
/*
- * The key is insecure, so mark the data as insecure also.
+ * There isn't a secure DNSKEY for this signature so move
+ * onto the next RRSIG.
*/
if (val->key == NULL) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
- return (DNS_R_MUSTBESECURE);
- }
- markanswer(val, "validate");
- return (ISC_R_SUCCESS);
+ resume = ISC_FALSE;
+ continue;
}
do {
@@ -3123,6 +3145,20 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
*/
result = DNS_R_NOVALIDNSEC;
goto out;
+ } else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
+ DNS_TRUST_ANSWER(val->frdataset.trust)) {
+ /*
+ * If we have "trust == answer" then this namespace
+ * has switched from insecure to should be secure.
+ */
+ result = create_validator(val, tname,
+ dns_rdatatype_ds,
+ &val->frdataset,
+ NULL, dsvalidated,
+ "proveunsecure");
+ if (result != ISC_R_SUCCESS)
+ goto out;
+ return (DNS_R_WAIT);
} else if (val->frdataset.trust < dns_trust_secure) {
/*
* This shouldn't happen, since the negative