1251. [func] Generate DNSSEC wildcard proofs.

This commit is contained in:
Mark Andrews
2002-07-19 03:50:42 +00:00
parent 0d993c02ba
commit c54c1eaf26
9 changed files with 150 additions and 28 deletions
+2
View File
@@ -1,3 +1,5 @@
1251. [func] Generate DNSSEC wildcard proofs.
1250. [bug] When processing events (non-threaded) only allow
the task one chance to use to use its quantum.
+2 -2
View File
@@ -112,8 +112,8 @@ BIND 9.2.0
BIND 9.2 is capable of acting as an authoritative server
for DNSSEC secured zones. This functionality is believed to
be stable and complete except for lacking support for wildcard
records in secure zones.
be stable and complete except for lacking support for
verifications involving wildcard records in secure zones.
When acting as a caching server, BIND 9.2 can be configured
to perform DNSSEC secure resolution on behalf of its clients.
+2 -6
View File
@@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dnssec-signzone.c,v 1.161 2002/07/01 07:37:38 marka Exp $ */
/* $Id: dnssec-signzone.c,v 1.162 2002/07/19 03:50:41 marka Exp $ */
#include <config.h>
@@ -701,12 +701,8 @@ warnwild(const char *name) {
if (warned++ != 0)
return;
fprintf(stderr, "%s: warning: BIND 9 doesn't properly "
"handle wildcards in secure zones:\n",
"validate responses containing wildcards.\n",
program);
fprintf(stderr, "\t- wildcard nonexistence proof is "
"not generated by the server\n");
fprintf(stderr, "\t- wildcard nonexistence proof is "
"not required by the resolver\n");
}
static isc_boolean_t
+122 -4
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.c,v 1.224 2002/07/17 06:09:41 marka Exp $ */
/* $Id: query.c,v 1.225 2002/07/19 03:50:42 marka Exp $ */
#include <config.h>
@@ -2109,6 +2109,113 @@ query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node) {
query_putrdataset(client, &sigrdataset);
}
static void
query_addwildcardproof(ns_client_t *client, dns_db_t *db,
isc_boolean_t ispositive)
{
isc_buffer_t *dbuf, b;
dns_name_t *fname;
dns_rdataset_t *rdataset, *sigrdataset;
dns_fixedname_t tfixed;
dns_name_t *tname;
dns_dbnode_t *node;
unsigned int options;
unsigned int odepth, ndepth, i;
isc_result_t result;
CTRACE("query_addwildcardproof");
fname = NULL;
rdataset = NULL;
sigrdataset = NULL;
node = NULL;
options = client->query.dboptions | DNS_DBFIND_NOWILD;
if (ispositive) {
/*
* We'll need some resources...
*/
dbuf = query_getnamebuf(client);
if (dbuf == NULL)
goto cleanup;
fname = query_newname(client, dbuf, &b);
rdataset = query_newrdataset(client);
sigrdataset = query_newrdataset(client);
if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
goto cleanup;
result = dns_db_find(db, client->query.qname, NULL,
dns_rdatatype_nxt, options, 0, &node,
fname, rdataset, sigrdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
if (result == DNS_R_NXDOMAIN)
query_addrrset(client, &fname, &rdataset, &sigrdataset,
dbuf, DNS_SECTION_AUTHORITY);
else {
query_putrdataset(client, &rdataset);
query_putrdataset(client, &sigrdataset);
if (fname != NULL)
query_releasename(client, &fname);
}
}
odepth = dns_name_depth(dns_db_origin(db));
ndepth = dns_name_depth(client->query.qname);
for (i = ndepth - 1; i >= odepth; i--) {
/*
* We'll need some resources...
*/
dbuf = query_getnamebuf(client);
if (dbuf == NULL)
goto cleanup;
fname = query_newname(client, dbuf, &b);
rdataset = query_newrdataset(client);
sigrdataset = query_newrdataset(client);
if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
goto cleanup;
dns_fixedname_init(&tfixed);
tname = dns_fixedname_name(&tfixed);
result = dns_name_splitatdepth(client->query.qname,
i, NULL, tname);
if (result != ISC_R_SUCCESS)
continue;
result = dns_name_concatenate(dns_wildcardname, tname, tname,
NULL);
if (result != ISC_R_SUCCESS)
continue;
result = dns_db_find(db, tname, NULL, dns_rdatatype_nxt,
client->query.dboptions, 0, &node,
fname, rdataset, sigrdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
/*
* If this returns success, we've found the wildcard for a
* successful answer, so we're done.
*/
if (result == ISC_R_SUCCESS && ispositive)
break;
if (result != DNS_R_NXDOMAIN) {
query_putrdataset(client, &rdataset);
query_putrdataset(client, &sigrdataset);
query_releasename(client, &fname);
continue;
}
query_addrrset(client, &fname, &rdataset, &sigrdataset,
dbuf, DNS_SECTION_AUTHORITY);
}
cleanup:
if (rdataset != NULL)
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
query_putrdataset(client, &sigrdataset);
if (fname != NULL)
query_releasename(client, &fname);
}
static void
query_resume(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
@@ -2379,7 +2486,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_rdataset_t **sigrdatasetp;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdatasetiter_t *rdsiter;
isc_boolean_t want_restart, authoritative, is_zone;
isc_boolean_t want_restart, authoritative, is_zone, need_wildcardproof;
unsigned int n, nlabels, nbits;
dns_namereln_t namereln;
int order;
@@ -2530,17 +2637,22 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
}
options = client->query.dboptions;
if (WANTDNSSEC(client) && is_zone && dns_db_issecure(db))
options |= DNS_DBFIND_INDICATEWILD;
/*
* Now look for an answer in the database.
*/
result = dns_db_find(db, client->query.qname, version, type,
client->query.dboptions, client->now,
options, client->now,
&node, fname, rdataset, sigrdataset);
resume:
CTRACE("query_find: resume");
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_WILDCARD:
/*
* This case is handled in the main line below.
*/
@@ -2824,10 +2936,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* Add NXT record if we found one.
*/
if (dns_rdataset_isassociated(rdataset)) {
if (WANTDNSSEC(client))
if (WANTDNSSEC(client)) {
query_addrrset(client, &fname, &rdataset,
&sigrdataset,
NULL, DNS_SECTION_AUTHORITY);
query_addwildcardproof(client, db, ISC_FALSE);
}
}
/*
* Set message rcode.
@@ -3028,6 +3142,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
goto cleanup;
}
need_wildcardproof = ISC_TF(result == DNS_R_WILDCARD);
if (type == dns_rdatatype_any) {
/*
* XXXRTH Need to handle zonecuts with special case
@@ -3137,6 +3253,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
*/
INSIST(rdataset == NULL);
}
if (need_wildcardproof)
query_addwildcardproof(client, db, ISC_TRUE);
addauth:
CTRACE("query_find: addauth");
+1 -9
View File
@@ -37,14 +37,6 @@ When acting as an authoritative name server, BIND9 includes KEY, SIG
and NXT records in responses as specified in RFC2535 when the request
has the DO flag set in the query.
Response generation for wildcard records in secure zones is not fully
supported. Responses indicating the nonexistence of a name include a
NXT record proving the nonexistence of the name itself, but do not
include any NXT records to prove the nonexistence of a matching
wildcard record. Positive responses resulting from wildcard expansion
do not include the NXT records to prove the nonexistence of a
non-wildcard match or a more specific wildcard match.
Secure Resolution
@@ -88,4 +80,4 @@ future as we consider them inferior to the use of TSIG or SIG(0) to
ensure the integrity of zone transfers.
$Id: dnssec,v 1.16 2001/11/20 23:32:09 gson Exp $
$Id: dnssec,v 1.17 2002/07/19 03:50:42 marka Exp $
+10 -1
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: db.h,v 1.68 2001/12/08 00:37:07 bwelling Exp $ */
/* $Id: db.h,v 1.69 2002/07/19 03:50:42 marka Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -187,6 +187,7 @@ struct dns_db {
#define DNS_DBFIND_PENDINGOK 0x08
#define DNS_DBFIND_NOEXACT 0x10
#define DNS_DBFIND_FORCENXT 0x20
#define DNS_DBFIND_INDICATEWILD 0x40
/*
* Options that can be specified for dns_db_addrdataset().
@@ -690,6 +691,14 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* ISC_R_SUCCESS The desired node and type were
* found.
*
* DNS_R_WILDCARD The desired node and type were
* found after performing
* wildcard matching. This is
* only returned if the
* DNS_DBFIND_INDICATEWILD
* option is set; otherwise
* ISC_R_SUCCESS is returned.
*
* DNS_R_GLUE The desired node and type were
* found, but are glue. This
* result can only occur if
+3 -2
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: result.h,v 1.90 2002/07/19 02:34:56 marka Exp $ */
/* $Id: result.h,v 1.91 2002/07/19 03:50:42 marka Exp $ */
#ifndef DNS_RESULT_H
#define DNS_RESULT_H 1
@@ -122,8 +122,9 @@
#define DNS_R_EXPECTEDRESPONSE (ISC_RESULTCLASS_DNS + 83)
#define DNS_R_NOVALIDDS (ISC_RESULTCLASS_DNS + 84)
#define DNS_R_NSISADDRESS (ISC_RESULTCLASS_DNS + 85)
#define DNS_R_WILDCARD (ISC_RESULTCLASS_DNS + 86)
#define DNS_R_NRESULTS 86 /* Number of results */
#define DNS_R_NRESULTS 87 /* Number of results */
/*
* DNS wire format rcodes.
+5 -2
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbtdb.c,v 1.176 2002/06/17 04:01:20 marka Exp $ */
/* $Id: rbtdb.c,v 1.177 2002/07/19 03:50:42 marka Exp $ */
/*
* Principal Author: Bob Halley
@@ -2113,7 +2113,10 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
/*
* An ordinary successful query!
*/
result = ISC_R_SUCCESS;
if (wild && (search.options & DNS_DBFIND_INDICATEWILD) != 0)
result = DNS_R_WILDCARD;
else
result = ISC_R_SUCCESS;
}
if (nodep != NULL) {
+3 -2
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: result.c,v 1.100 2002/07/19 02:34:56 marka Exp $ */
/* $Id: result.c,v 1.101 2002/07/19 03:50:42 marka Exp $ */
#include <config.h>
@@ -128,7 +128,8 @@ static const char *text[DNS_R_NRESULTS] = {
"expected a response", /* 83 DNS_R_EXPECTEDRESPONSE */
"no valid DS", /* 84 DNS_R_NOVALIDDS */
"NS is an address" /* 85 DNS_R_NSISADDRESS */
"NS is an address", /* 85 DNS_R_NSISADDRESS */
"wildcard" /* 86 DNS_R_WILDCARD */
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {