rr.ttl=3600;
rr.qtype=QType::NSEC3;
rr.content=n3rc.getZoneRepresentation();
- cerr<<"nsec3: '"<<rr.content<<"'"<<endl;
+ //cerr<<"nsec3: '"<<rr.content<<"'"<<endl;
rr.d_place = (mode == 2 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
rr.auth = true;
r->addRecord(rr);
{
NSEC3PARAMRecordContent ns3rc;
cerr<<"Doing NSEC3PARAM lookup for '"<<auth<<"', "<<p->qdomain<<"|"<<p->qtype.getName()<<": ";
- if(d_dk.getNSEC3PARAM(auth, &ns3rc)) {
- cerr<<"Present"<<endl;
- addNSEC3(p, r, target, auth, ns3rc, mode);
+ bool narrow;
+ if(d_dk.getNSEC3PARAM(auth, &ns3rc, &narrow)) {
+ cerr<<"Present, narrow="<<narrow<<endl;
+ addNSEC3(p, r, target, auth, ns3rc, narrow, mode);
}
else {
cerr<<"Not present"<<endl;
}
}
-void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const string& target, const string& auth, const NSEC3PARAMRecordContent& ns3rc, int mode)
+static void incrementHash(std::string& hash) // I wonder if this is correct, cmouse? ;-)
+{
+ if(hash.empty())
+ return;
+ for(string::size_type pos=hash.size(); pos; ) {
+ --pos;
+ unsigned char c = (unsigned char)hash[pos];
+ ++c;
+ hash[pos] = (char) c;
+ if(c)
+ break;
+ }
+}
+
+bool PacketHandler::getNSEC3Hashes(bool narrow, DNSBackend* db, int id, const std::string& hashed, string& unhashed, string& before, string& after)
+{
+ bool ret;
+ if(narrow) { // nsec3-narrow
+ ret=true;
+ before=hashed;
+ after=hashed;
+ incrementHash(after);
+ }
+ else {
+ ret=db->getBeforeAndAfterNamesAbsolute(id, hashed, unhashed, before, after);
+ }
+ // cerr<<"rgetNSEC3Hashes: "<<hashed<<", "<<unhashed<<", "<<before<<", "<<after<<endl;
+ return ret;
+}
+
+void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const string& target, const string& auth, const NSEC3PARAMRecordContent& ns3rc, bool narrow, int mode)
{
string hashed;
cerr<<"Could not get SOA for domain in NSEC3\n";
return;
}
- cerr<<"salt in ph: '"<<makeHexDump(ns3rc.d_salt)<<"'"<<endl;
+ cerr<<"salt in ph: '"<<makeHexDump(ns3rc.d_salt)<<"', narrow="<<narrow<<endl;
string unhashed, before,after;
// now add the closest encloser
- hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, auth)));
- sd.db->getBeforeAndAfterNamesAbsolute(sd.domain_id, hashed, unhashed, before, after);
+ unhashed=auth;
+ hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, unhashed)));
+
+ getNSEC3Hashes(narrow, sd.db, sd.domain_id, hashed, unhashed, before, after);
cerr<<"Done calling for closest encloser, before='"<<before<<"', after='"<<after<<"'"<<endl;
emitNSEC3(ns3rc, auth, unhashed, fromBase32Hex(before), fromBase32Hex(after), target, r, mode);
// now add the main nsec3
- hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, p->qdomain)));
- sd.db->getBeforeAndAfterNamesAbsolute(sd.domain_id, hashed, unhashed, before, after);
+ unhashed = p->qdomain;
+ hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, unhashed)));
+ getNSEC3Hashes(narrow, sd.db,sd.domain_id, hashed, unhashed, before, after);
cerr<<"Done calling for main, before='"<<before<<"', after='"<<after<<"'"<<endl;
emitNSEC3( ns3rc, auth, unhashed, fromBase32Hex(before), fromBase32Hex(after), target, r, mode);
// now add the *
- hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, dotConcat("*", auth))));
- sd.db->getBeforeAndAfterNamesAbsolute(sd.domain_id, hashed, unhashed, before, after);
+ unhashed=dotConcat("*", auth);
+ hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, unhashed)));
+
+ getNSEC3Hashes(narrow, sd.db, sd.domain_id, hashed, unhashed, before, after);
cerr<<"Done calling for '*', before='"<<before<<"', after='"<<after<<"'"<<endl;
emitNSEC3( ns3rc, auth, unhashed, fromBase32Hex(before), fromBase32Hex(after), target, r, mode);
}
nrc.d_set.insert(rr.qtype.getCode());
}
- // now get the fucking NSEC too (since we must sign it!)
+ // now get the NSEC too (since we must sign it!)
SOAData sd;
sd.db=(DNSBackend *)-1; // force uncached answer
bool doDNSSECProcessing(DNSPacket* p, DNSPacket *r);
void addNSECX(DNSPacket *p, DNSPacket* r, const string &target, const std::string& auth, int mode);
void addNSEC(DNSPacket *p, DNSPacket* r, const string &target, const std::string& auth, int mode);
- void addNSEC3(DNSPacket *p, DNSPacket* r, const string &target, const std::string& auth, const NSEC3PARAMRecordContent& nsec3param, int mode);
+ void addNSEC3(DNSPacket *p, DNSPacket* r, const string &target, const std::string& auth, const NSEC3PARAMRecordContent& nsec3param, bool narrow, int mode);
void emitNSEC(const std::string& before, const std::string& after, const std::string& toNSEC, const std::string& auth, DNSPacket *r, int mode);
void emitNSEC3(const NSEC3PARAMRecordContent &ns3rc, const std::string& auth, const std::string& unhashed, const std::string& begin, const std::string& end, const std::string& toNSEC3, DNSPacket *r, int mode);
+ bool getNSEC3Hashes(bool narrow, DNSBackend* db, int id, const std::string& hashed, string& unhashed, string& before, string& after);
void synthesiseRRSIGs(DNSPacket* p, DNSPacket* r);
void makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& target, SOAData& sd);
const string& zone=cmds[1];
NSEC3PARAMRecordContent ns3pr;
- dk.getNSEC3PARAM(zone, &ns3pr);
+ bool narrow;
+ dk.getNSEC3PARAM(zone, &ns3pr, &narrow);
if(ns3pr.d_salt.empty())
cerr<<"Zone has NSEC semantics"<<endl;
else
- cerr<<"Zone has hashed NSEC3 semantics, configuration: "<<ns3pr.getZoneRepresentation()<<endl;
+ cerr<<"Zone has " << (narrow ? "NARROW " : "") <<"hashed NSEC3 semantics, configuration: "<<ns3pr.getZoneRepresentation()<<endl;
DNSSECKeeper::keyset_t keyset=dk.getKeys(zone);
}
else if(cmds[0]=="set-nsec3") {
string nsec3params = cmds.size() > 2 ? cmds[2] : "1 0 1 ab";
-
+ bool narrow = cmds.size() > 3 && cmds[3]=="narrow";
NSEC3PARAMRecordContent ns3pr(nsec3params);
- dk.setNSEC3PARAM(cmds[1], ns3pr);
+ dk.setNSEC3PARAM(cmds[1], ns3pr, narrow);
}
else if(cmds[0]=="unset-nsec3") {
dk.unsetNSEC3PARAM(cmds[1]);