From: bert hubert Date: Fri, 9 Jan 2015 14:31:36 +0000 (+0100) Subject: make the webserver available via explicit API-key, add query-ring-querying for https... X-Git-Tag: rec-3.7.0-rc1~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c89f8cd022c4a9409b95d22ffa3b03e4e98dc400;p=thirdparty%2Fpdns.git make the webserver available via explicit API-key, add query-ring-querying for https://github.com/ahupowerdns/recuweb --- diff --git a/pdns/rec_channel.hh b/pdns/rec_channel.hh index 144e6564c0..f220d292d7 100644 --- a/pdns/rec_channel.hh +++ b/pdns/rec_channel.hh @@ -44,4 +44,5 @@ std::map getAllStatsMap(); extern pthread_mutex_t g_carbon_config_lock; void sortPublicSuffixList(); std::vector >* pleaseGetQueryRing(); +std::vector >* pleaseGetServfailQueryRing(); #endif diff --git a/pdns/webserver.cc b/pdns/webserver.cc index 6b8d51f603..4c012cf013 100644 --- a/pdns/webserver.cc +++ b/pdns/webserver.cc @@ -102,10 +102,11 @@ static void apiWrapper(WebServer::HandlerFunction handler, HttpRequest* req, Htt L<url.path << "\": Authentication failed, API Key missing in config" << endl; throw HttpUnauthorizedException(); } - bool auth_ok = req->compareHeader("x-api-key", api_key); + bool auth_ok = req->compareHeader("x-api-key", api_key) || req->getvars["api-key"]==api_key; + if (!auth_ok) { L<url.path << "\": Authentication by API Key failed" << endl; - throw HttpUnauthorizedException(); + throw HttpBadRequestException(); } resp->headers["Access-Control-Allow-Origin"] = "*"; diff --git a/pdns/ws-api.cc b/pdns/ws-api.cc index 44af01b383..7628fb61b8 100644 --- a/pdns/ws-api.cc +++ b/pdns/ws-api.cc @@ -21,6 +21,7 @@ #include #include #include +#include "version_generated.h" #include "namespaces.hh" #include "ws-api.hh" #include "json.hh" @@ -86,7 +87,7 @@ static void fillServerDetail(Value& out, Value::AllocatorType& allocator) out.AddMember("id", "localhost", allocator); out.AddMember("url", "/servers/localhost", allocator); out.AddMember("daemon_type", jdaemonType, allocator); - out.AddMember("version", VERSION, allocator); + out.AddMember("version", PDNS_VERSION, allocator); out.AddMember("config_url", "/servers/localhost/config{/config_setting}", allocator); out.AddMember("zones_url", "/servers/localhost/zones{/zone}", allocator); } diff --git a/pdns/ws-recursor.cc b/pdns/ws-recursor.cc index c61dd6387a..ff45004dc5 100644 --- a/pdns/ws-recursor.cc +++ b/pdns/ws-recursor.cc @@ -30,6 +30,7 @@ #include "arguments.hh" #include "misc.hh" #include "syncres.hh" +#include "dnsparser.hh" #include "rapidjson/document.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/writer.h" @@ -531,6 +532,50 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) resp->body = returnJsonObject(stats); return; } + else if(command == "get-query-ring") { + typedef pair query_t; + vector queries; + if(req->getvars["name"]=="servfail-queries") + queries=broadcastAccFunction >(pleaseGetServfailQueryRing); + else if(req->getvars["name"]=="queries") + queries=broadcastAccFunction >(pleaseGetQueryRing); + + typedef map counts_t; + counts_t counts; + unsigned int total=0; + BOOST_FOREACH(const query_t& q, queries) { + total++; + counts[make_pair(toLower(q.first), q.second)]++; + } + + typedef std::multimap rcounts_t; + rcounts_t rcounts; + + for(counts_t::const_iterator i=counts.begin(); i != counts.end(); ++i) + rcounts.insert(make_pair(-i->second, i->first)); + + + Document doc; + doc.SetObject(); + Value entries; + entries.SetArray(); + int tot=0; + BOOST_FOREACH(const rcounts_t::value_type& q, rcounts) { + Value arr; + + arr.SetArray(); + arr.PushBack(-q.first, doc.GetAllocator()); + arr.PushBack(q.second.first.c_str(), doc.GetAllocator()); + arr.PushBack(DNSRecordContent::NumberToType(q.second.second).c_str(), doc.GetAllocator()); + entries.PushBack(arr, doc.GetAllocator()); + if(tot++>=100) + break; + } + doc.AddMember("entries", entries, doc.GetAllocator()); + resp->setBody(doc); + return; + } + else if(command == "config") { vector items = ::arg().list(); BOOST_FOREACH(const string& var, items) { @@ -551,7 +596,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) return; } else { resp->status = 404; - resp->body = returnJsonError("Not found"); + resp->body = returnJsonError("Command '"+command+"' not found"); } } @@ -586,7 +631,7 @@ void AsyncWebServer::serveConnection(Socket *client) YaHTTP::AsyncRequestLoader yarl; yarl.initialize(&req); client->setNonBlocking(); - + string data; try { while(!req.complete) {