]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[1585] Merge branch 'master' into trac1585 with fixing conflicts, mainly
authorJINMEI Tatuya <jinmei@isc.org>
Tue, 14 Feb 2012 18:17:43 +0000 (10:17 -0800)
committerJINMEI Tatuya <jinmei@isc.org>
Tue, 14 Feb 2012 18:17:43 +0000 (10:17 -0800)
to be more synchronized with merged #1582.

1  2 
src/bin/auth/query.cc
src/bin/auth/tests/query_unittest.cc

index 4c220104c70bcdf544f1f9e1629652912adbdff7,70b672c6f2c6497b97d7da51298ed98519dcdff1..54361d1f8d192b9010eee6717740837577143ed5
@@@ -257,46 -236,28 +257,57 @@@ Query::addNXRRsetProof(ZoneFinder& find
          if (db_result.isWildcard()) {
              addWildcardNXRRSETProof(finder, db_result.rrset);
          }
 -    } else if (db_result.isNSEC3Signed()) {
 +    } else if (db_result.isNSEC3Signed() && !db_result.isWildcard()) {
-         // Case for RFC5155 Section 7.2.3
-         const 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());
 +            isc_throw(BadNSEC3, "No matching NSEC3 found for existing domain "
 +                      << qname_);
 +        }
 +    } else if (db_result.isNSEC3Signed() && db_result.isWildcard()) {
 +        // Case for RFC5155 Section 7.2.5
 +        const ZoneFinder::FindNSEC3Result result(finder.findNSEC3(qname_,
 +                                                                  true));
 +        // We know there's no exact match for the qname, so findNSEC3() should
 +        // return both closest and next proofs.  If the latter is NULL, it
 +        // means a run time collision (or the zone is broken in other way).
 +        // In that case addRRset() will throw, and it will be converted to
 +        // SERVFAIL.
 +        response_.addRRset(Message::SECTION_AUTHORITY,
 +                           boost::const_pointer_cast<AbstractRRset>(
 +                               result.closest_proof), dnssec_);
 +        response_.addRRset(Message::SECTION_AUTHORITY,
 +                           boost::const_pointer_cast<AbstractRRset>(
 +                               result.next_proof), dnssec_);
 +
 +        // Construct the matched wildcard name and add NSEC3 for it.
 +        const Name wname = Name("*").concatenate(
 +            qname_.split(qname_.getLabelCount() - result.closest_labels));
 +        const ZoneFinder::FindNSEC3Result wresult(finder.findNSEC3(wname,
 +                                                                   false));
 +        if (wresult.matched) {
 +            response_.addRRset(Message::SECTION_AUTHORITY,
 +                               boost::const_pointer_cast<AbstractRRset>(
 +                                   wresult.closest_proof), dnssec_);
 +        } else {
 +            isc_throw(BadNSEC3, "No matching NSEC3 found for existing domain "
 +                      << wname);
          }
      }
  }
index 7a0d52359362c51dc48fbe8858fe73af5bf13c3a,a1672bd6821a2a1da127cd1fc53cbb73f0f6031c..c5d8a7971359ed1d2b9bf491323104c191b88200
@@@ -208,6 -198,16 +208,17 @@@ const char* const unsigned_delegation_t
      "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";
++// This one will be added on demand
+ 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
@@@ -288,6 -287,8 +299,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_txt <<
+             unsigned_delegation_optout_nsec_txt <<
              bad_delegation_txt;
  
          masterLoad(zone_stream, origin_, rrclass_,
          hash_map_[Name("nxdomain3.example.com")] =
              "009mhaveqvm6t7vbl5lop2u3t2rp3tom";
          hash_map_[Name("unsigned-delegation.example.com")] =
-             "q04jkcevqvmu85r014c7dkba38o0ji8r"; // a bit larger than H(www)
 -            "q81r598950igr1eqvc60aedlq66425b5";
++            "q81r598950igr1eqvc60aedlq66425b5"; // a bit larger than H(www)
 +        hash_map_[Name("*.uwild.example.com")] =
 +            "b4um86eghhds6nea196smvmlo4ors995";
+         hash_map_[Name("unsigned-delegation-optout.example.com")] =
+             "vld46lphhasfapj8og1pglgiasa5o5gt";
 +
 +        // For closest encloser proof for www1.uwild.example.com:
 +        hash_map_[Name("uwild.example.com")] =
 +            "t644ebqk9bibcna874givr6joj62mlhv";
 +        hash_map_[Name("www1.uwild.example.com")] =
 +            "q04jkcevqvmu85r014c7dkba38o0ji6r"; // a bit larger than H(www)
      }
      virtual isc::dns::Name getOrigin() const { return (origin_); }
      virtual isc::dns::RRClass getClass() const { return (rrclass_); }
@@@ -1041,55 -1028,6 +1056,53 @@@ TEST_F(QueryTest, secureUnsignedDelegat
                    NULL);
  }
  
-     const string nsec3_insecurechild_str =
-         mock_finder->hash_map_[insecurechild_name] + ".example.com. 3600 "
-         "IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS\n";
 +TEST_F(QueryTest, secureUnsignedDelegationWithNSEC3) {
 +    // Similar to the previous case, but the zone is signed with NSEC3,
 +    // and this delegation is NOT an optout.
 +    const Name insecurechild_name("unsigned-delegation.example.com");
-     mock_finder->addRecord(nsec3_insecurechild_str);
 +    mock_finder->setNSEC3Flag(true);
-                    nsec3_insecurechild_str +
++    mock_finder->addRecord(unsigned_delegation_nsec3_txt);
 +
 +    Query(memory_client, Name("foo.unsigned-delegation.example.com"),
 +          qtype, response, true).process();
 +
 +    // The response should contain the NS and matching NSEC3 with its RRSIG
 +    responseCheck(response, Rcode::NOERROR(), 0, 0, 3, 0,
 +                  NULL,
 +                  (string(unsigned_delegation_txt) +
++                   string(unsigned_delegation_nsec3_txt) +
 +                   mock_finder->hash_map_[insecurechild_name] +
 +                   ".example.com. 3600 IN RRSIG " +
 +                   getCommonRRSIGText("NSEC3")).c_str(),
 +                  NULL);
 +}
 +
 +TEST_F(QueryTest, secureUnsignedDelegationWithNSEC3OptOut) {
 +    // Similar to the previous case, but the delegation is an optout.
 +    mock_finder->setNSEC3Flag(true);
 +
 +    Query(memory_client, Name("foo.unsigned-delegation.example.com"),
 +          qtype, response, true).process();
 +
 +    // The response should contain the NS and the closest provable encloser
 +    // proof (and their RRSIGs).  The closest encloser is the apex (origin),
 +    // and with our faked hash the covering NSEC3 for the next closer
 +    // (= child zone name) is that for www.example.com.
++    cout << response << endl;
 +    responseCheck(response, Rcode::NOERROR(), 0, 0, 5, 0,
 +                  NULL,
 +                  (string(unsigned_delegation_txt) +
 +                   string(nsec3_apex_txt) +
 +                   mock_finder->hash_map_[mock_finder->getOrigin()] +
 +                   ".example.com. 3600 IN RRSIG " +
 +                   getCommonRRSIGText("NSEC3") + "\n" +
 +                   string(nsec3_www_txt) +
 +                   mock_finder->hash_map_[Name("www.example.com")] +
 +                   ".example.com. 3600 IN RRSIG " +
 +                   getCommonRRSIGText("NSEC3")).c_str(),
 +                  NULL);
 +}
 +
  TEST_F(QueryTest, badSecureDelegation) {
      // Test whether exception is raised if DS query at delegation results in
      // something different than SUCCESS or NXRRSET
@@@ -2088,6 -1935,49 +2101,51 @@@ TEST_F(QueryTest, nxrrsetMissingNSEC3) 
                         response, true).process(), Query::BadNSEC3);
  }
  
+ TEST_F(QueryTest, nxrrsetWithNSEC3_ds_exact) {
++    mock_finder->addRecord(unsigned_delegation_nsec3_txt);
+     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->addRecord(unsigned_delegation_nsec3_txt);
+     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.