]> granicus.if.org Git - pdns/commitdiff
make the webserver available via explicit API-key, add query-ring-querying for https...
authorbert hubert <bert.hubert@netherlabs.nl>
Fri, 9 Jan 2015 14:31:36 +0000 (15:31 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Fri, 9 Jan 2015 14:31:36 +0000 (15:31 +0100)
pdns/rec_channel.hh
pdns/webserver.cc
pdns/ws-api.cc
pdns/ws-recursor.cc

index 144e6564c070027aa131f2f3f5eede75f459c7b8..f220d292d70bacc9177800445f8dc798ae5bef37 100644 (file)
@@ -44,4 +44,5 @@ std::map<std::string, std::string> getAllStatsMap();
 extern pthread_mutex_t g_carbon_config_lock;
 void sortPublicSuffixList();
 std::vector<std::pair<std::string, uint16_t> >* pleaseGetQueryRing();
+std::vector<std::pair<std::string, uint16_t> >* pleaseGetServfailQueryRing();
 #endif 
index 6b8d51f603637c9ee3359d1ecff384d5ad285193..4c012cf013037ffd4bbf378584cd063285a42175 100644 (file)
@@ -102,10 +102,11 @@ static void apiWrapper(WebServer::HandlerFunction handler, HttpRequest* req, Htt
     L<<Logger::Debug<<"HTTP API Request \"" << req->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<<Logger::Debug<<"HTTP Request \"" << req->url.path << "\": Authentication by API Key failed" << endl;
-    throw HttpUnauthorizedException();
+    throw HttpBadRequestException();
   }
 
   resp->headers["Access-Control-Allow-Origin"] = "*";
index 44af01b383584b53ddbf2434359d91e5af9b47a3..7628fb61b87015374c89ae6f7ec1f8bf4c35ebd7 100644 (file)
@@ -21,6 +21,7 @@
 #include <boost/foreach.hpp>
 #include <boost/tokenizer.hpp>
 #include <boost/circular_buffer.hpp>
+#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);
 }
index c61dd6387aa8d700b4891fa3a728fb0f316cdc4e..ff45004dc5af05bd19d1fe1614884d197f9fd691 100644 (file)
@@ -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<string,uint16_t> query_t;
+    vector<query_t> queries;
+    if(req->getvars["name"]=="servfail-queries")
+      queries=broadcastAccFunction<vector<query_t> >(pleaseGetServfailQueryRing);
+    else if(req->getvars["name"]=="queries")
+      queries=broadcastAccFunction<vector<query_t> >(pleaseGetQueryRing);
+    
+    typedef map<query_t,unsigned int> 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<int, query_t> 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<string> 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) {