]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Allow ip ranges as trusted-notification-proxy
authorPieter Lexis <pieter.lexis@powerdns.com>
Thu, 12 Nov 2020 13:32:02 +0000 (14:32 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Thu, 12 Nov 2020 13:33:18 +0000 (14:33 +0100)
This also stops us from doing string comparison for that setting.

Fixes #9711

docs/settings.rst
pdns/Makefile.am
pdns/common_startup.cc
pdns/packethandler.cc
pdns/test-trusted-notification-proxy_cc.cc [new file with mode: 0644]
pdns/trusted-notification-proxy.cc [new file with mode: 0644]
pdns/trusted-notification-proxy.hh [new file with mode: 0644]

index d9fa5f0607a9c0e1b2af696951364b4a87c78aba..314c865a5cd1369238b417ea39ca1d869dd56d6e 100644 (file)
@@ -1723,9 +1723,12 @@ Enable the Linux-only traceback handler.
 ``trusted-notification-proxy``
 ------------------------------
 
--  String
+.. versionchanged:: 4.4.0
+   This option now accepts a comma-separated list of IP ranges. This was a single IP address as a string before
+
+-  IP ranges, separated by commas
 
-IP address of incoming notification proxy
+IP ranges of incoming notification proxies.
 
 .. _setting-udp-truncation-threshold:
 
index d85f1d7050c1bddcc69abfd18ea1fca516a6bca5..dfdaf2289964ca434e5f1028d01400a190645934 100644 (file)
@@ -250,6 +250,7 @@ pdns_server_SOURCES = \
        tcpreceiver.cc tcpreceiver.hh \
        threadname.hh threadname.cc \
        tkey.cc \
+       trusted-notification-proxy.hh trusted-notification-proxy.cc \
        tsigutils.hh tsigutils.cc \
        tsigverifier.cc tsigverifier.hh \
        ueberbackend.cc ueberbackend.hh \
@@ -1358,11 +1359,13 @@ testrunner_SOURCES = \
        test-signers.cc \
        test-statbag_cc.cc \
        test-svc_records_cc.cc \
+       test-trusted-notification-proxy_cc.cc \
        test-tsig.cc \
        test-ueberbackend_cc.cc \
        test-zoneparser_tng_cc.cc \
        testrunner.cc \
        threadname.hh threadname.cc \
+       trusted-notification-proxy.cc \
        tsigverifier.cc tsigverifier.hh \
        ueberbackend.cc ueberbackend.hh \
        unix_utility.cc \
index 32fca88ede51a8ebdbfcb49dff45bea85be1ad5a..437ca3f7084f6c78cd891fcae5d54970a78e6a00 100644 (file)
@@ -32,6 +32,7 @@
 #include "threadname.hh"
 #include "misc.hh"
 #include "query-local-address.hh"
+#include "trusted-notification-proxy.hh"
 
 #include <thread>
 
@@ -641,6 +642,8 @@ void mainthread()
     pdns::parseQueryLocalAddress(::arg()["query-local-address6"]);
   }
 
+  pdns::parseTrustedNotificationProxy(::arg()["trusted-notification-proxy"]);
+
   // NOW SAFE TO CREATE THREADS!
   dl->go();
 
index 67a39c7ad98aee1e714664b439ba5f4e49761419..1cdb4470b88417fc91568f376cd6903facfa9bf5 100644 (file)
@@ -45,6 +45,7 @@
 #include "dnsproxy.hh"
 #include "version.hh"
 #include "common_startup.hh"
+#include "trusted-notification-proxy.hh"
 
 #if 0
 #undef DLOG
@@ -864,7 +865,7 @@ int PacketHandler::trySuperMaster(const DNSPacket& p, const DNSName& tsigkeyname
 int PacketHandler::trySuperMasterSynchronous(const DNSPacket& p, const DNSName& tsigkeyname)
 {
   ComboAddress remote = p.getRemote();
-  if(p.hasEDNSSubnet() && ::arg().contains("trusted-notification-proxy", remote.toString())) {
+  if(p.hasEDNSSubnet() && pdns::isAddressTrustedNotificationProxy(remote)) {
     remote = p.getRealRemote().getNetwork();
   }
   remote.setPort(53);
@@ -980,7 +981,7 @@ int PacketHandler::processNotify(const DNSPacket& p)
     return RCode::Refused;
   }
 
-  if(::arg().contains("trusted-notification-proxy", p.getRemote().toString())) {
+  if(pdns::isAddressTrustedNotificationProxy(p.getRemote())) {
     g_log<<Logger::Error<<"Received NOTIFY for "<<p.qdomain<<" from trusted-notification-proxy "<< p.getRemote()<<endl;
     if(di.masters.empty()) {
       g_log<<Logger::Error<<"However, "<<p.qdomain<<" does not have any masters defined (Refused)"<<endl;
diff --git a/pdns/test-trusted-notification-proxy_cc.cc b/pdns/test-trusted-notification-proxy_cc.cc
new file mode 100644 (file)
index 0000000..689e5c8
--- /dev/null
@@ -0,0 +1,88 @@
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_NO_MAIN
+#include <boost/test/unit_test.hpp>
+#include "trusted-notification-proxy.hh"
+
+using namespace boost;
+
+BOOST_AUTO_TEST_SUITE(test_trusted_notification_proxy_cc)
+
+BOOST_AUTO_TEST_CASE(test_trusted_notification_proxy_bad_addrs) {
+  string addrs = "127.0.0.1111";
+  BOOST_CHECK_THROW(pdns::parseTrustedNotificationProxy(addrs), PDNSException);
+  addrs = "127.0.0.1,:::2";
+  BOOST_CHECK_THROW(pdns::parseTrustedNotificationProxy(addrs), PDNSException);
+}
+
+BOOST_AUTO_TEST_CASE(test_trusted_notification_proxy_addresses_only) {
+  string addrs = "127.0.0.1";
+  BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.2")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
+
+  addrs = "::1";
+  BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
+
+  addrs = "::1,192.0.2.4";
+  BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.4")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
+}
+
+BOOST_AUTO_TEST_CASE(test_trusted_notification_proxy_with_netmasks) {
+  string addrs = "127.0.0.0/8";
+  BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.2")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("128.0.0.2")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
+
+  addrs = "192.0.2.0/25";
+  BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.2")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("128.0.0.2")));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.128")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
+
+  addrs = "2001:db8:15::/64";
+  BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:15::fee:1:2")));
+
+  addrs = "192.0.2.0/24,2001:db8:16::/64";
+  BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:15::fee:1:2")));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:16::5353")));
+}
+
+BOOST_AUTO_TEST_CASE(test_trusted_notification_proxy_with_netmasks_and_addresses) {
+  string addrs = "192.0.2.1,2001:db8:16::/64";
+  BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:15::fee:1:2")));
+  BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.2")));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
+  BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:16::5353")));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/pdns/trusted-notification-proxy.cc b/pdns/trusted-notification-proxy.cc
new file mode 100644 (file)
index 0000000..f851493
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <vector>
+#include "trusted-notification-proxy.hh"
+
+namespace pdns {
+  static NetmaskGroup g_trustedNotificationProxies;
+
+  void parseTrustedNotificationProxy(const std::string &addresses) {
+    g_trustedNotificationProxies.clear();
+    std::vector<std::string> parts;
+    stringtok(parts, addresses, ",\t ");
+    for (auto const &a : parts) {
+      try {
+        g_trustedNotificationProxies.addMask(Netmask(a));
+      } catch (const PDNSException &e) {
+        throw PDNSException("Unable to add address " + a + " as a trusted-notification-proxy: " + e.reason);
+      } catch (const std::exception &e) {
+        throw PDNSException("Unable to add address " + a + " as a trusted-notification-proxy: " + e.what());
+      }
+    }
+  }
+
+  bool isAddressTrustedNotificationProxy(const ComboAddress &address) {
+    return g_trustedNotificationProxies.match(address);
+  }
+} // namespace pdns
diff --git a/pdns/trusted-notification-proxy.hh b/pdns/trusted-notification-proxy.hh
new file mode 100644 (file)
index 0000000..903832b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#pragma once
+
+#include <string>
+#include "iputils.hh"
+
+namespace pdns {
+  /*! Parses the provided string into the trusted-notification variable
+   *
+   * Replaces any existing masks
+   *
+   * Throws on error.
+   *
+   * @param addresses String of addresses, separated by comma's
+   */
+  void parseTrustedNotificationProxy(const std::string &addresses);
+
+  bool isAddressTrustedNotificationProxy(const ComboAddress &address);
+} // namespace pdns