Commit 2f17238f authored by Evan Hunt's avatar Evan Hunt
Browse files

Merge branch '997-make-ntas-work-with-validating-forwarders' into 'master'

Make NTAs work with validating forwarders

Closes #997

See merge request isc-projects/bind9!1859
parents 7d1a7c46 5be7c6f4
5232. [bug] Negative trust anchors did not work with "forward only;"
to validating resolvers. [GL #997]
5231. [protocol] Add support for displaying CLIENT-TAG and SERVER-TAG.
[GL #960]
 
......
......@@ -44,6 +44,7 @@ cp trusted.conf ../ns3/trusted.conf
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
......
/*
* 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";
......@@ -27,6 +27,8 @@ 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
......
......@@ -2300,9 +2300,31 @@ fi
# cleanup
rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.3 2>/dev/null
n=$((n+1))
if [ "$ret" -ne 0 ]; then echo_i "failed - NTA lifetime clamping failed"; fi
status=$((status+ret))
ret=0
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_with_opts @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_with_opts @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_with_opts @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=$((status+ret))
echo_i "completed NTA tests"
......
......@@ -1189,14 +1189,16 @@ dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp);
isc_result_t
dns_view_issecuredomain(dns_view_t *view, const 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.
......
......@@ -2326,8 +2326,7 @@ compute_cc(resquery_t *query, unsigned char *cookie, size_t len) {
static isc_result_t
issecuredomain(dns_view_t *view, const 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;
......@@ -2345,7 +2344,8 @@ issecuredomain(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
name = &suffix;
}
return (dns_view_issecuredomain(view, name, now, checknta, issecure));
return (dns_view_issecuredomain(view, name, now, checknta,
ntap, issecure));
}
static isc_result_t
......@@ -2449,24 +2449,30 @@ resquery_send(resquery_t *query) {
* 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;
}
}
/*
......@@ -5921,7 +5927,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
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);
}
......@@ -6516,7 +6522,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
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);
......
......@@ -674,15 +674,17 @@ nta_test(void **state) {
/* 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 */
......@@ -698,14 +700,16 @@ nta_test(void **state) {
/* 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"),
......@@ -713,16 +717,18 @@ nta_test(void **state) {
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 */
......
......@@ -1908,7 +1908,7 @@ dns_view_ntacovers(dns_view_t *view, isc_stdtime_t now,
isc_result_t
dns_view_issecuredomain(dns_view_t *view, const 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;
......@@ -1918,19 +1918,29 @@ dns_view_issecuredomain(dns_view_t *view, const dns_name_t *name,
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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment