]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
AXFR-in: fix ent generation for insecure delegations
authorKees Monshouwer <mind04@monshouwer.org>
Fri, 21 Feb 2014 00:04:07 +0000 (01:04 +0100)
committermind04 <mind04@monshouwer.org>
Fri, 21 Feb 2014 22:32:21 +0000 (23:32 +0100)
modules/gmysqlbackend/gmysqlbackend.cc
modules/goraclebackend/goraclebackend.cc
modules/gpgsqlbackend/gpgsqlbackend.cc
modules/gsqlite3backend/gsqlite3backend.cc
pdns/backends/gsql/gsqlbackend.cc
pdns/backends/gsql/gsqlbackend.hh
pdns/dnsbackend.hh
pdns/slavecommunicator.cc

index 1c7d56012a908bd10cecc6f7ee21a60a04914600..97e1aa667b5384b17103a95591fcbc54a4aaf18b 100644 (file)
@@ -101,8 +101,8 @@ public:
     declare(suffix, "insert-record-query-auth", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,auth) values ('%s',%d,%d,'%s',%d,%d,'%s','%d')");
     declare(suffix, "insert-record-order-query-auth", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,ordername,auth) values ('%s',%d,%d,'%s',%d,%d,'%s','%s','%d')");
     declare(suffix, "insert-ent-query", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name) values (null,'%d',0,'%s')");
-    declare(suffix, "insert-ent-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,auth) values (null,'%d',0,'%s','1')");
-    declare(suffix, "insert-ent-order-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth) values (null,'%d',0,'%s','%s','1')");
+    declare(suffix, "insert-ent-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,auth) values (null,'%d',0,'%s','%d')");
+    declare(suffix, "insert-ent-order-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth) values (null,'%d',0,'%s','%s','%d')");
 
     declare(suffix, "get-order-first-query", "DNSSEC Ordering Query, first", "select ordername, name from records where domain_id=%d and disabled=0 and ordername is not null order by 1 asc limit 1");
     declare(suffix, "get-order-before-query", "DNSSEC Ordering Query, before", "select ordername, name from records where ordername <= '%s' and domain_id=%d and disabled=0 and ordername is not null order by 1 desc limit 1");
index 298b455dc477b38755d1260d4008cccb2ebee1a0..4b629ef5f6f08d54d9fa5c6ccc909be39a0fabc8 100644 (file)
@@ -108,8 +108,8 @@ public:
     declare(suffix, "insert-record-query-auth", "", "insert into records (id, content,ttl,prio,type,domain_id,disabled,name,auth) values (records_id_sequence.nextval, '%s',%d,%d,'%s',%d,%d,'%s','%d')");
     declare(suffix, "insert-record-order-query-auth", "", "insert into records (id, content,ttl,prio,type,domain_id,disabled,name,ordername,auth) values (records_id_sequence.nextval, '%s',%d,%d,'%s',%d,%d,'%s','%s ','%d')");
     declare(suffix, "insert-ent-query", "insert empty non-terminal in zone", "insert into records (id, type,domain_id,disabled,name) values (records_id_sequence.nextval, null,'%d',0,'%s')");
-    declare(suffix, "insert-ent-query-auth", "insert empty non-terminal in zone", "insert into records (id, type,domain_id,disabled,name,auth) values (records_id_sequence.nextval, null,'%d',0,'%s','1')");
-    declare(suffix, "insert-ent-order-query-auth", "insert empty non-terminal in zone", "insert into records (id, type,domain_id,disabled,name,ordername,auth) values (records_id_sequence.nextval, null,'%d',0,'%s','%s','1')");
+    declare(suffix, "insert-ent-query-auth", "insert empty non-terminal in zone", "insert into records (id, type,domain_id,disabled,name,auth) values (records_id_sequence.nextval, null,'%d',0,'%s','%d')");
+    declare(suffix, "insert-ent-order-query-auth", "insert empty non-terminal in zone", "insert into records (id, type,domain_id,disabled,name,ordername,auth) values (records_id_sequence.nextval, null,'%d',0,'%s','%s','%d')");
 
     declare(suffix, "get-order-first-query", "DNSSEC Ordering Query, first", "select trim(ordername),name from records where disabled=0 and domain_id=%d and ordername is not null and rownum=1 order by ordername asc");
     declare(suffix, "get-order-before-query", "DNSSEC Ordering Query, before", "select trim(ordername), name from records where disabled=0 and ordername <= '%s ' and domain_id=%d and ordername is not null and rownum=1 order by ordername desc");
index 26eab7a31946bb143629a6a85cf50c06a8110351..92e7c111a094a3b3108376530fbeef4a762ea6a7 100644 (file)
@@ -96,8 +96,8 @@ public:
     declare(suffix, "insert-record-query-auth", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,auth) values (E'%s',%d,%d,'%s',%d,%d::bool,E'%s','%d')");
     declare(suffix, "insert-record-order-query-auth", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,ordername,auth) values (E'%s',%d,%d,'%s',%d,%d::bool,E'%s',E'%s','%d')");
     declare(suffix, "insert-ent-query", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name) values (null,'%d',false,E'%s')");
-    declare(suffix, "insert-ent-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,auth) values (null,'%d',false,E'%s',true)");
-    declare(suffix, "insert-ent-order-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth) values (null,'%d',false,E'%s',E'%s',true)");
+    declare(suffix, "insert-ent-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,auth) values (null,'%d',false,E'%s','%d')");
+    declare(suffix, "insert-ent-order-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth) values (null,'%d',false,E'%s',E'%s','%d')");
 
     declare(suffix, "get-order-first-query", "DNSSEC Ordering Query, last", "select ordername, name from records where disabled=false and domain_id=%d and ordername is not null order by 1 using ~<~ limit 1");
     declare(suffix, "get-order-before-query", "DNSSEC Ordering Query, before", "select ordername, name from records where disabled=false and ordername ~<=~ E'%s' and domain_id=%d and ordername is not null order by 1 using ~>~ limit 1");
index 8aff9375fea1f1c27155dbbe3426c5a3a26d4197..0e0bb34822d06d18ac07b1ff637b3b0d756d3086 100644 (file)
@@ -118,8 +118,8 @@ public:
     declare(suffix, "insert-record-query-auth", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,auth) values ('%s',%d,%d,'%s',%d,%d,'%s',%d)");
     declare(suffix, "insert-record-order-query-auth", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,ordername,auth) values ('%s',%d,%d,%d,'%s','%s',%d,'%s','%d')");
     declare(suffix, "insert-ent-query", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name) values (null,'%d',0,'%s')");
-    declare(suffix, "insert-ent-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,auth) values (null,'%d',0,'%s','1')");
-    declare(suffix, "insert-ent-order-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth) values (null,'%d',0,'%s','%s','1')");
+    declare(suffix, "insert-ent-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,auth) values (null,'%d',0,'%s','%d')");
+    declare(suffix, "insert-ent-order-query-auth", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth) values (null,'%d',0,'%s','%s','%d')");
 
     declare( suffix, "update-master-query", "", "update domains set master='%s' where name='%s'");
     declare( suffix, "update-kind-query", "", "update domains set type='%s' where name='%s'");
index 4813ccd44c46b063a5867854e9bd81c6736b0ff7..164c819dc681f4892126315a8521c589661e78cc 100644 (file)
@@ -1153,14 +1153,27 @@ bool GSQLBackend::feedRecord(const DNSResourceRecord &r, string *ordername)
   return true; // XXX FIXME this API should not return 'true' I think -ahu 
 }
 
-bool GSQLBackend::feedEnts(int domain_id, set<string>& nonterm)
+bool GSQLBackend::feedEnts(int domain_id, map<string,bool>& nonterm)
 {
-  string output;
-  BOOST_FOREACH(const string qname, nonterm) {
-    output = (boost::format(d_InsertEntQuery) % domain_id % toLower(sqlEscape(qname))).str();
+  string query;
+  pair<string,bool> nt;
+
+  BOOST_FOREACH(nt, nonterm) {
+
+    if (!d_dnssecQueries)
+      query = (boost::format(d_InsertEntQuery)
+               % domain_id
+               % toLower(sqlEscape(nt.first))
+       ).str();
+    else
+      query = (boost::format(d_InsertEntQuery)
+               % domain_id
+               % toLower(sqlEscape(nt.first))
+               % 1
+       ).str();
 
     try {
-      d_db->doCommand(output.c_str());
+      d_db->doCommand(query);
     }
     catch (SSqlException &e) {
       throw PDNSException("GSQLBackend unable to feed empty non-terminal: "+e.txtReason());
@@ -1169,22 +1182,34 @@ bool GSQLBackend::feedEnts(int domain_id, set<string>& nonterm)
   return true;
 }
 
-bool GSQLBackend::feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow)
+bool GSQLBackend::feedEnts3(int domain_id, const string &domain, map<string,bool> &nonterm, unsigned int times, const string &salt, bool narrow)
 {
   if(!d_dnssecQueries)
       return false;
 
-  string ordername, output;
-  BOOST_FOREACH(const string qname, nonterm) {
-    if(narrow) {
-      output = (boost::format(d_InsertEntQuery) % domain_id % toLower(sqlEscape(qname))).str();
+  string ordername, query;
+  pair<string,bool> nt;
+
+  BOOST_FOREACH(nt, nonterm) {
+
+    if(narrow || !nt.second) {
+      query = (boost::format(d_InsertEntQuery)
+               % domain_id
+               % toLower(sqlEscape(nt.first))
+               % nt.second
+       ).str();
     } else {
-      ordername=toBase32Hex(hashQNameWithSalt(times, salt, qname));
-      output = (boost::format(d_InsertEntOrderQuery) % domain_id % toLower(sqlEscape(qname)) % toLower(sqlEscape(ordername))).str();
+      ordername=toBase32Hex(hashQNameWithSalt(times, salt, nt.first));
+      query = (boost::format(d_InsertEntOrderQuery)
+               % domain_id
+               % toLower(sqlEscape(nt.first))
+               % toLower(sqlEscape(ordername))
+               % nt.second
+       ).str();
     }
 
     try {
-      d_db->doCommand(output.c_str());
+      d_db->doCommand(query);
     }
     catch (SSqlException &e) {
       throw PDNSException("GSQLBackend unable to feed empty non-terminal: "+e.txtReason());
index 0a8c87b42466de2e814888bfdb68ea58159920e9..c28d0f43902d69044bff9b2000b63ab1cdab37b2 100644 (file)
@@ -37,8 +37,8 @@ public:
   bool commitTransaction();
   bool abortTransaction();
   bool feedRecord(const DNSResourceRecord &r, string *ordername=0);
-  bool feedEnts(int domain_id, set<string>& nonterm);
-  bool feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow);
+  bool feedEnts(int domain_id, map<string,bool>& nonterm);
+  bool feedEnts3(int domain_id, const string &domain, map<string,bool> &nonterm, unsigned int times, const string &salt, bool narrow);
   bool createDomain(const string &domain);
   bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account);
   bool deleteDomain(const string &domain);
index f5bfacd6e9f89ee89461dd3319001c6118e2256f..2b4fae59b75b5fc90455f68758a8daf72905fc69 100644 (file)
@@ -243,11 +243,11 @@ public:
   {
     return false; // no problem!
   }
-  virtual bool feedEnts(int domain_id, set<string> &nonterm)
+  virtual bool feedEnts(int domain_id, map<string,bool> &nonterm)
   {
     return false;
   }
-  virtual bool feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow)
+  virtual bool feedEnts3(int domain_id, const string &domain, map<string,bool> &nonterm, unsigned int times, const string &salt, bool narrow)
   {
     return false;
   }
index 3a8a090897cd1ba4d45caa4d2d8b3fd780ebda72..0dc932eb1b76909168dc9a4f0ed9d0209bf1d143 100644 (file)
@@ -274,7 +274,8 @@ void CommunicatorClass::suck(const string &domain,const string &remote)
     bool doent=true;
     uint32_t maxent = ::arg().asNum("max-ent-entries");
     string ordername, shorter;
-    set<string> nonterm, rrterm;
+    set<string> rrterm;
+    map<string,bool> nonterm;
 
     BOOST_FOREACH(DNSResourceRecord& rr, rrs) {
 
@@ -284,20 +285,32 @@ void CommunicatorClass::suck(const string &domain,const string &remote)
       rrterm.clear();
       do {
         if(doent) {
-          if (!qnames.count(shorter) && !nonterm.count(shorter) && !rrterm.count(shorter))
+          if (!qnames.count(shorter))
             rrterm.insert(shorter);
         }
-        if(nsset.count(shorter) && rr.qtype.getCode() != QType::DS) {
+        if(nsset.count(shorter) && rr.qtype.getCode() != QType::DS)
           rr.auth=false;
-          break;
-        }
+
         if (pdns_iequals(shorter, domain)) // stop at apex
           break;
       }while(chopOff(shorter));
 
-      // Insert ents for auth rrs
-      if(doent && rr.auth) {
-        nonterm.insert(rrterm.begin(), rrterm.end());
+      // Insert ents
+      if(doent && !rrterm.empty()) {
+        bool auth;
+        if (!rr.auth && rr.qtype.getCode() == QType::NS) {
+          ordername=toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, rr.qname));
+          auth=(!gotOptOutFlag || secured.count(ordername));
+        } else
+          auth=rr.auth;
+
+        BOOST_FOREACH(const string nt, rrterm){
+          if (!nonterm.count(nt))
+              nonterm.insert(pair<string, bool>(nt, auth));
+            else if (auth)
+              nonterm[nt]=true;
+        }
+
         if(nonterm.size() > maxent) {
           L<<Logger::Error<<"AXFR zone "<<domain<<" has too many empty non terminals."<<endl;
           nonterm.clear();