From 3bba454b35c883d20297a772c13f3e82b115ac88 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 30 Jun 2020 15:15:15 +0200 Subject: [PATCH] Backport of acl fix to 4.3.x --- pdns/ws-recursor.cc | 4 ++ pdns/ws-recursor.hh | 5 +- regression-tests.recursor-dnssec/test_API.py | 72 ++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 regression-tests.recursor-dnssec/test_API.py diff --git a/pdns/ws-recursor.cc b/pdns/ws-recursor.cc index 81651ab880..013159dd4f 100644 --- a/pdns/ws-recursor.cc +++ b/pdns/ws-recursor.cc @@ -674,6 +674,10 @@ void AsyncServer::newConnection() // This is an entry point from FDM, so it needs to catch everything. void AsyncWebServer::serveConnection(std::shared_ptr client) const { + if (!client->acl(d_acl)) { + return; + } + const string logprefix = d_logprefix + to_string(getUniqueID()) + " "; HttpRequest req(logprefix); diff --git a/pdns/ws-recursor.hh b/pdns/ws-recursor.hh index ae8e47568a..06821b4777 100644 --- a/pdns/ws-recursor.hh +++ b/pdns/ws-recursor.hh @@ -32,7 +32,10 @@ class HttpResponse; class AsyncServer : public Server { public: - AsyncServer(const string &localaddress, int port) : Server(localaddress, port) { }; + AsyncServer(const string &localaddress, int port) : Server(localaddress, port) + { + d_server_socket.setNonBlocking(); + }; friend void AsyncServerNewConnectionMT(void *p); diff --git a/regression-tests.recursor-dnssec/test_API.py b/regression-tests.recursor-dnssec/test_API.py new file mode 100644 index 0000000000..ec275dd76b --- /dev/null +++ b/regression-tests.recursor-dnssec/test_API.py @@ -0,0 +1,72 @@ +import os +import requests + +from recursortests import RecursorTest + +class APIRecursorTest(RecursorTest): + + @classmethod + def setUpClass(cls): + + # we don't need all the auth stuff + cls.setUpSockets() + cls.startResponders() + + confdir = os.path.join('configs', cls._confdir) + cls.createConfigDir(confdir) + + cls.generateRecursorConfig(confdir) + cls.startRecursor(confdir, cls._recursorPort) + + @classmethod + def tearDownClass(cls): + cls.tearDownRecursor() + +class APIAllowedRecursorTest(APIRecursorTest): + _confdir = 'API' + _wsPort = 8042 + _wsTimeout = 2 + _wsPassword = 'secretpassword' + _apiKey = 'secretapikey' + + _config_template = """ +webserver=yes +webserver-port=%d +webserver-address=127.0.0.1 +webserver-password=%s +webserver-allow-from=127.0.0.1 +api-key=%s +""" % (_wsPort, _wsPassword, _apiKey) + + def testAPI(self): + headers = {'x-api-key': self._apiKey} + url = 'http://127.0.0.1:' + str(self._wsPort) + '/api/v1/servers/localhost/statistics' + r = requests.get(url, headers=headers, timeout=self._wsTimeout) + self.assertTrue(r) + self.assertEquals(r.status_code, 200) + self.assertTrue(r.json()) + +class APIDeniedRecursorTest(APIRecursorTest): + _confdir = 'API' + _wsPort = 8042 + _wsTimeout = 2 + _wsPassword = 'secretpassword' + _apiKey = 'secretapikey' + + _config_template = """ +webserver=yes +webserver-port=%d +webserver-address=127.0.0.1 +webserver-password=%s +webserver-allow-from=192.0.2.1 +api-key=%s +""" % (_wsPort, _wsPassword, _apiKey) + + def testAPI(self): + headers = {'x-api-key': self._apiKey} + url = 'http://127.0.0.1:' + str(self._wsPort) + '/api/v1/servers/localhost/statistics' + try: + r = requests.get(url, headers=headers, timeout=self._wsTimeout) + self.assertTrue(False) + except requests.exceptions.ConnectionError as exp: + pass -- 2.47.2