From: Kees Monshouwer Date: Fri, 21 Feb 2014 00:04:07 +0000 (+0100) Subject: AXFR-in: fix ent generation for insecure delegations X-Git-Tag: rec-3.6.0-rc1~169^2~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e5c7239cca7cd228db01babbd8c71dd37c51a454;p=thirdparty%2Fpdns.git AXFR-in: fix ent generation for insecure delegations --- diff --git a/modules/gmysqlbackend/gmysqlbackend.cc b/modules/gmysqlbackend/gmysqlbackend.cc index 1c7d56012a..97e1aa667b 100644 --- a/modules/gmysqlbackend/gmysqlbackend.cc +++ b/modules/gmysqlbackend/gmysqlbackend.cc @@ -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"); diff --git a/modules/goraclebackend/goraclebackend.cc b/modules/goraclebackend/goraclebackend.cc index 298b455dc4..4b629ef5f6 100644 --- a/modules/goraclebackend/goraclebackend.cc +++ b/modules/goraclebackend/goraclebackend.cc @@ -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"); diff --git a/modules/gpgsqlbackend/gpgsqlbackend.cc b/modules/gpgsqlbackend/gpgsqlbackend.cc index 26eab7a319..92e7c111a0 100644 --- a/modules/gpgsqlbackend/gpgsqlbackend.cc +++ b/modules/gpgsqlbackend/gpgsqlbackend.cc @@ -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"); diff --git a/modules/gsqlite3backend/gsqlite3backend.cc b/modules/gsqlite3backend/gsqlite3backend.cc index 8aff9375fe..0e0bb34822 100644 --- a/modules/gsqlite3backend/gsqlite3backend.cc +++ b/modules/gsqlite3backend/gsqlite3backend.cc @@ -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'"); diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index 4813ccd44c..164c819dc6 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -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& nonterm) +bool GSQLBackend::feedEnts(int domain_id, map& nonterm) { - string output; - BOOST_FOREACH(const string qname, nonterm) { - output = (boost::format(d_InsertEntQuery) % domain_id % toLower(sqlEscape(qname))).str(); + string query; + pair 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& nonterm) return true; } -bool GSQLBackend::feedEnts3(int domain_id, const string &domain, set &nonterm, unsigned int times, const string &salt, bool narrow) +bool GSQLBackend::feedEnts3(int domain_id, const string &domain, map &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 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()); diff --git a/pdns/backends/gsql/gsqlbackend.hh b/pdns/backends/gsql/gsqlbackend.hh index 0a8c87b424..c28d0f4390 100644 --- a/pdns/backends/gsql/gsqlbackend.hh +++ b/pdns/backends/gsql/gsqlbackend.hh @@ -37,8 +37,8 @@ public: bool commitTransaction(); bool abortTransaction(); bool feedRecord(const DNSResourceRecord &r, string *ordername=0); - bool feedEnts(int domain_id, set& nonterm); - bool feedEnts3(int domain_id, const string &domain, set &nonterm, unsigned int times, const string &salt, bool narrow); + bool feedEnts(int domain_id, map& nonterm); + bool feedEnts3(int domain_id, const string &domain, map &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); diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index f5bfacd6e9..2b4fae59b7 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -243,11 +243,11 @@ public: { return false; // no problem! } - virtual bool feedEnts(int domain_id, set &nonterm) + virtual bool feedEnts(int domain_id, map &nonterm) { return false; } - virtual bool feedEnts3(int domain_id, const string &domain, set &nonterm, unsigned int times, const string &salt, bool narrow) + virtual bool feedEnts3(int domain_id, const string &domain, map &nonterm, unsigned int times, const string &salt, bool narrow) { return false; } diff --git a/pdns/slavecommunicator.cc b/pdns/slavecommunicator.cc index 3a8a090897..0dc932eb1b 100644 --- a/pdns/slavecommunicator.cc +++ b/pdns/slavecommunicator.cc @@ -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 nonterm, rrterm; + set rrterm; + map 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(nt, auth)); + else if (auth) + nonterm[nt]=true; + } + if(nonterm.size() > maxent) { L<