From: Peter van Dijk Date: Thu, 25 Oct 2012 08:00:45 +0000 (+0000) Subject: apply remotebackend service pack 1, by Aki Tuomi. Closes #597 X-Git-Tag: auth-3.2-rc1~58 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f4644dfcc244fbbc3ace160f1a937534f4785197;p=thirdparty%2Fpdns.git apply remotebackend service pack 1, by Aki Tuomi. Closes #597 git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2824 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/modules/remotebackend/httpconnector.cc b/modules/remotebackend/httpconnector.cc index 2433efbe8d..c5aae9f079 100644 --- a/modules/remotebackend/httpconnector.cc +++ b/modules/remotebackend/httpconnector.cc @@ -57,8 +57,12 @@ void HTTPConnector::requestbuilder(const std::string &method, const Json::Value ss << "/" << method; - // add the url components, if found, in following order - + // add the url components, if found, in following order. + // id must be first due to the fact that the qname/name can be empty + if ((param = parameters.get("id", Json::Value())).isNull() == false) { + json2string(param, sparam); + ss << "/" << sparam; + } if ((param = parameters.get("zonename", Json::Value())).isNull() == false) { json2string(param, sparam); ss << "/" << sparam; @@ -83,11 +87,6 @@ void HTTPConnector::requestbuilder(const std::string &method, const Json::Value ss << "/" << sparam; } - if ((param = parameters.get("id", Json::Value())).isNull() == false) { - json2string(param, sparam); - ss << "/" << sparam; - } - // finally add suffix ss << d_url_suffix; curl_easy_setopt(d_c, CURLOPT_URL, ss.str().c_str()); @@ -102,7 +101,7 @@ void HTTPConnector::requestbuilder(const std::string &method, const Json::Value // create post with keydata std::stringstream ss2; param = parameters["key"]; - ss2 << "flags" << param["flags"].asUInt() << "&active" << (param["active"].asBool() ? 1 : 0) << "&content="; + ss2 << "flags=" << param["flags"].asUInt() << "&active=" << (param["active"].asBool() ? 1 : 0) << "&content="; tmpstr = curl_easy_escape(d_c, param["content"].asCString(), 0); ss2 << tmpstr; sparam = ss2.str(); diff --git a/modules/remotebackend/pipeconnector.cc b/modules/remotebackend/pipeconnector.cc index 13a97c5f9f..133e36e425 100644 --- a/modules/remotebackend/pipeconnector.cc +++ b/modules/remotebackend/pipeconnector.cc @@ -1,6 +1,10 @@ #include "remotebackend.hh" PipeConnector::PipeConnector(std::map options) { + if (options.count("command") == 0) { + L<command = options.find("command")->second; this->options = options; this->coproc = NULL; diff --git a/modules/remotebackend/regression-tests/00dnssec-grabkeys/command b/modules/remotebackend/regression-tests/00dnssec-grabkeys/command new file mode 100755 index 0000000000..0d984d3b33 --- /dev/null +++ b/modules/remotebackend/regression-tests/00dnssec-grabkeys/command @@ -0,0 +1,16 @@ +#!/bin/sh -e +set pipefail +rm -f trustedkeys +rm -f unbound-host.conf +for zone in example.com +do + drill -p $port -o rd -D dnskey $zone @$nameserver | grep -v '^;' | grep -v AwEAAarTiHhPgvD28WCN8UBXcEcf8f >> trustedkeys + echo "stub-zone:" >> unbound-host.conf + echo " name: $zone" >> unbound-host.conf + echo " stub-addr: $nameserver@$port" >> unbound-host.conf + echo "" >> unbound-host.conf +done + +echo "server:" >> unbound-host.conf +echo " do-not-query-address: 192.168.0.0/16" >> unbound-host.conf +echo ' trust-anchor-file: "trustedkeys"' >> unbound-host.conf diff --git a/modules/remotebackend/regression-tests/00dnssec-grabkeys/description b/modules/remotebackend/regression-tests/00dnssec-grabkeys/description new file mode 100644 index 0000000000..4315650793 --- /dev/null +++ b/modules/remotebackend/regression-tests/00dnssec-grabkeys/description @@ -0,0 +1 @@ +Grab DNSKEY records for validation testing. diff --git a/modules/remotebackend/regression-tests/00dnssec-grabkeys/expected_result b/modules/remotebackend/regression-tests/00dnssec-grabkeys/expected_result new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/remotebackend/regression-tests/apex-test/command b/modules/remotebackend/regression-tests/apex-test/command new file mode 100755 index 0000000000..f8868dd0f0 --- /dev/null +++ b/modules/remotebackend/regression-tests/apex-test/command @@ -0,0 +1,3 @@ +#!/bin/sh + +cleandig up.example.com NS diff --git a/modules/remotebackend/regression-tests/apex-test/description b/modules/remotebackend/regression-tests/apex-test/description new file mode 100644 index 0000000000..a735cbf786 --- /dev/null +++ b/modules/remotebackend/regression-tests/apex-test/description @@ -0,0 +1 @@ +Verify that up.example.com NS records come out right diff --git a/modules/remotebackend/regression-tests/apex-test/expected_result b/modules/remotebackend/regression-tests/apex-test/expected_result new file mode 100644 index 0000000000..11c99e71c2 --- /dev/null +++ b/modules/remotebackend/regression-tests/apex-test/expected_result @@ -0,0 +1,6 @@ +0 up.example.com. IN NS 120 ns1.example.com. +0 up.example.com. IN NS 120 ns2.example.com. +2 ns1.example.com. IN A 120 192.168.2.2 +2 ns2.example.com. IN A 120 192.168.2.3 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='up.example.com.', qtype=NS diff --git a/modules/remotebackend/regression-tests/backend.rb b/modules/remotebackend/regression-tests/backend.rb index c7c882c957..8f85941809 100755 --- a/modules/remotebackend/regression-tests/backend.rb +++ b/modules/remotebackend/regression-tests/backend.rb @@ -8,34 +8,62 @@ def rr(qname, qtype, content, ttl, priority = 0, auth = 1, domain_id = -1) end class Handler - attr :db - def initialize(dbpath) - @db = SQLite3::Database.new dbpath + @dbpath = dbpath + end + + def db + d = SQLite3::Database.new @dbpath + if block_given? + d.transaction + begin + yield d + rescue + d.rollback + return + end + d.commit + else + d + end end def do_initialize(*args) return true, "Test bench initialized" end + def getbeforename(qname, id) + before = db.get_first_value("SELECT ordername FROM records WHERE ordername < ? AND domain_id = ? ORDER BY ordername DESC", qname, id) + if (before.nil?) + before = db.get_first_value("SELECT ordername FROM records WHERE domain_id = ? ORDER by ordername DESC LIMIT 1", id) + end + before + end + + def getaftername(qname, id) + after = db.get_first_value("SELECT ordername FROM records WHERE ordername > ? AND domain_id = ? ORDER BY ordername", qname, id) + if (after.nil?) + after = db.get_first_value("SELECT ordername FROM records WHERE domain_id = ? ORDER by ordername LIMIT 1", id) + end + after + end + + def do_getbeforeandafternamesabsolute(args) - before = @db.get_first_value("SELECT ordername FROM records WHERE ordername < ? AND domain_id = ?", args["qname"], args["id"]) - after = @db.get_first_value("SELECT ordername FROM records WHERE ordername > ? AND domain_id = ?", args["qname"], args["id"]) - return [{:before => before, :after => after, :unhashed => args["qname"]}, nil] + args["qname"] = "" if args["qname"].nil? + return [{:before => getbeforename(args["qname"],args["id"]), :after => getaftername(args["qname"],args["id"]), :unhashed => args["qname"]}, nil] end def do_getbeforeandafternames(args) - before = @db.get_first_value("SELECT ordername FROM records WHERE ordername < ? AND domain_id = ?", args["qname"], args["id"]) - after = @db.get_first_value("SELECT ordername FROM records WHERE ordername > ? AND domain_id = ?", args["qname"], args["id"]) - return [{:before => before, :after => after, :unhashed => args["qname"]}, nil] + args["qname"] = "" if args["qname"].nil? + return [{:before => getbeforename(args["qname"],args["id"]), :after => getaftername(args["qname"],args["id"]), :unhashed => args["qname"]}, nil] end def do_getdomainkeys(args) ret = [] - @db.execute("SELECT flags,active,content FROM domains JOIN cryptokeys ON domains.id = cryptokeys.domain_id WHERE domains.name = ?", args["name"]) do |row| - ret << {:flags => row[0].to_i, :active => !(row[1].to_i.zero?), :content => row[2]} + db.execute("SELECT cryptokeys.id,flags,active,content FROM domains JOIN cryptokeys ON domains.id = cryptokeys.domain_id WHERE domains.name = ?", [args["name"]]) do |row| + ret << {:id => row[0].to_i, :flags => row[1].to_i, :active => !(row[2].to_i.zero?), :content => row[3]} end - return false if ret.empty? return [ret,nil] end @@ -45,13 +73,25 @@ class Handler loop do begin sargs = {} - if (args["qtype"] == "ANY") - sql = "SELECT domain_id,name,type,content,ttl,prio,auth FROM records WHERE name = :qname" - sargs["qname"] = args["qname"] + if (args["zone-id"].to_i > 0) + sargs["domain_id"] = args["zone-id"].to_i + if (args["qtype"] == "ANY") + sql = "SELECT domain_id,name,type,content,ttl,prio,auth FROM records WHERE name = :qname AND domain_id = :domain_id" + sargs["qname"] = args["qname"] + else + sql = "SELECT domain_id,name,type,content,ttl,prio,auth FROM records WHERE name = :qname AND type = :qtype AND domain_id = :domain_id" + sargs["qname"] = args["qname"] + sargs["qtype"] = args["qtype"] + end else - sql = "SELECT domain_id,name,type,content,ttl,prio,auth FROM records WHERE name = :qname AND type = :qtype" - sargs["qname"] = args["qname"] - sargs["qtype"] = args["qtype"] + if (args["qtype"] == "ANY") + sql = "SELECT domain_id,name,type,content,ttl,prio,auth FROM records WHERE name = :qname" + sargs["qname"] = args["qname"] + else + sql = "SELECT domain_id,name,type,content,ttl,prio,auth FROM records WHERE name = :qname AND type = :qtype" + sargs["qname"] = args["qname"] + sargs["qtype"] = args["qtype"] + end end db.execute(sql, sargs) do |row| ret << rr(row[1], row[2], row[3], row[4], row[5], row[6], row[0]) @@ -64,9 +104,21 @@ class Handler return false unless ret.size > 0 return [ret,nil] end - + + def do_getdomaininfo(args) + ret = {} + sql = "SELECT name,content FROM records WHERE name = :name AND type = 'SOA'" + db.execute(sql, args) do |row| + ret[:zone] = row[0] + ret[:serial] = row[1].split(' ')[2].to_i + ret[:kind] = "native" + end + return [ret,nil] if ret.has_key?(:zone) + return false + end + def do_list(args) - target = args["target"] + target = args["zonename"] ret = [] loop do begin @@ -77,6 +129,7 @@ class Handler end rescue Exception => e e.backtrace + return false, [e.message] end break end @@ -84,11 +137,63 @@ class Handler return [ret,nil] end + def do_adddomainkey(args) + d_id = db.get_first_value("SELECT id FROM domains WHERE name = ?", args["name"]) + return false if d_id.nil? + sql = "INSERT INTO cryptokeys (domain_id, flags, active, content) VALUES(?,?,?,?)" + active = args["key"]["active"] + if (active) + active = 1 + else + active = 0 + end + db do |tx| + tx.execute(sql, [d_id, args["key"]["flags"].to_i, active, args["key"]["content"]]) + end + return db.get_first_value("SELECT last_insert_rowid()").to_i + end + + def do_deactivatedomainkey(args) + d_id = db.get_first_value("SELECT id FROM domains WHERE name = ?", args["name"]) + return false if d_id.nil? + db do |tx| + tx.execute("UPDATE cryptokeys SET active = 0 WHERE domain_id = ? AND id = ?", [d_id, args["id"]]) + end + return true + end + + def do_activatedomainkey(args) + d_id = db.get_first_value("SELECT id FROM domains WHERE name = ?", args["name"]) + return false if d_id.nil? + db do |tx| + db.execute("UPDATE cryptokeys SET active = 1 WHERE domain_id = ? AND id = ?", [d_id, args["id"]]) + end + return true + end + def do_getdomainmetadata(args) - return false + ret = [] + sql = "SELECT content FROM domainmetadata JOIN domains WHERE name = :name AND kind = :kind" + sargs = {:name => args["name"], :kind => args["kind"]} + db.execute(sql,sargs) do |row| + ret << row[0] + end + return false unless ret.size > 0 + return [ret,nil] end def do_setdomainmetadata(args) - return false + d_id = db.get_first_value("SELECT id FROM domains WHERE name = ?", args["name"]) + return false if d_id.nil? + db do |tx| + sql = "DELETE FROM domainmetadata WHERE domain_id = ?" + tx.execute(sql, [d_id]) + break if args["value"].nil? + sql = "INSERT INTO domainmetadata (domain_id,kind,content) VALUES(?,?,?)" + args["value"].each do |value| + tx.execute(sql,[d_id, args["kind"], value]) + end + end + return true end end diff --git a/modules/remotebackend/regression-tests/basic-a-dnssec/command b/modules/remotebackend/regression-tests/basic-a-dnssec/command new file mode 100755 index 0000000000..6d157fcb49 --- /dev/null +++ b/modules/remotebackend/regression-tests/basic-a-dnssec/command @@ -0,0 +1,3 @@ +#!/bin/sh + +cleandig outpost.example.com A dnssec diff --git a/modules/remotebackend/regression-tests/basic-a-dnssec/description b/modules/remotebackend/regression-tests/basic-a-dnssec/description new file mode 100644 index 0000000000..6cd423e240 --- /dev/null +++ b/modules/remotebackend/regression-tests/basic-a-dnssec/description @@ -0,0 +1 @@ +Basic DNSSEC test diff --git a/modules/remotebackend/regression-tests/basic-a-dnssec/expected_result b/modules/remotebackend/regression-tests/basic-a-dnssec/expected_result new file mode 100644 index 0000000000..76c3feccdd --- /dev/null +++ b/modules/remotebackend/regression-tests/basic-a-dnssec/expected_result @@ -0,0 +1,5 @@ +0 outpost.example.com. IN A 120 192.168.2.1 +0 outpost.example.com. IN RRSIG 120 A 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='outpost.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/basic-a-dnssec/skip.nodnssec b/modules/remotebackend/regression-tests/basic-a-dnssec/skip.nodnssec new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/remotebackend/regression-tests/basic-aaaa-resolution/command b/modules/remotebackend/regression-tests/basic-aaaa-resolution/command new file mode 100755 index 0000000000..4a6e523a15 --- /dev/null +++ b/modules/remotebackend/regression-tests/basic-aaaa-resolution/command @@ -0,0 +1,3 @@ +#!/bin/sh +cleandig outpost.example.com AAAA + diff --git a/modules/remotebackend/regression-tests/basic-aaaa-resolution/description b/modules/remotebackend/regression-tests/basic-aaaa-resolution/description new file mode 100644 index 0000000000..2bfe713ef9 --- /dev/null +++ b/modules/remotebackend/regression-tests/basic-aaaa-resolution/description @@ -0,0 +1,2 @@ +This test tries to resolve a straight AAAA record that is directly available in +the database backend. diff --git a/modules/remotebackend/regression-tests/basic-aaaa-resolution/expected_result b/modules/remotebackend/regression-tests/basic-aaaa-resolution/expected_result new file mode 100644 index 0000000000..1155d21a55 --- /dev/null +++ b/modules/remotebackend/regression-tests/basic-aaaa-resolution/expected_result @@ -0,0 +1,3 @@ +0 outpost.example.com. IN AAAA 120 fe80::1 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='outpost.example.com.', qtype=AAAA diff --git a/modules/remotebackend/regression-tests/basic-aaaa-resolution/tmp.rb b/modules/remotebackend/regression-tests/basic-aaaa-resolution/tmp.rb new file mode 100644 index 0000000000..3cbe477357 --- /dev/null +++ b/modules/remotebackend/regression-tests/basic-aaaa-resolution/tmp.rb @@ -0,0 +1,46 @@ +qname = "node-b.dyn.example.com" + +def to32(number) + number.to_s(32).tr "0123456789abcdefghijklmnopqrstuv", "ybndrfg8ejkmcpqxot1uwisza345h769" +end + +def from32(str) + str.tr("ybndrfg8ejkmcpqxot1uwisza345h769", "0123456789abcdefghijklmnopqrstuv").to_i(32) +end + +def rr(qname, qtype, content, ttl, priority = 0, auth = 1) + {:qname => qname, :qtype => qtype, :content => content, :ttl => ttl, :priority => priority, :auth => auth} +end + +def send_result(*params) + +end + +def main(qname,qtype) + if qname[/\.?dyn.example.com$/] + if qname == "dyn.example.com" + ret = [] + if (qtype != "SOA") + ret << rr(qname, "NS", "ns1.example.com",300) + ret << rr(qname, "NS", "ns2.example.com",300) + ret << rr(qname, "NS", "ns3.example.com",300) + end + ret << rr(qname,"SOA","ns1.example.com hostmaster.example.com #{Time.now.strftime("%Y%m%d%H")} 28800 7200 1209600 300",300) + return send_result ret + elsif qtype == "ANY" or qtype == "AAAA" + name = qname.match(/^node-(.*)\.dyn.example.com$/)[1] + if name.empty? + return send_result false + end +# if name.size < 16 +# pad = 15-name.size +# (1..pad).each do |i| name = "y#{name}" end +# end + puts from32(name) + return send_result [rr(qname, "AAAA", "", 300)] + end + end + send_result false +end + +main qname,"AAAA" diff --git a/modules/remotebackend/regression-tests/dnsbackend.rb b/modules/remotebackend/regression-tests/dnsbackend.rb index 427446f1d6..f896b683a4 100644 --- a/modules/remotebackend/regression-tests/dnsbackend.rb +++ b/modules/remotebackend/regression-tests/dnsbackend.rb @@ -1,28 +1,60 @@ require 'json' +require 'thread' class DNSBackendHandler < WEBrick::HTTPServlet::AbstractServlet def initialize(server, dnsbackend) @dnsbackend = dnsbackend + @semaphore = Mutex.new + @f = File.open("/tmp/tmp.txt","a") + end + + def parse_url(url) + url = url.split('/') + method = url.shift.downcase + + # do some determining based on method names + args = case method + when "lookup" + { + "qname" => url.shift, + "qtype" => url.shift, + } + when "list" + { + "zonename" => url.shift + } + when "getbeforeandafternamesabsolute", "getbeforeandafternames" + { + "id" => url.shift.to_i, + "qname" => url.shift + } + when "getdomainmetadata", "setdomainmetadata", "getdomainkeys" + { + "name" => url.shift, + "kind" => url.shift + } + when "removedomainkey", "activatedomainkey", "deactivatedomainkey" + { + "id" => url.shift, + "name" => url.shift + } + when "adddomainkey", "gettsigkey", "getdomaininfo" + { + "name" => url.shift + } + end + + [method, args] end def do_GET(req,res) tmp = req.path[/dns\/(.*)/,1] return 400, "Bad request" if (tmp.nil?) - tmp = tmp.split("/") - method = "do_#{tmp.shift}".downcase - args = {} - - if tmp.size > 0 - args["qname"] = tmp[0] - args["name"] = tmp[0] - args["target"] = tmp.shift - end - if tmp.size > 0 - args["kind"] = tmp[0] - args["qtype"] = tmp[0] - args["id"] = tmp.shift - end + method, args = parse_url(tmp) + + method = "do_#{method}" + # get more arguments req.each do |k,v| attr = k[/X-RemoteBackend-(.*)/,1] @@ -31,25 +63,39 @@ class DNSBackendHandler < WEBrick::HTTPServlet::AbstractServlet end end - if @dnsbackend.respond_to?(method.to_sym) - result, log = @dnsbackend.send(method.to_sym, args) - body = {:result => result, :log => log} - res.status = 200 - res["Content-Type"] = "application/javascript; charset=utf-8" - res.body = body.to_json - else - res.status = 404 - res["Content-Type"] = "application/javascript; charset=utf-8" - res.body = ({:result => false, :log => ["Method not found"]}).to_json + args = args.merge req.query + + if method == "do_adddomainkey" + args["key"] = { + "flags" => args.delete("flags").to_i, + "active" => args.delete("active").to_i, + "content" => args.delete("content") + } + end + + @f.puts method + @f.puts args + + @semaphore.synchronize do + if @dnsbackend.respond_to?(method.to_sym) + result, log = @dnsbackend.send(method.to_sym, args) + body = {:result => result, :log => log} + res.status = 200 + res["Content-Type"] = "application/javascript; charset=utf-8" + res.body = body.to_json + else + res.status = 404 + res["Content-Type"] = "application/javascript; charset=utf-8" + res.body = ({:result => false, :log => ["Method not found"]}).to_json + end end end def do_DELETE(req,res) + do_GET(req,res) end def do_POST(req,res) - req.continue - - # get method name and args + do_GET(req,res) end end diff --git a/modules/remotebackend/regression-tests/dnssec-keys/command b/modules/remotebackend/regression-tests/dnssec-keys/command new file mode 100755 index 0000000000..50dd9f3ad9 --- /dev/null +++ b/modules/remotebackend/regression-tests/dnssec-keys/command @@ -0,0 +1,3 @@ +#!/bin/sh + +cleandig example.com DNSKEY diff --git a/modules/remotebackend/regression-tests/dnssec-keys/description b/modules/remotebackend/regression-tests/dnssec-keys/description new file mode 100644 index 0000000000..ba38d23167 --- /dev/null +++ b/modules/remotebackend/regression-tests/dnssec-keys/description @@ -0,0 +1 @@ +Check that pdns can read keys from backend diff --git a/modules/remotebackend/regression-tests/dnssec-keys/expected_result b/modules/remotebackend/regression-tests/dnssec-keys/expected_result new file mode 100644 index 0000000000..5bff4c2af5 --- /dev/null +++ b/modules/remotebackend/regression-tests/dnssec-keys/expected_result @@ -0,0 +1,4 @@ +0 example.com. IN DNSKEY 120 256 3 8 ... +0 example.com. IN DNSKEY 120 257 3 8 ... +Rcode: 0, RD: 0, QR: 1, TC: 1, AA: 1, opcode: 0 +Reply to question for qname='example.com.', qtype=DNSKEY diff --git a/modules/remotebackend/regression-tests/dnssec-keys/skip.nodnssec b/modules/remotebackend/regression-tests/dnssec-keys/skip.nodnssec new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/remotebackend/regression-tests/example.com.ksk b/modules/remotebackend/regression-tests/example.com.ksk new file mode 100644 index 0000000000..f8740a50a5 --- /dev/null +++ b/modules/remotebackend/regression-tests/example.com.ksk @@ -0,0 +1,11 @@ +Private-key-format: v1.2 +Algorithm: 8 (RSASHA256) +Modulus: 50uFCCyl8CcSdUqOVHpbx38cL4yzRR4IULwnzMqjGkAQCZ/aMKJ6XzO1LUU/QIobJ5uO3r5GkLWAkW1ne+xEtuuj5CUuAG2lBifciNOVfrljmtuPRU1QahhzL48cZdiGjUvhcSKAo8ftwzH3NMLVzURZxT0C+JWvC18sZHs2w20+HVIZbZzCqwuTDpAsqPklxjflSZQRHrB3OI07hMRoWbAi2bIvjI6BgVUsMIUyNymfLPIROEMVj1fqQcygfzwAZcFWZSGU3Isxz8O4JTizGvaJ1E4Yh/QkHP1MMc6Kggbbd+KyYt1UfXLUFMDraiNFl8oNbOoJDdtA4oRX1bN8EQ== +PublicExponent: AQAB +PrivateExponent: Lsygh8Vk9AEr4nCp+NzjKiwFe3eIJHGNtCxGD1FnDB4vQItIHjQZ955iR90tjbUEBpEaqOYuKASZlZNh73igdLScLkL5mluVGvhAzqylIIWJamGHjTm2DimRUOuvjsnve7KBVJ9rEPiYmrjG8LWFhimQ0nBkZAEBcJcax+AIdiUHgR7SkyRIeuitZCbNiiJ7s2dkdN2JBxhEsZi+q13vDjGy1Ifu1M5nXXPjHsj3aoorSwmnOsR3AwSgC8nydL0OxNo2Fm54qdZC2EftX6KVaRYi3UWJd1lNt6wgBO6w2iDdLteg70P3XuzWyZe0CxHqG956LMQqvKSr59o5j2tYeQ== +Prime1: +DWjjc/Z+u8UiLDBjDFNmM2wzEPoIAFkq86dj+n427jd72hFlAeuO2K6AgXekXSB7TA3JeBGKLyXzCoLN9C4wKLCMAcZs3uOmA43xEgL+cufKfFgKmrrq/mX0y34B17jtt6fL+oSYHuoryN9WxBeNfpz94lb9xE6cptoUopiJJ0= +Prime2: 7o35Ayz2OhYeUkDsJCQ7Q38Vv5qdB8u8BXLYzEH3/fLiOViaHPUfg+jQ9TzEc3XCgQ212LI3yqwWsQ6nMnB+X9H1czW9OW9LJC9cS0mayIxdbYIa1HzUyYzCSiZfEFwzNXBPkfnmYjHqAPzCsAuBmrH9z3oo7c1rHcltrL84SQU= +Exponent1: D1W5ChzqWb+FpEBPZOry4Vrr7mLPp5KOdrLoNyj8cA7G33Cww8mJsS+TUGaubowlLtNIxPVLQF8OfdWnJcamc3hayP7XTqh2kdxnA6Bz5PX4mm3IRDag4toj0C9J4KKzLOwqJ5qtkfpx3IgzyXmEaI9VtNhuryAIXWZOlrLoB10= +Exponent2: zQxjmgMvskYI0hLT50ztU9sMyqEPkP/iIZzSFOAvVa1MHpa2AWYBLNUVp3YQNl5mTZ+HSzgFFMROzOoXdReUyLAkFl9+wruTDwtWfbBKx08/jz1h6ntSO9wttKa+18Uojyp2erce/BCDX03j2oZJZLrRu2D5hU4oYHYfO3kx3DE= +Coefficient: 1lIUp+1hdC3zOULOkFpMqXFKp4QTkRLxffMnvH5jvfTaofGwYAFSFKIj289OQrmjJ0HXMJNEQ5vK0pW7K4newD1fefPYI3zyRE4zzew3hWlsGFgTqAsqEqk/gpPOMKJ0fWXJoFN4N5+3SOKYUthyRQHpxPI4IXKsL6Ckygf7Ydg= + diff --git a/modules/remotebackend/regression-tests/example.com.zsk.1 b/modules/remotebackend/regression-tests/example.com.zsk.1 new file mode 100644 index 0000000000..bd7d3f226f --- /dev/null +++ b/modules/remotebackend/regression-tests/example.com.zsk.1 @@ -0,0 +1,11 @@ +Private-key-format: v1.2 +Algorithm: 8 (RSASHA256) +Modulus: yIrPfzxbh4ndcbY/Kv0pp5/wVDBkrNaPOJMRKmASPFP8tbBSsvk49ARQEdrTGtPg0tMdUCX1nPZPIVmJsrD2/xGcpW0A+CAOB4H7Akz+nHlhkgPtErM6zPktxoQXBVUWKkcddJjEO5gAgXHN3Y/Ji6fDmtiRTjFUPyNYrBzf7zc= +PublicExponent: AQAB +PrivateExponent: Aiff2CXNdBUK0NydLDiheIBTJIyKoIMD8h8+mX6D46shddCJ6wubzZ+4PqDkEQ9DBPEpCQIHdGL/ccPVI5scZJerFbEdZP12n+0ZRoAkhbuhgTYlUQh253y8w+CIOipgIMo9WAM66/F6Y8KBpPp2qq7OJHbbKGhEQMKrx/dsHeE= +Prime1: 7MnlWpyUSc5vKcnZjo4Qj3OC+VQXiC3vXFSWFY3xF5dKc0tIbaznTwH+KQ35gFZ6ZBVPkHQP/v6VPv6t5V5h1w== +Prime2: 2NATZQeCOwtPCuahak8pM2166PmTI84zUYmRWINf957KniyP44eM068HOm5RZeF7MwdnzrOV+tx3l3tftb/xoQ== +Exponent1: hj40RHnO7EUX6sYgDFzocJuZXodZTABW2q6t5Axz6d8A+3pr1poXDUjg8h+VGzhr7P/T+t6CDxwAOxWiOw6WQw== +Exponent2: ke78HvR+498oxN2XqEbAJK18HXRfZapVQHyoKDvFTJbFKtIzx6JlV9ZntxyqDTlIA4DojmiyergKhxuzwFICAQ== +Coefficient: m0leC8nHk+4zytiraipFK2/WRzmDw9+pHLqWpCKnXkWSVCdbhw1tyNfS4WDKL8iBXcV774WL0oR/naOwU72IpA== + diff --git a/modules/remotebackend/regression-tests/example.com.zsk.2 b/modules/remotebackend/regression-tests/example.com.zsk.2 new file mode 100644 index 0000000000..e74a199e01 --- /dev/null +++ b/modules/remotebackend/regression-tests/example.com.zsk.2 @@ -0,0 +1,11 @@ +Private-key-format: v1.2 +Algorithm: 8 (RSASHA256) +Modulus: r+vmQll38ndQqNSCx9eqRBUbSOLcH4PZFX824sGhY2NSQChqt1G4ZfndzRwgjXMUwiE7GkkqU2Vbt/g4iP67V/+MYecMV9YHkCRnEzb47nBXvs9JCf8AHMCnma567GQjPECh4HevPE9wmcOfpy/u7UN1oHKSKRWuZJadUwcjbp8= +PublicExponent: AQAB +PrivateExponent: CYC93UtVnOM6wrFJZ+qA9+Yx+p5yk0CSi0Q7c+/6EVMuABQ5gNyTuu0j65lU3X81bwUk2wHPx6smfgoVDRAW5jjO4jgIFV6nE4inzk5YQKycQSL8YG3Nm9GciLFya1KUXs81sHsQpkvK7MNaSbvkaHZQ6iv16bZ4t73Wascwa/E= +Prime1: 6a165cIC0nNsGlTW/s2jRu7idq5+U203iE1HzSIddmWgx5KIKE/s3I+pwfmXYRUmq+4H9ASd/Yot1lSYW98szw== +Prime2: wLoCPKxxnuxDx6/9IKOYz8t9ZNLY74iCeQ85koqvTctkFmB9jpOUHTU9BhecaFY2euP9CuHV7z3PLtCoO8s1MQ== +Exponent1: CuzJaiR/7UboLvL4ekEy+QYCIHpX/Z6FkiHK0ZRevEJUGgCHzRqvgEBXN3Jr2WYbwL4IMShmGoxzSCn8VY9BkQ== +Exponent2: LDR9/tyu0vzuLwc20B22FzNdd5rFF2wAQTQ0yF/3Baj5NAi9w84l0u07KgKQZX4g0N8qUyypnU5YDyzc6ZoagQ== +Coefficient: 6S0vhIQITWzqfQSLj+wwRzs6qCvJckHb1+SD1XpwYjSgMTEUlZhf96m8WiaE1/fIt4Zl2PC3fF7YIBoFLln22w== + diff --git a/modules/remotebackend/regression-tests/http-backend.rb b/modules/remotebackend/regression-tests/http-backend.rb index a0e0529b5a..8a49989dc6 100755 --- a/modules/remotebackend/regression-tests/http-backend.rb +++ b/modules/remotebackend/regression-tests/http-backend.rb @@ -5,10 +5,17 @@ require "webrick" require "../modules/remotebackend/regression-tests/dnsbackend" require "../modules/remotebackend/regression-tests/backend" -server = WEBrick::HTTPServer.new :Port => 62434 +server = WEBrick::HTTPServer.new( + Port: 62434, + BindAddress: "localhost", +# Logger: WEBrick::Log.new("remotebackend-server.log"), + AccessLog: [ [ File.open("remotebackend-access.log", "w"), WEBrick::AccessLog::COMBINED_LOG_FORMAT ] ] +) be = Handler.new("../modules/remotebackend/regression-tests/remote.sqlite3") - server.mount "/dns", DNSBackendHandler, be + trap('INT') { server.stop } +trap('TERM') { server.stop } + server.start diff --git a/modules/remotebackend/regression-tests/list-all-records/command b/modules/remotebackend/regression-tests/list-all-records/command new file mode 100755 index 0000000000..bf5680dc18 --- /dev/null +++ b/modules/remotebackend/regression-tests/list-all-records/command @@ -0,0 +1,3 @@ +#!/bin/sh + +dig example.com AXFR @$nameserver -p $port | grep "IN" | egrep -v "(NSEC|RRSIG|DNSKEY)" | LC_ALL=C sort diff --git a/modules/remotebackend/regression-tests/list-all-records/description b/modules/remotebackend/regression-tests/list-all-records/description new file mode 100644 index 0000000000..2106ef6a72 --- /dev/null +++ b/modules/remotebackend/regression-tests/list-all-records/description @@ -0,0 +1 @@ +Makes sure listing works diff --git a/modules/remotebackend/regression-tests/list-all-records/expected_result b/modules/remotebackend/regression-tests/list-all-records/expected_result new file mode 100644 index 0000000000..f9d0649c48 --- /dev/null +++ b/modules/remotebackend/regression-tests/list-all-records/expected_result @@ -0,0 +1,14 @@ +example.com. 120 IN NS ns1.example.com. +example.com. 120 IN NS ns2.example.com. +example.com. 120 IN SOA ns1.example.com. hostmaster.example.com. 2000010101 28800 7200 1209600 120 +example.com. 120 IN SOA ns1.example.com. hostmaster.example.com. 2000010101 28800 7200 1209600 120 +ns1.example.com. 120 IN A 192.168.2.2 +ns2.example.com. 120 IN A 192.168.2.3 +outpost.example.com. 120 IN A 192.168.2.1 +outpost.example.com. 120 IN AAAA fe80::1 +up.example.com. 120 IN DS 38674 8 1 50EA84825288D03BF9DDDA0B0B5F8964C6FBAFA8 +up.example.com. 120 IN DS 38674 8 2 BF31EF7AEA46F2ADCA7A61FBB0629FB5C24116DF0F22EC0115DBC7EB DDDEE04E +up.example.com. 120 IN DS 38674 8 3 6ED18DCEABA6D2547F2FC82BA3801FDC919DB51B0E44BAA261B887C8 24DD9A2D +up.example.com. 120 IN NS ns1.example.com. +up.example.com. 120 IN NS ns2.example.com. +www.example.com. 120 IN A 192.168.2.255 diff --git a/modules/remotebackend/regression-tests/long-txt-resolution/command b/modules/remotebackend/regression-tests/long-txt-resolution/command new file mode 100755 index 0000000000..3fdd4be8f2 --- /dev/null +++ b/modules/remotebackend/regression-tests/long-txt-resolution/command @@ -0,0 +1,3 @@ +#!/bin/sh +cleandig jump.up.example.com TXT + diff --git a/modules/remotebackend/regression-tests/long-txt-resolution/description b/modules/remotebackend/regression-tests/long-txt-resolution/description new file mode 100644 index 0000000000..bd43c6320b --- /dev/null +++ b/modules/remotebackend/regression-tests/long-txt-resolution/description @@ -0,0 +1 @@ +Check that long TXT comes out clean diff --git a/modules/remotebackend/regression-tests/long-txt-resolution/expected_result b/modules/remotebackend/regression-tests/long-txt-resolution/expected_result new file mode 100644 index 0000000000..7ae60e605f --- /dev/null +++ b/modules/remotebackend/regression-tests/long-txt-resolution/expected_result @@ -0,0 +1,3 @@ +0 jump.up.example.com. IN TXT 120 "a very very long indeed text string that should pass out clean and proper thru the entire chain of powerdns processing" +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='jump.up.example.com.', qtype=TXT diff --git a/modules/remotebackend/regression-tests/long-txt-resolution/tmp.rb b/modules/remotebackend/regression-tests/long-txt-resolution/tmp.rb new file mode 100644 index 0000000000..3cbe477357 --- /dev/null +++ b/modules/remotebackend/regression-tests/long-txt-resolution/tmp.rb @@ -0,0 +1,46 @@ +qname = "node-b.dyn.example.com" + +def to32(number) + number.to_s(32).tr "0123456789abcdefghijklmnopqrstuv", "ybndrfg8ejkmcpqxot1uwisza345h769" +end + +def from32(str) + str.tr("ybndrfg8ejkmcpqxot1uwisza345h769", "0123456789abcdefghijklmnopqrstuv").to_i(32) +end + +def rr(qname, qtype, content, ttl, priority = 0, auth = 1) + {:qname => qname, :qtype => qtype, :content => content, :ttl => ttl, :priority => priority, :auth => auth} +end + +def send_result(*params) + +end + +def main(qname,qtype) + if qname[/\.?dyn.example.com$/] + if qname == "dyn.example.com" + ret = [] + if (qtype != "SOA") + ret << rr(qname, "NS", "ns1.example.com",300) + ret << rr(qname, "NS", "ns2.example.com",300) + ret << rr(qname, "NS", "ns3.example.com",300) + end + ret << rr(qname,"SOA","ns1.example.com hostmaster.example.com #{Time.now.strftime("%Y%m%d%H")} 28800 7200 1209600 300",300) + return send_result ret + elsif qtype == "ANY" or qtype == "AAAA" + name = qname.match(/^node-(.*)\.dyn.example.com$/)[1] + if name.empty? + return send_result false + end +# if name.size < 16 +# pad = 15-name.size +# (1..pad).each do |i| name = "y#{name}" end +# end + puts from32(name) + return send_result [rr(qname, "AAAA", "", 300)] + end + end + send_result false +end + +main qname,"AAAA" diff --git a/modules/remotebackend/regression-tests/ns-at-delegation/command b/modules/remotebackend/regression-tests/ns-at-delegation/command new file mode 100755 index 0000000000..f8868dd0f0 --- /dev/null +++ b/modules/remotebackend/regression-tests/ns-at-delegation/command @@ -0,0 +1,3 @@ +#!/bin/sh + +cleandig up.example.com NS diff --git a/modules/remotebackend/regression-tests/ns-at-delegation/description b/modules/remotebackend/regression-tests/ns-at-delegation/description new file mode 100644 index 0000000000..d7492c85de --- /dev/null +++ b/modules/remotebackend/regression-tests/ns-at-delegation/description @@ -0,0 +1 @@ +Verify that asking for NS at a delegation point returns a referral. diff --git a/modules/remotebackend/regression-tests/ns-at-delegation/expected_result b/modules/remotebackend/regression-tests/ns-at-delegation/expected_result new file mode 100644 index 0000000000..11c99e71c2 --- /dev/null +++ b/modules/remotebackend/regression-tests/ns-at-delegation/expected_result @@ -0,0 +1,6 @@ +0 up.example.com. IN NS 120 ns1.example.com. +0 up.example.com. IN NS 120 ns2.example.com. +2 ns1.example.com. IN A 120 192.168.2.2 +2 ns2.example.com. IN A 120 192.168.2.3 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='up.example.com.', qtype=NS diff --git a/modules/remotebackend/regression-tests/nsec-middle/command b/modules/remotebackend/regression-tests/nsec-middle/command new file mode 100755 index 0000000000..9745b8bb7b --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-middle/command @@ -0,0 +1,3 @@ +#!/bin/sh +cleandig outerpost.example.com A dnssec + diff --git a/modules/remotebackend/regression-tests/nsec-middle/description b/modules/remotebackend/regression-tests/nsec-middle/description new file mode 100644 index 0000000000..f12919571a --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-middle/description @@ -0,0 +1,2 @@ +This test verifies that an NXDOMAIN in the middle of a zone +generates a correct NSEC(3). diff --git a/modules/remotebackend/regression-tests/nsec-middle/expected_result b/modules/remotebackend/regression-tests/nsec-middle/expected_result new file mode 100644 index 0000000000..86441a9e53 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-middle/expected_result @@ -0,0 +1,9 @@ +1 example.com. IN NSEC 120 ns1.example.com. NS SOA RRSIG NSEC DNSKEY +1 example.com. IN RRSIG 120 NSEC 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN RRSIG 120 SOA 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN SOA 120 ns1.example.com. hostmaster.example.com. 2000010101 28800 7200 1209600 120 +1 ns2.example.com. IN NSEC 120 outpost.example.com. A RRSIG NSEC +1 ns2.example.com. IN RRSIG 120 NSEC 8 3 120 [expiry] [inception] [keytag] example.com. ... +2 . IN OPT 32768 +Rcode: 3, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='outerpost.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-middle/expected_result.narrow b/modules/remotebackend/regression-tests/nsec-middle/expected_result.narrow new file mode 100644 index 0000000000..65a5f891b0 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-middle/expected_result.narrow @@ -0,0 +1,7 @@ +1 example.com. IN NSEC 120 outpost.example.com. NS SOA RRSIG NSEC DNSKEY +1 example.com. IN RRSIG 120 NSEC 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN RRSIG 120 SOA 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN SOA 120 ns1.example.com. hostmaster.example.com. 2000010101 28800 7200 1209600 120 +2 . IN OPT 32768 +Rcode: 3, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='outerpost.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-middle/expected_result.nsec3 b/modules/remotebackend/regression-tests/nsec-middle/expected_result.nsec3 new file mode 100644 index 0000000000..65a5f891b0 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-middle/expected_result.nsec3 @@ -0,0 +1,7 @@ +1 example.com. IN NSEC 120 outpost.example.com. NS SOA RRSIG NSEC DNSKEY +1 example.com. IN RRSIG 120 NSEC 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN RRSIG 120 SOA 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN SOA 120 ns1.example.com. hostmaster.example.com. 2000010101 28800 7200 1209600 120 +2 . IN OPT 32768 +Rcode: 3, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='outerpost.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-middle/skip.nodnssec b/modules/remotebackend/regression-tests/nsec-middle/skip.nodnssec new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/remotebackend/regression-tests/nsec-sibling-test/command b/modules/remotebackend/regression-tests/nsec-sibling-test/command new file mode 100755 index 0000000000..7cb2d949c2 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-sibling-test/command @@ -0,0 +1,3 @@ +#!/bin/sh + +cleandig jump.up.example.com A dnssec diff --git a/modules/remotebackend/regression-tests/nsec-sibling-test/description b/modules/remotebackend/regression-tests/nsec-sibling-test/description new file mode 100644 index 0000000000..3da7d7b236 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-sibling-test/description @@ -0,0 +1 @@ +Tests that DS delegation comes out right diff --git a/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result b/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result new file mode 100644 index 0000000000..018dacf8df --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result @@ -0,0 +1,6 @@ +0 jump.up.example.com. IN A 120 192.168.3.1 +0 jump.up.example.com. IN RRSIG 120 A 8 4 120 [expiry] [inception] [keytag] up.example.com. ... +0 jump.up.example.com. IN RRSIG 120 A 8 4 120 [expiry] [inception] [keytag] up.example.com. ... +2 . IN OPT 32768 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='jump.up.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result.narrow b/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result.narrow new file mode 100644 index 0000000000..018dacf8df --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result.narrow @@ -0,0 +1,6 @@ +0 jump.up.example.com. IN A 120 192.168.3.1 +0 jump.up.example.com. IN RRSIG 120 A 8 4 120 [expiry] [inception] [keytag] up.example.com. ... +0 jump.up.example.com. IN RRSIG 120 A 8 4 120 [expiry] [inception] [keytag] up.example.com. ... +2 . IN OPT 32768 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='jump.up.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result.nsec3 b/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result.nsec3 new file mode 100644 index 0000000000..018dacf8df --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-sibling-test/expected_result.nsec3 @@ -0,0 +1,6 @@ +0 jump.up.example.com. IN A 120 192.168.3.1 +0 jump.up.example.com. IN RRSIG 120 A 8 4 120 [expiry] [inception] [keytag] up.example.com. ... +0 jump.up.example.com. IN RRSIG 120 A 8 4 120 [expiry] [inception] [keytag] up.example.com. ... +2 . IN OPT 32768 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='jump.up.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-sibling-test/skip.nodnssec b/modules/remotebackend/regression-tests/nsec-sibling-test/skip.nodnssec new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-begin/command b/modules/remotebackend/regression-tests/nsec-wraparound-begin/command new file mode 100755 index 0000000000..c2e90555c6 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-wraparound-begin/command @@ -0,0 +1,3 @@ +#!/bin/sh +cleandig a.example.com A dnssec + diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-begin/description b/modules/remotebackend/regression-tests/nsec-wraparound-begin/description new file mode 100644 index 0000000000..55df335aae --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-wraparound-begin/description @@ -0,0 +1,2 @@ +This test verifies that NXDOMAINS beyond the last record of a zone +generate a correct wraparound NSEC. diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-begin/expected_result b/modules/remotebackend/regression-tests/nsec-wraparound-begin/expected_result new file mode 100644 index 0000000000..89c9aa9414 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-wraparound-begin/expected_result @@ -0,0 +1,7 @@ +1 example.com. IN NSEC 120 ns1.example.com. NS SOA RRSIG NSEC DNSKEY +1 example.com. IN RRSIG 120 NSEC 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN RRSIG 120 SOA 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN SOA 120 ns1.example.com. hostmaster.example.com. 2000010101 28800 7200 1209600 120 +2 . IN OPT 32768 +Rcode: 3, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='a.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-begin/expected_result.nsec3 b/modules/remotebackend/regression-tests/nsec-wraparound-begin/expected_result.nsec3 new file mode 100644 index 0000000000..a20b5458d2 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-wraparound-begin/expected_result.nsec3 @@ -0,0 +1,11 @@ +1 9f8hti7cc7oqnqjv84klnp89glqrss3r.example.com. IN NSEC3 86400 1 1 1 abcd 9FDAOFPLLN0FQFU9DP274GOU59QFHSLD A RRSIG +1 9f8hti7cc7oqnqjv84klnp89glqrss3r.example.com. IN RRSIG 86400 NSEC3 8 3 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 gnk5kv3h2h1h8ge405j6093608ukp3i5.example.com. IN NSEC3 86400 1 1 1 abcd GNO4LESKG6U7HKEJ9UL71SF1HD7F1P96 A RRSIG +1 gnk5kv3h2h1h8ge405j6093608ukp3i5.example.com. IN RRSIG 86400 NSEC3 8 3 86400 [expiry] [inception] [keytag] example.com. ... +1 vtnq6ocn2vkuiv3nju14oqtaen2mt5sk.example.com. IN NSEC3 86400 1 1 1 abcd VTP9NUQBEH436S7J0K8TI2A32MMKCUUL NS SOA MX RRSIG DNSKEY NSEC3PARAM +1 vtnq6ocn2vkuiv3nju14oqtaen2mt5sk.example.com. IN RRSIG 86400 NSEC3 8 3 86400 [expiry] [inception] [keytag] example.com. ... +2 . IN OPT 32768 +Rcode: 3, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='zzz.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-begin/skip.nodnssec b/modules/remotebackend/regression-tests/nsec-wraparound-begin/skip.nodnssec new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-end/command b/modules/remotebackend/regression-tests/nsec-wraparound-end/command new file mode 100755 index 0000000000..7af813e5ef --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-wraparound-end/command @@ -0,0 +1,3 @@ +#!/bin/sh +cleandig zzz.example.com A dnssec + diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-end/description b/modules/remotebackend/regression-tests/nsec-wraparound-end/description new file mode 100644 index 0000000000..55df335aae --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-wraparound-end/description @@ -0,0 +1,2 @@ +This test verifies that NXDOMAINS beyond the last record of a zone +generate a correct wraparound NSEC. diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-end/expected_result b/modules/remotebackend/regression-tests/nsec-wraparound-end/expected_result new file mode 100644 index 0000000000..f0dd6f4082 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-wraparound-end/expected_result @@ -0,0 +1,9 @@ +1 example.com. IN NSEC 120 ns1.example.com. NS SOA RRSIG NSEC DNSKEY +1 example.com. IN RRSIG 120 NSEC 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN RRSIG 120 SOA 8 2 120 [expiry] [inception] [keytag] example.com. ... +1 example.com. IN SOA 120 ns1.example.com. hostmaster.example.com. 2000010101 28800 7200 1209600 120 +1 www.example.com. IN NSEC 120 example.com. A RRSIG NSEC +1 www.example.com. IN RRSIG 120 NSEC 8 3 120 [expiry] [inception] [keytag] example.com. ... +2 . IN OPT 32768 +Rcode: 3, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='zzz.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-end/expected_result.nsec3 b/modules/remotebackend/regression-tests/nsec-wraparound-end/expected_result.nsec3 new file mode 100644 index 0000000000..a20b5458d2 --- /dev/null +++ b/modules/remotebackend/regression-tests/nsec-wraparound-end/expected_result.nsec3 @@ -0,0 +1,11 @@ +1 9f8hti7cc7oqnqjv84klnp89glqrss3r.example.com. IN NSEC3 86400 1 1 1 abcd 9FDAOFPLLN0FQFU9DP274GOU59QFHSLD A RRSIG +1 9f8hti7cc7oqnqjv84klnp89glqrss3r.example.com. IN RRSIG 86400 NSEC3 8 3 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 gnk5kv3h2h1h8ge405j6093608ukp3i5.example.com. IN NSEC3 86400 1 1 1 abcd GNO4LESKG6U7HKEJ9UL71SF1HD7F1P96 A RRSIG +1 gnk5kv3h2h1h8ge405j6093608ukp3i5.example.com. IN RRSIG 86400 NSEC3 8 3 86400 [expiry] [inception] [keytag] example.com. ... +1 vtnq6ocn2vkuiv3nju14oqtaen2mt5sk.example.com. IN NSEC3 86400 1 1 1 abcd VTP9NUQBEH436S7J0K8TI2A32MMKCUUL NS SOA MX RRSIG DNSKEY NSEC3PARAM +1 vtnq6ocn2vkuiv3nju14oqtaen2mt5sk.example.com. IN RRSIG 86400 NSEC3 8 3 86400 [expiry] [inception] [keytag] example.com. ... +2 . IN OPT 32768 +Rcode: 3, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='zzz.example.com.', qtype=A diff --git a/modules/remotebackend/regression-tests/nsec-wraparound-end/skip.nodnssec b/modules/remotebackend/regression-tests/nsec-wraparound-end/skip.nodnssec new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/remotebackend/regression-tests/pipe-backend.rb b/modules/remotebackend/regression-tests/pipe-backend.rb index 0e4125f87e..a71c519b9e 100755 --- a/modules/remotebackend/regression-tests/pipe-backend.rb +++ b/modules/remotebackend/regression-tests/pipe-backend.rb @@ -5,9 +5,12 @@ require '../modules/remotebackend/regression-tests/backend' h = Handler.new("../modules/remotebackend/regression-tests/remote.sqlite3") +f = File.open "/tmp/tmp.txt","a" + STDOUT.sync = true begin STDIN.each_line do |line| + f.puts line # expect json input = {} line = line.strip @@ -25,8 +28,9 @@ begin res, log = h.send(method) end puts ({:result => res, :log => log}).to_json + f.puts ({:result => res, :log => log}).to_json rescue JSON::ParserError - send_failure "Cannot parse input #{line}" + puts ({:result => false, :log => "Cannot parse input #{line}"}).to_json next end end diff --git a/modules/remotebackend/regression-tests/test-schema.sql b/modules/remotebackend/regression-tests/test-schema.sql index ba64010f90..dbc2e8a5e5 100644 --- a/modules/remotebackend/regression-tests/test-schema.sql +++ b/modules/remotebackend/regression-tests/test-schema.sql @@ -20,12 +20,15 @@ CREATE TABLE records ( content VARCHAR(65535) DEFAULT NULL, ttl INTEGER DEFAULT NULL, prio INTEGER DEFAULT NULL, - change_date INTEGER DEFAULT NULL + change_date INTEGER DEFAULT NULL, + ordername VARCHAR(255) DEFAULT NULL, + auth BOOL DEFAULT 0 ); CREATE INDEX rec_name_index ON records(name); CREATE INDEX nametype_index ON records(name,type); CREATE INDEX domain_id ON records(domain_id); +create index orderindex on records(ordername); create table supermasters ( ip VARCHAR(25) NOT NULL, @@ -33,10 +36,6 @@ create table supermasters ( account VARCHAR(40) DEFAULT NULL ); -alter table records add ordername VARCHAR(255); -alter table records add auth bool; -create index orderindex on records(ordername); - create table domainmetadata ( id INTEGER PRIMARY KEY, domain_id INT NOT NULL, @@ -64,11 +63,27 @@ create table tsigkeys ( ); create unique index namealgoindex on tsigkeys(name, algorithm); -insert into domains (name,type) VALUES('delegated.dnssec-parent.com','NATIVE'); -insert into domains (name,type) VALUES('dnssec-parent.com','NATIVE'); + insert into domains (name,type) VALUES('example.com','NATIVE'); -insert into domains (name,type) VALUES('minimal.com','NATIVE'); -insert into domains (name,type) VALUES('test.com','NATIVE'); -insert into domains (name,type) VALUES('wtest.com','NATIVE'); +insert into domains (name,type) VALUES('up.example.com','NATIVE'); + +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "example.com", "SOA", "120", "ns1.example.com hostmaster.example.com 2000010101 28800 7200 1209600 120", "", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "example.com", "NS", "120", "ns1.example.com", "", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "example.com", "NS", "120", "ns2.example.com", "", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "outpost.example.com", "A", "120", "192.168.2.1", "outpost", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "outpost.example.com", "AAAA", "120", "fe80::1", "outpost", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "www.example.com", "A", "120", "192.168.2.255", "www", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "up.example.com", "NS", "120", "ns1.example.com", "up", 0 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "up.example.com", "NS", "120", "ns2.example.com", "up", 0 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "ns1.example.com", "A", "120", "192.168.2.2", "ns1", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "ns2.example.com", "A", "120", "192.168.2.3", "ns2", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "up.example.com", "DS", "120", "38674 8 1 50ea84825288d03bf9ddda0b0b5f8964c6fbafa8", "up", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "up.example.com", "DS", "120", "38674 8 2 bf31ef7aea46f2adca7a61fbb0629fb5c24116df0f22ec0115dbc7ebdddee04e", "up", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "up.example.com", "DS", "120", "38674 8 3 6ed18dceaba6d2547f2fc82ba3801fdc919db51b0e44baa261b887c824dd9a2d", "up", 1 FROM domains WHERE name = "example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "up.example.com", "SOA", "120", "ns1.example.com hostmaster.example.com 2000010101 28800 7200 1209600 120", "", 1 FROM domains WHERE name = "up.example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "up.example.com", "NS", "120", "ns1.example.com", "", 1 FROM domains WHERE name = "up.example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "up.example.com", "NS", "120", "ns2.example.com", "", 1 FROM domains WHERE name = "up.example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "jump.up.example.com", "A", "120", "192.168.3.1", "jump", 1 FROM domains WHERE name = "up.example.com"; +insert into records (domain_id, name, type, ttl, content, ordername, auth) select id as domain_id, "jump.up.example.com", "TXT", "120", "a very very long indeed text string that should pass out clean and proper thru the entire chain of powerdns processing", "jump", 1 FROM domains WHERE name = "up.example.com"; commit; diff --git a/modules/remotebackend/regression-tests/up.example.com.ksk b/modules/remotebackend/regression-tests/up.example.com.ksk new file mode 100644 index 0000000000..919861771a --- /dev/null +++ b/modules/remotebackend/regression-tests/up.example.com.ksk @@ -0,0 +1,11 @@ +Private-key-format: v1.2 +Algorithm: 8 (RSASHA256) +Modulus: uJPhQJzTPtwYCo/e9p+bIVB+JqSm79/3dcAdbrl5hMC4GFpdsqNbrhgzxrnic5Te0Kgt5ewWm9uXirq9eYFHmOmdwYKvbEjeEpBo2/HhDCRtRpuTHYsfqsJqbNAR5j0cMmjYq9UicZmrBR0rg8nqfZIMuTSAhAyTKd96ntA4Q1MS/XKd6tzeaeRjBAm263toW22C+c7A233NH3Q+DQIBul0vO9gKMRcdDGTmrjJleHzYRWGETZx9/OJwhroV4XH3z3gs0pBIEbGM4vKzrN3ER9lfQ/hn9ZSo6ksjawOY4NleVO4PofM8PlF0Hjg4Qzjqow2IgyL0Y3kVbSWpx7caNw== +PublicExponent: AQAB +PrivateExponent: COSdg1ULAiOG+2gX857La3BK/UzZlJ0gRlaA4VQJlgSjDULtWMbXvl+ai9MEJVJHs5rAYcX3B0z61DHphyOPcfKiwy9EvHbjHD0Q9rS36+alZs2AHRN8hxtIfWc/aLrXbPMlEI8uuNwQ8I7wCP1/Hf9RCNHBKQH7sfzIFhBgmMqG63bVhaFI3Dae3R8mbRPurNCQqqpQRnY6QCo+MT4oCcPtUhknNdrMfiXk1OIlKXQy5fcF1CcKM9SseL2OQ6BSR5zmzvuPtr214F0Nsx3jl9zw9Dq29fDEQRuxmITJNeXeBkTc0S87CVIc9wX4Xke9S4t0cYEcIFaFLAf5nDk5gQ== +Prime1: 4Ff95nOa40oewS0KgKvbPTd9ZT7bqXBqvUNYV4t+oAtsA01qikrg13FlEDOgGn65LpWPia3WAOj3x+RNKqSs2lDn1DcRiY5QIVUtvGYicJfoNW9XAZC8qb6shhzxdQto8s0g8Q2M+i6vFNG+buAY/1h0FopNRIvMSC+rpFDl06c= +Prime2: 0p9pWeanOBmnB00B6GYXNJ04xK0FysGnRdLLSJ1wd++9SxggVy7i3fLBVMtW6RIKho1alu/vnPNRkOk3ns1TliNfgVk2E+BF/9lJoXQaD7PKT62tRSH+7dSluW/MmakFNrlQeAylFsFSFepdbXYODWaOzyl7qNmZziLKksbRlvE= +Exponent1: Uo9POt3UZEzEoKaotM2J8y9WkEnfoK1kOp5sBlupj9BkQZrd2GLR97cdUCcPhnCYSZJ0rmAw30jc1s0nsMfFbNpVVn2lkI+04W9tU2XqyrC8nd2JkWPoajdnWjuQiFhYmPHwa4VnGjLP78N4Z2lFCcNNhXYEFXO1C+OvMNssmQU= +Exponent2: YG+69f3E/MvKDW61++maoG2IS40JRN/MLg0pJLNphpDPdC20yRZfq831tVRxE8A974OTQd7UMGG8LASMgfpzViAWH4xwVUNv6YhczT7ym9PvQvI7jpbVOaIOy0wkOwsHpxnMfVsUz8luQziO1IqkPoCBzNqqkxIm+Ro29GNyHZE= +Coefficient: CEAJV5fxzzRBxE5Sjwk1cCycIRc4knBywzI0+SKiwGjnieCuJY3VDU0c9kkXfJPL6CydhQg7w4d/uOzKv4UY74Pt3a7JgfhSmRpl9pEGS3vytcc5rRl/VYN9a+S6iUU2YbpWziQZt6tujA+WuvXmr5RsgvqnFYAwYYGav1cogMc= + diff --git a/modules/remotebackend/regression-tests/up.example.com.zsk.1 b/modules/remotebackend/regression-tests/up.example.com.zsk.1 new file mode 100644 index 0000000000..bb32fb5038 --- /dev/null +++ b/modules/remotebackend/regression-tests/up.example.com.zsk.1 @@ -0,0 +1,11 @@ +Private-key-format: v1.2 +Algorithm: 8 (RSASHA256) +Modulus: 5rFrlB6aOKdmqATnpW42XOwbvmRFD2Bj7hprkZ5sx1UX9ZqRsml0ZUuPvzpXZlxDdOYbrJVR7OJXy/KTGSEaKtdBIE1sGqTqSmGuAjf1eKCDY3AQoLau/kVo+3f2TWhnKalm7PKWaHxJFgw6/fpMHipQPlEvpiqEnk0z1ioWKhk= +PublicExponent: AQAB +PrivateExponent: Agt7ZDgjjqeAi9zj7xiLlPtxy9hTMA2fF86g+qI1yCGLYWhcl2vYYIfQ2crVrf5Y3w8lb9GbWjcaZ0rP6NEyjGovtM+RjykBeSxlu4zaH2vuW+6MH8Ed6kpLMXAqewFf7mxodsom3RllXAA2ZLspZYdvO7QDageN7e6NWy1+FUE= +Prime1: 57E4mG4RAqoyetlXPZaKhb9X/GASccIXv0zfH7I/KUpaySSUfzcxojIOkoAFb2Ur8YDemE3f6coXraVx+qXbYQ== +Prime2: /uVcsoQDurkOJ0kH/4vLvooU98J9ozGKg0CyBMrUQBhhSkr/o4W8obNoLHlMGeJYWeSAs5QonMamlLS9V+dBuQ== +Exponent1: G4TJHBG2o4JjjIPUANSoj0oywR8IEcrj1yziM3mQVu8l6U4W9SUxF/qqEGx0OM7jcUPFLIHTXolKVq2X5BVfAQ== +Exponent2: m9uRX9KbGSyYe+sLCfXoAj0abxisjAH56SHA+G8xc3O04aGUSN+4pMM3uqH8p4MgdO7kx2mbn6lUKG+Pq1VLeQ== +Coefficient: S1bcDTTRVPoGEv9Zun57TL654I+XO9HHCneacZYAyJC5jI1GDbbVQmfXknuuvoh9Z4YsFRoh0zANy9cHjusk2Q== + diff --git a/modules/remotebackend/regression-tests/up.example.com.zsk.2 b/modules/remotebackend/regression-tests/up.example.com.zsk.2 new file mode 100644 index 0000000000..e3eca70203 --- /dev/null +++ b/modules/remotebackend/regression-tests/up.example.com.zsk.2 @@ -0,0 +1,11 @@ +Private-key-format: v1.2 +Algorithm: 8 (RSASHA256) +Modulus: wJQvmbajlCnSj5XsqgxC7kWpslPSMFjkt1Rn2zuriyup/WeQAGxcPwCVVCq0pGrEqAP0hRnxpe8hhWLVJSpRiaaSqISBbZ+ebCqcTXo7C3d10XyKxBE5qxBePjJz3CvK0ellmbocC+QkeZSxBSRXjMAlFwsTroanoFhOtvjizS0= +PublicExponent: AQAB +PrivateExponent: JIGS2nFAZhxdgYGauQuU/oUvK5JvNGINjWFPRMR1eu7ejR5+Mk5YWEscg7WKw+ZHfFAvoLGv2NRRhu8a165DgV8fd5m38P20PpxqqzP2z8K6YANv2CkxsvvIBSwOUmkB/HqL6/Nhy4xTlKCcQxpm1gq5+XM1hXFmrEtzLgMqBVE= +Prime1: /mXttF4hg/BDGHqaAAaZ5J8EFvoPRZIpFz6UU/5v8Kxx2se/FH6GCyEEdIebaNvB0gyZsC7lf4yIOCx9jx2EVQ== +Prime2: wcqb8PZpsgxtSLYifXM0iZgs5k4LH8AwrrRjnGKkGPycxbbZb2qLddqwdP01YRCxkAnq4g9f/V33ozBm7Ms9eQ== +Exponent1: zm1xPAmh0ojUOPnLGrhAigYKcIaKe96FH0p1W867kKStYmTxBTVBmag6EEC1d5nSpZn537++FAi5xDM90zKVXQ== +Exponent2: XbEcJaqsvTU+3MmZ8TbyrpdRFeOjgy1DHCQAiMoz9hSjov9dLn2/gTJC37zPwub0QeRZmAPA79kvcclj6ZX1WQ== +Coefficient: Z19qS5JSev5auSgG4UdNqqd4t5MlxdRaiigOPOzkipYxFCJGmscgU6aZ6OsjjpTCOaqd9voEgEVIW5CKHAtBUQ== + diff --git a/modules/remotebackend/remotebackend.cc b/modules/remotebackend/remotebackend.cc index 29d7a50b67..0cb9c28b61 100644 --- a/modules/remotebackend/remotebackend.cc +++ b/modules/remotebackend/remotebackend.cc @@ -352,6 +352,10 @@ bool RemoteBackend::deactivateDomainKey(const string& name, unsigned int id) { return answer.asBool(); } +bool RemoteBackend::doesDNSSEC() { + return d_dnssec; +} + bool RemoteBackend::getTSIGKey(const std::string& name, std::string* algorithm, std::string* content) { Json::Value query,answer; query["method"] = "getTSIGKey"; @@ -369,6 +373,45 @@ bool RemoteBackend::getTSIGKey(const std::string& name, std::string* algorithm, return true; } +bool RemoteBackend::getDomainInfo(const string &domain, DomainInfo &di) { + Json::Value query,answer; + std::string kind; + query["method"] = "getDomainInfo"; + query["parameters"] = Json::Value(); + query["parameters"]["name"] = domain; + + if (connector->send(query) == false || connector->recv(answer) == false) + return false; + + // make sure we got zone & kind + if (!answer.isMember("zone")) { + L< options; + int fd; + std::string path; + bool connected; }; class HTTPConnector: public Connector { @@ -88,6 +96,8 @@ class RemoteBackend : public DNSBackend virtual int addDomainKey(const string& name, const KeyData& key); virtual bool activateDomainKey(const string& name, unsigned int id); virtual bool deactivateDomainKey(const string& name, unsigned int id); + virtual bool getDomainInfo(const string&, DomainInfo&); + virtual bool doesDNSSEC(); static DNSBackend *maker(); diff --git a/modules/remotebackend/test_backend.rb b/modules/remotebackend/test_backend.rb deleted file mode 100755 index 424c765ae4..0000000000 --- a/modules/remotebackend/test_backend.rb +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/ruby - -require 'json' - -prefix = "2001:06e8:0500:0000" - -# domain keys - -$domain_keys = [ - { - :id => 8, - :flags => 257, - :active => true, - :content => "Private-key-format: v1.2 -Algorithm: 8 (RSASHA256) -Modulus: nFfl3jgFE+KET9PFPVmRCVmGZ+o+Stnqq7AZPAmhSYf96BPqK3t22vKHJhmVla+td94if2XUSggRUDz8YSeIybVNDTCmhF4xNyhAYAeh+HxJQU7CL8jQLs0b86Hd/Ua/s2pmSFSX4vzoAg+1lucLT3AiGYWjrvciFFpWnMyYftqcfTy3Vu/TMA9Kr7tr75CsJ2mzu1rywHsvOErCY8xH6dGd2LCY9ozuOwsgAlou+rOF5W71UPIuomM9QcIdVD2nq8+aHSsKeWk8gabLEsKU0SFFutO/R41lYXiUaFv+zY7r7NmP+d0Wmr0rgnzq2vlV0USQhlDPAsPSVstAuMrjgw== -PublicExponent: AQAB -PrivateExponent: kSdnrMbKe7dqfcpDG9WMgYp6BS88A5/a2F2ysv+Ds+Q9cAENXTpPn2yNDd4+sd3pgcmYsjsS6deTr9/YFRXw9bKBKLI80JFdZhKng5hMvYqnBGQmt/Dz4/RE87PVLNIC4/mrFE4Bn2vStnRTu3WY/wURXf3YkgI+IdXsfQTsBNloLiRoVV1QmB4kkHtRXsr02dg4kMhaXA13kT7lsrquCvGoxP++keVJ88AaQA8si30/E+CSgrbCHThUXeL6ErYz6myI5O2RJqodlcEQeXYi2cNkzQJnO3yjXcaSJy2u3tVNE2wXCXf1pwHXyTA4YT1qMbMIABq9TiVW8Q2Kg4sN -Prime1: wrNo1cyyL/LpO+Das2EQzMbX0ctdy0OPvg3kWZqt2ZEwJjcVe1Vav5ZzSWKQWuT0IytUst7qdTE7lKpWWKDAbxJ4IMcMiMN2iQqE9V/dhIJluIrshupQzdhnXR46MfbazkDuvMTM1Fk4ZOgm3lrJoRvl6EOxl7e9veTwCjKqrA8= -Prime2: zZDvTPq/Ea7aKa+CNmP7oOYxpvE1fpPV8MRjQ+IMi8VIDHpE72NoSSVoVuSL7fgl7qAFlbJMEtQGIlqUFQkC0sbI6ddb1/Ane+xhH4aPaljtIJQs0GlM/ECz30qZCreyHqaVzXlk9ZrN7HlnIOQ//DV3lCsS8EE1djeQxFThrU0= -Exponent1: S9uW1uX/7sqXsKq0yvrgjshSQf0YOB/Em2nSNE8duQzmU51Wk0z4JHk7xbXPRHq73A//2gkcFDjwW8XaCoHnN99cSnkDGy38uvwMPYXySrR7aWFHMnGMtgbAjvk990WUjpOh8I5Et99jJ32D11JMCKdT9iCZyuDd3mSaWX7QHGU= -Exponent2: hiaslG8a3B5gz01zS62KHCG9i3XkdDtkJeDz6uwNRfW0JDhy3krgVsPryLETxHPpxUV2/49A6BSoACledC/SQN1rZnedv1lBWzUS2PEGjN+FuHoamNPvYruS5wiWwZDJ1AjgwBwVz9Z7xnQf4i4yt5Po+q/1hwb3LbPrbMT8Fg0= -Coefficient: zZDvTPq/Ea7aKa+CNmP7oOYxpvE1fpPV8MRjQ+IMi8VIDHpE72NoSSVoVuSL7fgl7qAFlbJMEtQGIlqUFQkC0sbI6ddb1/Ane+xhH4aPaljtIJQs0GlM/ECz30qZCreyHqaVzXlk9ZrN7HlnIOQ//DV3lCsS8EE1djeQxFThrU0=" - }, - { - :id => 9, - :flags => 256, - :active => true, - :content => "Private-key-format: v1.2 -Algorithm: 8 (RSASHA256) -Modulus: 0fcOKzIHcE5K3B3zwu0iAm4Z/cRBH9JX0mMhl9h58i0C8QEK3fK+425MEI/q4P7qGkwB9hJ9TefC5ny3b+F2iSIDTqcrMoRr6/lJO2YH7MyeuAv1T5HMsC7DoCkdaq0xuoOkOtKaVz5/FwSFmCIlCNeboFX3Fq4kCoWsa1m63AE= -PublicExponent: AQAB -PrivateExponent: BWc0q6LlcxvorEJvD/CXQ/W+YHvo6x84GFdpuWUeOj+zSC1tMKn7BJJFjdWOR0z4DEYxdLokFFmm99R0ygHE0ZWh7WS1OX5AzqoFczeC0BDLvoAYu6XMvwlYp78ffqlI2qv4ohfew5TYzWCugxIufFsC55i2FoworGBLSFUloaM= -Prime1: +aIMyvDUAzL/JZDHsPLnawLhy7sfZB4BbtARAYxZ6HSE9MAnFKbQhXQ9yRdGLSZEhe8g5b9tXBvxT8TPIGhwcw== -Prime2: 11H/gYNtYkloQuRcL2xd3ElxosgncgFvXKY0y4sGyJuEhHJfttaxXCmNfVN9fg5lX18kfxCv4s8rqI+M+rZouw== -Exponent1: SmrNp34NpfqA52D2tsBizproVwSsgfsT8EXkm/KMJuj9bb0OqXBlPzN868Kdb/41dTvpMbRUVJ4b3OzN1lpsEw== -Exponent2: zPRiTzd48SuKsNGJ5iIynbLTFe2LjntLM1eJvY2SYXWXCDOOZA2sOVvcMEU+mLS/Ta7UoJaTtUMZ/ZLW0Pa8bQ== -Coefficient: 11H/gYNtYkloQuRcL2xd3ElxosgncgFvXKY0y4sGyJuEhHJfttaxXCmNfVN9fg5lX18kfxCv4s8rqI+M+rZouw==" - }, - { - :id => 10, - :flags => 256, - :active => false, - :content => "Private-key-format: v1.2 -Algorithm: 8 (RSASHA256) -Modulus: rzJLZNmV+xQLkYWT3PytSYDeE8SovXi9+WCp9MVkWcSj1BgrBbugregqsSQLvz+rGsgc2nK3kqygDhypRMExmd2TRHeIrtcLHZ3nq+mmL/GfE0K6KWS2FJx06ol7v9xG8esLe+TUSAENo2xFR0BFmkiJN+R5hq06Rb0Y7OMSBs8= -PublicExponent: AQAB -PrivateExponent: FwH6jMABG6bCQ4DQrlDbS6/felEf/TdXcOHqRU7houMEG4fLqUZpZO1Rzfmh4U0x4fktxjJn5pyXrcLDKAMHHv+DjtPSC4B+49HFOZEHl/522VYw6NyJ+Firk41hbFxIStSFYh47qxKyAwbI/LuyTJE0Au8D+4dl8oFwfh0x+aE= -Prime1: 0sDZukxVtL4zI9JPvEdBUAXLu4I98GS7xhxiLNeb+iF2+Vvw06igV7+CccMldz/r3gqr9y+NdAloErFvkieLRQ== -Prime2: 1M822AT25uYwdKiiYuBPQlUIKVuP1paa8y4rh+uDuoHpm9E29hwHr2uLXESOO5YxB0oc8yauNOdH+HGTg8GhAw== -Exponent1: IOq2Fv7tM/mxCxtCEOogLVt6YqMJAY76NQsh2lciqYKojnHpv2VLBemHejU8mM+HC3snOMhYk5MUijbkcjNy8Q== -Exponent2: V0LUkUWP3GQ9MEjJtVOXDHMDkrnZxDsjNF4VOXmoHT0SBnOGXupleFfX4DC4RdSzK/MG5elRe53ulAA2Zctq8w== -Coefficient: 1M822AT25uYwdKiiYuBPQlUIKVuP1paa8y4rh+uDuoHpm9E29hwHr2uLXESOO5YxB0oc8yauNOdH+HGTg8GhAw==" - } -] - -def to32(number) - number.to_s(32).tr "0123456789abcdefghijklmnopqrstuv", "ybndrfg8ejkmcpqxot1uwisza345h769" -end - -def from32(str) - str.tr("0123456789abcdefghijklmnopqrstuv", "ybndrfg8ejkmcpqxot1uwisza345h769").to_i(32) -end - -def rr(qname, qtype, content, ttl, priority = 0, auth = 1) - {:qname => qname, :qtype => qtype, :content => content, :ttl => ttl, :priority => priority, :auth => auth} -end - -def send_result(result, log = nil) - out = {:result => result} - if log.class != Array - log = [log] - end - out[:log] = log unless log.nil? - print out.to_json - print "\n" -end - -def send_failure(msg) - send_result false, [msg] -end - -class Handler - attr :prefix, :plen, :suffix, :domain - - def initialize(prefix) - @prefix = prefix - end - - def do_initialize(*args) - # precalculate some things - tmp = self.prefix.gsub(/[^0-9a-f]/,'') - @plen = tmp.size - @suffix = tmp.split(//).reverse.join('.')+".ip6.arpa" - @domain = "dyn.example.com" - send_result true, "Autorev v6 backend initialized" - end - - def do_getbeforeandafternamesabsolute(args) - qname = args["qname"] - # assume prefix - name = qname.gsub(/ /,'') - nlen = 32-self.plen - - name_a = nil - name_b = nil - unhashed = nil - - if name == '' - name_a = sprintf("%0#{nlen}x",0).split(//).join(' ') - elsif name.size < nlen - name_a = sprintf("%0#{nlen}x",0).split(//).join(' ') - else - unhashed = sprintf("%0#{nlen}x",name.to_i(16)).split(//).join(' ') - if (name.to_i(16) > 0) - name_b = sprintf("%0#{nlen}x",(name.to_i(16)-1)).split(//).join ' ' - end - unless (name[/[^f]/].nil?) - name_a = sprintf("%0#{nlen}x",(name.to_i(16)+1)).split(//).join ' ' - end - end - send_result ({:before => name_b, :after => name_a, :unhashed => unhashed}) - end - - def do_getbeforeandafternames(args) - self.do_getbeforeandafternamesabsolute(args) - end - - def do_getdomainkeys(args) - if args["name"] == self.suffix - send_result $domain_keys - else - send_result false - end - end - - def do_lookup(args) - qtype = args["qtype"] - qname = args["qname"] - - if qname[/.ip6.arpa$/] - if qname == self.suffix - ret = [] - if (qtype != "SOA") - ret << rr(qname, "NS", "ns1.example.com",300) - ret << rr(qname, "NS", "ns2.example.com",300) - ret << rr(qname, "NS", "ns3.example.com",300) - end - ret << rr(qname,"SOA","ns1.example.com hostmaster.example.com #{Time.now.strftime("%Y%m%d%H")} 28800 7200 1209600 300",300) - return send_result ret - elsif qtype == "ANY" or qtype == "PTR" - # assume suffix - name = qname.gsub(self.suffix,"").split(".").reverse.join("") - if name.empty? or name.size != 32-plen - return send_result false - end - name = to32(name.to_i(16)) - return send_result [rr(qname, "PTR", "node-#{name}.#{self.domain}", 300)] - end - end - send_result false - end - - def do_getdomainmetadata(args) - name = args["name"] - kind = args["kind"] - send_result false - end -end - -h = Handler.new(prefix) - -STDOUT.sync = true -begin - STDIN.each_line do |line| - # expect json - input = {} - line = line.strip - next if line.empty? - begin - input = JSON.parse(line) - method = "do_#{input["method"].downcase}" - args = input["parameters"] - - if h.respond_to?(method.to_sym) == false - res = false - send_result res, nil - elsif args.size > 0 - h.send(method,args) - else - h.send(method) - end - rescue JSON::ParserError - send_failure "Cannot parse input #{line}" - next - end - end -rescue SystemExit, Interrupt -end diff --git a/modules/remotebackend/unixconnector.cc b/modules/remotebackend/unixconnector.cc index a1216e0aeb..8f7d14d2c4 100644 --- a/modules/remotebackend/unixconnector.cc +++ b/modules/remotebackend/unixconnector.cc @@ -9,133 +9,21 @@ #define UNIX_PATH_MAX 108 #endif - -// Singleton class to maintain client connection -// via single unix socket connection -static int n_unix_socket_connection; -static pthread_mutex_t unix_build_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t unix_mutex = PTHREAD_MUTEX_INITIALIZER; -class UnixsocketConnection { - public: - UnixsocketConnection(const std::string &path) - { - this->path = path; - connected = false; - }; - - ~UnixsocketConnection() { - L<fd, buf, sizeof buf); - // just try again later... - if (nread==-1 && errno == EAGAIN) return 0; - - if (nread==-1) { - connected = false; - close(fd); - return -1; - } - - data.append(buf, nread); - return nread; - }; - - ssize_t write(const std::string &data) { - ssize_t nwrite, nbuf; - char buf[1500]; - Lock scoped_lock(&unix_mutex); - - reconnect(); - if (!connected) return -1; - nbuf = data.copy(buf, sizeof buf); // copy data and write - nwrite = ::write(fd, buf, nbuf); - if (nwrite == -1) { - connected = false; - close(fd); - return -1; - } - return nwrite; - }; - - private: - int fd; - bool connected; - std::string path; - - void reconnect() { - struct sockaddr_un sock; - struct timeval tv; - fd_set rd; - - if (connected) return; // no point reconnecting if connected... - connected = true; - - L<(&sock), sizeof sock)==-1 && (errno == EINPROGRESS)) { - tv.tv_sec = 0; - tv.tv_usec = 500; - FD_ZERO(&rd); - FD_SET(fd, &rd); - select(fd+1,&rd,NULL,NULL,&tv); // wait a moment - }; - if (errno != EISCONN && errno != 0) { - L< options) { - Lock scoped_lock(&unix_build_mutex); - - if (unix_socket_connection == NULL) { - Json::Value init,res; - unix_socket_connection = new UnixsocketConnection(options.find("path")->second); - n_unix_socket_connection = 1; - init["method"] = "initialize"; - init["parameters"] = Json::Value(); - for(std::map::iterator i = options.begin(); i != options.end(); i++) - init["parameters"][i->first] = i->second; - this->send(init); - if (this->recv(res) == false) - L<path = options.find("path")->second; + this->options = options; + this->connected = false; } UnixsocketConnector::~UnixsocketConnector() { - Lock scoped_lock(&unix_build_mutex); - - n_unix_socket_connection--; - if (n_unix_socket_connection == 0) { - delete unix_socket_connection; - unix_socket_connection = NULL; - } + if (this->connected) { + L<read(temp)>0) { temp = ""; } - rv = unix_socket_connection->write(data); + rv = this->write(data); if (rv == -1) - throw AhuException("Failed to write to socket"); + return -1; return rv; } @@ -164,9 +49,11 @@ int UnixsocketConnector::recv_message(Json::Value &output) { while(time(NULL) - t0 < 2) { // 2 second timeout std::string temp; - rv = unix_socket_connection->read(temp); + temp.clear(); + + rv = this->read(temp); if (rv == -1) - throw AhuException("Failed to read from socket"); + return -1; if (rv>0) { nread += rv; @@ -179,3 +66,97 @@ int UnixsocketConnector::recv_message(Json::Value &output) { return -1; } + +ssize_t UnixsocketConnector::read(std::string &data) { + ssize_t nread; + char buf[1500] = {0}; + + reconnect(); + if (!connected) return -1; + nread = ::read(this->fd, buf, sizeof buf); + + // just try again later... + if (nread==-1 && errno == EAGAIN) return 0; + + if (nread==-1) { + connected = false; + close(fd); + return -1; + } + + data.append(buf, nread); + return nread; +} + +ssize_t UnixsocketConnector::write(const std::string &data) { + ssize_t nwrite, nbuf; + size_t pos; + char buf[1500]; + + reconnect(); + if (!connected) return -1; + pos = 0; + nwrite = 0; + while(pos < data.size()) { + nbuf = data.copy(buf, sizeof buf, pos); // copy data and write + nwrite = ::write(fd, buf, nbuf); + pos = pos + sizeof(buf); + if (nwrite == -1) { + connected = false; + close(fd); + return -1; + } + } + return nwrite; +} + +void UnixsocketConnector::reconnect() { + struct sockaddr_un sock; + struct timeval tv; + fd_set rd; + Json::Value init,res; + + if (connected) return; // no point reconnecting if connected... + connected = true; + + L<(&sock), sizeof sock)==-1 && (errno == EINPROGRESS)) { + tv.tv_sec = 0; + tv.tv_usec = 500; + FD_ZERO(&rd); + FD_SET(fd, &rd); + select(fd+1,&rd,NULL,NULL,&tv); // wait a moment + } + + if (errno != EISCONN && errno != 0) { + L<::iterator i = options.begin(); i != options.end(); i++) + init["parameters"][i->first] = i->second; + + this->send_message(init); + if (this->recv_message(res) == false) { + L<connected = false; + } +} + diff --git a/regression-tests/start-test-stop b/regression-tests/start-test-stop index 8aa880d792..59048527ec 100755 --- a/regression-tests/start-test-stop +++ b/regression-tests/start-test-stop @@ -32,7 +32,7 @@ testsdir=. if [ "$port" = help ] || [ "$context" = help ] then set +x - cat << '__EOF__' + grep -v '^#' << '__EOF__' Usage: ./start-test-stop [] [wait] @@ -45,6 +45,8 @@ opendbx-sqlite3 tinydns remotebackend-pipe remotebackend-unix remotebackend-http remotebackend-pipe-dnssec remotebackend-unix-dnssec remotebackend-http-dnssec +#remotebackend-pipe-nsec3 remotebackend-unix-nsec3 remotebackend-http-nsec3 +#remotebackend-pipe-nsec3-narrow remotebackend-unix-nsec3-narrow remotebackend-http-nsec3-narrow add -presigned to any gmysql test (except narrow) to test presigned operation @@ -355,20 +357,26 @@ __EOF__ remotebackend-*) remotetype=$(echo $context | cut -d- -f 2) remotesec=$(echo $context | cut -d- -f 3) + narrow=$(echo $context | cut -d- -f 4) + testsdir=../modules/remotebackend/regression-tests/ case $remotetype in http) connstr="http:url=http://localhost:62434/dns" - ../modules/remotebackend/regression-tests/http-backend.rb & + rm -f remotebackend-server.log + rm -f remotebackend-access.log + $testsdir/http-backend.rb & echo $! > pdns-remotebackend.pid + # make sure it runs before continuing + sleep 2 ;; unix) connstr="unix:path=/tmp/remote.socket" - socat unix-listen:/tmp/remote.socket exec:../modules/remotebackend/regression-tests/pipe-backend.rb & + socat unix-listen:/tmp/remote.socket,fork exec:$testsdir/unix-backend.rb & echo $! > pdns-remotebackend.pid ;; pipe) - connstr="pipe:command=../modules/remotebackend/regression-tests/pipe-backend.rb" + connstr="pipe:command=$testsdir/pipe-backend.rb" ;; *) echo "Invalid usage" @@ -376,24 +384,66 @@ __EOF__ ;; esac - if [ "$remotesec" = "dnssec" ]; then - remote_add_param="--remote-dnssec=yes" + skipreasons="nodnssec" + + if [ "$remotesec" = "nsec3" ]; then + remotedosec="yes" + if [ "$narrow" = "narrow" ]; then + extracontexts="dnssec nsec3 narrow" + skipreasons="narrow nsec3" + else + extracontexts="dnssec nsec3" + skipreasons="nsec3" + fi + remote_add_param="--remote-dnssec=yes" + else + if [ "$remotesec" = "dnssec" ]; then + remotedosec="yes" + remote_add_param="--remote-dnssec=yes" + extracontexts="dnssec" + skipreasons="nonsec3 nonarrow" + fi fi + # generate pdns.conf for pdnssec + cat > pdns-remote.conf <> pdns-remote.conf + ../pdns/pdnssec --config-dir=. --config-name=remote import-zone-key example.com $testsdir/example.com.ksk ksk + ../pdns/pdnssec --config-dir=. --config-name=remote import-zone-key example.com $testsdir/example.com.zsk.1 zsk + ../pdns/pdnssec --config-dir=. --config-name=remote import-zone-key example.com $testsdir/example.com.zsk.2 zsk + ../pdns/pdnssec --config-dir=. --config-name=remote activate-zone-key example.com 1 + ../pdns/pdnssec --config-dir=. --config-name=remote activate-zone-key example.com 2 + ../pdns/pdnssec --config-dir=. --config-name=remote deactivate-zone-key example.com 3 + + ../pdns/pdnssec --config-dir=. --config-name=remote import-zone-key up.example.com $testsdir/up.example.com.ksk ksk + ../pdns/pdnssec --config-dir=. --config-name=remote import-zone-key up.example.com $testsdir/up.example.com.zsk.1 zsk + ../pdns/pdnssec --config-dir=. --config-name=remote import-zone-key up.example.com $testsdir/up.example.com.zsk.2 zsk + ../pdns/pdnssec --config-dir=. --config-name=remote activate-zone-key example.com 4 + ../pdns/pdnssec --config-dir=. --config-name=remote activate-zone-key example.com 5 + ../pdns/pdnssec --config-dir=. --config-name=remote deactivate-zone-key example.com 6 + + if [ "$remotesec" = "nsec3" ]; then + ../pdns/pdnssec --config-dir=. --config-name=remote set-nsec3 example.com + ../pdns/pdnssec --config-dir=. --config-name=remote set-nsec3 up.example.com + fi - testsdir=../modules/remotebackend/regression-tests/ + fi ;; *)