cp trusted.conf ../ns4/trusted.conf
cp trusted.conf ../ns6/trusted.conf
cp trusted.conf ../ns7/trusted.conf
+cp trusted.conf ../ns9/trusted.conf
# ...or with a managed key.
keyfile_to_managed_keys $keyname > managed.conf
echo_i "ns2/sign.sh"
# Get the DS records for the "trusted." and "managed." zones.
-for subdomain in secure unsupported disabled enabled
+for subdomain in secure unsupported
do
cp ../ns3/dsset-$subdomain.managed$TP .
cp ../ns3/dsset-$subdomain.trusted$TP .
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+// NS9
+
+options {
+ query-source address 10.53.0.9;
+ notify-source 10.53.0.9;
+ transfer-source 10.53.0.9;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.9; };
+ listen-on-v6 { none; };
+ recursion yes;
+ dnssec-enable yes;
+ dnssec-validation yes;
+ forward only;
+ forwarders { 10.53.0.4; };
+};
+
+key rndc_key {
+ secret "1234abcd8765";
+ algorithm hmac-sha256;
+};
+
+controls {
+ inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+include "trusted.conf";
copy_setports ns6/named.conf.in ns6/named.conf
copy_setports ns7/named.conf.in ns7/named.conf
copy_setports ns8/named.conf.in ns8/named.conf
+copy_setports ns9/named.conf.in ns9/named.conf
cd ns1
$SHELL sign.sh
if [ $ret != 0 ]; then echo_i "failed - NTA lifetime clamping failed"; fi
status=`expr $status + $ret`
-ret=0
+
+n=`expr $n + 1`
+echo_i "checking that NTAs work with 'forward only;' to a validating resolver ($n)"
+ret=0
+# Sanity check behavior without an NTA in place.
+$DIG $DIGOPTS @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.1 || ret=1
+grep "SERVFAIL" dig.out.ns9.test$n.1 > /dev/null || ret=1
+grep "ANSWER: 0" dig.out.ns9.test$n.1 > /dev/null || ret=1
+grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.1 > /dev/null && ret=1
+# Add an NTA, expecting that to cause resolution to succeed.
+$RNDCCMD 10.53.0.9 nta badds.example > rndc.out.ns9.test$n.1 2>&1 || ret=1
+$DIG $DIGOPTS @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.2 || ret=1
+grep "NOERROR" dig.out.ns9.test$n.2 > /dev/null || ret=1
+grep "ANSWER: 2" dig.out.ns9.test$n.2 > /dev/null || ret=1
+grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.2 > /dev/null && ret=1
+# Remove the NTA, expecting that to cause resolution to fail again.
+$RNDCCMD 10.53.0.9 nta -remove badds.example > rndc.out.ns9.test$n.2 2>&1 || ret=1
+$DIG $DIGOPTS @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.3 || ret=1
+grep "SERVFAIL" dig.out.ns9.test$n.3 > /dev/null || ret=1
+grep "ANSWER: 0" dig.out.ns9.test$n.3 > /dev/null || ret=1
+grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.3 > /dev/null && ret=1
+if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
echo_i "completed NTA tests"
isc_result_t
dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
- isc_stdtime_t now, bool checknta,
+ isc_stdtime_t now, bool checknta, bool *ntap,
bool *secure_domain);
/*%<
* Is 'name' at or beneath a trusted key, and not covered by a valid
* negative trust anchor? Put answer in '*secure_domain'.
*
* If 'checknta' is false, ignore the NTA table in determining
- * whether this is a secure domain.
+ * whether this is a secure domain. If 'checknta' is not false, and if
+ * 'ntap' is non-NULL, then '*ntap' will be updated with true if the
+ * name is covered by an NTA.
*
* Requires:
* \li 'view' is valid.
static isc_result_t
issecuredomain(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
- isc_stdtime_t now, bool checknta,
- bool *issecure)
+ isc_stdtime_t now, bool checknta, bool *ntap, bool *issecure)
{
dns_name_t suffix;
unsigned int labels;
name = &suffix;
}
- return (dns_view_issecuredomain(view, name, now, checknta, issecure));
+ return (dns_view_issecuredomain(view, name, now, checknta,
+ ntap, issecure));
}
static bool
isc_result_t result;
isc_stdtime_t now;
- if (!fctx->res->view->enablevalidation)
+ if (!fctx->res->view->enablevalidation) {
return (false);
+ }
- if (fctx->res->view->dlv != NULL)
+ if (fctx->res->view->dlv != NULL) {
return (true);
+ }
isc_stdtime_get(&now);
result = dns_view_issecuredomain(fctx->res->view, &fctx->name,
- now, true, &secure_domain);
- if (result != ISC_R_SUCCESS)
+ now, true, NULL, &secure_domain);
+ if (result != ISC_R_SUCCESS) {
return (false);
+ }
return (secure_domain);
}
* question is under a secure entry point and this is a
* recursive/forward query -- unless the client said not to.
*/
- if ((query->options & DNS_FETCHOPT_NOCDFLAG) != 0)
+ if ((query->options & DNS_FETCHOPT_NOCDFLAG) != 0) {
/* Do nothing */
- ;
- else if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0)
+ } else if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
- else if (res->view->enablevalidation &&
- ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0))
+ } else if (res->view->enablevalidation &&
+ ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0))
{
bool checknta = ((query->options & DNS_FETCHOPT_NONTA) == 0);
+ bool ntacovered = false;
result = issecuredomain(res->view, &fctx->name, fctx->type,
isc_time_seconds(&query->start),
- checknta, &secure_domain);
- if (result != ISC_R_SUCCESS)
+ checknta, &ntacovered, &secure_domain);
+ if (result != ISC_R_SUCCESS) {
secure_domain = false;
- if (res->view->dlv != NULL)
+ }
+ if (res->view->dlv != NULL) {
secure_domain = true;
- if (secure_domain)
+ }
+
+ if (secure_domain ||
+ (ISFORWARDER(query->addrinfo) && ntacovered))
+ {
fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
+ }
}
/*
if (res->view->enablevalidation) {
result = issecuredomain(res->view, name, fctx->type,
- now, checknta, &secure_domain);
+ now, checknta, NULL, &secure_domain);
if (result != ISC_R_SUCCESS) {
return (result);
}
if (fctx->res->view->enablevalidation) {
result = issecuredomain(res->view, name, fctx->type,
- now, checknta, &secure_domain);
+ now, checknta, NULL, &secure_domain);
if (result != ISC_R_SUCCESS)
return (result);
/* Should be secure */
result = dns_view_issecuredomain(myview,
str2name("test.secure.example"),
- now, true, &issecure);
+ now, true, &covered, &issecure);
assert_int_equal(result, ISC_R_SUCCESS);
+ assert_false(covered);
assert_true(issecure);
/* Should not be secure */
result = dns_view_issecuredomain(myview,
str2name("test.insecure.example"),
- now, true, &issecure);
+ now, true, &covered, &issecure);
assert_int_equal(result, ISC_R_SUCCESS);
+ assert_true(covered);
assert_false(issecure);
/* NTA covered */
/* As of now + 2, the NTA should be clear */
result = dns_view_issecuredomain(myview,
str2name("test.insecure.example"),
- now + 2, true, &issecure);
+ now + 2, true, &covered, &issecure);
assert_int_equal(result, ISC_R_SUCCESS);
+ assert_false(covered);
assert_true(issecure);
/* Now check deletion */
result = dns_view_issecuredomain(myview, str2name("test.new.example"),
- now, true, &issecure);
+ now, true, &covered, &issecure);
assert_int_equal(result, ISC_R_SUCCESS);
+ assert_false(covered);
assert_true(issecure);
result = dns_ntatable_add(ntatable, str2name("new.example"),
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_view_issecuredomain(myview, str2name("test.new.example"),
- now, true, &issecure);
+ now, true, &covered, &issecure);
assert_int_equal(result, ISC_R_SUCCESS);
+ assert_true(covered);
assert_false(issecure);
result = dns_ntatable_delete(ntatable, str2name("new.example"));
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_view_issecuredomain(myview, str2name("test.new.example"),
- now, true, &issecure);
+ now, true, &covered, &issecure);
assert_int_equal(result, ISC_R_SUCCESS);
+ assert_false(covered);
assert_true(issecure);
/* Clean up */
isc_result_t
dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
- isc_stdtime_t now, bool checknta,
+ isc_stdtime_t now, bool checknta, bool *ntap,
bool *secure_domain)
{
isc_result_t result;
REQUIRE(DNS_VIEW_VALID(view));
- if (view->secroots_priv == NULL)
+ if (view->secroots_priv == NULL) {
return (ISC_R_NOTFOUND);
+ }
anchor = dns_fixedname_initname(&fn);
result = dns_keytable_issecuredomain(view->secroots_priv, name,
anchor, &secure);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
return (result);
+ }
+ if (ntap != NULL) {
+ *ntap = false;
+ }
if (checknta && secure && view->ntatable_priv != NULL &&
dns_ntatable_covered(view->ntatable_priv, now, name, anchor))
+ {
+ if (ntap != NULL) {
+ *ntap = true;
+ }
secure = false;
+ }
*secure_domain = secure;
return (ISC_R_SUCCESS);
./bin/tests/system/dnssec/ns7/sign.sh SH 2014,2016,2018,2019
./bin/tests/system/dnssec/ns7/split-rrsig.db.in ZONE 2014,2016,2018,2019
./bin/tests/system/dnssec/ns8/named.conf.in CONF-C 2019
+./bin/tests/system/dnssec/ns9/named.conf.in CONF-C 2019
./bin/tests/system/dnssec/ntadiff.pl PERL 2015,2016,2018,2019
./bin/tests/system/dnssec/prereq.sh SH 2000,2001,2002,2004,2006,2007,2009,2012,2014,2015,2016,2018,2019
./bin/tests/system/dnssec/setup.sh SH 2000,2001,2004,2007,2009,2011,2012,2013,2014,2015,2016,2018,2019