File: secpoll-recursor.cc

package info (click to toggle)
pdns-recursor 4.0.4-1+deb9u3~bpo8+1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-backports
  • size: 5,484 kB
  • sloc: cpp: 36,380; sh: 11,771; makefile: 305; xml: 37
file content (86 lines) | stat: -rw-r--r-- 2,572 bytes parent folder | download
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;
  }
}