]> granicus.if.org Git - pdns/commitdiff
JSON-API: Send 401 on bad API-Key
authorPieter Lexis <pieter@plexis.eu>
Tue, 10 Feb 2015 18:09:51 +0000 (19:09 +0100)
committerPieter Lexis <pieter@plexis.eu>
Mon, 16 Feb 2015 16:34:26 +0000 (17:34 +0100)
  * Closes #2179
  * We send an HTTP 401 (Unauthorized) when:
    * The API Key is wrong
    * The API Key is empty or missing
  * Authentication failures are logged as Error (was Debug)
  * Fix the API regression test to accept this 401 as valid

pdns/webserver.cc
pdns/webserver.hh
regression-tests.api/test_Basics.py

index 506c06af9750e177cbd1034757d58249bd355224..308da1394d6e5087c0d412dced181a00f05b594e 100644 (file)
@@ -118,14 +118,14 @@ static void apiWrapper(WebServer::HandlerFunction handler, HttpRequest* req, Htt
   resp->headers["access-control-allow-origin"] = "*";
 
   if (api_key.empty()) {
-    L<<Logger::Debug<<"HTTP API Request \"" << req->url.path << "\": Authentication failed, API Key missing in config" << endl;
-    throw HttpUnauthorizedException();
+    L<<Logger::Error<<"HTTP API Request \"" << req->url.path << "\": Authentication failed, API Key missing in config" << endl;
+    throw HttpUnauthorizedException("X-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 HttpBadRequestException();
+    L<<Logger::Error<<"HTTP Request \"" << req->url.path << "\": Authentication by API Key failed" << endl;
+    throw HttpUnauthorizedException("X-API-Key");
   }
 
   resp->headers["Content-Type"] = "application/json";
@@ -174,7 +174,7 @@ static void webWrapper(WebServer::HandlerFunction handler, HttpRequest* req, Htt
     bool auth_ok = req->compareAuthorization(web_password);
     if (!auth_ok) {
       L<<Logger::Debug<<"HTTP Request \"" << req->url.path << "\": Web Authentication failed" << endl;
-      throw HttpUnauthorizedException();
+      throw HttpUnauthorizedException("Basic");
     }
   }
 
index cbfdc1f8a14cc671a4dc309872041864a824c666..7eee5e2663f80ae9176a61d693bfee0532646122 100644 (file)
@@ -81,12 +81,17 @@ public:
 
 class HttpUnauthorizedException : public HttpException {
 public:
-  HttpUnauthorizedException() : HttpException(401)
+  HttpUnauthorizedException(string const &scheme) : HttpException(401)
   {
-    d_response.headers["WWW-Authenticate"] = "Basic realm=\"PowerDNS\"";
+    d_response.headers["WWW-Authenticate"] = scheme + " realm=\"PowerDNS\"";
   }
 };
 
+class HttpForbiddenException : public HttpException {
+public:
+  HttpForbiddenException() : HttpException(403) { };
+};
+
 class HttpNotFoundException : public HttpException {
 public:
   HttpNotFoundException() : HttpException(404) { };
index c275018e5efe4a1dfce63378972e199bfd6e23ed..79c3d9ecfdd975d998ec22f464c13c0436846121 100644 (file)
@@ -8,7 +8,7 @@ class TestBasics(ApiTestCase):
 
     def test_unauth(self):
         r = requests.get(self.url("/servers/localhost"))
-        self.assertEquals(r.status_code, requests.codes.bad_request)
+        self.assertEquals(r.status_code, requests.codes.unauthorized)
 
     def test_split_request(self):
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)