+2828. [security] Cached CNAME or DNAME RR could be returned to clients
+ without DNSSEC validation. [RT #20737]
+
2827. [security] Bogus NXDOMAIN could be cached as if valid. [RT #20712]
2826. [bug] NSEC3->NSEC transitions could fail due to a lock not
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.335 2009/11/28 15:57:36 vjs Exp $ */
+/* $Id: query.c,v 1.336 2009/12/30 08:02:22 jinmei Exp $ */
/*! \file */
dns_rdataset_t *noqname;
isc_boolean_t resuming;
int line = -1;
- dns_rdataset_t tmprdataset;
- unsigned int dboptions;
CTRACE("query_find");
/*
* Now look for an answer in the database.
*/
- dboptions = client->query.dboptions;
- if (sigrdataset == NULL && client->view->enablednssec) {
- /*
- * If the client doesn't want DNSSEC we still want to
- * look for any data pending validation to save a remote
- * lookup if possible.
- */
- dns_rdataset_init(&tmprdataset);
- sigrdataset = &tmprdataset;
- dboptions |= DNS_DBFIND_PENDINGOK;
- }
- refind:
result = dns_db_find(db, client->query.qname, version, type,
- dboptions, client->now, &node, fname,
- rdataset, sigrdataset);
- /*
- * If we have found pending data try to validate it.
- * If the data does not validate as secure and we can't
- * use the unvalidated data requery the database with
- * pending disabled to prevent infinite looping.
- */
- if (result != ISC_R_SUCCESS || !DNS_TRUST_PENDING(rdataset->trust))
- goto validation_done;
- if (validate(client, db, fname, rdataset, sigrdataset))
- goto validation_done;
- if (rdataset->trust != dns_trust_pending_answer ||
- !PENDINGOK(client->query.dboptions)) {
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(sigrdataset))
- dns_rdataset_disassociate(sigrdataset);
- if (sigrdataset == &tmprdataset)
- sigrdataset = NULL;
- dns_db_detachnode(db, &node);
- dboptions &= ~DNS_DBFIND_PENDINGOK;
- goto refind;
- }
- validation_done:
- if (sigrdataset == &tmprdataset) {
- if (dns_rdataset_isassociated(sigrdataset))
- dns_rdataset_disassociate(sigrdataset);
- sigrdataset = NULL;
- }
+ client->query.dboptions, client->now,
+ &node, fname, rdataset, sigrdataset);
resume:
CTRACE("query_find: resume");
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.138 2009/12/05 23:31:40 each Exp $
+# $Id: Makefile.in,v 1.139 2009/12/30 08:02:22 jinmei Exp $
srcdir = @srcdir@
VPATH = @srcdir@
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rwlock_test.@O@ \
${ISCLIBS} ${LIBS}
+rwlock_upgradetest@EXEEXT@: rwlock_upgradetest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGSe} -o $@ rwlock_upgradetest.@O@ \
+ ${ISCLIBS} ${LIBS}
+
wire_test@EXEEXT@: wire_test.@O@ printmsg.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ wire_test.@O@ printmsg.@O@ \
${DNSLIBS} ${ISCLIBS} ${LIBS}
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: example.db.in,v 1.21 2009/10/27 23:47:44 tbox Exp $
+; $Id: example.db.in,v 1.22 2009/12/30 08:02:22 jinmei Exp $
$TTL 300 ; 5 minutes
@ IN SOA mname1. . (
foo TXT "testing"
foo A 10.0.1.0
+bad-cname CNAME a
+bad-dname DNAME @
+
; Used for testing CNAME queries
cname1 CNAME cname1-target
cname1-target TXT "testing cname"
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: sign.sh,v 1.35 2009/10/28 00:27:10 marka Exp $
+# $Id: sign.sh,v 1.36 2009/12/30 08:02:22 jinmei Exp $
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
$SIGNER -P -g -r $RANDFILE -o $zone -k $keyname1 $zonefile $keyname2 > /dev/null
+#
+# lower/uppercase the signature bits with the exception of the last characters
+# changing the last 4 characters will lead to a bad base64 encoding.
+#
+$CHECKZONE -D -q -i local $zone $zonefile.signed |
+awk '
+tolower($1) == "bad-cname.example." && $4 == "RRSIG" && $5 == "CNAME" {
+ for (i = 1; i <= NF; i++ ) {
+ if (i <= 12) {
+ printf("%s ", $i);
+ continue;
+ }
+ prefix = substr($i, 1, length($i) - 4);
+ suffix = substr($i, length($i) - 4, 4);
+ if (i > 12 && tolower(prefix) != prefix)
+ printf("%s%s", tolower(prefix), suffix);
+ else if (i > 12 && toupper(prefix) != prefix)
+ printf("%s%s", toupper(prefix), suffix);
+ else
+ printf("%s%s ", prefix, suffix);
+ }
+ printf("\n");
+ next;
+}
+
+tolower($1) == "bad-dname.example." && $4 == "RRSIG" && $5 == "DNAME" {
+ for (i = 1; i <= NF; i++ ) {
+ if (i <= 12) {
+ printf("%s ", $i);
+ continue;
+ }
+ prefix = substr($i, 1, length($i) - 4);
+ suffix = substr($i, length($i) - 4, 4);
+ if (i > 12 && tolower(prefix) != prefix)
+ printf("%s%s", tolower(prefix), suffix);
+ else if (i > 12 && toupper(prefix) != prefix)
+ printf("%s%s", toupper(prefix), suffix);
+ else
+ printf("%s%s ", prefix, suffix);
+ }
+ printf("\n");
+ next;
+}
+
+{ print; }' > $zonefile.signed++ && mv $zonefile.signed++ $zonefile.signed
+
+
# Sign the privately secure file
privzone=private.secure.example.
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: tests.sh,v 1.55 2009/10/27 23:47:44 tbox Exp $
+# $Id: tests.sh,v 1.56 2009/12/30 08:02:22 jinmei Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
+echo "I:Checking that a bad CNAME signature is caught after a +CD query ($n)"
+ret=0
+#prime
+$DIG $DIGOPTS +cd bad-cname.example. @10.53.0.4 > dig.out.ns4.prime$n || ret=1
+#check: requery with +CD. pending data should be returned even if it's bogus
+expect="a.example.
+10.0.0.1"
+ans=`$DIG $DIGOPTS +cd +nodnssec +short bad-cname.example. @10.53.0.4` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+#check: requery without +CD. bogus cached data should be rejected.
+$DIG $DIGOPTS +nodnssec bad-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
+grep "SERVFAIL" 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 that a bad DNAME signature is caught after a +CD query ($n)"
+ret=0
+#prime
+$DIG $DIGOPTS +cd a.bad-dname.example. @10.53.0.4 > dig.out.ns4.prime$n || ret=1
+#check: requery with +CD. pending data should be returned even if it's bogus
+expect="example.
+a.example.
+10.0.0.1"
+ans=`$DIG $DIGOPTS +cd +nodnssec +short a.bad-dname.example. @10.53.0.4` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+#check: requery without +CD. bogus cached data should be rejected.
+$DIG $DIGOPTS +nodnssec a.bad-dname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
+grep "SERVFAIL" 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.secure.example domain (insecurity proof)
echo "I:checking 2-server insecurity proof ($n)"
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: clean.sh,v 1.3 2009/12/03 04:51:41 marka Exp $
+# $Id: clean.sh,v 1.4 2009/12/30 08:02:22 jinmei Exp $
rm -rf */*.signed
+rm -rf */*.jnl
rm -rf */K*
rm -rf */dsset-*
rm -rf */named.memstats
rm -rf */trusted.conf
rm -rf ns1/root.db
rm -rf ns2/example.db
+rm -rf ns2/example.com.db
rm -rf random.data
+rm -rf nsupdate.out.test
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: root.db.in,v 1.3 2009/11/18 23:48:06 tbox Exp $
+; $Id: root.db.in,v 1.4 2009/12/30 08:02:22 jinmei Exp $
$TTL 30
. IN SOA marka.isc.org. a.root.servers.nil. (
example. NS ns2.example.
ns2.example. A 10.53.0.2
+example.com. NS ns2.example.com.
+ns2.example.com. A 10.53.0.2
hostile. NS ns3.hostile.
ns3.hostile. A 10.53.0.3
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: sign.sh,v 1.2 2009/11/17 23:55:18 marka Exp $
+# $Id: sign.sh,v 1.3 2009/12/30 08:02:22 jinmei Exp $
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
(cd ../ns2 && sh -e sign.sh )
cp ../ns2/dsset-example. .
+cp ../ns2/dsset-example.com. .
keyname1=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone $zone`
keyname2=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 2048 -f KSK -n zone $zone`
--- /dev/null
+; Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+; $Id: example.com.db.in,v 1.2 2009/12/30 08:02:22 jinmei Exp $
+
+$TTL 30
+@ IN SOA mname1. . (
+ 2009110300 ; serial
+ 20 ; refresh (20 seconds)
+ 20 ; retry (20 seconds)
+ 1814400 ; expire (3 weeks)
+ 3600 ; minimum (1 hour)
+ )
+ NS ns2
+ MX 10 mail
+ns2 A 10.53.0.2
+mail A 192.0.2.2
+ AAAA 2001:db8::2
+pending-ok A 192.0.2.2
+pending-ng A 192.0.2.102
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named.conf,v 1.3 2009/11/18 23:48:06 tbox Exp $ */
+/* $Id: named.conf,v 1.4 2009/12/30 08:02:22 jinmei Exp $ */
// NS2
type master;
file "example.db.signed";
};
+
+zone "example.com" {
+ type master;
+ file "example.com.db.signed";
+ allow-update { 10.53.0.0/8; };
+};
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: sign.sh,v 1.3 2009/11/18 23:48:07 tbox Exp $
+# $Id: sign.sh,v 1.4 2009/12/30 08:02:22 jinmei Exp $
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
RANDFILE=../random.data
-zone=example.
-infile=example.db.in
-zonefile=example.db
+for domain in example example.com; do
+ zone=${domain}.
+ infile=${domain}.db.in
+ zonefile=${domain}.db
-keyname1=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
-keyname2=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -f KSK -n zone $zone`
+ keyname1=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
+ keyname2=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -f KSK -n zone $zone`
-cat $infile $keyname1.key $keyname2.key >$zonefile
+ cat $infile $keyname1.key $keyname2.key >$zonefile
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+ $SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+done
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: tests.sh,v 1.3 2009/11/18 23:48:06 tbox Exp $
+# $Id: tests.sh,v 1.4 2009/12/30 08:02:22 jinmei Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
+# replace_data dname RR old_data new_data
+replace_data()
+{
+ if [ $# -ne 4 ]; then
+ echo I:unexpected input for replace_data
+ return 1
+ fi
+
+ _dname=$1
+ _rr=$2
+ _olddata=$3
+ _newdata=$4
+
+ _ret=0
+ $NSUPDATE -d <<END>> nsupdate.out.test 2>&1 || _ret=1
+server 10.53.0.2 5300
+update delete ${_dname} 30 ${_rr} ${_olddata}
+update add ${_dname} 30 ${_rr} ${_newdata}
+send
+END
+
+ if [ $_ret != 0 ]; then
+ echo I:failed to update the test data
+ return 1
+ fi
+
+ return 0
+}
+
status=0
n=0
-rm -f dig.out.*
-
-DIGOPTS="+short +tcp +cd -p 5300"
+DIGOPTS="+short +tcp -p 5300"
+DIGOPTS_CD="$DIGOPTS +cd"
echo I:Priming cache.
ret=0
expect="10 mail.example."
-ans=`$DIG $DIGOPTS @10.53.0.4 hostile MX` || ret=1
+ans=`$DIG $DIGOPTS_CD @10.53.0.4 hostile MX` || ret=1
test "$ans" = "$expect" || ret=1
test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
status=`expr $status + $ret`
echo I:Checking that bogus additional is not returned with +CD.
ret=0
expect="10.0.0.2"
-ans=`$DIG $DIGOPTS @10.53.0.4 mail.example A` || ret=1
+ans=`$DIG $DIGOPTS_CD @10.53.0.4 mail.example A` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+status=`expr $status + $ret`
+
+#
+# Prime cache with pending additional records. These should not be promoted
+# to answer.
+#
+echo "I:Priming cache (pending additional A and AAAA)"
+ret=0
+expect="10 mail.example.com."
+ans=`$DIG $DIGOPTS @10.53.0.4 example.com MX` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+status=`expr $status + $ret`
+
+echo "I:Replacing pending A"
+ret=0
+replace_data mail.example.com. A 192.0.2.2 192.0.2.3 || ret=1
+status=`expr $status + $ret`
+
+echo "I:Replacing pending AAAA"
+ret=0
+replace_data mail.example.com. AAAA 2001:db8::2 2001:db8::3 || ret=1
+status=`expr $status + $ret`
+
+echo "I:Checking updated data to be returned (without CD)"
+ret=0
+expect="192.0.2.3"
+ans=`$DIG $DIGOPTS @10.53.0.4 mail.example.com A` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+status=`expr $status + $ret`
+
+echo "I:Checking updated data to be returned (with CD)"
+ret=0
+expect="2001:db8::3"
+ans=`$DIG $DIGOPTS_CD @10.53.0.4 mail.example.com AAAA` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+status=`expr $status + $ret`
+
+#
+# Prime cache with a pending answer record. It can be returned (without
+# validation) with +CD.
+#
+echo "I:Priming cache (pending answer)"
+ret=0
+expect="192.0.2.2"
+ans=`$DIG $DIGOPTS_CD @10.53.0.4 pending-ok.example.com A` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+status=`expr $status + $ret`
+
+echo I:Replacing pending data
+ret=0
+replace_data pending-ok.example.com. A 192.0.2.2 192.0.2.3 || ret=1
+status=`expr $status + $ret`
+
+echo I:Confirming cached pending data to be returned with CD
+ret=0
+expect="192.0.2.2"
+ans=`$DIG $DIGOPTS_CD @10.53.0.4 pending-ok.example.com A` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+status=`expr $status + $ret`
+
+#
+# Prime cache with a pending answer record. It should not be returned
+# to no-DNSSEC clients.
+#
+echo "I:Priming cache (pending answer)"
+ret=0
+expect="192.0.2.102"
+ans=`$DIG $DIGOPTS_CD @10.53.0.4 pending-ng.example.com A` || ret=1
+test "$ans" = "$expect" || ret=1
+test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
+status=`expr $status + $ret`
+
+echo I:Replacing pending data
+ret=0
+replace_data pending-ng.example.com. A 192.0.2.102 192.0.2.103 || ret=1
+status=`expr $status + $ret`
+
+echo I:Confirming updated data returned, not the cached one, without CD
+ret=0
+expect="192.0.2.103"
+ans=`$DIG $DIGOPTS @10.53.0.4 pending-ng.example.com A` || ret=1
test "$ans" = "$expect" || ret=1
test $ret = 0 || echo I:failed, got "'""$ans""'", expected "'""$expect""'"
status=`expr $status + $ret`
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.138 2009/11/17 23:55:18 marka Exp $ */
+/* $Id: types.h,v 1.139 2009/12/30 08:02:23 jinmei Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
#define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \
(x) == dns_trust_pending_additional)
+#define DNS_TRUST_ADDITIONAL(x) ((x) == dns_trust_additional || \
+ (x) == dns_trust_pending_additional)
#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue)
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.295 2009/12/29 22:04:16 marka Exp $ */
+/* $Id: rbtdb.c,v 1.296 2009/12/30 08:02:23 jinmei Exp $ */
/*! \file */
* If we didn't find what we were looking for...
*/
if (found == NULL ||
- (found->trust == dns_trust_additional &&
+ (DNS_TRUST_ADDITIONAL(found->trust) &&
((options & DNS_DBFIND_ADDITIONALOK) == 0)) ||
(found->trust == dns_trust_glue &&
((options & DNS_DBFIND_GLUEOK) == 0)) ||