declare(suffix,"get-order-after-query","DNSSEC Ordering Query, after", "select min(ordername) from records where ordername > '%s' and domain_id=%d and ordername is not null");
declare(suffix,"get-order-last-query","DNSSEC Ordering Query, last", "select ordername, name from records where ordername != '' and domain_id=%d and ordername is not null order by 1 desc limit 1");
declare(suffix,"set-order-and-auth-query", "DNSSEC set ordering query", "update records set ordername='%s',auth=%d where name='%s' and domain_id='%d'");
- declare(suffix,"nullify-ordername-query", "DNSSEC nullify ordername query", "update records set ordername=NULL where domain_id='%d' and name='%s' and type is null");
+ declare(suffix,"nullify-ordername-and-update-auth-query", "DNSSEC nullify ordername and update auth query", "update records set ordername=NULL,auth=%d where domain_id='%d' and name='%s'");
declare(suffix,"nullify-ordername-and-auth-query", "DNSSEC nullify ordername and auth query", "update records set ordername=NULL,auth=0 where name='%s' and type='%s' and domain_id='%d'");
+ declare(suffix,"set-auth-on-ds-record-query", "DNSSEC set auth on a DS record", "update records set auth=1 where domain_id='%d' and name='%s' and type='DS'");
declare(suffix,"update-serial-query","", "update domains set notified_serial=%d where id=%d");
declare(suffix,"update-lastcheck-query","", "update domains set last_check=%d where id=%d");
declare(suffix,"get-order-after-query","DNSSEC Ordering Query, after", "select ordername from records where ordername ~>~ E'%s' and domain_id=%d and ordername is not null order by 1 using ~<~ limit 1");
declare(suffix,"get-order-last-query","DNSSEC Ordering Query, last", "select ordername, name from records where ordername != '' and domain_id=%d and ordername is not null order by 1 using ~>~ limit 1");
declare(suffix,"set-order-and-auth-query", "DNSSEC set ordering query", "update records set ordername=E'%s',auth=(%d = 1) where name=E'%s' and domain_id='%d'");
+ declare(suffix,"set-auth-on-ds-record-query", "DNSSEC set auth on a DS record", "update records set auth=true where domain_id='%d' and name='%s' and type='DS'");
- declare(suffix,"nullify-ordername-query", "DNSSEC nullify ordername query", "update records set ordername=NULL where domain_id='%d' and name='%s' and type is null");
+ declare(suffix,"nullify-ordername-and-update-auth-query", "DNSSEC nullify ordername and update auth query", "update records set ordername=NULL,auth=(%d = 1) where domain_id='%d' and name='%s'");
declare(suffix,"nullify-ordername-and-auth-query", "DNSSEC nullify ordername and auth query", "update records set ordername=NULL,auth=false where name=E'%s' and type=E'%s' and domain_id='%d'");
declare(suffix,"update-serial-query","", "update domains set notified_serial=%d where id=%d");
declare(suffix,"get-order-last-query","DNSSEC Ordering Query, last", "select ordername, name from records where ordername != '' and domain_id=%d and ordername is not null order by 1 desc limit 1");
declare(suffix,"set-order-and-auth-query", "DNSSEC set ordering query", "update records set ordername='%s',auth=%d where name='%s' and domain_id='%d'");
- declare(suffix,"nullify-ordername-query", "DNSSEC nullify ordername query", "update records set ordername=NULL where domain_id='%d' and name='%s' and type is null");
+ declare(suffix,"nullify-ordername-and-update-auth-query", "DNSSEC nullify ordername and update auth query", "update records set ordername=NULL,auth=%d where domain_id='%d' and name='%s'");
declare(suffix,"nullify-ordername-and-auth-query", "DNSSEC nullify ordername and auth query", "update records set ordername=NULL,auth=0 where name='%s' and type='%s' and domain_id='%d'");
+ declare(suffix,"set-auth-on-ds-record-query", "DNSSEC set auth on a DS record", "update records set auth=1 where domain_id='%d' and name='%s' and type='DS'");
declare( suffix, "master-zone-query", "Data", "select master from domains where name='%s' and type='SLAVE'");
d_afterOrderQuery = getArg("get-order-after-query");
d_lastOrderQuery = getArg("get-order-last-query");
d_setOrderAuthQuery = getArg("set-order-and-auth-query");
- d_nullifyOrderNameQuery = getArg("nullify-ordername-query");
+ d_nullifyOrderNameAndUpdateAuthQuery = getArg("nullify-ordername-and-update-auth-query");
d_nullifyOrderNameAndAuthQuery = getArg("nullify-ordername-and-auth-query");
+ d_setAuthOnDsRecordQuery = getArg("set-auth-on-ds-record-query");
d_AddDomainKeyQuery = getArg("add-domain-key-query");
d_ListDomainKeysQuery = getArg("list-domain-keys-query");
if(!d_dnssecQueries)
return false;
char output[1024];
- // ordername='%s',auth=%d where name='%s' and domain_id='%d'
-
+
snprintf(output, sizeof(output)-1, d_setOrderAuthQuery.c_str(), sqlEscape(ordername).c_str(), auth, sqlEscape(qname).c_str(), domain_id);
-// cerr<<"sql: '"<<output<<"'\n";
-
try {
d_db->doCommand(output);
}
return true;
}
-bool GSQLBackend::nullifyDNSSECOrderName(uint32_t domain_id, const std::string& qname)
+bool GSQLBackend::nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth)
{
if(!d_dnssecQueries)
return false;
char output[1024];
- snprintf(output, sizeof(output)-1, d_nullifyOrderNameQuery.c_str(), domain_id, sqlEscape(qname).c_str());
+ snprintf(output, sizeof(output)-1, d_nullifyOrderNameAndUpdateAuthQuery.c_str(), auth, domain_id, sqlEscape(qname).c_str());
try {
d_db->doCommand(output);
}
catch(SSqlException &e) {
- throw AhuException("GSQLBackend unable to nullify ordername for domain_id "+itoa(domain_id)+": "+e.txtReason());
+ throw AhuException("GSQLBackend unable to nullify ordername and update auth for domain_id "+itoa(domain_id)+": "+e.txtReason());
}
return true;
}
return true;
}
+bool GSQLBackend::setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname)
+{
+ if(!d_dnssecQueries)
+ return false;
+ char output[1024];
+
+ snprintf(output, sizeof(output)-1, d_setAuthOnDsRecordQuery.c_str(), domain_id, sqlEscape(qname).c_str());
+ try {
+ d_db->doCommand(output);
+ }
+ catch(SSqlException &e) {
+ throw AhuException("GSQLBackend unable to set auth on DS record "+qname+" for domain_id "+itoa(domain_id)+": "+e.txtReason());
+ }
+ return true;
+}
+
bool GSQLBackend::updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert, set<string>& erase, bool remove)
{
char output[1024];
virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after);
bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth);
virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth);
- virtual bool nullifyDNSSECOrderName(uint32_t domain_id, const std::string& qname);
+ virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth);
virtual bool nullifyDNSSECOrderNameAndAuth(uint32_t domain_id, const std::string& qname, const std::string& type);
+ virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname);
virtual bool updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert ,set<string>& erase, bool remove);
virtual bool doesDNSSEC();
string d_afterOrderQuery;
string d_lastOrderQuery;
string d_setOrderAuthQuery;
- string d_nullifyOrderNameQuery;
+ string d_nullifyOrderNameAndUpdateAuthQuery;
string d_nullifyOrderNameAndAuthQuery;
+ string d_setAuthOnDsRecordQuery;
string d_removeEmptyNonTerminalsFromZoneQuery;
string d_insertEmptyNonTerminalQuery;
string d_deleteEmptyNonTerminalQuery;
return false;
}
- virtual bool nullifyDNSSECOrderName(uint32_t domain_id, const std::string& qname)
+ virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth)
{
return false;
}
return false;
}
+ virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname)
+ {
+ return false;
+ }
+
virtual bool doesDNSSEC()
{
return false;
break;
}
} while(chopOff(shorter));
-
- if(dsnames.count(qname))
- auth=true;
}
if(haveNSEC3)
hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, qname)));
if(g_verbose)
cerr<<"'"<<qname<<"' -> '"<< hashed <<"'"<<endl;
+ sd.db->updateDNSSECOrderAndAuthAbsolute(sd.domain_id, qname, hashed, auth);
}
- sd.db->updateDNSSECOrderAndAuthAbsolute(sd.domain_id, qname, hashed, auth);
- if((!auth || dsnames.count(qname)) && realrr)
+ else
+ sd.db->nullifyDNSSECOrderNameAndUpdateAuth(sd.domain_id, qname, auth);
+ if(realrr)
{
- sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "NS");
- sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "A");
- sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "AAAA");
+ if (dsnames.count(qname))
+ sd.db->setDNSSECAuthOnDsRecord(sd.domain_id, qname);
+ if (!auth || nsset.count(qname)) {
+ sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "NS");
+ sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "A");
+ sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "AAAA");
+ }
}
}
else // NSEC
if(realrr)
{
sd.db->updateDNSSECOrderAndAuth(sd.domain_id, zone, qname, auth);
- if(!auth || dsnames.count(qname))
- {
+ if (dsnames.count(qname))
+ sd.db->setDNSSECAuthOnDsRecord(sd.domain_id, qname);
+ if (!auth || nsset.count(qname)) {
sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "A");
sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "AAAA");
}
}
else
{
- sd.db->nullifyDNSSECOrderName(sd.domain_id, qname);
+ sd.db->nullifyDNSSECOrderNameAndUpdateAuth(sd.domain_id, qname, auth);
}
}
break;
}
}while(chopOff(shorter));
-
- if(dsnames.count(qname))
- auth=true;
}
if(dnssecZone && haveNSEC3)
{
if(!narrow) {
hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, qname)));
+ di.backend->updateDNSSECOrderAndAuthAbsolute(domain_id, qname, hashed, auth);
}
- di.backend->updateDNSSECOrderAndAuthAbsolute(domain_id, qname, hashed, auth); // this should always be done
- if((!auth || dsnames.count(qname)) && realrr)
+ else
+ di.backend->nullifyDNSSECOrderNameAndUpdateAuth(domain_id, qname, auth);
+ if(realrr)
{
- di.backend->nullifyDNSSECOrderNameAndAuth(domain_id, qname, "NS");
- di.backend->nullifyDNSSECOrderNameAndAuth(domain_id, qname, "A");
- di.backend->nullifyDNSSECOrderNameAndAuth(domain_id, qname, "AAAA");
+ if (dsnames.count(qname))
+ di.backend->setDNSSECAuthOnDsRecord(domain_id, qname);
+ if (!auth || nsset.count(qname)) {
+ di.backend->nullifyDNSSECOrderNameAndAuth(domain_id, qname, "NS");
+ di.backend->nullifyDNSSECOrderNameAndAuth(domain_id, qname, "A");
+ di.backend->nullifyDNSSECOrderNameAndAuth(domain_id, qname, "AAAA");
+ }
}
}
else // NSEC
if(realrr)
{
di.backend->updateDNSSECOrderAndAuth(domain_id, domain, qname, auth);
- if(!auth || dsnames.count(qname))
- {
+ if (dsnames.count(qname))
+ di.backend->setDNSSECAuthOnDsRecord(domain_id, qname);
+ if (!auth || nsset.count(qname)) {
di.backend->nullifyDNSSECOrderNameAndAuth(domain_id, qname, "A");
di.backend->nullifyDNSSECOrderNameAndAuth(domain_id, qname, "AAAA");
}
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400
0 nxd.example.com. IN CNAME 120 nxdomain.example.com.
0 nxd.example.com. IN RRSIG 120 CNAME 8 3 120 [expiry] [inception] [keytag] example.com. ...
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400
--- /dev/null
+#!/bin/sh
+cleandig dsdelegation.example.com DS dnssec
--- /dev/null
+This test tries to resolve a DS question at a secure delegation.
+It was written specifically to verify that we do not sign NS records
+at secure delegations.
+
--- /dev/null
+0 dsdelegation.example.com. IN DS 120 28129 8 1 caf1eaaecdabe7616670788f9022454bf5fd9fda
+2 . IN OPT 32768
+Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='dsdelegation.example.com.', qtype=DS
--- /dev/null
+0 dsdelegation.example.com. IN DS 120 28129 8 1 caf1eaaecdabe7616670788f9022454bf5fd9fda
+0 dsdelegation.example.com. IN RRSIG 120 DS 8 3 120 [expiry] [inception] [keytag] example.com. ...
+2 . IN OPT 32768
+Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='dsdelegation.example.com.', qtype=DS
;
unauth IN CNAME no-idea.example.org.
;
+dsdelegation IN NS ns.example.com.
+ IN DS 28129 8 1 caf1eaaecdabe7616670788f9022454bf5fd9fda
+;
nxd IN CNAME nxdomain.example.com.
;
hwinfo IN HINFO "abc" "def"
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400
--- /dev/null
+#!/bin/sh
+cleandig www.dsdelegation.example.com A dnssec
--- /dev/null
+This test checks the DS/NS response for a secure referral.
+It was written specifically to verify that we do not sign NS records
+at secure delegations.
+
--- /dev/null
+1 dsdelegation.example.com. IN NS 120 ns.example.com.
+2 . IN OPT 32768
+Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 0, opcode: 0
+Reply to question for qname='www.dsdelegation.example.com.', qtype=A
--- /dev/null
+1 dsdelegation.example.com. IN DS 120 28129 8 1 caf1eaaecdabe7616670788f9022454bf5fd9fda
+1 dsdelegation.example.com. IN NS 120 ns.example.com.
+1 dsdelegation.example.com. IN RRSIG 120 DS 8 3 120 [expiry] [inception] [keytag] example.com. ...
+2 . IN OPT 32768
+Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 0, opcode: 0
+Reply to question for qname='www.dsdelegation.example.com.', qtype=A
-1 example.com. IN NSEC 86400 escapedtext.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1 example.com. IN NSEC 86400 dsdelegation.example.com. NS SOA MX RRSIG NSEC DNSKEY
1 example.com. IN RRSIG 86400 NSEC 8 2 86400 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN RRSIG 86400 SOA 8 2 100000 [expiry] [inception] [keytag] example.com. ...
1 example.com. IN SOA 86400 ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400