]> granicus.if.org Git - pdns/commitdiff
dnsdist: Correctly handle PACKAGEVERSION, check name in secpoll reply
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 31 Oct 2018 09:21:54 +0000 (10:21 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 31 Oct 2018 09:21:54 +0000 (10:21 +0100)
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistdist/configure.ac
pdns/dnsdistdist/dnsdist-secpoll.cc

index 1f19cb56b1363de02806619d39d898ed0dae6cb7..48805687061864b1f5621315c1e1cdcfa77d9479 100644 (file)
@@ -1732,6 +1732,15 @@ catch(...)
   return nullptr;
 }
 
+uint16_t getRandomDNSID()
+{
+#ifdef HAVE_LIBSODIUM
+  return (randombytes_random() % 65536);
+#else
+  return (random() % 65536);
+#endif
+}
+
 static bool upCheck(DownstreamState& ds)
 try
 {
@@ -1742,18 +1751,13 @@ try
   memset(&checkHeader, 0, sizeof(checkHeader));
 
   checkHeader.qdcount = htons(1);
-#ifdef HAVE_LIBSODIUM
-  checkHeader.id = randombytes_random() % 65536;
-#else
-  checkHeader.id = random() % 65536;
-#endif
+  checkHeader.id = getRandomDNSID();
 
   checkHeader.rd = true;
   if (ds.setCD) {
     checkHeader.cd = true;
   }
 
-
   if (ds.checkFunction) {
     std::lock_guard<std::mutex> lock(g_luamutex);
     auto ret = ds.checkFunction(checkName, checkType, checkClass, &checkHeader);
index 08393675e88db78ae9be24bae695479f673d2c7b..8d0454bab729b966fef06d6d8e488f24787232d9 100644 (file)
@@ -1012,6 +1012,8 @@ int handleDNSCryptQuery(char* packet, uint16_t len, std::shared_ptr<DNSCryptQuer
 
 bool addXPF(DNSQuestion& dq, uint16_t optionCode);
 
+uint16_t getRandomDNSID();
+
 #include "dnsdist-snmp.hh"
 
 extern bool g_snmpEnabled;
index 055ee344b5aa66909300eee8f56e01f89614e6a2..f55e394eeee5e6f6a39a3e69324003285f0bdd9e 100644 (file)
@@ -96,6 +96,11 @@ AC_SUBST([AM_CPPFLAGS],
   ["AS_ESCAPE([-I$(top_builddir) -I$(top_srcdir)]) -Wall -O3 -pthread $BOOST_CPPFLAGS"]
 )
 
+AC_ARG_VAR(PACKAGEVERSION, [The version used in secpoll queries])
+AS_IF([test "x$PACKAGEVERSION" != "x"],
+  [AC_DEFINE_UNQUOTED([PACKAGEVERSION], "$PACKAGEVERSION", [Set to the package version used for secpoll])]
+)
+
 AC_CONFIG_FILES([Makefile
        ext/yahttp/Makefile
        ext/yahttp/yahttp/Makefile])
index 49b95595671c9e408f3c00b393b0f6e33e450786..b40bbf5ab7b730951369cfc0fd7174e132ac0f2a 100644 (file)
 #include "misc.hh"
 #include "sstuff.hh"
 
+#include "dnsdist.hh"
 #include "dnsdist-secpoll.hh"
 
+#ifndef PACKAGEVERSION
+#define PACKAGEVERSION PACKAGE_VERSION
+#endif
+
 static std::string getFirstTXTAnswer(const std::string& answer)
 {
   if (answer.size() <= sizeof(struct dnsheader)) {
@@ -85,13 +90,10 @@ static std::string getFirstTXTAnswer(const std::string& answer)
 
 static std::string getSecPollStatus(const std::string& queriedName, int timeout=2)
 {
+  const DNSName& sentName = DNSName(queriedName);
   vector<uint8_t> packet;
-  DNSPacketWriter pw(packet, DNSName(queriedName), QType::TXT);
-#ifdef HAVE_LIBSODIUM
-  pw.getHeader()->id = randombytes_random() % 65536;
-#else
-  pw.getHeader()->id = random() % 65536;
-#endif
+  DNSPacketWriter pw(packet, sentName, QType::TXT);
+  pw.getHeader()->id = getRandomDNSID();
   pw.getHeader()->rd = 1;
 
   const auto& resolversForStub = getResolvers("/etc/resolv.conf");
@@ -162,6 +164,17 @@ static std::string getSecPollStatus(const std::string& queriedName, int timeout=
       continue;
     }
 
+    uint16_t receivedType;
+    uint16_t receivedClass;
+    DNSName receivedName(reply.c_str(), reply.size(), sizeof(dnsheader), false, &receivedType, &receivedClass);
+
+    if (receivedName != sentName || receivedType != QType::TXT || receivedClass != QClass::IN) {
+      if (g_verbose) {
+        warnlog("Invalid answer, either the qname (%s / %s), qtype (%s / %s) or qclass (%d / %d) does not match, received from the secpoll stub resolver %s", receivedName, sentName, QType(receivedType).getName(), QType(QType::TXT).getName(), receivedClass, QClass::IN, dest.toString());
+      }
+      continue;
+    }
+
     return getFirstTXTAnswer(reply);
   }
 
@@ -178,13 +191,13 @@ void doSecPoll(const std::string& suffix)
     return;
   }
 
-  const std::string pkgv(PACKAGE_VERSION);
+  const std::string pkgv(PACKAGEVERSION);
   bool releaseVersion = pkgv.find("0.0.") != 0;
 
   struct timeval now;
   gettimeofday(&now, 0);
 
-  const std::string version = "dnsdist-" + std::string(VERSION);
+  const std::string version = "dnsdist-" + std::string(PACKAGEVERSION);
   std::string queriedName = version.substr(0, 63) + ".security-status." + suffix;
 
   if (*queriedName.rbegin() != '.') {