1331. [func] Generate DNSSEC wildcard proofs.

This commit is contained in:
Mark Andrews 2003-08-18 07:35:54 +00:00
parent 2bb0b0009e
commit d930eaf77b
9 changed files with 151 additions and 27 deletions

View file

@ -1,6 +1,8 @@
1332. [func] Report the current serial with periodic commits when
rolling forward the journal.
1331. [func] Generate DNSSEC wildcard proofs.
1329. [func] named-checkzone will now check if nameservers that
appear to be IP addresses. Available modes "fail",
"warn" (default) and "ignore" the results of the

4
README
View file

@ -125,8 +125,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.

View file

@ -17,7 +17,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dnssec-signzone.c,v 1.139.2.2.4.3 2003/08/11 05:28:08 marka Exp $ */
/* $Id: dnssec-signzone.c,v 1.139.2.2.4.4 2003/08/18 07:35:48 marka Exp $ */
#include <config.h>
@ -794,12 +794,8 @@ signname(dns_dbnode_t *node, dns_name_t *name) {
dns_name_format(name, namestr, sizeof namestr);
if (warnwild++ == 0) {
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");
}
fprintf(stderr, "%s: warning: wildcard name seen: %s\n",
program, namestr);

View file

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.c,v 1.198.2.13.4.6 2003/08/15 03:22:42 marka Exp $ */
/* $Id: query.c,v 1.198.2.13.4.7 2003/08/18 07:35:49 marka Exp $ */
#include <config.h>
@ -2033,6 +2033,114 @@ query_addbestns(ns_client_t *client) {
}
}
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);
if (rdataset != NULL)
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
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_addrrset(client, &fname, &rdataset, &sigrdataset,
dbuf, DNS_SECTION_AUTHORITY);
if (rdataset != NULL)
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
query_putrdataset(client, &sigrdataset);
if (fname != NULL)
query_releasename(client, &fname);
}
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;
@ -2380,7 +2488,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;
@ -2392,6 +2500,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_zone_t *zone;
dns_rdata_cname_t cname;
dns_rdata_dname_t dname;
unsigned int options;
isc_boolean_t empty_wild;
CTRACE("query_find");
@ -2416,6 +2525,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
version = NULL;
zone = NULL;
empty_wild = ISC_FALSE;
options = 0;
if (event != NULL) {
/*
@ -2528,11 +2638,15 @@ 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);
/*
@ -2596,6 +2710,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
CTRACE("query_find: resume");
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_WILDCARD:
/*
* This case is handled in the main line below.
*/
@ -2882,10 +2997,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.
@ -3089,6 +3206,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
@ -3198,6 +3317,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");

View file

@ -38,14 +38,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
@ -89,4 +81,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.14.2.6 2003/03/06 04:38:20 marka Exp $
$Id: dnssec,v 1.14.2.6.4.1 2003/08/18 07:35:49 marka Exp $

View file

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: db.h,v 1.67 2001/08/28 03:58:13 marka Exp $ */
/* $Id: db.h,v 1.67.12.1 2003/08/18 07:35:54 marka Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@ -186,6 +186,7 @@ struct dns_db {
#define DNS_DBFIND_NOWILD 0x04
#define DNS_DBFIND_PENDINGOK 0x08
#define DNS_DBFIND_NOEXACT 0x10
#define DNS_DBFIND_INDICATEWILD 0x40
/*
* Options that can be specified for dns_db_addrdataset().
@ -684,6 +685,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

View file

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: result.h,v 1.81.2.7.2.1 2003/08/18 05:56:58 marka Exp $ */
/* $Id: result.h,v 1.81.2.7.2.2 2003/08/18 07:35:54 marka Exp $ */
#ifndef DNS_RESULT_H
#define DNS_RESULT_H 1
@ -121,6 +121,7 @@
#define DNS_R_UNKNOWNFLAG (ISC_RESULTCLASS_DNS + 82)
#define DNS_R_EXPECTEDRESPONSE (ISC_RESULTCLASS_DNS + 83)
#define DNS_R_NSISADDRESS (ISC_RESULTCLASS_DNS + 85)
#define DNS_R_WILDCARD (ISC_RESULTCLASS_DNS + 86)
#define DNS_R_EMPTYNAME (ISC_RESULTCLASS_DNS + 92)
#define DNS_R_EMPTYWILD (ISC_RESULTCLASS_DNS + 93)
#define DNS_R_BADBITMAP (ISC_RESULTCLASS_DNS + 94)

View file

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbtdb.c,v 1.168.2.11 2003/07/22 04:03:43 marka Exp $ */
/* $Id: rbtdb.c,v 1.168.2.11.2.1 2003/08/18 07:35:53 marka Exp $ */
/*
* Principal Author: Bob Halley
@ -2286,7 +2286,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) {

View file

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: result.c,v 1.90.2.9.2.1 2003/08/18 05:56:56 marka Exp $ */
/* $Id: result.c,v 1.90.2.9.2.2 2003/08/18 07:35:53 marka Exp $ */
#include <config.h>
@ -129,7 +129,7 @@ static const char *text[DNS_R_NRESULTS] = {
"<unused 84>",
"NS is an address", /* 85 DNS_R_NSISADDRESS */
"<unused 86>",
"wildcard", /* 86 DNS_R_WILDCARD */
"<unused 87>",
"<unused 88>",
"<unused 89>",