Commit a915ddb9 authored by Jelte Jansen's avatar Jelte Jansen
Browse files

[master] Merge branch 'master' of ssh://git.bind10.isc.org/var/bind10/git/bind10

parents fe58afc5 5b2b5a2c
......@@ -117,7 +117,7 @@ Query::addSOA(ZoneFinder& finder) {
// either an SERVFAIL response or just ignoring the query. We at least prevent
// a complete crash due to such broken behavior.
void
Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
Query::addNXDOMAINProofByNSEC(ZoneFinder& finder, ConstRRsetPtr nsec) {
if (nsec->getRdataCount() == 0) {
isc_throw(BadNSEC, "NSEC for NXDOMAIN is empty");
}
......@@ -167,6 +167,40 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
}
}
void
Query::addNXDOMAINProofByNSEC3(ZoneFinder& finder) {
// Firstly get the NSEC3 proves for Closest Encloser Proof
// See section 7.2.1 of RFC 5155.
// Since this is a Name Error case both closest and next proofs should
// be available (see addNXRRsetProof).
const ZoneFinder::FindNSEC3Result fresult1 = finder.findNSEC3(qname_,
true);
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<AbstractRRset>(
fresult1.closest_proof),
dnssec_);
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<AbstractRRset>(
fresult1.next_proof),
dnssec_);
// Next, construct the wildcard name at the closest encloser, i.e.,
// '*' followed by the closest encloser, and add NSEC3 for it.
const Name wildname(Name("*").concatenate(
qname_.split(qname_.getLabelCount() -
fresult1.closest_labels)));
const ZoneFinder::FindNSEC3Result fresult2 =
finder.findNSEC3(wildname, false);
if (fresult2.matched) {
isc_throw(BadNSEC3, "Matching NSEC3 found for nonexistent domain "
<< wildname);
}
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<AbstractRRset>(
fresult2.closest_proof),
dnssec_);
}
void
Query::addWildcardProof(ZoneFinder& finder) {
// The query name shouldn't exist in the zone if there were no wildcard
......@@ -508,8 +542,12 @@ Query::process() {
case ZoneFinder::NXDOMAIN:
response_.setRcode(Rcode::NXDOMAIN());
addSOA(*result.zone_finder);
if (dnssec_ && db_result.rrset) {
addNXDOMAINProof(zfinder, db_result.rrset);
if (dnssec_) {
if (db_result.isNSECSigned() && db_result.rrset) {
addNXDOMAINProofByNSEC(zfinder, db_result.rrset);
} else if (db_result.isNSEC3Signed()) {
addNXDOMAINProofByNSEC3(zfinder);
}
}
break;
case ZoneFinder::NXRRSET:
......
......@@ -101,8 +101,13 @@ private:
/// Add NSEC RRs that prove an NXDOMAIN result.
///
/// This corresponds to Section 3.1.3.2 of RFC 4035.
void addNXDOMAINProof(isc::datasrc::ZoneFinder& finder,
isc::dns::ConstRRsetPtr nsec);
void addNXDOMAINProofByNSEC(isc::datasrc::ZoneFinder& finder,
isc::dns::ConstRRsetPtr nsec);
/// Add NSEC3 RRs that prove an NXDOMAIN result.
///
/// This corresponds to Section 7.2.2 of RFC 5155.
void addNXDOMAINProofByNSEC3(isc::datasrc::ZoneFinder& finder);
/// Add NSEC RRs that prove a wildcard answer is the best one.
///
......
......@@ -329,6 +329,8 @@ public:
"q00jkcevqvmu85r014c7dkba38o0ji5r";
hash_map_[Name("nxdomain3.example.com")] =
"009mhaveqvm6t7vbl5lop2u3t2rp3tom";
hash_map_[Name("*.example.com")] =
"r53bq7cc2uvmubfu5ocmm6pers9tk9en";
hash_map_[Name("unsigned-delegation.example.com")] =
"q81r598950igr1eqvc60aedlq66425b5"; // a bit larger than H(www)
hash_map_[Name("*.uwild.example.com")] =
......@@ -371,7 +373,8 @@ public:
ConstRRsetPtr rrset)
{
nsec_name_ = nsec_name;
nsec_result_.reset(new ZoneFinder::FindResult(code, rrset));
nsec_result_.reset(new ZoneFinder::FindResult(code, rrset,
RESULT_NSEC_SIGNED));
}
// Once called, the findNSEC3 will return the provided result for the next
......@@ -2146,19 +2149,79 @@ TEST_F(QueryTest, nxrrsetWithNSEC3_ds_no_exact) {
NULL, mock_finder->getOrigin());
}
// The following are tentative tests until we really add tests for the
// query logic for these cases. At that point it's probably better to
// clean them up.
TEST_F(QueryTest, nxdomainWithNSEC3) {
TEST_F(QueryTest, nxdomainWithNSEC3Proof) {
// Name Error (NXDOMAIN) case with NSEC3 proof per RFC5155 Section 7.2.2.
// Enable NSEC3
mock_finder->setNSEC3Flag(true);
ZoneFinder::FindResult result = mock_finder->find(
Name("nxdomain.example.com"), RRType::A(), ZoneFinder::FIND_DNSSEC);
EXPECT_EQ(ZoneFinder::NXDOMAIN, result.code);
EXPECT_FALSE(result.rrset);
EXPECT_TRUE(result.isNSEC3Signed());
EXPECT_FALSE(result.isWildcard());
// This will be the covering NSEC3 for the next closer
mock_finder->addRecord(nsec3_uwild_txt);
// This will be the covering NSEC3 for the possible wildcard
mock_finder->addRecord(unsigned_delegation_nsec3_txt);
Query(memory_client, Name("nxdomain.example.com"), qtype,
response, true).process();
responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 8, 0, NULL,
// SOA + its RRSIG
(string(soa_txt) +
string("example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("SOA") + "\n" +
// NSEC3 for the closest encloser + its RRSIG
string(nsec3_apex_txt) + "\n" +
mock_finder->hash_map_[mock_finder->getOrigin()] +
string(".example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("NSEC3") + "\n" +
// NSEC3 for the next closer + its RRSIG
string(nsec3_uwild_txt) + "\n" +
mock_finder->hash_map_[Name("uwild.example.com")] +
".example.com. 3600 IN RRSIG " +
getCommonRRSIGText("NSEC3") + "\n" +
// NSEC3 for the wildcard + its RRSIG
string(unsigned_delegation_nsec3_txt) +
mock_finder->hash_map_[
Name("unsigned-delegation.example.com")] +
".example.com. 3600 IN RRSIG " +
getCommonRRSIGText("NSEC3")).c_str(),
NULL, mock_finder->getOrigin());
}
TEST_F(QueryTest, nxdomainWithBadNextNSEC3Proof) {
// Similar to the previous case, but emulating run time collision by
// returning NULL in the next closer proof for the closest encloser
// proof.
mock_finder->setNSEC3Flag(true);
ZoneFinder::FindNSEC3Result nsec3(true, 0, textToRRset(nsec3_apex_txt),
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3);
// Message::addRRset() will detect it and throw InvalidParameter.
EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"),
RRType::TXT(), response, true).process(),
isc::InvalidParameter);
}
TEST_F(QueryTest, nxdomainWithBadWildcardNSEC3Proof) {
// Similar to nxdomainWithNSEC3Proof, but let findNSEC3() return a matching
// NSEC3 for the possible wildcard name, emulating run-time collision.
// This should result in BadNSEC3 exception.
mock_finder->setNSEC3Flag(true);
mock_finder->addRecord(nsec3_uwild_txt);
mock_finder->addRecord(unsigned_delegation_nsec3_txt);
const Name wname("*.example.com");
ZoneFinder::FindNSEC3Result nsec3(true, 0, textToRRset(nsec3_apex_txt),
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3, &wname);
EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"), qtype,
response, true).process(),
Query::BadNSEC3);
}
// The following are tentative tests until we really add tests for the
// query logic for these cases. At that point it's probably better to
// clean them up.
TEST_F(QueryTest, emptyNameWithNSEC3) {
mock_finder->setNSEC3Flag(true);
ZoneFinder::FindResult result = mock_finder->find(
......
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