mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 07:35:26 +00:00
1558. [func] New DNSSEC 'disable-algorithms'. Support entry into
child zones for which we don't have a supported algorithm. Such child zones are treated as unsigned. 1557. [func] Implement missing DNSSEC tests for * NOQNAME proof with wildcard answers. * NOWILDARD proof with NXDOMAIN. Cache and return NOQNAME with wildcard answers.
This commit is contained in:
9
CHANGES
9
CHANGES
@@ -1,3 +1,12 @@
|
||||
1558. [func] New DNSSEC 'disable-algorithms'. Support entry into
|
||||
child zones for which we don't have a supported
|
||||
algorithm. Such child zones are treated as unsigned.
|
||||
|
||||
1557. [func] Implement missing DNSSEC tests for
|
||||
* NOQNAME proof with wildcard answers.
|
||||
* NOWILDARD proof with NXDOMAIN.
|
||||
Cache and return NOQNAME with wildcard answers.
|
||||
|
||||
1556. [placeholder] rt6427
|
||||
|
||||
1555. [func] 'rrset-order cyclic' no longer has a random starting
|
||||
|
@@ -17,7 +17,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dnssec-signzone.c,v 1.172 2004/01/05 05:14:51 marka Exp $ */
|
||||
/* $Id: dnssec-signzone.c,v 1.173 2004/01/14 02:06:48 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -729,19 +729,6 @@ nsec_setbit(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdatatype_t type,
|
||||
return (answer);
|
||||
}
|
||||
|
||||
static void
|
||||
warnwild(const char *name) {
|
||||
static int warned = 0;
|
||||
|
||||
fprintf(stderr, "%s: warning: wildcard name seen: %s\n",
|
||||
program, name);
|
||||
if (warned++ != 0)
|
||||
return;
|
||||
fprintf(stderr, "%s: warning: BIND 9 doesn't properly "
|
||||
"validate responses containing wildcards.\n",
|
||||
program);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
delegation(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) {
|
||||
dns_rdataset_t nsset;
|
||||
@@ -782,9 +769,6 @@ signname(dns_dbnode_t *node, dns_name_t *name) {
|
||||
|
||||
dns_name_format(name, namestr, sizeof(namestr));
|
||||
|
||||
if (dns_name_iswildcard(name))
|
||||
warnwild(namestr);
|
||||
|
||||
atorigin = dns_name_equal(name, gorigin);
|
||||
|
||||
/*
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.h,v 1.34 2002/11/27 09:52:46 marka Exp $ */
|
||||
/* $Id: query.h,v 1.35 2004/01/14 02:06:49 marka Exp $ */
|
||||
|
||||
#ifndef NAMED_QUERY_H
|
||||
#define NAMED_QUERY_H 1
|
||||
@@ -64,7 +64,7 @@ struct ns_query {
|
||||
#define NS_QUERYATTR_QUERYOKVALID 0x0040
|
||||
#define NS_QUERYATTR_QUERYOK 0x0080
|
||||
#define NS_QUERYATTR_WANTRECURSION 0x0100
|
||||
/* unused */
|
||||
#define NS_QUERYATTR_SECURE 0x0200
|
||||
#define NS_QUERYATTR_NOAUTHORITY 0x0400
|
||||
#define NS_QUERYATTR_NOADDITIONAL 0x0800
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.c,v 1.248 2003/10/25 00:31:06 jinmei Exp $ */
|
||||
/* $Id: query.c,v 1.249 2004/01/14 02:06:48 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -69,6 +69,8 @@
|
||||
NS_QUERYATTR_NOAUTHORITY) != 0)
|
||||
#define NOADDITIONAL(c) (((c)->query.attributes & \
|
||||
NS_QUERYATTR_NOADDITIONAL) != 0)
|
||||
#define SECURE(c) (((c)->query.attributes & \
|
||||
NS_QUERYATTR_SECURE) != 0)
|
||||
|
||||
#if 0
|
||||
#define CTRACE(m) isc_log_write(ns_g_lctx, \
|
||||
@@ -241,7 +243,8 @@ query_reset(ns_client_t *client, isc_boolean_t everything) {
|
||||
query_maybeputqname(client);
|
||||
|
||||
client->query.attributes = (NS_QUERYATTR_RECURSIONOK |
|
||||
NS_QUERYATTR_CACHEOK);
|
||||
NS_QUERYATTR_CACHEOK |
|
||||
NS_QUERYATTR_SECURE);
|
||||
client->query.restarts = 0;
|
||||
client->query.timerset = ISC_FALSE;
|
||||
client->query.origqname = NULL;
|
||||
@@ -1337,6 +1340,10 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
|
||||
query_releasename(client, namep);
|
||||
}
|
||||
|
||||
if (rdataset->trust != dns_trust_secure &&
|
||||
(section == DNS_SECTION_ANSWER ||
|
||||
section == DNS_SECTION_AUTHORITY))
|
||||
client->query.attributes &= ~NS_QUERYATTR_SECURE;
|
||||
/*
|
||||
* Note: we only add SIGs if we've added the type they cover, so
|
||||
* we do not need to check if the SIG rdataset is already in the
|
||||
@@ -1728,6 +1735,11 @@ query_addbestns(ns_client_t *client) {
|
||||
(sigrdataset != NULL && sigrdataset->trust == dns_trust_pending)))
|
||||
goto cleanup;
|
||||
|
||||
if (WANTDNSSEC(client) && SECURE(client) &&
|
||||
(rdataset->trust == dns_trust_glue ||
|
||||
(sigrdataset != NULL && sigrdataset->trust == dns_trust_glue)))
|
||||
goto cleanup;
|
||||
|
||||
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
|
||||
@@ -2245,13 +2257,51 @@ setup_query_sortlist(ns_client_t *client) {
|
||||
dns_message_setsortorder(client->message, order, order_arg);
|
||||
}
|
||||
|
||||
static void
|
||||
query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) {
|
||||
isc_buffer_t *dbuf, b;
|
||||
dns_name_t *fname;
|
||||
dns_rdataset_t *nsec, *nsecsig;
|
||||
isc_result_t result = ISC_R_NOMEMORY;
|
||||
|
||||
CTRACE("query_addnoqnameproof");
|
||||
|
||||
fname = NULL;
|
||||
nsec = NULL;
|
||||
nsecsig = NULL;
|
||||
|
||||
dbuf = query_getnamebuf(client);
|
||||
if (dbuf == NULL)
|
||||
goto cleanup;
|
||||
fname = query_newname(client, dbuf, &b);
|
||||
nsec = query_newrdataset(client);
|
||||
nsecsig = query_newrdataset(client);
|
||||
if (fname == NULL || nsec == NULL || nsecsig == NULL)
|
||||
goto cleanup;
|
||||
|
||||
result = dns_rdataset_getnoqname(rdataset, fname, nsec, nsecsig);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
query_addrrset(client, &fname, &nsec, &nsecsig, dbuf,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
|
||||
cleanup:
|
||||
if (nsec != NULL)
|
||||
query_putrdataset(client, &nsec);
|
||||
if (nsecsig != NULL)
|
||||
query_putrdataset(client, &nsecsig);
|
||||
if (fname != NULL)
|
||||
query_releasename(client, &fname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the bulk of query processing for the current query of 'client'.
|
||||
* If 'event' is non-NULL, we are returning from recursion and 'qtype'
|
||||
* is ignored. Otherwise, 'qtype' is the query type.
|
||||
*/
|
||||
static void
|
||||
query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) {
|
||||
query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
{
|
||||
dns_db_t *db, *zdb;
|
||||
dns_dbnode_t *node;
|
||||
dns_rdatatype_t type;
|
||||
@@ -2276,6 +2326,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
dns_rdata_dname_t dname;
|
||||
unsigned int options;
|
||||
isc_boolean_t empty_wild;
|
||||
dns_rdataset_t *noqname;
|
||||
|
||||
CTRACE("query_find");
|
||||
|
||||
@@ -2852,8 +2903,15 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
NULL);
|
||||
need_wildcardproof = ISC_TRUE;
|
||||
}
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0 &&
|
||||
WANTDNSSEC(client))
|
||||
noqname = rdataset;
|
||||
else
|
||||
noqname = NULL;
|
||||
query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
if (noqname != NULL)
|
||||
query_addnoqnameproof(client, noqname);
|
||||
/*
|
||||
* We set the PARTIALANSWER attribute so that if anything goes
|
||||
* wrong later on, we'll return what we've got so far.
|
||||
@@ -3124,8 +3182,15 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
sigrdatasetp = &sigrdataset;
|
||||
else
|
||||
sigrdatasetp = NULL;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0 &&
|
||||
WANTDNSSEC(client))
|
||||
noqname = rdataset;
|
||||
else
|
||||
noqname = NULL;
|
||||
query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
if (noqname != NULL)
|
||||
query_addnoqnameproof(client, noqname);
|
||||
/*
|
||||
* We shouldn't ever fail to add 'rdataset'
|
||||
* because it's already in the answer.
|
||||
@@ -3385,6 +3450,13 @@ ns_query_start(ns_client_t *client) {
|
||||
client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow glue NS records to be added to the authority section
|
||||
* if the answer is secure.
|
||||
*/
|
||||
if (message->flags & DNS_MESSAGEFLAG_CD)
|
||||
client->query.attributes &= ~NS_QUERYATTR_SECURE;
|
||||
|
||||
/*
|
||||
* This is an ordinary query.
|
||||
*/
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: server.c,v 1.407 2004/01/05 06:56:44 marka Exp $ */
|
||||
/* $Id: server.c,v 1.408 2004/01/14 02:06:49 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <isc/file.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/lex.h>
|
||||
#include <isc/parseint.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/resource.h>
|
||||
#include <isc/stdio.h>
|
||||
@@ -56,6 +57,7 @@
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/resolver.h>
|
||||
#include <dns/rootns.h>
|
||||
#include <dns/secalg.h>
|
||||
#include <dns/stats.h>
|
||||
#include <dns/tkey.h>
|
||||
#include <dns/view.h>
|
||||
@@ -583,6 +585,52 @@ configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
disable_algorithms(cfg_obj_t *disabled, dns_resolver_t *resolver) {
|
||||
isc_result_t result;
|
||||
cfg_obj_t *algorithms;
|
||||
cfg_listelt_t *element;
|
||||
const char *str;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name;
|
||||
isc_buffer_t b;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
name = dns_fixedname_name(&fixed);
|
||||
str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
|
||||
isc_buffer_init(&b, str, strlen(str));
|
||||
isc_buffer_add(&b, strlen(str));
|
||||
CHECK(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL));
|
||||
|
||||
algorithms = cfg_tuple_get(disabled, "algorithms");
|
||||
for (element = cfg_list_first(algorithms);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
isc_textregion_t r;
|
||||
dns_secalg_t alg;
|
||||
|
||||
r.base = cfg_obj_asstring(cfg_listelt_value(element));
|
||||
r.length = strlen(r.base);
|
||||
|
||||
result = dns_secalg_fromtext(&alg, &r);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_uint8_t ui;
|
||||
result = isc_parse_uint8(&ui, r.base, 10);
|
||||
alg = ui;
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(cfg_listelt_value(element),
|
||||
ns_g_lctx, ISC_LOG_ERROR,
|
||||
"invalid algorithm");
|
||||
CHECK(result);
|
||||
}
|
||||
CHECK(dns_resolver_disable_algorithm(resolver, name, alg));
|
||||
}
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure 'view' according to 'vconfig', taking defaults from 'config'
|
||||
* where values are missing in 'vconfig'.
|
||||
@@ -603,6 +651,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
|
||||
cfg_obj_t *forwarders;
|
||||
cfg_obj_t *alternates;
|
||||
cfg_obj_t *zonelist;
|
||||
cfg_obj_t *disabled;
|
||||
cfg_obj_t *obj;
|
||||
cfg_listelt_t *element;
|
||||
in_port_t port;
|
||||
@@ -794,6 +843,20 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
|
||||
udpsize = 4096;
|
||||
dns_resolver_setudpsize(view->resolver, udpsize);
|
||||
|
||||
/*
|
||||
* Set supported DNSSEC algorithms.
|
||||
*/
|
||||
dns_resolver_reset_algorithms(view->resolver);
|
||||
disabled = NULL;
|
||||
(void)ns_config_get(maps, "disable-algorithms", &disabled);
|
||||
if (disabled != NULL) {
|
||||
for (element = cfg_list_first(disabled);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
CHECK(disable_algorithms(cfg_listelt_value(element),
|
||||
view->resolver));
|
||||
}
|
||||
|
||||
/*
|
||||
* A global or view "forwarders" option, if present,
|
||||
* creates an entry for "." in the forwarding table.
|
||||
|
@@ -15,7 +15,7 @@
|
||||
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: sign.sh,v 1.16 2003/10/26 21:33:45 marka Exp $
|
||||
# $Id: sign.sh,v 1.17 2004/01/14 02:06:49 marka Exp $
|
||||
|
||||
SYSTEMTESTTOP=../..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
@@ -51,3 +51,4 @@ EOF
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
cp trusted.conf ../ns3/trusted.conf
|
||||
cp trusted.conf ../ns4/trusted.conf
|
||||
cp trusted.conf ../ns6/trusted.conf
|
||||
|
@@ -13,7 +13,7 @@
|
||||
; NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
; WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: example.db.in,v 1.11 2002/02/20 03:33:53 marka Exp $
|
||||
; $Id: example.db.in,v 1.12 2004/01/14 02:06:49 marka Exp $
|
||||
|
||||
$TTL 300 ; 5 minutes
|
||||
@ IN SOA mname1. . (
|
||||
@@ -70,3 +70,5 @@ z A 10.0.0.26
|
||||
|
||||
keyless NS ns.keyless
|
||||
ns.keyless A 10.53.0.3
|
||||
|
||||
*.wild A 10.0.0.27
|
||||
|
@@ -13,7 +13,7 @@
|
||||
; NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
; WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: private.secure.example.db.in,v 1.6 2001/01/09 21:42:53 bwelling Exp $
|
||||
; $Id: private.secure.example.db.in,v 1.7 2004/01/14 02:06:49 marka Exp $
|
||||
|
||||
$TTL 300 ; 5 minutes
|
||||
@ IN SOA mname1. . (
|
||||
@@ -30,3 +30,5 @@ a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
d A 10.0.0.4
|
||||
z A 10.0.0.26
|
||||
private2secure-nxdomain CNAME r.example.
|
||||
*.wild CNAME s.example.
|
||||
|
@@ -15,7 +15,7 @@
|
||||
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: tests.sh,v 1.41 2002/07/19 06:20:24 marka Exp $
|
||||
# $Id: tests.sh,v 1.42 2004/01/14 02:06:49 marka Exp $
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
@@ -48,6 +48,16 @@ n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking positive wildcard validation ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS a.wild.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
|
||||
$DIG $DIGOPTS a.wild.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
|
||||
$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
||||
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking negative validation ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
|
||||
@@ -58,6 +68,16 @@ n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking negative wildcard validation ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS b.wild.example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
|
||||
$DIG $DIGOPTS b.wild.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1
|
||||
$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
||||
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
# Check the insecure.example domain
|
||||
|
||||
echo "I:checking 1-server insecurity proof ($n)"
|
||||
@@ -382,6 +402,45 @@ n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking that lookups succeed after disabling a algorithm works ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS +noauth example. SOA @10.53.0.2 \
|
||||
> dig.out.ns2.test$n || ret=1
|
||||
$DIG $DIGOPTS +noauth example. SOA @10.53.0.6 \
|
||||
> dig.out.ns6.test$n || ret=1
|
||||
$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns6.test$n || ret=1
|
||||
# Note - this is looking for failure, hence the &&
|
||||
grep "flags:.*ad.*QUERY" dig.out.ns6.test$n > /dev/null && ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking privately secure to nxdomain works ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.2 \
|
||||
> dig.out.ns2.test$n || ret=1
|
||||
$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.4 \
|
||||
> dig.out.ns4.test$n || ret=1
|
||||
$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
||||
# Note - this is looking for failure, hence the &&
|
||||
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking privately secure wilcard to nxdomain works ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS +noauth a.wild.private.secure.example. SOA @10.53.0.2 \
|
||||
> dig.out.ns2.test$n || ret=1
|
||||
$DIG $DIGOPTS +noauth a.wild.private.secure.example. SOA @10.53.0.4 \
|
||||
> dig.out.ns4.test$n || ret=1
|
||||
$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
||||
# Note - this is looking for failure, hence the &&
|
||||
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
# Run a minimal update test if possible. This is really just
|
||||
# a regression test for RT #2399; more tests should be added.
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: ifconfig.sh,v 1.42 2003/07/30 01:38:47 marka Exp $
|
||||
# $Id: ifconfig.sh,v 1.43 2004/01/14 02:06:49 marka Exp $
|
||||
|
||||
#
|
||||
# Set up interface aliases for bind9 system tests.
|
||||
@@ -57,7 +57,7 @@ esac
|
||||
case "$1" in
|
||||
|
||||
start|up)
|
||||
for ns in 1 2 3 4 5
|
||||
for ns in 1 2 3 4 5 6
|
||||
do
|
||||
if test -n "$base"
|
||||
then
|
||||
@@ -117,7 +117,7 @@ case "$1" in
|
||||
;;
|
||||
|
||||
stop|down)
|
||||
for ns in 5 4 3 2 1
|
||||
for ns in 6 5 4 3 2 1
|
||||
do
|
||||
if test -n "$base"
|
||||
then
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
|
||||
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.231 2003/10/07 03:34:30 marka Exp $ -->
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.232 2004/01/14 02:06:49 marka Exp $ -->
|
||||
|
||||
<book>
|
||||
<title>BIND 9 Administrator Reference Manual</title>
|
||||
@@ -2818,6 +2818,7 @@ statement in the <filename>named.conf</filename> file:</para>
|
||||
<optional> edns-udp-size <replaceable>number</replaceable>; </optional>
|
||||
<optional> root-delegation-only <optional> exclude { <replaceable>namelist</replaceable> } </optional> ; </optional>
|
||||
};
|
||||
<optional> disable-algorithms <replaceable>domain</replaceable> { <replaceable>algorithm</replaceable>; <optional> <replaceable>algorithm</replaceable>; </optional> }; </optional>
|
||||
</programlisting>
|
||||
</sect2>
|
||||
|
||||
@@ -2955,8 +2956,14 @@ options {
|
||||
};
|
||||
</programlisting>
|
||||
</listitem></varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<varlistentry><term><command>disable-algorithms</command></term>
|
||||
<listitem><para>
|
||||
Disable the specified DNSSEC algorithms at and below the specified name.
|
||||
Multiple <command>disable-algorithms</command> statements are allowed.
|
||||
Only the most specific will be applied.
|
||||
</para></listitem></varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<sect3 id="boolean_options"><title>Boolean Options</title>
|
||||
|
||||
|
@@ -79,6 +79,7 @@ options {
|
||||
<integer>] | <ipv4_address> [port <integer>] | <ipv6_address> [port <integer>] ); ... };
|
||||
edns-udp-size <integer>;
|
||||
root-delegation-only [ exclude { <quoted_string>; ... } ];
|
||||
disable-algorithms <string> { <string>; ... };
|
||||
allow-query { <address_match_element>; ... };
|
||||
allow-transfer { <address_match_element>; ... };
|
||||
allow-update-forwarding { <address_match_element>; ... };
|
||||
@@ -255,6 +256,7 @@ view <string> <optional_class> {
|
||||
<integer>] | <ipv4_address> [port <integer>] | <ipv6_address> [port <integer>] ); ... };
|
||||
edns-udp-size <integer>;
|
||||
root-delegation-only [ exclude { <quoted_string>; ... } ];
|
||||
disable-algorithms <string> { <string>; ... };
|
||||
allow-query { <address_match_element>; ... };
|
||||
allow-transfer { <address_match_element>; ... };
|
||||
allow-update-forwarding { <address_match_element>; ... };
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: check.c,v 1.41 2003/09/25 18:16:47 jinmei Exp $ */
|
||||
/* $Id: check.c,v 1.42 2004/01/14 02:06:49 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <isc/log.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/parseint.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/sockaddr.h>
|
||||
@@ -35,6 +36,7 @@
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdatatype.h>
|
||||
#include <dns/secalg.h>
|
||||
|
||||
#include <isccfg/cfg.h>
|
||||
|
||||
@@ -219,6 +221,57 @@ check_forward(cfg_obj_t *options, isc_log_t *logctx) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
disabled_algorithms(cfg_obj_t *disabled, isc_log_t *logctx) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_result_t tresult;
|
||||
cfg_listelt_t *element;
|
||||
const char *str;
|
||||
isc_buffer_t b;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name;
|
||||
cfg_obj_t *obj;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
name = dns_fixedname_name(&fixed);
|
||||
obj = cfg_tuple_get(disabled, "name");
|
||||
str = cfg_obj_asstring(obj);
|
||||
isc_buffer_init(&b, str, strlen(str));
|
||||
isc_buffer_add(&b, strlen(str));
|
||||
tresult = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"bad domain name '%s'", str);
|
||||
result = tresult;
|
||||
}
|
||||
|
||||
obj = cfg_tuple_get(disabled, "algorithms");
|
||||
|
||||
for (element = cfg_list_first(obj);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
isc_textregion_t r;
|
||||
dns_secalg_t alg;
|
||||
isc_result_t tresult;
|
||||
|
||||
r.base = cfg_obj_asstring(cfg_listelt_value(element));
|
||||
r.length = strlen(r.base);
|
||||
|
||||
tresult = dns_secalg_fromtext(&alg, &r);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
isc_uint8_t ui;
|
||||
result = isc_parse_uint8(&ui, r.base, 10);
|
||||
}
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(cfg_listelt_value(element), logctx,
|
||||
ISC_LOG_ERROR, "invalid algorithm");
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
unsigned int scale;
|
||||
@@ -228,8 +281,10 @@ typedef struct {
|
||||
static isc_result_t
|
||||
check_options(cfg_obj_t *options, isc_log_t *logctx) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_result_t tresult;
|
||||
unsigned int i;
|
||||
cfg_obj_t *obj = NULL;
|
||||
cfg_listelt_t *element;
|
||||
|
||||
static intervaltable intervals[] = {
|
||||
{ "cleaning-interval", 60, 28 * 24 * 60 }, /* 28 days */
|
||||
@@ -289,7 +344,6 @@ check_options(cfg_obj_t *options, isc_log_t *logctx) {
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name;
|
||||
isc_buffer_t b;
|
||||
isc_result_t tresult;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
name = dns_fixedname_name(&fixed);
|
||||
@@ -312,6 +366,24 @@ check_options(cfg_obj_t *options, isc_log_t *logctx) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set supported DNSSEC algorithms.
|
||||
*/
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(options, "disable-algorithms", &obj);
|
||||
if (obj != NULL) {
|
||||
for (element = cfg_list_first(obj);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
obj = cfg_listelt_value(element);
|
||||
tresult = disabled_algorithms(obj, logctx);
|
||||
if (tresult != ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: dnssec.c,v 1.78 2003/10/25 00:31:09 jinmei Exp $
|
||||
* $Id: dnssec.c,v 1.79 2004/01/14 02:06:50 marka Exp $
|
||||
*/
|
||||
|
||||
|
||||
@@ -337,9 +337,9 @@ cleanup_signature:
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
isc_boolean_t ignoretime, isc_mem_t *mctx,
|
||||
dns_rdata_t *sigrdata)
|
||||
dns_rdata_t *sigrdata, dns_name_t *wild)
|
||||
{
|
||||
dns_rdata_rrsig_t sig;
|
||||
dns_fixedname_t fnewname;
|
||||
@@ -351,7 +351,7 @@ dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
isc_result_t ret;
|
||||
unsigned char data[300];
|
||||
dst_context_t *ctx = NULL;
|
||||
int labels;
|
||||
int labels = 0;
|
||||
isc_uint32_t flags;
|
||||
|
||||
REQUIRE(name != NULL);
|
||||
@@ -489,9 +489,30 @@ cleanup_context:
|
||||
cleanup_struct:
|
||||
dns_rdata_freestruct(&sig);
|
||||
|
||||
if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) {
|
||||
if (wild != NULL)
|
||||
RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname,
|
||||
dns_fixedname_name(&fnewname),
|
||||
wild, NULL) == ISC_R_SUCCESS);
|
||||
ret = DNS_R_FROMWILDCARD;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
isc_boolean_t ignoretime, isc_mem_t *mctx,
|
||||
dns_rdata_t *sigrdata)
|
||||
{
|
||||
isc_result_t result;
|
||||
|
||||
result = dns_dnssec_verify2(name, set, key, ignoretime, mctx,
|
||||
sigrdata, NULL);
|
||||
if (result == DNS_R_FROMWILDCARD)
|
||||
result = ISC_R_SUCCESS;
|
||||
return (result);
|
||||
}
|
||||
|
||||
#define is_zone_key(key) ((dst_key_flags(key) & DNS_KEYFLAG_OWNERMASK) \
|
||||
== DNS_KEYOWNER_ZONE)
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dnssec.h,v 1.24 2002/02/20 03:34:30 marka Exp $ */
|
||||
/* $Id: dnssec.h,v 1.25 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#ifndef DNS_DNSSEC_H
|
||||
#define DNS_DNSSEC_H 1
|
||||
@@ -83,6 +83,11 @@ isc_result_t
|
||||
dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
isc_boolean_t ignoretime, isc_mem_t *mctx,
|
||||
dns_rdata_t *sigrdata);
|
||||
|
||||
isc_result_t
|
||||
dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
isc_boolean_t ignoretime, isc_mem_t *mctx,
|
||||
dns_rdata_t *sigrdata, dns_name_t *wild);
|
||||
/*
|
||||
* Verifies the SIG record covering this rdataset signed by a specific
|
||||
* key. This does not determine if the key's owner is authorized to
|
||||
@@ -95,10 +100,14 @@ dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
* 'key' is a valid key
|
||||
* 'mctx' is not NULL
|
||||
* 'sigrdata' is a valid rdata containing a SIG record
|
||||
* 'wild' if non-NULL then is a valid and has a buffer.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS
|
||||
* ISC_R_NOMEMORY
|
||||
* DNS_R_FROMWILDCARD - the signature is valid and is from
|
||||
* a wildcard expansion. dns_dnssec_verify2() only.
|
||||
* 'wild' contains the name of the wildcard if non-NULL.
|
||||
* DNS_R_SIGINVALID - the signature fails to verify
|
||||
* DNS_R_SIGEXPIRED - the signature has expired
|
||||
* DNS_R_SIGFUTURE - the signature's validity period has not begun
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataset.h,v 1.48 2004/01/12 04:19:42 marka Exp $ */
|
||||
/* $Id: rdataset.h,v 1.49 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RDATASET_H
|
||||
#define DNS_RDATASET_H 1
|
||||
@@ -68,6 +68,12 @@ typedef struct dns_rdatasetmethods {
|
||||
void (*clone)(dns_rdataset_t *source,
|
||||
dns_rdataset_t *target);
|
||||
unsigned int (*count)(dns_rdataset_t *rdataset);
|
||||
isc_result_t (*addnoqname)(dns_rdataset_t *rdataset,
|
||||
dns_name_t *name);
|
||||
isc_result_t (*getnoqname)(dns_rdataset_t *rdataset,
|
||||
dns_name_t *name,
|
||||
dns_rdataset_t *nsec,
|
||||
dns_rdataset_t *nsecsig);
|
||||
} dns_rdatasetmethods_t;
|
||||
|
||||
#define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R')
|
||||
@@ -113,6 +119,7 @@ struct dns_rdataset {
|
||||
void * private3;
|
||||
unsigned int privateuint4;
|
||||
void * private5;
|
||||
void * private6;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -137,6 +144,7 @@ struct dns_rdataset {
|
||||
#define DNS_RDATASETATTR_RANDOMIZE 0x0800
|
||||
#define DNS_RDATASETATTR_CHASE 0x1000 /* Used by resolver. */
|
||||
#define DNS_RDATASETATTR_NXDOMAIN 0x2000
|
||||
#define DNS_RDATASETATTR_NOQNAME 0x4000
|
||||
|
||||
/*
|
||||
* _OMITDNSSEC:
|
||||
@@ -429,6 +437,31 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
||||
* Any error that dns_rdata_additionaldata() can return.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
|
||||
dns_rdataset_t *nsec, dns_rdataset_t *nsecsig);
|
||||
/*
|
||||
* Return the noqname proof for this record.
|
||||
*
|
||||
* Requires:
|
||||
* 'rdataset' to be valid and DNS_RDATASETATTR_NOQNAME to be set.
|
||||
* 'name' to be valid.
|
||||
* 'nsec' and 'nsecsig' to be valid and not associated.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name);
|
||||
/*
|
||||
* Associate a noqname proof with this record.
|
||||
* Sets DNS_RDATASETATTR_NOQNAME if successful.
|
||||
* Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and
|
||||
* the 'nsec' and 'rrsig(nsec)' ttl.
|
||||
*
|
||||
* Requires:
|
||||
* 'rdataset' to be valid and DNS_RDATASETATTR_NOQNAME to be set.
|
||||
* 'name' to be valid and have NSEC and RRSIG(NSEC) rdatasets.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_RDATASET_H */
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: resolver.h,v 1.37 2003/02/26 02:03:59 marka Exp $ */
|
||||
/* $Id: resolver.h,v 1.38 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RESOLVER_H
|
||||
#define DNS_RESOLVER_H 1
|
||||
@@ -383,6 +383,35 @@ dns_resolver_getudpsize(dns_resolver_t *resolver);
|
||||
* Get the current EDNS UDP buffer size.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_resolver_reset_algorithms(dns_resolver_t *resolver);
|
||||
/*
|
||||
* Clear the disabled DNSSEC algorithms.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int alg);
|
||||
/*
|
||||
* Mark the give DNSSEC algorithm as disabled and below 'name'.
|
||||
* Valid algorithms are less than 256.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS
|
||||
* ISC_R_RANGE
|
||||
* ISC_R_NOMEMORY
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int alg);
|
||||
/*
|
||||
* Check if the given algorithm is supported by this resolver.
|
||||
* This checks if the algorithm has been disabled via
|
||||
* dns_resolver_disable_algorithm() then the underlying
|
||||
* crypto libraries if not specifically disabled.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_RESOLVER_H */
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: result.h,v 1.99 2003/09/30 05:56:17 marka Exp $ */
|
||||
/* $Id: result.h,v 1.100 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RESULT_H
|
||||
#define DNS_RESULT_H 1
|
||||
@@ -136,8 +136,9 @@
|
||||
#define DNS_R_EMPTYNAME (ISC_RESULTCLASS_DNS + 92)
|
||||
#define DNS_R_EMPTYWILD (ISC_RESULTCLASS_DNS + 93)
|
||||
#define DNS_R_BADBITMAP (ISC_RESULTCLASS_DNS + 94)
|
||||
#define DNS_R_FROMWILDCARD (ISC_RESULTCLASS_DNS + 95)
|
||||
|
||||
#define DNS_R_NRESULTS 95 /* Number of results */
|
||||
#define DNS_R_NRESULTS 96 /* Number of results */
|
||||
|
||||
/*
|
||||
* DNS wire format rcodes.
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: validator.h,v 1.24 2003/09/30 05:56:17 marka Exp $ */
|
||||
/* $Id: validator.h,v 1.25 2004/01/14 02:06:51 marka Exp $ */
|
||||
|
||||
#ifndef DNS_VALIDATOR_H
|
||||
#define DNS_VALIDATOR_H 1
|
||||
@@ -74,8 +74,12 @@ typedef struct dns_validatorevent {
|
||||
dns_rdataset_t * rdataset;
|
||||
dns_rdataset_t * sigrdataset;
|
||||
dns_message_t * message;
|
||||
dns_name_t * proofs[3];
|
||||
} dns_validatorevent_t;
|
||||
|
||||
#define DNS_VALIDATOR_NOQNAMEPROOF 0
|
||||
#define DNS_VALIDATOR_NODATAPROOF 1
|
||||
#define DNS_VALIDATOR_NOWILDCARDPROOF 2
|
||||
|
||||
/*
|
||||
* A validator object represents a validation in procgress.
|
||||
@@ -114,6 +118,7 @@ struct dns_validator {
|
||||
dns_rdataset_t frdataset;
|
||||
dns_rdataset_t fsigrdataset;
|
||||
dns_fixedname_t fname;
|
||||
dns_fixedname_t wild;
|
||||
ISC_LINK(dns_validator_t) link;
|
||||
};
|
||||
|
||||
|
158
lib/dns/rbtdb.c
158
lib/dns/rbtdb.c
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rbtdb.c,v 1.191 2004/01/12 04:19:42 marka Exp $ */
|
||||
/* $Id: rbtdb.c,v 1.192 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
/*
|
||||
* Principal Author: Bob Halley
|
||||
@@ -94,6 +94,12 @@ typedef isc_uint32_t rbtdb_rdatatype_t;
|
||||
#define RBTDB_RDATATYPE_NCACHEANY \
|
||||
RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any)
|
||||
|
||||
struct noqname {
|
||||
dns_name_t name;
|
||||
void * nsec;
|
||||
void * nsecsig;
|
||||
};
|
||||
|
||||
typedef struct rdatasetheader {
|
||||
/*
|
||||
* Locked by the owning node's lock.
|
||||
@@ -103,6 +109,7 @@ typedef struct rdatasetheader {
|
||||
rbtdb_rdatatype_t type;
|
||||
isc_uint16_t attributes;
|
||||
dns_trust_t trust;
|
||||
struct noqname *noqname;
|
||||
/*
|
||||
* We don't use the LIST macros, because the LIST structure has
|
||||
* both head and tail pointers, and is doubly linked.
|
||||
@@ -249,6 +256,10 @@ static isc_result_t rdataset_next(dns_rdataset_t *rdataset);
|
||||
static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
|
||||
static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target);
|
||||
static unsigned int rdataset_count(dns_rdataset_t *rdataset);
|
||||
static isc_result_t rdataset_getnoqname(dns_rdataset_t *rdataset,
|
||||
dns_name_t *name,
|
||||
dns_rdataset_t *nsec,
|
||||
dns_rdataset_t *nsecsig);
|
||||
|
||||
static dns_rdatasetmethods_t rdataset_methods = {
|
||||
rdataset_disassociate,
|
||||
@@ -256,7 +267,9 @@ static dns_rdatasetmethods_t rdataset_methods = {
|
||||
rdataset_next,
|
||||
rdataset_current,
|
||||
rdataset_clone,
|
||||
rdataset_count
|
||||
rdataset_count,
|
||||
NULL,
|
||||
rdataset_getnoqname
|
||||
};
|
||||
|
||||
static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
|
||||
@@ -561,10 +574,28 @@ add_changed(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
|
||||
return (changed);
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_noqname(isc_mem_t *mctx, struct noqname **noqname) {
|
||||
|
||||
if (dns_name_dynamic(&(*noqname)->name))
|
||||
dns_name_free(&(*noqname)->name, mctx);
|
||||
if ((*noqname)->nsec != NULL)
|
||||
isc_mem_put(mctx, (*noqname)->nsec,
|
||||
dns_rdataslab_size((*noqname)->nsec, 0));
|
||||
if ((*noqname)->nsec != NULL)
|
||||
isc_mem_put(mctx, (*noqname)->nsecsig,
|
||||
dns_rdataslab_size((*noqname)->nsecsig, 0));
|
||||
isc_mem_put(mctx, *noqname, sizeof(**noqname));
|
||||
*noqname = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_rdataset(isc_mem_t *mctx, rdatasetheader_t *rdataset) {
|
||||
unsigned int size;
|
||||
|
||||
if (rdataset->noqname != NULL)
|
||||
free_noqname(mctx, &rdataset->noqname);
|
||||
|
||||
if ((rdataset->attributes & RDATASET_ATTR_NONEXISTENT) != 0)
|
||||
size = sizeof(*rdataset);
|
||||
else
|
||||
@@ -1372,6 +1403,13 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
||||
*/
|
||||
rdataset->privateuint4 = 0;
|
||||
rdataset->private5 = NULL;
|
||||
|
||||
/*
|
||||
* Add noqname proof.
|
||||
*/
|
||||
rdataset->private6 = header->noqname;
|
||||
if (rdataset->private6 != NULL)
|
||||
rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
@@ -3812,11 +3850,13 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
* Don't replace existing NS, A and AAAA RRsets
|
||||
* in the cache if they are already exist. This
|
||||
* prevents named being locked to old servers.
|
||||
* Don't lower trust of existing record if the
|
||||
* update is forced.
|
||||
*/
|
||||
if (IS_CACHE(rbtdb) && header->ttl > now &&
|
||||
header->type == dns_rdatatype_ns &&
|
||||
!header_nx && !newheader_nx &&
|
||||
header->trust == newheader->trust &&
|
||||
header->trust >= newheader->trust &&
|
||||
dns_rdataslab_equalx((unsigned char *)header,
|
||||
(unsigned char *)newheader,
|
||||
(unsigned int)(sizeof(*newheader)),
|
||||
@@ -3828,6 +3868,11 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
*/
|
||||
if (header->ttl > newheader->ttl)
|
||||
header->ttl = newheader->ttl;
|
||||
if (header->noqname == NULL &&
|
||||
newheader->noqname != NULL) {
|
||||
header->noqname = newheader->noqname;
|
||||
newheader->noqname = NULL;
|
||||
}
|
||||
free_rdataset(rbtdb->common.mctx, newheader);
|
||||
if (addedrdataset != NULL)
|
||||
bind_rdataset(rbtdb, rbtnode, header, now,
|
||||
@@ -3838,7 +3883,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
(header->type == dns_rdatatype_a ||
|
||||
header->type == dns_rdatatype_aaaa) &&
|
||||
!header_nx && !newheader_nx &&
|
||||
header->trust == newheader->trust &&
|
||||
header->trust >= newheader->trust &&
|
||||
dns_rdataslab_equal((unsigned char *)header,
|
||||
(unsigned char *)newheader,
|
||||
(unsigned int)(sizeof(*newheader)))) {
|
||||
@@ -3848,6 +3893,11 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
*/
|
||||
if (header->ttl > newheader->ttl)
|
||||
header->ttl = newheader->ttl;
|
||||
if (header->noqname == NULL &&
|
||||
newheader->noqname != NULL) {
|
||||
header->noqname = newheader->noqname;
|
||||
newheader->noqname = NULL;
|
||||
}
|
||||
free_rdataset(rbtdb->common.mctx, newheader);
|
||||
if (addedrdataset != NULL)
|
||||
bind_rdataset(rbtdb, rbtnode, header, now,
|
||||
@@ -3952,6 +4002,51 @@ delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
|
||||
dns_rdataset_t *rdataset)
|
||||
{
|
||||
struct noqname *noqname;
|
||||
isc_mem_t *mctx = rbtdb->common.mctx;
|
||||
dns_name_t name;
|
||||
dns_rdataset_t nsec, nsecsig;
|
||||
isc_result_t result;
|
||||
isc_region_t r;
|
||||
|
||||
dns_name_init(&name, NULL);
|
||||
dns_rdataset_init(&nsec);
|
||||
dns_rdataset_init(&nsecsig);
|
||||
|
||||
result = dns_rdataset_getnoqname(rdataset, &name, &nsec, &nsecsig);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
noqname = isc_mem_get(mctx, sizeof(*noqname));
|
||||
if (noqname == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
dns_name_init(&noqname->name, NULL);
|
||||
noqname->nsec = NULL;
|
||||
noqname->nsecsig = NULL;
|
||||
result = dns_name_dup(&name, mctx, &noqname->name);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = dns_rdataslab_fromrdataset(&nsec, mctx, &r, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
noqname->nsec = r.base;
|
||||
result = dns_rdataslab_fromrdataset(&nsecsig, mctx, &r, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
noqname->nsecsig = r.base;
|
||||
dns_rdataset_disassociate(&nsec);
|
||||
dns_rdataset_disassociate(&nsecsig);
|
||||
newheader->noqname = noqname;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
free_noqname(mctx, &noqname);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
|
||||
@@ -3984,6 +4079,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
|
||||
rdataset->covers);
|
||||
newheader->attributes = 0;
|
||||
newheader->noqname = NULL;
|
||||
newheader->count = 0;
|
||||
if (rbtversion != NULL) {
|
||||
newheader->serial = rbtversion->serial;
|
||||
@@ -3994,6 +4090,13 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
newheader->trust = rdataset->trust;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
|
||||
newheader->attributes |= RDATASET_ATTR_NXDOMAIN;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) {
|
||||
result = addnoqname(rbtdb, newheader, rdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
free_rdataset(rbtdb->common.mctx, newheader);
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4051,6 +4154,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
newheader->attributes = 0;
|
||||
newheader->serial = rbtversion->serial;
|
||||
newheader->trust = 0;
|
||||
newheader->noqname = NULL;
|
||||
newheader->count = 0;
|
||||
|
||||
LOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
|
||||
@@ -4121,6 +4225,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
newheader->attributes = RDATASET_ATTR_NONEXISTENT;
|
||||
newheader->trust = 0;
|
||||
newheader->serial = rbtversion->serial;
|
||||
newheader->noqname = NULL;
|
||||
newheader->count = 0;
|
||||
} else {
|
||||
free_rdataset(rbtdb->common.mctx, newheader);
|
||||
@@ -4186,6 +4291,7 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
newheader->type = RBTDB_RDATATYPE_VALUE(type, covers);
|
||||
newheader->attributes = RDATASET_ATTR_NONEXISTENT;
|
||||
newheader->trust = 0;
|
||||
newheader->noqname = NULL;
|
||||
if (rbtversion != NULL)
|
||||
newheader->serial = rbtversion->serial;
|
||||
else
|
||||
@@ -4266,6 +4372,7 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
|
||||
newheader->attributes = 0;
|
||||
newheader->trust = rdataset->trust;
|
||||
newheader->serial = 1;
|
||||
newheader->noqname = NULL;
|
||||
newheader->count = 0;
|
||||
|
||||
result = add(rbtdb, node, rbtdb->current_version, newheader,
|
||||
@@ -4782,6 +4889,49 @@ rdataset_count(dns_rdataset_t *rdataset) {
|
||||
return (count);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
|
||||
dns_rdataset_t *nsec, dns_rdataset_t *nsecsig)
|
||||
{
|
||||
dns_db_t *db = rdataset->private1;
|
||||
dns_dbnode_t *node = rdataset->private2;
|
||||
dns_dbnode_t *cloned_node;
|
||||
struct noqname *noqname = rdataset->private6;
|
||||
|
||||
attachnode(db, node, &cloned_node);
|
||||
attachnode(db, node, &cloned_node);
|
||||
|
||||
nsec->methods = &rdataset_methods;
|
||||
nsec->rdclass = db->rdclass;
|
||||
nsec->type = dns_rdatatype_nsec;
|
||||
nsec->covers = 0;
|
||||
nsec->ttl = rdataset->ttl;
|
||||
nsec->trust = rdataset->trust;
|
||||
nsec->private1 = rdataset->private1;
|
||||
nsec->private2 = rdataset->private2;
|
||||
nsec->private3 = noqname->nsec;
|
||||
nsec->privateuint4 = 0;
|
||||
nsec->private5 = NULL;
|
||||
nsec->private6 = NULL;
|
||||
|
||||
nsecsig->methods = &rdataset_methods;
|
||||
nsecsig->rdclass = db->rdclass;
|
||||
nsecsig->type = dns_rdatatype_rrsig;
|
||||
nsecsig->covers = dns_rdatatype_nsec;
|
||||
nsecsig->ttl = rdataset->ttl;
|
||||
nsecsig->trust = rdataset->trust;
|
||||
nsecsig->private1 = rdataset->private1;
|
||||
nsecsig->private2 = rdataset->private2;
|
||||
nsecsig->private3 = noqname->nsecsig;
|
||||
nsecsig->privateuint4 = 0;
|
||||
nsecsig->private5 = NULL;
|
||||
nsec->private6 = NULL;
|
||||
|
||||
dns_name_clone(&noqname->name, name);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Rdataset Iterator Methods
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdatalist.c,v 1.26 2003/02/26 23:52:29 marka Exp $ */
|
||||
/* $Id: rdatalist.c,v 1.27 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/name.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/rdataset.h>
|
||||
@@ -35,7 +36,9 @@ static dns_rdatasetmethods_t methods = {
|
||||
isc__rdatalist_next,
|
||||
isc__rdatalist_current,
|
||||
isc__rdatalist_clone,
|
||||
isc__rdatalist_count
|
||||
isc__rdatalist_count,
|
||||
isc__rdatalist_addnoqname,
|
||||
isc__rdatalist_getnoqname
|
||||
};
|
||||
|
||||
void
|
||||
@@ -150,3 +153,72 @@ isc__rdatalist_count(dns_rdataset_t *rdataset) {
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
|
||||
dns_rdataset_t *nsec = NULL;
|
||||
dns_rdataset_t *nsecsig = NULL;
|
||||
dns_rdataset_t *rdset;
|
||||
dns_ttl_t ttl;
|
||||
|
||||
for (rdset = ISC_LIST_HEAD(name->list);
|
||||
rdset != NULL;
|
||||
rdset = ISC_LIST_NEXT(rdset, link))
|
||||
{
|
||||
if (rdset->rdclass != rdataset->rdclass)
|
||||
continue;
|
||||
if (rdset->type == dns_rdatatype_nsec)
|
||||
nsec = rdset;
|
||||
if (rdset->type == dns_rdatatype_rrsig &&
|
||||
rdset->covers == dns_rdatatype_nsec)
|
||||
nsecsig = rdset;
|
||||
}
|
||||
|
||||
if (nsec == NULL || nsecsig == NULL)
|
||||
return (ISC_R_NOTFOUND);
|
||||
/*
|
||||
* Minimise ttl.
|
||||
*/
|
||||
ttl = rdataset->ttl;
|
||||
if (nsec->ttl < ttl)
|
||||
ttl = nsec->ttl;
|
||||
if (nsecsig->ttl < ttl)
|
||||
ttl = nsecsig->ttl;
|
||||
rdataset->ttl = nsec->ttl = nsecsig->ttl = ttl;
|
||||
rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
|
||||
rdataset->private6 = name;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
|
||||
dns_rdataset_t *nsec, dns_rdataset_t *nsecsig)
|
||||
{
|
||||
dns_rdataclass_t rdclass = rdataset->rdclass;
|
||||
dns_rdataset_t *tnsec = NULL;
|
||||
dns_rdataset_t *tnsecsig = NULL;
|
||||
dns_name_t *noqname = rdataset->private6;
|
||||
|
||||
REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0);
|
||||
(void)dns_name_dynamic(noqname); /* Sanity Check. */
|
||||
|
||||
for (rdataset = ISC_LIST_HEAD(noqname->list);
|
||||
rdataset != NULL;
|
||||
rdataset = ISC_LIST_NEXT(rdataset, link))
|
||||
{
|
||||
if (rdataset->rdclass != rdclass)
|
||||
continue;
|
||||
if (rdataset->type == dns_rdatatype_nsec)
|
||||
tnsec = rdataset;
|
||||
if (rdataset->type == dns_rdatatype_rrsig &&
|
||||
rdataset->covers == dns_rdatatype_nsec)
|
||||
tnsecsig = rdataset;
|
||||
}
|
||||
if (tnsec == NULL || tnsecsig == NULL)
|
||||
return (ISC_R_NOTFOUND);
|
||||
|
||||
dns_name_clone(noqname, name);
|
||||
dns_rdataset_clone(tnsec, nsec);
|
||||
dns_rdataset_clone(tnsecsig, nsecsig);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdatalist_p.h,v 1.3 2001/01/09 21:51:22 bwelling Exp $ */
|
||||
/* $Id: rdatalist_p.h,v 1.4 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RDATALIST_P_H
|
||||
#define DNS_RDATALIST_P_H
|
||||
@@ -43,6 +43,13 @@ isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target);
|
||||
unsigned int
|
||||
isc__rdatalist_count(dns_rdataset_t *rdataset);
|
||||
|
||||
isc_result_t
|
||||
isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name);
|
||||
|
||||
isc_result_t
|
||||
isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
|
||||
dns_rdataset_t *nsec, dns_rdataset_t *nsecsig);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_RDATALIST_P_H */
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataset.c,v 1.69 2004/01/12 04:19:42 marka Exp $ */
|
||||
/* $Id: rdataset.c,v 1.70 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -55,6 +55,7 @@ dns_rdataset_init(dns_rdataset_t *rdataset) {
|
||||
rdataset->private3 = NULL;
|
||||
rdataset->privateuint4 = 0;
|
||||
rdataset->private5 = NULL;
|
||||
rdataset->private6 = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -108,6 +109,7 @@ dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
|
||||
rdataset->private3 = NULL;
|
||||
rdataset->privateuint4 = 0;
|
||||
rdataset->private5 = NULL;
|
||||
rdataset->private6 = NULL;
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
@@ -169,7 +171,9 @@ static dns_rdatasetmethods_t question_methods = {
|
||||
question_cursor,
|
||||
question_current,
|
||||
question_clone,
|
||||
question_count
|
||||
question_count,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
@@ -585,3 +589,24 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
|
||||
|
||||
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
||||
REQUIRE(rdataset->methods != NULL);
|
||||
if (rdataset->methods->addnoqname == NULL)
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
return((rdataset->methods->addnoqname)(rdataset, name));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
|
||||
dns_rdataset_t *nsec, dns_rdataset_t *nsecsig)
|
||||
{
|
||||
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
||||
REQUIRE(rdataset->methods != NULL);
|
||||
|
||||
if (rdataset->methods->getnoqname == NULL)
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
return((rdataset->methods->getnoqname)(rdataset, name, nsec, nsecsig));
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataslab.c,v 1.33 2003/02/26 23:52:29 marka Exp $ */
|
||||
/* $Id: rdataslab.c,v 1.34 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -239,7 +239,9 @@ static dns_rdatasetmethods_t rdataset_methods = {
|
||||
rdataset_next,
|
||||
rdataset_current,
|
||||
rdataset_clone,
|
||||
rdataset_count
|
||||
rdataset_count,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: resolver.c,v 1.275 2004/01/05 07:45:34 marka Exp $ */
|
||||
/* $Id: resolver.c,v 1.276 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <dns/ncache.h>
|
||||
#include <dns/opcode.h>
|
||||
#include <dns/peer.h>
|
||||
#include <dns/rbt.h>
|
||||
#include <dns/rcode.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdataclass.h>
|
||||
@@ -286,6 +287,10 @@ struct dns_resolver {
|
||||
isc_uint32_t lame_ttl;
|
||||
ISC_LIST(alternate_t) alternates;
|
||||
isc_uint16_t udpsize;
|
||||
#if USE_ALGLOG
|
||||
isc_rwlock_t alglock;
|
||||
#endif
|
||||
dns_rbt_t * algorithms;
|
||||
/* Locked by lock. */
|
||||
unsigned int references;
|
||||
isc_boolean_t exiting;
|
||||
@@ -2847,6 +2852,8 @@ clone_results(fetchctx_t *fctx) {
|
||||
isc_result_t result;
|
||||
dns_name_t *name, *hname;
|
||||
|
||||
FCTXTRACE("clone_results");
|
||||
|
||||
/*
|
||||
* Set up any other events to have the same data as the first
|
||||
* event.
|
||||
@@ -2939,6 +2946,10 @@ validated(isc_task_t *task, isc_event_t *event) {
|
||||
isc_boolean_t chaining;
|
||||
isc_boolean_t sentresponse;
|
||||
isc_uint32_t ttl;
|
||||
dns_dbnode_t *nsnode = NULL;
|
||||
dns_name_t *name;
|
||||
dns_rdataset_t *rdataset;
|
||||
dns_rdataset_t *sigrdataset;
|
||||
|
||||
UNUSED(task); /* for now */
|
||||
|
||||
@@ -3069,6 +3080,14 @@ validated(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
FCTXTRACE("validation OK");
|
||||
|
||||
if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
|
||||
|
||||
result = dns_rdataset_addnoqname(vevent->rdataset,
|
||||
vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
vevent->sigrdataset->ttl = vevent->rdataset->ttl;
|
||||
}
|
||||
|
||||
/*
|
||||
* The data was already cached as pending data.
|
||||
* Re-cache it as secure and bind the cached
|
||||
@@ -3116,6 +3135,49 @@ validated(isc_task_t *task, isc_event_t *event) {
|
||||
goto cleanup_event;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache any NS records that happened to be validate.
|
||||
*/
|
||||
result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
name = NULL;
|
||||
dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY,
|
||||
&name);
|
||||
for (rdataset = ISC_LIST_HEAD(name->list);
|
||||
rdataset != NULL;
|
||||
rdataset = ISC_LIST_NEXT(rdataset, link)) {
|
||||
if (rdataset->type != dns_rdatatype_ns ||
|
||||
rdataset->trust != dns_trust_secure)
|
||||
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_ns)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (sigrdataset == NULL ||
|
||||
sigrdataset->trust != dns_trust_secure)
|
||||
continue;
|
||||
result = dns_db_findnode(fctx->cache, name, ISC_TRUE,
|
||||
&nsnode);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
continue;
|
||||
|
||||
result = dns_db_addrdataset(fctx->cache, nsnode, NULL,
|
||||
now, rdataset, 0, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = dns_db_addrdataset(fctx->cache, nsnode,
|
||||
NULL, now,
|
||||
sigrdataset, 0,
|
||||
NULL);
|
||||
dns_db_detachnode(fctx->cache, &nsnode);
|
||||
}
|
||||
result = dns_message_nextname(fctx->rmessage,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
}
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
answer_response:
|
||||
@@ -4568,15 +4630,10 @@ answer_response(fetchctx_t *fctx) {
|
||||
rdataset,
|
||||
check_related,
|
||||
fctx);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Since we've found a non-external name in the
|
||||
* authority section, we should stop looking, even
|
||||
* if we didn't find any NS or SIG NS.
|
||||
*/
|
||||
done = ISC_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
|
||||
}
|
||||
if (result == ISC_R_NOMORE)
|
||||
@@ -5297,6 +5354,7 @@ destroy(dns_resolver_t *res) {
|
||||
dns_name_free(&a->_u._n.name, res->mctx);
|
||||
isc_mem_put(res->mctx, a, sizeof(*a));
|
||||
}
|
||||
dns_resolver_reset_algorithms(res);
|
||||
res->magic = 0;
|
||||
isc_mem_put(res->mctx, res, sizeof(*res));
|
||||
}
|
||||
@@ -5376,6 +5434,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
res->lame_ttl = 0;
|
||||
ISC_LIST_INIT(res->alternates);
|
||||
res->udpsize = RECV_BUFFER_SIZE;
|
||||
res->algorithms = NULL;
|
||||
|
||||
res->nbuckets = ntasks;
|
||||
res->activebuckets = ntasks;
|
||||
@@ -5429,12 +5488,23 @@ dns_resolver_create(dns_view_t *view,
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_nlock;
|
||||
|
||||
#if USE_ALGLOCK
|
||||
result = isc_rwlock_init(&res->alglock, 0, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_primelock;
|
||||
#endif
|
||||
|
||||
res->magic = RES_MAGIC;
|
||||
|
||||
*resp = res;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
#if USE_ALGLOCK
|
||||
cleanup_primelock:
|
||||
DESTROYLOCK(&res->nlock);
|
||||
#endif
|
||||
|
||||
cleanup_nlock:
|
||||
DESTROYLOCK(&res->nlock);
|
||||
|
||||
@@ -6040,3 +6110,118 @@ dns_resolver_getudpsize(dns_resolver_t *resolver) {
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
return (resolver->udpsize);
|
||||
}
|
||||
|
||||
static void
|
||||
free_algorithm(void *node, void *arg) {
|
||||
unsigned char *algorithms = node;
|
||||
isc_mem_t *mctx = arg;
|
||||
|
||||
isc_mem_put(mctx, algorithms, *algorithms);
|
||||
}
|
||||
|
||||
void
|
||||
dns_resolver_reset_algorithms(dns_resolver_t *resolver) {
|
||||
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
|
||||
#if USE_ALGLOCK
|
||||
RWLOCK(&resolver->alglock, isc_rwlocktype_write);
|
||||
#endif
|
||||
if (resolver->algorithms != NULL)
|
||||
dns_rbt_destroy(&resolver->algorithms);
|
||||
#if USE_ALGLOCK
|
||||
RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
|
||||
#endif
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int alg)
|
||||
{
|
||||
unsigned int len, mask;
|
||||
unsigned char *new;
|
||||
unsigned char *algorithms;
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
if (alg > 255)
|
||||
return (ISC_R_RANGE);
|
||||
|
||||
#if USE_ALGLOCK
|
||||
RWLOCK(&resolver->alglock, isc_rwlocktype_write);
|
||||
#endif
|
||||
if (resolver->algorithms == NULL) {
|
||||
result = dns_rbt_create(resolver->mctx, free_algorithm,
|
||||
resolver->mctx, &resolver->algorithms);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
len = alg/8 + 2;
|
||||
mask = 1 << (alg%8);
|
||||
|
||||
result = dns_rbt_addnode(resolver->algorithms, name, &node);
|
||||
|
||||
if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
|
||||
algorithms = node->data;
|
||||
if (algorithms == NULL || len > *algorithms) {
|
||||
new = isc_mem_get(resolver->mctx, len);
|
||||
if (new == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
memset(new, 0, len);
|
||||
if (algorithms != NULL)
|
||||
memcpy(new, algorithms, *algorithms);
|
||||
new[len-1] |= mask;
|
||||
*new = len;
|
||||
node->data = new;
|
||||
if (algorithms != NULL)
|
||||
isc_mem_put(resolver->mctx, algorithms,
|
||||
*algorithms);
|
||||
} else
|
||||
algorithms[len-1] |= mask;
|
||||
}
|
||||
result = ISC_R_SUCCESS;
|
||||
cleanup:
|
||||
#if USE_ALGLOCK
|
||||
RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
|
||||
#endif
|
||||
return (result);
|
||||
};
|
||||
|
||||
isc_boolean_t
|
||||
dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int alg)
|
||||
{
|
||||
unsigned int len, mask;
|
||||
unsigned char *algorithms;
|
||||
void *data = NULL;
|
||||
isc_result_t result;
|
||||
isc_boolean_t found = ISC_FALSE;
|
||||
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
|
||||
if (resolver->algorithms == NULL)
|
||||
return (dst_algorithm_supported(alg));
|
||||
|
||||
#if USE_ALGLOCK
|
||||
RWLOCK(&resolver->alglock, isc_rwlocktype_read)
|
||||
#endif
|
||||
result = dns_rbt_findname(resolver->algorithms, name,
|
||||
DNS_RBTFIND_NOEXACT, NULL, &data);
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
|
||||
len = alg/8 + 2;
|
||||
mask = 1 << (alg%8);
|
||||
algorithms = data;
|
||||
if (len <= *algorithms && (algorithms[len-1] & mask) != 0)
|
||||
found = ISC_TRUE;
|
||||
}
|
||||
#if USE_ALGLOCK
|
||||
RWUNLOCK(&resolver->alglock, isc_rwlocktype_read)
|
||||
#endif
|
||||
if (found)
|
||||
return (ISC_FALSE);
|
||||
return (dst_algorithm_supported(alg));
|
||||
};
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: result.c,v 1.110 2003/10/17 03:46:44 marka Exp $ */
|
||||
/* $Id: result.c,v 1.111 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -142,7 +142,9 @@ static const char *text[DNS_R_NRESULTS] = {
|
||||
"chase DS servers", /* 91 DNS_R_CHASEDSSERVERS */
|
||||
"empty name", /* 92 DNS_R_EMPTYNAME */
|
||||
"empty wild", /* 93 DNS_R_EMPTYWILD */
|
||||
"bad bitmap" /* 94 DNS_R_BADBITMAP */
|
||||
"bad bitmap", /* 94 DNS_R_BADBITMAP */
|
||||
|
||||
"from wildcard" /* 95 DNS_R_FROMWILDCARD */
|
||||
};
|
||||
|
||||
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: sdb.c,v 1.40 2003/09/30 05:56:13 marka Exp $ */
|
||||
/* $Id: sdb.c,v 1.41 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -1352,7 +1352,9 @@ static dns_rdatasetmethods_t methods = {
|
||||
isc__rdatalist_next,
|
||||
isc__rdatalist_current,
|
||||
rdataset_clone,
|
||||
isc__rdatalist_count
|
||||
isc__rdatalist_count,
|
||||
isc__rdatalist_addnoqname,
|
||||
isc__rdatalist_getnoqname
|
||||
};
|
||||
|
||||
static void
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: validator.c,v 1.114 2003/10/25 00:31:11 jinmei Exp $ */
|
||||
/* $Id: validator.c,v 1.115 2004/01/14 02:06:50 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -45,11 +45,24 @@
|
||||
#define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
|
||||
#define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
|
||||
|
||||
#define VALATTR_SHUTDOWN 0x01
|
||||
#define VALATTR_FOUNDNONEXISTENCE 0x02
|
||||
#define VALATTR_TRIEDVERIFY 0x04
|
||||
#define VALATTR_NEGATIVE 0x08
|
||||
#define VALATTR_INSECURITY 0x10
|
||||
#define VALATTR_SHUTDOWN 0x0001
|
||||
#define VALATTR_FOUNDNONEXISTENCE 0x0002
|
||||
#define VALATTR_TRIEDVERIFY 0x0004
|
||||
#define VALATTR_NEGATIVE 0x0008
|
||||
#define VALATTR_INSECURITY 0x0010
|
||||
|
||||
#define VALATTR_NEEDNOQNAME 0x0100
|
||||
#define VALATTR_NEEDNOWILDCARD 0x0200
|
||||
#define VALATTR_NEEDNODATA 0x0400
|
||||
|
||||
#define VALATTR_FOUNDNOQNAME 0x1000
|
||||
#define VALATTR_FOUNDNOWILDCARD 0x2000
|
||||
#define VALATTR_FOUNDNODATA 0x4000
|
||||
|
||||
#define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
|
||||
#define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
|
||||
#define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
|
||||
|
||||
#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
|
||||
|
||||
static void
|
||||
@@ -432,104 +445,83 @@ dsvalidated(isc_task_t *task, isc_event_t *event) {
|
||||
destroy(val);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
nsecprovesnonexistence(dns_validator_t *val, dns_name_t *nsecname,
|
||||
dns_rdataset_t *nsecset)
|
||||
/*
|
||||
* Return ISC_R_SUCCESS if we can determine that the name doesn't exist
|
||||
* or we can determine whether there is data or not at the name.
|
||||
* If the name does not exist return the wildcard name.
|
||||
*/
|
||||
static isc_result_t
|
||||
nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname,
|
||||
dns_rdataset_t *nsecset, isc_boolean_t *exists,
|
||||
isc_boolean_t *data, dns_name_t *wild)
|
||||
{
|
||||
int order;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
isc_boolean_t isnxdomain;
|
||||
isc_result_t result;
|
||||
dns_namereln_t relation;
|
||||
unsigned int olabels, nlabels, labels;
|
||||
dns_rdata_nsec_t nsec;
|
||||
isc_boolean_t atparent;
|
||||
|
||||
INSIST(DNS_MESSAGE_VALID(val->event->message));
|
||||
|
||||
if (val->event->message->rcode == dns_rcode_nxdomain)
|
||||
isnxdomain = ISC_TRUE;
|
||||
else
|
||||
isnxdomain = ISC_FALSE;
|
||||
REQUIRE(exists != NULL);
|
||||
REQUIRE(data != NULL);
|
||||
|
||||
result = dns_rdataset_first(nsecset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"failure processing NSEC set");
|
||||
return (ISC_FALSE);
|
||||
return (result);
|
||||
}
|
||||
dns_rdataset_current(nsecset, &rdata);
|
||||
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant nsec");
|
||||
relation = dns_name_fullcompare(val->event->name, nsecname,
|
||||
&order, &olabels);
|
||||
relation = dns_name_fullcompare(name, nsecname, &order, &olabels);
|
||||
|
||||
if (order < 0) {
|
||||
/*
|
||||
* The name is not within the NSEC range.
|
||||
*/
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"NSEC does not cover name, before NSEC");
|
||||
return (ISC_R_IGNORE);
|
||||
}
|
||||
|
||||
if (order == 0) {
|
||||
/*
|
||||
* The names are the same. Look for the type present bit.
|
||||
* The names are the same.
|
||||
*/
|
||||
atparent = dns_rdatatype_atparent(val->event->type);
|
||||
if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
|
||||
!dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
|
||||
{
|
||||
if (!atparent) {
|
||||
/*
|
||||
* This NSEC record is from somewhere higher in
|
||||
* the DNS, and at the parent of a delegation.
|
||||
* It can not be legitimately used here.
|
||||
*/
|
||||
if (isnxdomain) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"NSEC record seen at nonexistent name");
|
||||
return (ISC_FALSE);
|
||||
"ignoring parent nsec");
|
||||
return (ISC_R_IGNORE);
|
||||
}
|
||||
if (val->event->type >= 128) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "invalid type %d",
|
||||
val->event->type);
|
||||
return (ISC_FALSE);
|
||||
} else if (atparent) {
|
||||
/*
|
||||
* This NSEC record is from the child.
|
||||
* It can not be legitimately used here.
|
||||
*/
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"ignoring child nsec");
|
||||
return (ISC_R_IGNORE);
|
||||
}
|
||||
*exists = ISC_TRUE;
|
||||
*data = dns_nsec_typepresent(&rdata, val->event->type);
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"nsec proves name exists (owner) data=%d",
|
||||
*data);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
if (dns_nsec_typepresent(&rdata, val->event->type)) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"type should not be present");
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "nsec bitmask ok");
|
||||
} else if (order > 0) {
|
||||
dns_rdata_nsec_t nsec;
|
||||
|
||||
/*
|
||||
* The NSEC owner name is less than the nonexistent name.
|
||||
*/
|
||||
if (!isnxdomain) {
|
||||
/*
|
||||
* Is this a empty node?
|
||||
*/
|
||||
result = dns_rdata_tostruct(&rdata, &nsec, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
relation = dns_name_fullcompare(&nsec.next,
|
||||
val->event->name,
|
||||
&order, &nlabels);
|
||||
if (order > 0 && relation == dns_namereln_subdomain) {
|
||||
dns_rdata_freestruct(&nsec);
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"nsec proves empty node, ok");
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
/*
|
||||
* Look for empty wildcard matches.
|
||||
*/
|
||||
labels = dns_name_countlabels(&nsec.next);
|
||||
if (nlabels >= olabels && nlabels + 1 < labels) {
|
||||
dns_name_t wild;
|
||||
dns_name_init(&wild, NULL);
|
||||
dns_name_getlabelsequence(&nsec.next,
|
||||
labels - 1 - nlabels,
|
||||
nlabels + 1,
|
||||
&wild);
|
||||
if (dns_name_iswildcard(&wild)) {
|
||||
dns_rdata_freestruct(&nsec);
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"nsec proves empty wildcard, ok");
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We are not a empty name.
|
||||
*/
|
||||
dns_rdata_freestruct(&nsec);
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"missing NSEC record at name");
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
if (dns_name_issubdomain(val->event->name, nsecname) &&
|
||||
if (relation == dns_namereln_subdomain &&
|
||||
dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
|
||||
!dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
|
||||
{
|
||||
@@ -538,48 +530,63 @@ nsecprovesnonexistence(dns_validator_t *val, dns_name_t *nsecname,
|
||||
* the DNS, and at the parent of a delegation.
|
||||
* It can not be legitimately used here.
|
||||
*/
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"ignoring parent nsec");
|
||||
return (ISC_FALSE);
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "ignoring parent nsec");
|
||||
return (ISC_R_IGNORE);
|
||||
}
|
||||
|
||||
result = dns_rdata_tostruct(&rdata, &nsec, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_FALSE);
|
||||
dns_rdata_reset(&rdata);
|
||||
relation = dns_name_fullcompare(&nsec.next, val->event->name,
|
||||
&order, &nlabels);
|
||||
if (order <= 0) {
|
||||
/*
|
||||
* The NSEC next name is less than the nonexistent
|
||||
* name. This is only ok if the next name is the zone
|
||||
* name.
|
||||
*/
|
||||
if (!dns_name_equal(val->soaname, &nsec.next)) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"next name is not greater");
|
||||
return (result);
|
||||
relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);
|
||||
if (order == 0) {
|
||||
dns_rdata_freestruct(&nsec);
|
||||
return (ISC_FALSE);
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"ignoring nsec matches next name");
|
||||
return (ISC_R_IGNORE);
|
||||
}
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"nsec points to zone apex, ok");
|
||||
} else if (relation == dns_namereln_subdomain) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"nsec proves empty node, bad");
|
||||
|
||||
if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) {
|
||||
/*
|
||||
* The name is not within the NSEC range.
|
||||
*/
|
||||
dns_rdata_freestruct(&nsec);
|
||||
return (ISC_FALSE);
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"ignoring nsec because name is past end of range");
|
||||
return (ISC_R_IGNORE);
|
||||
}
|
||||
|
||||
if (order > 0 && relation == dns_namereln_subdomain) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"nsec proves name exist (empty)");
|
||||
dns_rdata_freestruct(&nsec);
|
||||
*exists = ISC_TRUE;
|
||||
*data = ISC_FALSE;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
if (wild != NULL) {
|
||||
dns_name_t common;
|
||||
dns_name_init(&common, NULL);
|
||||
if (olabels > nlabels) {
|
||||
labels = dns_name_countlabels(nsecname);
|
||||
dns_name_getlabelsequence(nsecname, labels - olabels,
|
||||
olabels, &common);
|
||||
} else {
|
||||
labels = dns_name_countlabels(&nsec.next);
|
||||
dns_name_getlabelsequence(&nsec.next, labels - nlabels,
|
||||
nlabels, &common);
|
||||
}
|
||||
result = dns_name_concatenate(dns_wildcardname, &common,
|
||||
wild, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"failure generating wilcard name");
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
dns_rdata_freestruct(&nsec);
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok");
|
||||
} else {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"nsec owner name is not less");
|
||||
/*
|
||||
* The NSEC owner name is greater than the supposedly
|
||||
* nonexistent name. This NSEC is irrelevant.
|
||||
*/
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
return (ISC_TRUE);
|
||||
*exists = ISC_FALSE;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -589,6 +596,7 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
|
||||
dns_rdataset_t *rdataset, *sigrdataset;
|
||||
isc_boolean_t want_destroy;
|
||||
isc_result_t result;
|
||||
isc_boolean_t exists, data;
|
||||
|
||||
UNUSED(task);
|
||||
INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
|
||||
@@ -616,11 +624,35 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
|
||||
validator_done(val, result);
|
||||
}
|
||||
} else {
|
||||
if (val->soaname != NULL && val->nsecset != NULL &&
|
||||
(val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0 &&
|
||||
nsecprovesnonexistence(val, devent->name, rdataset))
|
||||
val->attributes |= VALATTR_FOUNDNONEXISTENCE;
|
||||
dns_name_t **proofs = val->event->proofs;
|
||||
|
||||
if (rdataset->trust == dns_trust_secure)
|
||||
val->seensig = ISC_TRUE;
|
||||
|
||||
if (val->nsecset != NULL &&
|
||||
rdataset->trust == dns_trust_secure &&
|
||||
((val->attributes & VALATTR_NEEDNODATA) != 0 ||
|
||||
(val->attributes & VALATTR_NEEDNOQNAME) != 0) &&
|
||||
(val->attributes & VALATTR_FOUNDNODATA) == 0 &&
|
||||
(val->attributes & VALATTR_FOUNDNOQNAME) == 0 &&
|
||||
nsecnoexistnodata(val, val->event->name, devent->name,
|
||||
rdataset, &exists, &data,
|
||||
dns_fixedname_name(&val->wild))
|
||||
== ISC_R_SUCCESS)
|
||||
{
|
||||
if (exists && !data) {
|
||||
val->attributes |= VALATTR_FOUNDNODATA;
|
||||
if (NEEDNODATA(val))
|
||||
proofs[DNS_VALIDATOR_NODATAPROOF] =
|
||||
devent->name;
|
||||
}
|
||||
if (!exists) {
|
||||
val->attributes |= VALATTR_FOUNDNOQNAME;
|
||||
if (NEEDNOQNAME(val))
|
||||
proofs[DNS_VALIDATOR_NOQNAMEPROOF] =
|
||||
devent->name;
|
||||
}
|
||||
}
|
||||
result = nsecvalidate(val, ISC_TRUE);
|
||||
if (result != DNS_R_WAIT)
|
||||
validator_done(val, result);
|
||||
@@ -987,13 +1019,22 @@ isselfsigned(dns_validator_t *val) {
|
||||
static isc_result_t
|
||||
verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata) {
|
||||
isc_result_t result;
|
||||
dns_fixedname_t fixed;
|
||||
|
||||
val->attributes |= VALATTR_TRIEDVERIFY;
|
||||
result = dns_dnssec_verify(val->event->name, val->event->rdataset,
|
||||
key, ISC_FALSE, val->view->mctx, rdata);
|
||||
dns_fixedname_init(&fixed);
|
||||
result = dns_dnssec_verify2(val->event->name, val->event->rdataset,
|
||||
key, ISC_FALSE, val->view->mctx, rdata,
|
||||
dns_fixedname_name(&fixed));
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"verify rdataset: %s",
|
||||
isc_result_totext(result));
|
||||
if (result == DNS_R_FROMWILDCARD) {
|
||||
if (!dns_name_equal(val->event->name,
|
||||
dns_fixedname_name(&fixed)))
|
||||
val->attributes |= VALATTR_NEEDNOQNAME;
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -1046,9 +1087,12 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
|
||||
|
||||
/*
|
||||
* At this point we could check that the signature algorithm
|
||||
* was known and "sufficiently good". For now, any algorithm
|
||||
* is acceptable.
|
||||
* was known and "sufficiently good".
|
||||
*/
|
||||
if (!dns_resolver_algorithm_supported(val->view->resolver,
|
||||
event->name,
|
||||
val->siginfo->algorithm))
|
||||
continue;
|
||||
|
||||
if (!resume) {
|
||||
result = get_key(val, val->siginfo);
|
||||
@@ -1067,7 +1111,6 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"marking as answer");
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -1122,7 +1165,16 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
|
||||
}
|
||||
}
|
||||
val->key = NULL;
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if ((val->attributes & VALATTR_NEEDNOQNAME) != 0) {
|
||||
if (val->event->message == NULL) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"no message available for noqname proof");
|
||||
return (DNS_R_NOVALIDSIG);
|
||||
}
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"looking for noqname proof");
|
||||
return (nsecvalidate(val, ISC_FALSE));
|
||||
} else if (result == ISC_R_SUCCESS) {
|
||||
event->rdataset->trust = dns_trust_secure;
|
||||
event->sigrdataset->trust = dns_trust_secure;
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
@@ -1170,6 +1222,7 @@ validatezonekey(dns_validator_t *val, isc_boolean_t resume) {
|
||||
dns_rdata_dnskey_t key;
|
||||
dns_rdata_rrsig_t sig;
|
||||
dst_key_t *dstkey;
|
||||
isc_boolean_t supported_algorithm;
|
||||
|
||||
UNUSED(resume);
|
||||
|
||||
@@ -1311,6 +1364,8 @@ validatezonekey(dns_validator_t *val, isc_boolean_t resume) {
|
||||
* verification.
|
||||
*/
|
||||
|
||||
supported_algorithm = ISC_FALSE;
|
||||
|
||||
for (result = dns_rdataset_first(val->dsset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(val->dsset))
|
||||
@@ -1319,6 +1374,13 @@ validatezonekey(dns_validator_t *val, isc_boolean_t resume) {
|
||||
dns_rdataset_current(val->dsset, &dsrdata);
|
||||
(void)dns_rdata_tostruct(&dsrdata, &ds, NULL);
|
||||
|
||||
if (!dns_resolver_algorithm_supported(val->view->resolver,
|
||||
val->event->name,
|
||||
ds.algorithm))
|
||||
continue;
|
||||
|
||||
supported_algorithm = ISC_TRUE;
|
||||
|
||||
dns_rdataset_init(&trdataset);
|
||||
dns_rdataset_clone(val->event->rdataset, &trdataset);
|
||||
|
||||
@@ -1356,15 +1418,9 @@ validatezonekey(dns_validator_t *val, isc_boolean_t resume) {
|
||||
dns_rdataset_current(val->event->sigrdataset,
|
||||
&sigrdata);
|
||||
(void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
|
||||
if (ds.key_tag == sig.keyid &&
|
||||
ds.algorithm == sig.algorithm)
|
||||
break;
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"no SIG matching DS key");
|
||||
if (ds.key_tag != sig.keyid &&
|
||||
ds.algorithm != sig.algorithm)
|
||||
continue;
|
||||
}
|
||||
|
||||
dstkey = NULL;
|
||||
result = dns_dnssec_keyfromrdata(val->event->name,
|
||||
@@ -1379,15 +1435,25 @@ validatezonekey(dns_validator_t *val, isc_boolean_t resume) {
|
||||
|
||||
result = verify(val, dstkey, &sigrdata);
|
||||
dst_key_free(&dstkey);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
break;
|
||||
}
|
||||
dns_rdataset_disassociate(&trdataset);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
break;
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "no SIG matching DS key");
|
||||
}
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
event->rdataset->trust = dns_trust_secure;
|
||||
event->sigrdataset->trust = dns_trust_secure;
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
|
||||
return (result);
|
||||
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
|
||||
val->event->rdataset->trust = dns_trust_answer;
|
||||
val->event->sigrdataset->trust = dns_trust_answer;
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"no supported algorithm (ds)");
|
||||
return (ISC_R_SUCCESS);
|
||||
} else
|
||||
return (DNS_R_NOVALIDSIG);
|
||||
}
|
||||
@@ -1412,6 +1478,78 @@ start_positive_validation(dns_validator_t *val) {
|
||||
return (validatezonekey(val, ISC_FALSE));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
checkwildcard(dns_validator_t *val) {
|
||||
dns_name_t *name, *wild;
|
||||
dns_message_t *message = val->event->message;
|
||||
isc_result_t result;
|
||||
isc_boolean_t exists, data;
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
|
||||
wild = dns_fixedname_name(&val->wild);
|
||||
dns_name_format(wild, namebuf, sizeof(namebuf));
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf);
|
||||
|
||||
for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
|
||||
{
|
||||
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
|
||||
|
||||
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_nsec)
|
||||
continue;
|
||||
val->nsecset = rdataset;
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (((val->attributes & VALATTR_NEEDNODATA) != 0 ||
|
||||
(val->attributes & VALATTR_NEEDNOWILDCARD) != 0) &&
|
||||
(val->attributes & VALATTR_FOUNDNODATA) == 0 &&
|
||||
(val->attributes & VALATTR_FOUNDNOWILDCARD) == 0 &&
|
||||
nsecnoexistnodata(val, wild, name, rdataset,
|
||||
&exists, &data, NULL)
|
||||
== ISC_R_SUCCESS)
|
||||
{
|
||||
dns_name_t **proofs = val->event->proofs;
|
||||
if (exists && !data)
|
||||
val->attributes |= VALATTR_FOUNDNODATA;
|
||||
if (exists && !data && NEEDNODATA(val))
|
||||
proofs[DNS_VALIDATOR_NODATAPROOF] =
|
||||
name;
|
||||
if (!exists)
|
||||
val->attributes |=
|
||||
VALATTR_FOUNDNOWILDCARD;
|
||||
if (!exists && NEEDNOQNAME(val))
|
||||
proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
|
||||
name;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_SUCCESS;
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
||||
dns_name_t *name;
|
||||
@@ -1437,8 +1575,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
||||
rdataset = ISC_LIST_NEXT(val->currentset, link);
|
||||
val->currentset = NULL;
|
||||
resume = ISC_FALSE;
|
||||
}
|
||||
else
|
||||
} else
|
||||
rdataset = ISC_LIST_HEAD(name->list);
|
||||
|
||||
for (;
|
||||
@@ -1465,7 +1602,6 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
||||
}
|
||||
if (sigrdataset == NULL)
|
||||
continue;
|
||||
val->seensig = ISC_TRUE;
|
||||
/*
|
||||
* If a signed zone is missing the zone key, bad
|
||||
* things could happen. A query for data in the zone
|
||||
@@ -1508,6 +1644,46 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
/*
|
||||
* Do we only need to check for NOQNAME?
|
||||
*/
|
||||
if ((val->attributes & VALATTR_NEEDNODATA) == 0 &&
|
||||
(val->attributes & VALATTR_NEEDNOWILDCARD) == 0 &&
|
||||
(val->attributes & VALATTR_NEEDNOQNAME) != 0) {
|
||||
if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"noqname proof found");
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"marking as secure");
|
||||
val->event->rdataset->trust = dns_trust_secure;
|
||||
val->event->sigrdataset->trust = dns_trust_secure;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"noqname proof not found");
|
||||
return (DNS_R_NOVALIDNSEC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do we need to check for the wildcard?
|
||||
*/
|
||||
if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0 &&
|
||||
(((val->attributes & VALATTR_NEEDNODATA) != 0 &&
|
||||
(val->attributes & VALATTR_FOUNDNODATA) == 0) ||
|
||||
(val->attributes & VALATTR_NEEDNOWILDCARD) != 0)) {
|
||||
result = checkwildcard(val);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (((val->attributes & VALATTR_NEEDNODATA) != 0 &&
|
||||
(val->attributes & VALATTR_FOUNDNODATA) != 0) ||
|
||||
((val->attributes & VALATTR_NEEDNOQNAME) != 0 &&
|
||||
(val->attributes & VALATTR_FOUNDNOQNAME) != 0 &&
|
||||
(val->attributes & VALATTR_NEEDNOWILDCARD) != 0 &&
|
||||
(val->attributes & VALATTR_FOUNDNOWILDCARD) != 0))
|
||||
val->attributes |= VALATTR_FOUNDNONEXISTENCE;
|
||||
|
||||
if ((val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0) {
|
||||
if (!val->seensig && val->soaset != NULL) {
|
||||
result = create_validator(val, name, dns_rdatatype_soa,
|
||||
@@ -1528,6 +1704,27 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
|
||||
}
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
check_ds_algorithm(dns_validator_t *val, dns_name_t *name,
|
||||
dns_rdataset_t *rdataset) {
|
||||
dns_rdata_t dsrdata = DNS_RDATA_INIT;
|
||||
dns_rdata_ds_t ds;
|
||||
isc_result_t result;
|
||||
|
||||
for (result = dns_rdataset_first(rdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(rdataset)) {
|
||||
dns_rdataset_current(rdataset, &dsrdata);
|
||||
(void)dns_rdata_tostruct(&dsrdata, &ds, NULL);
|
||||
|
||||
if (dns_resolver_algorithm_supported(val->view->resolver,
|
||||
name, ds.algorithm))
|
||||
return (ISC_TRUE);
|
||||
dns_rdata_reset(&dsrdata);
|
||||
}
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
|
||||
isc_result_t result;
|
||||
@@ -1552,6 +1749,15 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
|
||||
dns_name_countlabels(dns_fixedname_name(&secroot)) + 1;
|
||||
} else {
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");
|
||||
if (val->frdataset.trust >= dns_trust_secure &&
|
||||
!check_ds_algorithm(val, dns_fixedname_name(&val->fname),
|
||||
&val->frdataset)) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"no supported algorithm (ds)");
|
||||
val->event->rdataset->trust = dns_trust_answer;
|
||||
result = ISC_R_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
val->labels++;
|
||||
}
|
||||
|
||||
@@ -1561,14 +1767,13 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
|
||||
{
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
|
||||
if (val->labels == dns_name_countlabels(val->event->name)) {
|
||||
tname = val->event->name;
|
||||
} else {
|
||||
dns_fixedname_init(&val->fname);
|
||||
tname = dns_fixedname_name(&val->fname);
|
||||
if (val->labels == dns_name_countlabels(val->event->name))
|
||||
dns_name_copy(val->event->name, tname, NULL);
|
||||
else
|
||||
dns_name_split(val->event->name, val->labels,
|
||||
NULL, tname);
|
||||
}
|
||||
|
||||
dns_name_format(tname, namebuf, sizeof(namebuf));
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
@@ -1601,8 +1806,18 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
|
||||
* There is a DS here. Verify that it's secure and
|
||||
* continue.
|
||||
*/
|
||||
if (val->frdataset.trust >= dns_trust_secure)
|
||||
if (val->frdataset.trust >= dns_trust_secure) {
|
||||
if (!check_ds_algorithm(val, tname,
|
||||
&val->frdataset)) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"no supported algorithm (ds)");
|
||||
val->event->rdataset->trust =
|
||||
dns_trust_answer;
|
||||
result = ISC_R_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (!dns_rdataset_isassociated(&val->fsigrdataset))
|
||||
{
|
||||
result = DNS_R_NOVALIDSIG;
|
||||
@@ -1728,6 +1943,11 @@ validator_start(isc_task_t *task, isc_event_t *event) {
|
||||
"attempting negative response validation");
|
||||
|
||||
val->attributes |= VALATTR_NEGATIVE;
|
||||
if (val->event->message->rcode == dns_rcode_nxdomain) {
|
||||
val->attributes |= VALATTR_NEEDNOQNAME;
|
||||
val->attributes |= VALATTR_NEEDNOWILDCARD;
|
||||
} else
|
||||
val->attributes |= VALATTR_NEEDNODATA;
|
||||
result = nsecvalidate(val, ISC_FALSE);
|
||||
} else {
|
||||
/*
|
||||
@@ -1790,6 +2010,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
||||
event->rdataset = rdataset;
|
||||
event->sigrdataset = sigrdataset;
|
||||
event->message = message;
|
||||
memset(event->proofs, 0, sizeof(event->proofs));
|
||||
result = isc_mutex_init(&val->lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_event;
|
||||
@@ -1817,6 +2038,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
||||
val->seensig = ISC_FALSE;
|
||||
dns_rdataset_init(&val->frdataset);
|
||||
dns_rdataset_init(&val->fsigrdataset);
|
||||
dns_fixedname_init(&val->wild);
|
||||
ISC_LINK_INIT(val, link);
|
||||
val->magic = VALIDATOR_MAGIC;
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: namedconf.c,v 1.24 2003/09/25 18:16:50 jinmei Exp $ */
|
||||
/* $Id: namedconf.c,v 1.25 2004/01/14 02:06:51 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -618,6 +618,21 @@ static cfg_type_t cfg_type_optional_exclude = {
|
||||
"optional_exclude", parse_optional_keyvalue, print_keyvalue,
|
||||
doc_optional_keyvalue, &cfg_rep_list, &exclude_kw };
|
||||
|
||||
static cfg_type_t cfg_type_algorithmlist = {
|
||||
"algorithmlist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
|
||||
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring };
|
||||
|
||||
static cfg_tuplefielddef_t disablealgorithm_fields[] = {
|
||||
{ "name", &cfg_type_astring, 0 },
|
||||
{ "algorithms", &cfg_type_algorithmlist, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static cfg_type_t cfg_type_disablealgorithm = {
|
||||
"disablealgorithm", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
|
||||
&cfg_rep_tuple, disablealgorithm_fields
|
||||
};
|
||||
|
||||
/*
|
||||
* Clauses that can be found within the 'view' statement,
|
||||
* with defaults in the 'options' statement.
|
||||
@@ -661,6 +676,8 @@ view_clauses[] = {
|
||||
{ "dual-stack-servers", &cfg_type_nameportiplist, 0 },
|
||||
{ "edns-udp-size", &cfg_type_uint32, 0 },
|
||||
{ "root-delegation-only", &cfg_type_optional_exclude, 0 },
|
||||
{ "disable-algorithms", &cfg_type_disablealgorithm,
|
||||
CFG_CLAUSEFLAG_MULTI },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user