BIND 10 trac1580, updated. 48aa1e839cf475521de07bdc0d8c870bb29f335e [1580] Add Bad NSEC3 next_proof test.
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Feb 16 03:49:37 UTC 2012
The branch, trac1580 has been updated
via 48aa1e839cf475521de07bdc0d8c870bb29f335e (commit)
via 5af17f43de48dd58fe87b85d974a554ac0136b83 (commit)
from eb872b35100ce2b602064017cd2de8ab517ffb76 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 48aa1e839cf475521de07bdc0d8c870bb29f335e
Author: Xie Jiagui <xiejiagui at cnnic.cn>
Date: Thu Feb 16 11:48:46 2012 +0800
[1580] Add Bad NSEC3 next_proof test.
commit 5af17f43de48dd58fe87b85d974a554ac0136b83
Author: Xie Jiagui <xiejiagui at cnnic.cn>
Date: Thu Feb 16 10:05:46 2012 +0800
[1580] Add new comments to NSEC3 proves for NXDOMAIN,and fix the
construction of wildcard domain name.
-----------------------------------------------------------------------
Summary of changes:
src/bin/auth/query.cc | 50 +++++++++++++++++---------------
src/bin/auth/tests/query_unittest.cc | 52 +++++++++++++++++++++++++++++++++-
2 files changed, 78 insertions(+), 24 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc
index 2cb645c..cfb0ccb 100644
--- a/src/bin/auth/query.cc
+++ b/src/bin/auth/query.cc
@@ -171,48 +171,52 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
// is broken, 'nsec3' should be a valid NSEC3 RR. Likewise, the call to
// findNSEC3() in this method should result an FindNSEC3Result that proves
// the Closest Encloser Proof and non existent of matching wildcard.
-// If these assumptions aren't met due to a buggy data source implementation
-// or a broken zone, we'll let underlying libdns++ modules throw an exception,
-// which would result in either an SERVFAIL response or just ignoring the
-// query. We at least prevent a complete crash due to such broken behavior.
+// Firstly, the call to findNSEC3() set the recursive to true in order to
+// get the an NSEC3 RR that matches the closest (provable) encloser and
+// an NSEC3 RR that covers the "next closer" name to the closest encloser.
+// This corresponds to Section 7.2.1 of RFC 5155.
+// Then,construct the wildcard domain, call to findNSEC3() set the recursive
+// to false to get the prove that the wildcard that could have matched QNAME
+// also does not exist.
void
Query::addNSEC3NXDOMAINProof(ZoneFinder& finder) {
// Firstly get the NSEC3 proves for Closest Encloser Proof
+ // See section 7.2.1 of RFC 5155.
const ZoneFinder::FindNSEC3Result fresult1 = finder.findNSEC3(qname_,
true);
- if (fresult1.closest_proof->getRdataCount() == 0) {
- isc_throw(BadNSEC3, "NSEC3 for NXDOMAIN proving that matches the "
+ if (!fresult1.closest_proof) {
+ isc_throw(BadNSEC3, "NSEC3 RR for NXDOMAIN proving that matches the "
"closest encloser is empty.");
}
// Add the NSEC3 proving that matches the closest (provable) encloser.
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<AbstractRRset>(
- fresult1.closest_proof),
+ fresult1.closest_proof),
dnssec_);
- // Add the NSEC3 RR that covers the "next closer" name to the closest
- // encloser
- if (fresult1.next_proof) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- fresult1.next_proof),
- dnssec_);
+ if (!fresult1.next_proof) {
+ isc_throw(BadNSEC3, "NSEC3 RR for NXDOMAIN proving that covers the "
+ "next closer to the closest encloser is empty.");
}
+ // Add the NSEC3 RR that covers the "next closer" name to the closest
+ // encloser.
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<AbstractRRset>(
+ fresult1.next_proof),
+ dnssec_);
// Next, identify the best possible wildcard name that would match
// the query name. It's the longer common suffix with the qname
- // between the owner or the next domain of the NSEC that proves NXDOMAIN,
- // prefixed by the wildcard label, "*".
- const Name wildname(Name("*").concatenate(qname_.split(1)));
+ // between the owner and the 'matched' domain of the NSEC3 that
+ // proves NXDOMAIN,prefixed by the wildcard label, "*".
+ const Name wildname(Name("*").concatenate(
+ qname_.split(qname_.getLabelCount() - fresult1.closest_labels)));
const ZoneFinder::FindNSEC3Result fresult2 =
finder.findNSEC3(wildname, false);
- if (fresult2.closest_proof->getRdataCount() == 0) {
+ if (!fresult2.closest_proof) {
isc_throw(BadNSEC3, "NSEC3 for NXDOMAIN covering the wildcard "
"RR at the closest encloser is empty.");
}
- // Add the (no-) wildcard proof only when it's different from the NSEC
- // that proves NXDOMAIN; sometimes they can be the same.
- // Note: name comparison is relatively expensive. When we are at the
- // stage of performance optimization, we should consider optimizing this
- // for some optimized data source implementations.
+ // Add the wildcard proof only when it's different from the NSEC3 RR
+ // that covers the "next closer" name to the closest encloser.
if (fresult1.next_proof->getName() != fresult2.closest_proof->getName()) {
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<AbstractRRset>(
diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc
index 3873e55..8d82d97 100644
--- a/src/bin/auth/tests/query_unittest.cc
+++ b/src/bin/auth/tests/query_unittest.cc
@@ -195,6 +195,27 @@ getCommonRRSIGText(const string& type) {
"example.com. FAKEFAKEFAKE"));
}
+// A helper callback of masterLoad() used in InMemoryZoneFinderTest.
+void
+setRRset(RRsetPtr rrset, vector<RRsetPtr*>::iterator& it) {
+ *(*it) = rrset;
+ ++it;
+}
+
+// A helper function that converts a textual form of a single RR into a
+// RRsetPtr object. If it's SOA, origin must be set to its owner name;
+// otherwise masterLoad() will reject it.
+RRsetPtr
+textToRRset(const string& text_rrset, const Name& origin = Name::ROOT_NAME()) {
+ stringstream ss(text_rrset);
+ RRsetPtr rrset;
+ vector<RRsetPtr*> rrsets;
+ rrsets.push_back(&rrset);
+ masterLoad(ss, origin, RRClass::IN(),
+ boost::bind(setRRset, _1, rrsets.begin()));
+ return (rrset);
+}
+
// This is a mock Zone Finder class for testing.
// It is a derived class of ZoneFinder for the convenient of tests.
// Its find() method emulates the common behavior of protocol compliant
@@ -220,7 +241,8 @@ public:
rrclass_(RRClass::IN()),
include_rrsig_anyway_(false),
use_nsec3_(false),
- nsec_name_(origin_)
+ nsec_name_(origin_),
+ nsec3_fake_(NULL)
{
stringstream zone_stream;
zone_stream << soa_txt << zone_ns_txt << ns_addrs_txt <<
@@ -296,6 +318,14 @@ public:
nsec_result_.reset(new ZoneFinder::FindResult(code, rrset));
}
+ // Once called, the findNSEC3 will return the provided result for the next
+ // query. After that, it'll return to operate normally.
+ // NULL disables. Does not take ownership of the pointer (it is generally
+ // expected to be a local variable in the test function).
+ void setNSEC3Result(const FindNSEC3Result* result) {
+ nsec3_fake_ = result;
+ }
+
// If true is passed return an empty NSEC3 RRset for some negative
// answers when DNSSEC is required.
void setNSEC3Flag(bool on) { use_nsec3_ = on; }
@@ -387,6 +417,9 @@ private:
Name nsec_name_;
boost::scoped_ptr<ZoneFinder::FindResult> nsec_result_;
map<Name, string> hash_map_;
+ // The following two are for faking bad NSEC3 responses
+ // Enabled when not NULL
+ const FindNSEC3Result* nsec3_fake_;
};
// A helper function that generates a new RRset based on "wild_rrset",
@@ -430,6 +463,12 @@ MockZoneFinder::findAll(const Name& name, std::vector<ConstRRsetPtr>& target,
ZoneFinder::FindNSEC3Result
MockZoneFinder::findNSEC3(const Name& name, bool recursive) {
+ // Do we have a fake result set? If so, use it.
+ if (nsec3_fake_ != NULL) {
+ const FindNSEC3Result* result(nsec3_fake_);
+ return (*result);
+ }
+
ConstRRsetPtr covering_proof;
const int labels = name.getLabelCount();
@@ -1628,6 +1667,17 @@ TEST_F(QueryTest, findNSEC3) {
mock_finder->findNSEC3(Name("nxdomain3.example.com"), false));
}
+TEST_F(QueryTest, nxdomainWithBadNextNSEC3Proof) {
+ mock_finder->setNSEC3Flag(true);
+ ZoneFinder::FindNSEC3Result nsec3(true, 0, textToRRset(nsec3_apex_txt),
+ ConstRRsetPtr());
+ mock_finder->setNSEC3Result(&nsec3);
+
+ EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"),
+ RRType::TXT(), response, true).process(),
+ Query::BadNSEC3);
+}
+
TEST_F(QueryTest, nxdomainWithNSEC3Proof) {
mock_finder->setNSEC3Flag(true);
Query(memory_client, Name("nxdomain.example.com"), qtype,
More information about the bind10-changes
mailing list