From 2d40d42b9117cd34f8b1a234dc7eaf3fd6e22694 Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Mon, 24 Jun 2019 13:42:14 +0200 Subject: [PATCH] auth+rec secpoll: Combine secpoll result parsing code --- pdns/Makefile.am | 1 + pdns/recursordist/Makefile.am | 4 +- pdns/recursordist/secpoll.cc | 1 + pdns/recursordist/secpoll.hh | 1 + pdns/secpoll-auth.cc | 40 ++++++++----------- pdns/secpoll-recursor.cc | 50 ++++++++++-------------- pdns/secpoll.cc | 73 +++++++++++++++++++++++++++++++++++ pdns/secpoll.hh | 36 +++++++++++++++++ pdns/stubresolver.cc | 9 +++++ pdns/stubresolver.hh | 1 + 10 files changed, 161 insertions(+), 55 deletions(-) create mode 120000 pdns/recursordist/secpoll.cc create mode 120000 pdns/recursordist/secpoll.hh create mode 100644 pdns/secpoll.cc create mode 100644 pdns/secpoll.hh diff --git a/pdns/Makefile.am b/pdns/Makefile.am index b29a58686c83..4f71e1190846 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -207,6 +207,7 @@ pdns_server_SOURCES = \ resolver.cc resolver.hh \ responsestats.cc responsestats.hh responsestats-auth.cc \ rfc2136handler.cc \ + secpoll.cc secpoll.hh \ secpoll-auth.cc secpoll-auth.hh \ serialtweaker.cc \ sha.hh \ diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 12d93f680fd8..65a8e5b3d0b0 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -161,8 +161,8 @@ pdns_recursor_SOURCES = \ root-addresses.hh \ root-dnssec.hh \ rpzloader.cc rpzloader.hh \ - secpoll-recursor.cc \ - secpoll-recursor.hh \ + secpoll-recursor.cc secpoll-recursor.hh \ + secpoll.cc secpoll.hh \ sholder.hh \ sillyrecords.cc \ snmp-agent.hh snmp-agent.cc \ diff --git a/pdns/recursordist/secpoll.cc b/pdns/recursordist/secpoll.cc new file mode 120000 index 000000000000..997c3935e978 --- /dev/null +++ b/pdns/recursordist/secpoll.cc @@ -0,0 +1 @@ +../secpoll.cc \ No newline at end of file diff --git a/pdns/recursordist/secpoll.hh b/pdns/recursordist/secpoll.hh new file mode 120000 index 000000000000..a1beadc32d3e --- /dev/null +++ b/pdns/recursordist/secpoll.hh @@ -0,0 +1 @@ +../secpoll.hh \ No newline at end of file diff --git a/pdns/secpoll-auth.cc b/pdns/secpoll-auth.cc index a4d60561f532..65ab81d3521f 100644 --- a/pdns/secpoll-auth.cc +++ b/pdns/secpoll-auth.cc @@ -15,6 +15,7 @@ #include "namespaces.hh" #include "statbag.hh" #include "stubresolver.hh" +#include "secpoll.hh" #include "dnsrecords.hh" #include #ifndef PACKAGEVERSION @@ -35,8 +36,9 @@ void doSecPoll(bool first) struct timeval now; gettimeofday(&now, 0); + string pkgv(PACKAGEVERSION); - string version = "auth-" + string(PACKAGEVERSION); + string version = "auth-" + pkgv; string query = version.substr(0, 63) +".security-status."+::arg()["security-poll-suffix"]; if(*query.rbegin()!='.') @@ -47,33 +49,27 @@ void doSecPoll(bool first) int security_status = std::stoi(S.getValueStr("security-status")); - vector ret; - int res=stubDoResolve(DNSName(query), QType::TXT, ret); + vector ret; + int res = stubDoResolve(DNSName(query), QType::TXT, ret); - if (res != 0) { // not NOERROR - if(security_status == 1) // it was ok, now it is unknown - S.set("security-status", 0); - - string pkgv(PACKAGEVERSION); - if (std::count(pkgv.begin(), pkgv.end(), '.') > 2) { - g_log<(ret.begin()->dr)->d_text; - pair split = splitField(unquotify(content), ' '); - security_status = std::stoi(split.first); - g_security_message = split.second; + + S.set("security-status", security_status); + g_security_message = security_message; if(security_status == 1 && first) { g_log< #ifndef PACKAGEVERSION @@ -36,7 +37,7 @@ void doSecPoll(time_t* last_secpoll) } vector ret; - + string version = "recursor-" +pkgv; string qstring(version.substr(0, 63)+ ".security-status."+::arg()["security-poll-suffix"]); @@ -48,7 +49,7 @@ void doSecPoll(time_t* last_secpoll) vState state = Indeterminate; DNSName query(qstring); - int res=sr.beginResolve(query, QType(QType::TXT), 1, ret); + int res = sr.beginResolve(query, QType(QType::TXT), 1, ret); if (g_dnssecmode != DNSSECMode::Off && res) { state = sr.getValidationState(); @@ -61,44 +62,33 @@ void doSecPoll(time_t* last_secpoll) return; } - if (res != 0) { // Not NOERROR - if(g_security_status == 1) // it was ok, now it is unknown - g_security_status = 0; - - if (std::count(pkgv.begin(), pkgv.end(), '.') > 2) { - g_log<getZoneRepresentation(); - } + g_security_message = security_message; - if(!content.empty() && content[0]=='"' && content[content.size()-1]=='"') { - content=content.substr(1, content.length()-2); + if(g_security_status != 1 && security_status == 1) { + g_log< split = splitField(content, ' '); - - g_security_status = std::stoi(split.first); - g_security_message = split.second; - - if(g_security_status == 2) { + if(security_status == 2) { g_log< +#include +#include "dnsrecords.hh" +#include "pdnsexception.hh" +#include "misc.hh" + +bool isReleaseVersion(const std::string &version) { + return std::count(version.begin(), version.end(), '.') == 2; +} + +void processSecPoll(const int res, const std::vector &ret, int &secPollStatus, std::string &secPollMessage) { + secPollMessage.clear(); + if (res != 0) { // not NOERROR + if(secPollStatus == 1) // it was ok, now it is unknown + secPollStatus = 0; + throw PDNSException("RCODE was not NOERROR but " + RCode::to_s(res)); + } + + if (ret.empty()) { // empty NOERROR... wat? + if(secPollStatus == 1) // it was ok, now it is unknown + secPollStatus = 0; + throw PDNSException("Had empty answer on NOERROR RCODE"); + } + + DNSRecord record; + for (auto const &r: ret) { + if (r.d_type == QType::TXT && r.d_place == DNSResourceRecord::Place::ANSWER) { + record = r; + break; + } + } + + if (record.d_name.empty()) { + throw PDNSException("No TXT record found in response"); + } + + auto recordContent = getRR(record); + if (recordContent == nullptr) { + throw PDNSException("Could not parse TXT record content"); + } + string content = recordContent->d_text; + + pair split = splitField(unquotify(content), ' '); + + try { + secPollStatus = std::stoi(split.first); + } catch (const std::exception &e) { + throw PDNSException(std::string("Could not parse status number: ") + e.what()); + } + secPollMessage = split.second; +} diff --git a/pdns/secpoll.hh b/pdns/secpoll.hh new file mode 100644 index 000000000000..141bb83c1a3a --- /dev/null +++ b/pdns/secpoll.hh @@ -0,0 +1,36 @@ +/* + * 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 +#include +#include "dnsrecords.hh" + +/* Parses the result of a security poll, will throw a PDNSException when it could not be parsed, secPollStatus is + * set correctly regardless whether or not an exception was thrown. + * + * res: DNS Rcode result from the secpoll + * ret: Records returned during secpoll + * secPollStatus: The actual secpoll status, pass the current status in here and it is changed to the new status + * secPollMessage: Will be cleared and filled with the message from the secpoll message + */ +void processSecPoll(const int res, const std::vector &ret, int &secPollStatus, std::string &secPollMessage); +bool isReleaseVersion(const std::string &version); diff --git a/pdns/stubresolver.cc b/pdns/stubresolver.cc index 3068842bfa84..8f593f9f22d5 100644 --- a/pdns/stubresolver.cc +++ b/pdns/stubresolver.cc @@ -169,3 +169,12 @@ int stubDoResolve(const DNSName& qname, uint16_t qtype, vector& r } return RCode::ServFail; } + +int stubDoResolve(const DNSName& qname, uint16_t qtype, vector& ret) { + vector ret2; + int res = stubDoResolve(qname, qtype, ret2); + for (const auto &r : ret2) { + ret.push_back(r.dr); + } + return res; +} diff --git a/pdns/stubresolver.hh b/pdns/stubresolver.hh index bcbec421da07..1cb94c8d4246 100644 --- a/pdns/stubresolver.hh +++ b/pdns/stubresolver.hh @@ -26,3 +26,4 @@ void stubParseResolveConf(); bool resolversDefined(); int stubDoResolve(const DNSName& qname, uint16_t qtype, vector& ret); +int stubDoResolve(const DNSName& qname, uint16_t qtype, vector& ret);