1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "secpoll-recursor.hh"
#include "syncres.hh"
#include "logger.hh"
#include "arguments.hh"
#include "version.hh"
#include "validate-recursor.hh"
#include <stdint.h>
#ifndef PACKAGEVERSION
#define PACKAGEVERSION getPDNSVersion()
#endif
uint32_t g_security_status;
string g_security_message;
void doSecPoll(time_t* last_secpoll)
{
if(::arg()["security-poll-suffix"].empty())
return;
string pkgv(PACKAGEVERSION);
struct timeval now;
gettimeofday(&now, 0);
SyncRes sr(now);
if (g_dnssecmode != DNSSECMode::Off)
sr.d_doDNSSEC=true;
vector<DNSRecord> ret;
string version = "recursor-" +pkgv;
string qstring(version.substr(0, 63)+ ".security-status."+::arg()["security-poll-suffix"]);
if(*qstring.rbegin()!='.')
qstring+='.';
boost::replace_all(qstring, "+", "_");
boost::replace_all(qstring, "~", "_");
vState state = Indeterminate;
DNSName query(qstring);
int res=sr.beginResolve(query, QType(QType::TXT), 1, ret);
if (g_dnssecmode != DNSSECMode::Off && res)
state = validateRecords(ret);
if(state == Bogus) {
L<<Logger::Error<<"Could not retrieve security status update for '" +pkgv+ "' on '"<<query<<"', DNSSEC validation result was Bogus!"<<endl;
if(g_security_status == 1) // If we were OK, go to unknown
g_security_status = 0;
return;
}
if(!res && !ret.empty()) {
string content=ret.begin()->d_content->getZoneRepresentation();
if(!content.empty() && content[0]=='"' && content[content.size()-1]=='"') {
content=content.substr(1, content.length()-2);
}
pair<string, string> split = splitField(content, ' ');
g_security_status = std::stoi(split.first);
g_security_message = split.second;
*last_secpoll=now.tv_sec;
}
else {
if(pkgv.find("0.0."))
L<<Logger::Warning<<"Could not retrieve security status update for '" +pkgv+ "' on '"<<query<<"', RCODE = "<< RCode::to_s(res)<<endl;
else
L<<Logger::Warning<<"Ignoring response for security status update, this a non-release version."<<endl;
if(g_security_status == 1) // it was ok, now it is unknown
g_security_status = 0;
if(res == RCode::NXDomain) // if we had NXDOMAIN, keep on trying more more frequently
*last_secpoll=now.tv_sec;
}
if(g_security_status == 2) {
L<<Logger::Error<<"PowerDNS Security Update Recommended: "<<g_security_message<<endl;
}
else if(g_security_status == 3) {
L<<Logger::Error<<"PowerDNS Security Update Mandatory: "<<g_security_message<<endl;
}
}
|