Commit 47ed2b14 authored by Jelte Jansen's avatar Jelte Jansen
Browse files

[master] Merge branch 'trac1582'

parents 8c5e01a8 9ba95c66
......@@ -237,12 +237,24 @@ Query::addNXRRsetProof(ZoneFinder& finder,
addWildcardNXRRSETProof(finder, db_result.rrset);
}
} else if (db_result.isNSEC3Signed()) {
ZoneFinder::FindNSEC3Result result(finder.findNSEC3(qname_, false));
// Handling depends on whether query type is DS or not
// (see RFC5155, 7.2.3 and 7.2.4): If qtype == DS, do
// recursive search (and add next_proof, if necessary),
// otherwise, do non-recursive search
const bool qtype_ds = (qtype_ == RRType::DS());
ZoneFinder::FindNSEC3Result result(finder.findNSEC3(qname_, qtype_ds));
if (result.matched) {
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<AbstractRRset>(
result.closest_proof), dnssec_);
// For qtype == DS, next_proof could be set
// (We could check for opt-out here, but that's really the
// responsibility of the datasource)
if (qtype_ds && result.next_proof != ConstRRsetPtr()) {
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<AbstractRRset>(
result.next_proof), dnssec_);
}
} else {
isc_throw(BadNSEC3, "No NSEC3 found for existing domain " <<
qname_.toText());
......
......@@ -86,10 +86,11 @@ private:
void addDS(isc::datasrc::ZoneFinder& finder,
const isc::dns::Name& ds_name);
/// \brief Adds NSEC denial proof for the given NXRRset result
/// \brief Adds NSEC(3) denial proof for the given NXRRset result
///
/// NSEC records, if available (signaled by isNSECSigned(), are added
/// to the authority section.
/// If available, NSEC or NSEC3 records are added to the authority
/// section (depending on whether isNSECSigned() or isNSEC3Signed()
/// returns true).
///
/// \param finder The ZoneFinder that was used to search for the missing
/// data
......
......@@ -192,12 +192,22 @@ const char* const signed_delegation_ds_txt =
"signed-delegation.example.com. 3600 IN DS 12345 8 2 "
"764501411DE58E8618945054A3F620B36202E115D015A7773F4B78E0F952CECA\n";
// (Secure) delegation data; Delegation without DS record (and NSEC denying
// its existence.
// (Secure) delegation data; Delegation without DS record (and both NSEC
// and NSEC3 denying its existence)
const char* const unsigned_delegation_txt =
"unsigned-delegation.example.com. 3600 IN NS ns.example.net.\n";
const char* const unsigned_delegation_nsec_txt =
"unsigned-delegation.example.com. 3600 IN NSEC "
"unsigned-delegation-optout.example.com. NS RRSIG NSEC\n";
const char* const unsigned_delegation_nsec3_txt =
"q81r598950igr1eqvc60aedlq66425b5.example.com. 3600 IN NSEC3 1 1 12 "
"aabbccdd 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom NS RRSIG\n";
// Delegation without DS record, and no direct matching NSEC3 record
const char* const unsigned_delegation_optout_txt =
"unsigned-delegation-optout.example.com. 3600 IN NS ns.example.net.\n";
const char* const unsigned_delegation_optout_nsec_txt =
"unsigned-delegation-optout.example.com. 3600 IN NSEC "
"*.uwild.example.com. NS RRSIG NSEC\n";
// (Secure) delegation data; Delegation where the DS lookup will raise an
......@@ -277,6 +287,8 @@ public:
nsec3_apex_txt << nsec3_www_txt <<
signed_delegation_txt << signed_delegation_ds_txt <<
unsigned_delegation_txt << unsigned_delegation_nsec_txt <<
unsigned_delegation_nsec3_txt << unsigned_delegation_optout_txt <<
unsigned_delegation_optout_nsec_txt <<
bad_delegation_txt;
masterLoad(zone_stream, origin_, rrclass_,
......@@ -305,6 +317,10 @@ public:
"q00jkcevqvmu85r014c7dkba38o0ji5r";
hash_map_[Name("nxdomain3.example.com")] =
"009mhaveqvm6t7vbl5lop2u3t2rp3tom";
hash_map_[Name("unsigned-delegation.example.com")] =
"q81r598950igr1eqvc60aedlq66425b5";
hash_map_[Name("unsigned-delegation-optout.example.com")] =
"vld46lphhasfapj8og1pglgiasa5o5gt";
}
virtual isc::dns::Name getOrigin() const { return (origin_); }
virtual isc::dns::RRClass getClass() const { return (rrclass_); }
......@@ -1649,25 +1665,25 @@ TEST_F(QueryTest, findNSEC3) {
// Non existent name. Disabling recursion, a covering NSEC3 should be
// returned.
nsec3Check(false, 4, nsec3_www_txt,
nsec3Check(false, 4, unsigned_delegation_nsec3_txt,
mock_finder->findNSEC3(Name("nxdomain.example.com"), false));
// Non existent name. The closest provable encloser is the apex,
// and next closer is the query name.
nsec3Check(true, expected_closest_labels,
string(nsec3_apex_txt) + string(nsec3_www_txt),
string(nsec3_apex_txt) + string(unsigned_delegation_nsec3_txt),
mock_finder->findNSEC3(Name("nxdomain.example.com"), true));
// Similar to the previous case, but next closer name is different
// (is the parent) of the non existent name.
nsec3Check(true, expected_closest_labels,
string(nsec3_apex_txt) + string(nsec3_www_txt),
string(nsec3_apex_txt) + string(unsigned_delegation_nsec3_txt),
mock_finder->findNSEC3(Name("nx.domain.example.com"), true));
// In the rest of test we check hash comparison for wrap around cases.
nsec3Check(false, 4, nsec3_apex_txt,
mock_finder->findNSEC3(Name("nxdomain2.example.com"), false));
nsec3Check(false, 4, nsec3_www_txt,
nsec3Check(false, 4, unsigned_delegation_nsec3_txt,
mock_finder->findNSEC3(Name("nxdomain3.example.com"), false));
}
......@@ -1919,6 +1935,49 @@ TEST_F(QueryTest, nxrrsetMissingNSEC3) {
response, true).process(), Query::BadNSEC3);
}
TEST_F(QueryTest, nxrrsetWithNSEC3_ds_exact) {
mock_finder->setNSEC3Flag(true);
// This delegation has no DS, but does have a matching NSEC3 record
// (See RFC5155 section 7.2.4)
Query(memory_client, Name("unsigned-delegation.example.com."),
RRType::DS(), response, true).process();
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("SOA") + "\n" +
string(unsigned_delegation_nsec3_txt) + "\n" +
mock_finder->
hash_map_[Name("unsigned-delegation.example.com.")] +
".example.com. 3600 IN RRSIG " +
getCommonRRSIGText("NSEC3") + "\n").c_str(),
NULL, mock_finder->getOrigin());
}
TEST_F(QueryTest, nxrrsetWithNSEC3_ds_no_exact) {
mock_finder->setNSEC3Flag(true);
// This delegation has no DS, and no directly matching NSEC3 record
// So the response should contain closest encloser proof (and the
// 'next closer' should have opt-out set, though that is not
// actually checked)
// (See RFC5155 section 7.2.4)
Query(memory_client, Name("unsigned-delegation-optout.example.com."),
RRType::DS(), response, true).process();
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 6, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("SOA") + "\n" +
string(nsec3_apex_txt) + "\n" +
mock_finder->hash_map_[Name("example.com.")] +
".example.com. 3600 IN RRSIG " +
getCommonRRSIGText("NSEC3") + "\n" +
string(unsigned_delegation_nsec3_txt) + "\n" +
mock_finder->
hash_map_[Name("unsigned-delegation.example.com.")] +
".example.com. 3600 IN RRSIG " +
getCommonRRSIGText("NSEC3") + "\n").c_str(),
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.
......
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