*/
#include "validate.hh"
-#include "misc.hh"
-#include "dnssecinfra.hh"
#include "dnssec.hh"
-#include "rec-lua-conf.hh"
#include "base32.hh"
-#include "logger.hh"
uint32_t g_signatureInceptionSkew{0};
uint16_t g_maxNSEC3Iterations{0};
return (key.d_flags & 128) != 0;
}
-static vector<shared_ptr<const DNSKEYRecordContent > > getByTag(const skeyset_t& keys, uint16_t tag, uint8_t algorithm, const OptLog& log)
+static vector<shared_ptr<const DNSKEYRecordContent>> getByTag(const skeyset_t& keys, uint16_t tag, uint8_t algorithm, const OptLog& log)
{
vector<shared_ptr<const DNSKEYRecordContent>> ret;
for (const auto& key : keys) {
if (!isAZoneKey(*key)) {
- VLOG(log, "Key for tag "<<std::to_string(tag)<<" and algorithm "<<std::to_string(algorithm)<<" is not a zone key, skipping"<<endl;);
+ VLOG(log, "Key for tag " << std::to_string(tag) << " and algorithm " << std::to_string(algorithm) << " is not a zone key, skipping" << endl;);
continue;
}
if (isRevokedKey(*key)) {
- VLOG(log, "Key for tag "<<std::to_string(tag)<<" and algorithm "<<std::to_string(algorithm)<<" has been revoked, skipping"<<endl;);
+ VLOG(log, "Key for tag " << std::to_string(tag) << " and algorithm " << std::to_string(algorithm) << " has been revoked, skipping" << endl;);
continue;
}
return sign.d_labels < labelCount;
}
-static bool isWildcardExpanded(const DNSName& owner, const std::vector<std::shared_ptr<const RRSIGRecordContent> >& signatures)
+static bool isWildcardExpanded(const DNSName& owner, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures)
{
if (signatures.empty()) {
return false;
return owner.isWildcard() && (labelCount - 1) == sign.d_labels;
}
-static bool isWildcardExpandedOntoItself(const DNSName& owner, const std::vector<std::shared_ptr<const RRSIGRecordContent> >& signatures)
+static bool isWildcardExpandedOntoItself(const DNSName& owner, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures)
{
if (signatures.empty()) {
return false;
/* if this is a wildcard NSEC, the owner name has been modified
to match the name. Make sure we use the original '*' form. */
-DNSName getNSECOwnerName(const DNSName& initialOwner, const std::vector<std::shared_ptr<const RRSIGRecordContent> >& signatures)
+DNSName getNSECOwnerName(const DNSName& initialOwner, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures)
{
DNSName result = initialOwner;
do {
result.chopOff();
labelsCount--;
- }
- while (sign->d_labels < labelsCount);
+ } while (sign->d_labels < labelsCount);
result = g_wildcarddnsname + result;
}
static bool isNSECAncestorDelegation(const DNSName& signer, const DNSName& owner, const NSECRecordContent& nsec)
{
- return nsec.isSet(QType::NS) &&
- !nsec.isSet(QType::SOA) &&
- signer.countLabels() < owner.countLabels();
+ return nsec.isSet(QType::NS) && !nsec.isSet(QType::SOA) && signer.countLabels() < owner.countLabels();
}
bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const NSEC3RecordContent& nsec3)
{
- return nsec3.isSet(QType::NS) &&
- !nsec3.isSet(QType::SOA) &&
- signer.countLabels() < owner.countLabels();
+ return nsec3.isSet(QType::NS) && !nsec3.isSet(QType::SOA) && signer.countLabels() < owner.countLabels();
}
static bool provesNoDataWildCard(const DNSName& qname, const uint16_t qtype, const DNSName& closestEncloser, const cspmap_t& validrrsets, const OptLog& log)
{
const DNSName wildcard = g_wildcarddnsname + closestEncloser;
- VLOG(log, qname << ": Trying to prove that there is no data in wildcard for "<<qname<<"/"<<QType(qtype)<<endl);
+ VLOG(log, qname << ": Trying to prove that there is no data in wildcard for " << qname << "/" << QType(qtype) << endl);
for (const auto& validset : validrrsets) {
- VLOG(log, qname << ": Do have: "<<validset.first.first<<"/"<<DNSRecordContent::NumberToType(validset.first.second)<<endl);
+ VLOG(log, qname << ": Do have: " << validset.first.first << "/" << DNSRecordContent::NumberToType(validset.first.second) << endl);
if (validset.first.second == QType::NSEC) {
for (const auto& record : validset.second.records) {
- VLOG(log, ":\t"<<record->getZoneRepresentation()<<endl);
+ VLOG(log, ":\t" << record->getZoneRepresentation() << endl);
auto nsec = std::dynamic_pointer_cast<const NSECRecordContent>(record);
if (!nsec) {
continue;
VLOG(log, qname << ":\tWildcard matches");
if (qtype == 0 || isTypeDenied(*nsec, QType(qtype))) {
- VLOG_NO_PREFIX(log, " and proves that the type did not exist"<<endl);
+ VLOG_NO_PREFIX(log, " and proves that the type did not exist" << endl);
return true;
}
- VLOG_NO_PREFIX(log, " BUT the type did exist!"<<endl);
+ VLOG_NO_PREFIX(log, " BUT the type did exist!" << endl);
return false;
}
}
This function checks whether the non-existence of a wildcard covering qname|qtype
is proven by the NSEC records in validrrsets.
*/
-static bool provesNoWildCard(const DNSName& qname, const uint16_t qtype, const DNSName& closestEncloser, const cspmap_t & validrrsets, const OptLog& log)
+static bool provesNoWildCard(const DNSName& qname, const uint16_t qtype, const DNSName& closestEncloser, const cspmap_t& validrrsets, const OptLog& log)
{
- VLOG(log, qname << ": Trying to prove that there is no wildcard for "<<qname<<"/"<<QType(qtype)<<endl);
+ VLOG(log, qname << ": Trying to prove that there is no wildcard for " << qname << "/" << QType(qtype) << endl);
const DNSName wildcard = g_wildcarddnsname + closestEncloser;
for (const auto& validset : validrrsets) {
- VLOG(log, qname << ": Do have: "<<validset.first.first<<"/"<<DNSRecordContent::NumberToType(validset.first.second)<<endl);
+ VLOG(log, qname << ": Do have: " << validset.first.first << "/" << DNSRecordContent::NumberToType(validset.first.second) << endl);
if (validset.first.second == QType::NSEC) {
for (const auto& records : validset.second.records) {
- VLOG(log, qname << ":\t"<<records->getZoneRepresentation()<<endl);
+ VLOG(log, qname << ":\t" << records->getZoneRepresentation() << endl);
auto nsec = std::dynamic_pointer_cast<const NSECRecordContent>(records);
if (!nsec) {
continue;
}
const DNSName owner = getNSECOwnerName(validset.first.first, validset.second.signatures);
- VLOG(log, qname << ": Comparing owner: "<<owner<<" with target: "<<wildcard<<endl);
+ VLOG(log, qname << ": Comparing owner: " << owner << " with target: " << wildcard << endl);
if (qname != owner && qname.isPartOf(owner) && nsec->isSet(QType::DNAME)) {
/* rfc6672 section 5.3.2: DNAME Bit in NSEC Type Map
asserted, then DNAME substitution should have been done, but the
substitution has not been done as specified.
*/
- VLOG(log, qname << ":\tThe qname is a subdomain of the NSEC and the DNAME bit is set"<<endl);
+ VLOG(log, qname << ":\tThe qname is a subdomain of the NSEC and the DNAME bit is set" << endl);
return false;
}
if (wildcard != owner && isCoveredByNSEC(wildcard, owner, nsec->d_next)) {
- VLOG(log, qname << ":\tWildcard is covered"<<endl);
+ VLOG(log, qname << ":\tWildcard is covered" << endl);
return true;
}
}
static bool provesNSEC3NoWildCard(const DNSName& closestEncloser, uint16_t const qtype, const cspmap_t& validrrsets, bool* wildcardExists, const OptLog& log, pdns::validation::ValidationContext& context)
{
auto wildcard = g_wildcarddnsname + closestEncloser;
- VLOG(log, closestEncloser << ": Trying to prove that there is no wildcard for "<<wildcard<<"/"<<QType(qtype)<<endl);
+ VLOG(log, closestEncloser << ": Trying to prove that there is no wildcard for " << wildcard << "/" << QType(qtype) << endl);
for (const auto& validset : validrrsets) {
- VLOG(log, closestEncloser << ": Do have: "<<validset.first.first<<"/"<<DNSRecordContent::NumberToType(validset.first.second)<<endl);
+ VLOG(log, closestEncloser << ": Do have: " << validset.first.first << "/" << DNSRecordContent::NumberToType(validset.first.second) << endl);
if (validset.first.second == QType::NSEC3) {
for (const auto& records : validset.second.records) {
- VLOG(log, closestEncloser << ":\t"<<records->getZoneRepresentation()<<endl);
+ VLOG(log, closestEncloser << ":\t" << records->getZoneRepresentation() << endl);
auto nsec3 = std::dynamic_pointer_cast<const NSEC3RecordContent>(records);
if (!nsec3) {
continue;
string hash = getHashFromNSEC3(wildcard, *nsec3, context);
if (hash.empty()) {
- VLOG(log, closestEncloser << ": Unsupported hash, ignoring"<<endl);
+ VLOG(log, closestEncloser << ": Unsupported hash, ignoring" << endl);
return false;
}
- VLOG(log, closestEncloser << ":\tWildcard hash: "<<toBase32Hex(hash)<<endl);
- string beginHash=fromBase32Hex(validset.first.first.getRawLabel(0));
- VLOG(log, closestEncloser << ":\tNSEC3 hash: "<<toBase32Hex(beginHash)<<" -> "<<toBase32Hex(nsec3->d_nexthash)<<endl);
+ VLOG(log, closestEncloser << ":\tWildcard hash: " << toBase32Hex(hash) << endl);
+ string beginHash = fromBase32Hex(validset.first.first.getRawLabel(0));
+ VLOG(log, closestEncloser << ":\tNSEC3 hash: " << toBase32Hex(beginHash) << " -> " << toBase32Hex(nsec3->d_nexthash) << endl);
if (beginHash == hash) {
VLOG(log, closestEncloser << ":\tWildcard hash matches");
*/
if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, validset.first.first, *nsec3)) {
/* this is an "ancestor delegation" NSEC3 RR */
- VLOG_NO_PREFIX(log, " BUT an ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
+ VLOG_NO_PREFIX(log, " BUT an ancestor delegation NSEC3 RR can only deny the existence of a DS" << endl);
return false;
}
if (qtype == 0 || isTypeDenied(*nsec3, QType(qtype))) {
- VLOG_NO_PREFIX(log, " and proves that the type did not exist"<<endl);
+ VLOG_NO_PREFIX(log, " and proves that the type did not exist" << endl);
return true;
}
- VLOG_NO_PREFIX(log, " BUT the type did exist!"<<endl);
+ VLOG_NO_PREFIX(log, " BUT the type did exist!" << endl);
return false;
}
if (isCoveredByNSEC3Hash(hash, beginHash, nsec3->d_nexthash)) {
- VLOG(log, closestEncloser << ":\tWildcard hash is covered"<<endl);
+ VLOG(log, closestEncloser << ":\tWildcard hash is covered" << endl);
return true;
}
}
if (name.isPartOf(owner) && isNSECAncestorDelegation(signer, owner, nsec)) {
/* this is an "ancestor delegation" NSEC RR */
if (qtype != QType::DS || name != owner) {
- VLOG_NO_PREFIX(log, "An ancestor delegation NSEC RR can only deny the existence of a DS"<<endl);
+ VLOG_NO_PREFIX(log, "An ancestor delegation NSEC RR can only deny the existence of a DS" << endl);
return dState::NODENIAL;
}
}
/* check if the type is denied */
if (name == owner) {
if (!isTypeDenied(nsec, QType(qtype))) {
- VLOG_NO_PREFIX(log, "does _not_ deny existence of type "<<QType(qtype)<<endl);
+ VLOG_NO_PREFIX(log, "does _not_ deny existence of type " << QType(qtype) << endl);
return dState::NODENIAL;
}
if (qtype == QType::DS && signer == name) {
- VLOG_NO_PREFIX(log, "the NSEC comes from the child zone and cannot be used to deny a DS"<<endl);
+ VLOG_NO_PREFIX(log, "the NSEC comes from the child zone and cannot be used to deny a DS" << endl);
return dState::NODENIAL;
}
- VLOG_NO_PREFIX(log, "Denies existence of type "<<QType(qtype)<<endl);
+ VLOG_NO_PREFIX(log, "Denies existence of type " << QType(qtype) << endl);
return dState::NXQTYPE;
}
}
if (isCoveredByNSEC(name, owner, nsec.d_next)) {
- VLOG_NO_PREFIX(log, name << ": is covered by ("<<owner<<" to "<<nsec.d_next<<")");
+ VLOG_NO_PREFIX(log, name << ": is covered by (" << owner << " to " << nsec.d_next << ")");
if (nsecProvesENT(name, owner, nsec.d_next)) {
- VLOG_NO_PREFIX(log, " denies existence of type "<<name<<"/"<<QType(qtype)<<" by proving that "<<name<<" is an ENT"<<endl);
+ VLOG_NO_PREFIX(log, " denies existence of type " << name << "/" << QType(qtype) << " by proving that " << name << " is an ENT" << endl);
return dState::NXQTYPE;
}
useful when we have a positive answer synthesized from a wildcard and we only need to prove that the exact
name does not exist.
*/
-dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16_t qtype, bool referralToUnsigned, bool wantsNoDataProof, pdns::validation::ValidationContext& context, const OptLog& log, bool needWildcardProof, unsigned int wildcardLabelsCount) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791
+dState getDenial(const cspmap_t& validrrsets, const DNSName& qname, const uint16_t qtype, bool referralToUnsigned, bool wantsNoDataProof, pdns::validation::ValidationContext& context, const OptLog& log, bool needWildcardProof, unsigned int wildcardLabelsCount) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791
{
bool nsec3Seen = false;
if (!needWildcardProof && wildcardLabelsCount == 0) {
uint8_t numberOfLabelsOfParentZone{std::numeric_limits<uint8_t>::max()};
uint16_t nsec3sConsidered = 0;
for (const auto& validset : validrrsets) {
- VLOG(log, qname << ": Do have: "<<validset.first.first<<"/"<<DNSRecordContent::NumberToType(validset.first.second)<<endl);
+ VLOG(log, qname << ": Do have: " << validset.first.first << "/" << DNSRecordContent::NumberToType(validset.first.second) << endl);
- if (validset.first.second==QType::NSEC) {
+ if (validset.first.second == QType::NSEC) {
for (const auto& record : validset.second.records) {
- VLOG(log, qname << ":\t"<<record->getZoneRepresentation()<<endl);
+ VLOG(log, qname << ":\t" << record->getZoneRepresentation() << endl);
if (validset.second.signatures.empty()) {
continue;
const DNSName owner = getNSECOwnerName(validset.first.first, validset.second.signatures);
const DNSName signer = getSigner(validset.second.signatures);
if (!validset.first.first.isPartOf(signer) || !owner.isPartOf(signer) || !qname.isPartOf(signer)) {
- continue;
+ continue;
}
/* The NSEC is either a delegation one, from the parent zone, and
*/
const bool notApex = signer.countLabels() < owner.countLabels();
if (notApex && nsec->isSet(QType::NS) && nsec->isSet(QType::SOA)) {
- VLOG(log, qname << ": However, that NSEC is not at the apex and has both the NS and the SOA bits set!"<<endl);
+ VLOG(log, qname << ": However, that NSEC is not at the apex and has both the NS and the SOA bits set!" << endl);
continue;
}
if (qname.isPartOf(owner) && isNSECAncestorDelegation(signer, owner, *nsec)) {
/* this is an "ancestor delegation" NSEC RR */
if (qtype != QType::DS || qname != owner) {
- VLOG(log, qname << ": An ancestor delegation NSEC RR can only deny the existence of a DS"<<endl);
+ VLOG(log, qname << ": An ancestor delegation NSEC RR can only deny the existence of a DS" << endl);
return dState::NODENIAL;
}
}
if (qtype == QType::DS && !qname.isRoot() && signer == qname) {
- VLOG(log, qname << ": A NSEC RR from the child zone cannot deny the existence of a DS"<<endl);
+ VLOG(log, qname << ": A NSEC RR from the child zone cannot deny the existence of a DS" << endl);
continue;
}
/* check if the type is denied */
if (qname == owner) {
if (!isTypeDenied(*nsec, QType(qtype))) {
- VLOG(log, qname << ": Does _not_ deny existence of type "<<QType(qtype)<<endl);
+ VLOG(log, qname << ": Does _not_ deny existence of type " << QType(qtype) << endl);
return dState::NODENIAL;
}
- VLOG(log, qname << ": Denies existence of type "<<QType(qtype)<<endl);
+ VLOG(log, qname << ": Denies existence of type " << QType(qtype) << endl);
/*
* RFC 4035 Section 2.3:
*/
if (referralToUnsigned && qtype == QType::DS) {
if (!nsec->isSet(QType::NS)) {
- VLOG(log, qname << ": However, no NS record exists at this level!"<<endl);
+ VLOG(log, qname << ": However, no NS record exists at this level!" << endl);
return dState::NODENIAL;
}
}
return dState::NXQTYPE;
}
- VLOG(log, qname << ": But the existence of a wildcard is not denied for "<<qname<<"/"<<endl);
+ VLOG(log, qname << ": But the existence of a wildcard is not denied for " << qname << "/" << endl);
return dState::NODENIAL;
}
asserted, then DNAME substitution should have been done, but the
substitution has not been done as specified.
*/
- VLOG(log, qname << ": The DNAME bit is set and the query name is a subdomain of that NSEC"<< endl);
+ VLOG(log, qname << ": The DNAME bit is set and the query name is a subdomain of that NSEC" << endl);
return dState::NODENIAL;
}
/* check if the whole NAME is denied existing */
if (isCoveredByNSEC(qname, owner, nsec->d_next)) {
- VLOG(log, qname<< ": Is covered by ("<<owner<<" to "<<nsec->d_next<<") ");
+ VLOG(log, qname << ": Is covered by (" << owner << " to " << nsec->d_next << ") ");
if (nsecProvesENT(qname, owner, nsec->d_next)) {
if (wantsNoDataProof) {
/* if the name is an ENT and we received a NODATA answer,
we are fine with a NSEC proving that the name does not exist. */
- VLOG_NO_PREFIX(log, "Denies existence of type "<<qname<<"/"<<QType(qtype)<<" by proving that "<<qname<<" is an ENT"<<endl);
+ VLOG_NO_PREFIX(log, "Denies existence of type " << qname << "/" << QType(qtype) << " by proving that " << qname << " is an ENT" << endl);
return dState::NXQTYPE;
}
/* but for a NXDOMAIN proof, this doesn't make sense! */
- VLOG_NO_PREFIX(log, "but it tries to deny the existence of "<<qname<<" by proving that "<<qname<<" is an ENT, this does not make sense!"<<endl);
+ VLOG_NO_PREFIX(log, "but it tries to deny the existence of " << qname << " by proving that " << qname << " is an ENT, this does not make sense!" << endl);
return dState::NODENIAL;
}
if (!needWildcardProof) {
- VLOG_NO_PREFIX(log, "and we did not need a wildcard proof"<<endl);
+ VLOG_NO_PREFIX(log, "and we did not need a wildcard proof" << endl);
return dState::NXDOMAIN;
}
VLOG_NO_PREFIX(log, "but we do need a wildcard proof so ");
DNSName closestEncloser = getClosestEncloserFromNSEC(qname, owner, nsec->d_next);
if (wantsNoDataProof) {
- VLOG_NO_PREFIX(log, "looking for NODATA proof"<<endl);
+ VLOG_NO_PREFIX(log, "looking for NODATA proof" << endl);
if (provesNoDataWildCard(qname, qtype, closestEncloser, validrrsets, log)) {
return dState::NXQTYPE;
}
}
else {
- VLOG_NO_PREFIX(log, "looking for NO wildcard proof"<<endl);
+ VLOG_NO_PREFIX(log, "looking for NO wildcard proof" << endl);
if (provesNoWildCard(qname, qtype, closestEncloser, validrrsets, log)) {
return dState::NXDOMAIN;
}
}
- VLOG(log, qname << ": But the existence of a wildcard is not denied for "<<qname<<"/"<<endl);
+ VLOG(log, qname << ": But the existence of a wildcard is not denied for " << qname << "/" << endl);
return dState::NODENIAL;
}
- VLOG(log, qname << ": Did not deny existence of "<<QType(qtype)<<", "<<validset.first.first<<"?="<<qname<<", "<<nsec->isSet(qtype)<<", next: "<<nsec->d_next<<endl);
+ VLOG(log, qname << ": Did not deny existence of " << QType(qtype) << ", " << validset.first.first << "?=" << qname << ", " << nsec->isSet(qtype) << ", next: " << nsec->d_next << endl);
}
- } else if(validset.first.second==QType::NSEC3) {
+ }
+ else if (validset.first.second == QType::NSEC3) {
for (const auto& record : validset.second.records) {
- VLOG(log, qname << ":\t"<<record->getZoneRepresentation()<<endl);
+ VLOG(log, qname << ":\t" << record->getZoneRepresentation() << endl);
auto nsec3 = std::dynamic_pointer_cast<const NSEC3RecordContent>(record);
if (!nsec3) {
continue;
const DNSName& hashedOwner = validset.first.first;
const DNSName signer = getSigner(validset.second.signatures);
if (!hashedOwner.isPartOf(signer)) {
- VLOG(log, qname << ": Owner "<<hashedOwner<<" is not part of the signer "<<signer<<", ignoring"<<endl);
+ VLOG(log, qname << ": Owner " << hashedOwner << " is not part of the signer " << signer << ", ignoring" << endl);
continue;
}
numberOfLabelsOfParentZone = std::min(numberOfLabelsOfParentZone, static_cast<uint8_t>(signer.countLabels()));
}
if (qtype == QType::DS && !qname.isRoot() && signer == qname) {
- VLOG(log, qname << ": A NSEC3 RR from the child zone cannot deny the existence of a DS"<<endl);
+ VLOG(log, qname << ": A NSEC3 RR from the child zone cannot deny the existence of a DS" << endl);
continue;
}
if (g_maxNSEC3sPerRecordToConsider > 0 && nsec3sConsidered >= g_maxNSEC3sPerRecordToConsider) {
- VLOG(log, qname << ": Too many NSEC3s for this record"<<endl);
+ VLOG(log, qname << ": Too many NSEC3s for this record" << endl);
context.d_limitHit = true;
return dState::NODENIAL;
}
string hash = getHashFromNSEC3(qname, *nsec3, context);
if (hash.empty()) {
- VLOG(log, qname << ": Unsupported hash, ignoring"<<endl);
+ VLOG(log, qname << ": Unsupported hash, ignoring" << endl);
return dState::INSECURE;
}
nsec3Seen = true;
- VLOG(log, qname << ":\tquery hash: "<<toBase32Hex(hash)<<endl);
+ VLOG(log, qname << ":\tquery hash: " << toBase32Hex(hash) << endl);
string beginHash = fromBase32Hex(hashedOwner.getRawLabel(0));
// If the name exists, check if the qtype is denied
*/
const bool notApex = signer.countLabels() < qname.countLabels();
if (notApex && nsec3->isSet(QType::NS) && nsec3->isSet(QType::SOA)) {
- VLOG(log, qname << ": However, that NSEC3 is not at the apex and has both the NS and the SOA bits set!"<<endl);
+ VLOG(log, qname << ": However, that NSEC3 is not at the apex and has both the NS and the SOA bits set!" << endl);
continue;
}
*/
if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, qname, *nsec3)) {
/* this is an "ancestor delegation" NSEC3 RR */
- VLOG(log, qname << ": An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
+ VLOG(log, qname << ": An ancestor delegation NSEC3 RR can only deny the existence of a DS" << endl);
return dState::NODENIAL;
}
if (!isTypeDenied(*nsec3, QType(qtype))) {
- VLOG(log, qname << ": Does _not_ deny existence of type "<<QType(qtype)<<" for name "<<qname<<" (not opt-out)."<<endl);
+ VLOG(log, qname << ": Does _not_ deny existence of type " << QType(qtype) << " for name " << qname << " (not opt-out)." << endl);
return dState::NODENIAL;
}
- VLOG(log, qname << ": Denies existence of type "<<QType(qtype)<<" for name "<<qname<<" (not opt-out)."<<endl);
+ VLOG(log, qname << ": Denies existence of type " << QType(qtype) << " for name " << qname << " (not opt-out)." << endl);
/*
* RFC 5155 section 8.9:
*/
if (referralToUnsigned && qtype == QType::DS) {
if (!nsec3->isSet(QType::NS)) {
- VLOG(log, qname << ": However, no NS record exists at this level!"<<endl);
+ VLOG(log, qname << ": However, no NS record exists at this level!" << endl);
return dState::NODENIAL;
}
}
RFC 5155 section-7.2.1
RFC 7129 section-5.5
*/
- VLOG(log, qname << ": Now looking for the closest encloser for "<<qname<<endl);
+ VLOG(log, qname << ": Now looking for the closest encloser for " << qname << endl);
while (!found && closestEncloser.chopOff() && closestEncloser.countLabels() >= numberOfLabelsOfParentZone) {
nsec3sConsidered = 0;
- for(const auto& validset : validrrsets) {
- if(validset.first.second==QType::NSEC3) {
- for(const auto& record : validset.second.records) {
- VLOG(log, qname << ":\t"<<record->getZoneRepresentation()<<endl);
+ for (const auto& validset : validrrsets) {
+ if (validset.first.second == QType::NSEC3) {
+ for (const auto& record : validset.second.records) {
+ VLOG(log, qname << ":\t" << record->getZoneRepresentation() << endl);
auto nsec3 = std::dynamic_pointer_cast<const NSEC3RecordContent>(record);
if (!nsec3) {
continue;
const DNSName signer = getSigner(validset.second.signatures);
if (!validset.first.first.isPartOf(signer)) {
- VLOG(log, qname << ": Owner "<<validset.first.first<<" is not part of the signer "<<signer<<", ignoring"<<endl);
+ VLOG(log, qname << ": Owner " << validset.first.first << " is not part of the signer " << signer << ", ignoring" << endl);
continue;
}
}
if (g_maxNSEC3sPerRecordToConsider > 0 && nsec3sConsidered >= g_maxNSEC3sPerRecordToConsider) {
- VLOG(log, qname << ": Too many NSEC3s for this record"<<endl);
+ VLOG(log, qname << ": Too many NSEC3s for this record" << endl);
context.d_limitHit = true;
return dState::NODENIAL;
}
string hash = getHashFromNSEC3(closestEncloser, *nsec3, context);
if (hash.empty()) {
- VLOG(log, qname << ": Unsupported hash, ignoring"<<endl);
+ VLOG(log, qname << ": Unsupported hash, ignoring" << endl);
return dState::INSECURE;
}
- string beginHash=fromBase32Hex(validset.first.first.getRawLabel(0));
+ string beginHash = fromBase32Hex(validset.first.first.getRawLabel(0));
- VLOG(log, qname << ": Comparing "<<toBase32Hex(hash)<<" ("<<closestEncloser<<") against "<<toBase32Hex(beginHash)<<endl);
+ VLOG(log, qname << ": Comparing " << toBase32Hex(hash) << " (" << closestEncloser << ") against " << toBase32Hex(beginHash) << endl);
if (beginHash == hash) {
/* If the closest encloser is a delegation NS we know nothing about the names in the child zone. */
if (isNSEC3AncestorDelegation(signer, validset.first.first, *nsec3)) {
- VLOG(log, qname << ": An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
+ VLOG(log, qname << ": An ancestor delegation NSEC3 RR can only deny the existence of a DS" << endl);
continue;
}
- VLOG(log, qname << ": Closest encloser for "<<qname<<" is "<<closestEncloser<<endl);
+ VLOG(log, qname << ": Closest encloser for " << qname << " is " << closestEncloser << endl);
found = true;
if (nsec3->isSet(QType::DNAME)) {
asserted, then DNAME substitution should have been done, but the
substitution has not been done as specified.
*/
- VLOG(log, qname << ":\tThe closest encloser NSEC3 has the DNAME bit is set"<<endl);
+ VLOG(log, qname << ":\tThe closest encloser NSEC3 has the DNAME bit is set" << endl);
return dState::NODENIAL;
}
DNSName nextCloser(closestEncloser);
nextCloser.prependRawLabel(qname.getRawLabel(labelIdx - 1));
nsec3sConsidered = 0;
- VLOG(log, qname << ":Looking for a NSEC3 covering the next closer name "<<nextCloser<<endl);
+ VLOG(log, qname << ":Looking for a NSEC3 covering the next closer name " << nextCloser << endl);
for (const auto& validset : validrrsets) {
if (validset.first.second == QType::NSEC3) {
for (const auto& record : validset.second.records) {
- VLOG(log, qname << ":\t"<<record->getZoneRepresentation()<<endl);
+ VLOG(log, qname << ":\t" << record->getZoneRepresentation() << endl);
auto nsec3 = std::dynamic_pointer_cast<const NSEC3RecordContent>(record);
if (!nsec3) {
continue;
}
if (g_maxNSEC3sPerRecordToConsider > 0 && nsec3sConsidered >= g_maxNSEC3sPerRecordToConsider) {
- VLOG(log, qname << ": Too many NSEC3s for this record"<<endl);
+ VLOG(log, qname << ": Too many NSEC3s for this record" << endl);
context.d_limitHit = true;
return dState::NODENIAL;
}
string hash = getHashFromNSEC3(nextCloser, *nsec3, context);
if (hash.empty()) {
- VLOG(log, qname << ": Unsupported hash, ignoring"<<endl);
+ VLOG(log, qname << ": Unsupported hash, ignoring" << endl);
return dState::INSECURE;
}
const DNSName signer = getSigner(validset.second.signatures);
if (!validset.first.first.isPartOf(signer)) {
- VLOG(log, qname << ": Owner "<<validset.first.first<<" is not part of the signer "<<signer<<", ignoring"<<endl);
+ VLOG(log, qname << ": Owner " << validset.first.first << " is not part of the signer " << signer << ", ignoring" << endl);
continue;
}
continue;
}
- string beginHash=fromBase32Hex(validset.first.first.getRawLabel(0));
+ string beginHash = fromBase32Hex(validset.first.first.getRawLabel(0));
- VLOG(log, qname << ": Comparing "<<toBase32Hex(hash)<<" against "<<toBase32Hex(beginHash)<<" -> "<<toBase32Hex(nsec3->d_nexthash)<<endl);
+ VLOG(log, qname << ": Comparing " << toBase32Hex(hash) << " against " << toBase32Hex(beginHash) << " -> " << toBase32Hex(nsec3->d_nexthash) << endl);
if (isCoveredByNSEC3Hash(hash, beginHash, nsec3->d_nexthash)) {
- VLOG(log, qname << ": Denies existence of name "<<qname<<"/"<<QType(qtype));
+ VLOG(log, qname << ": Denies existence of name " << qname << "/" << QType(qtype));
nextCloserFound = true;
if (nsec3->isOptOut()) {
VLOG_NO_PREFIX(log, endl);
break;
}
- VLOG(log, qname << ": Did not cover us ("<<qname<<"), start="<<validset.first.first<<", us="<<toBase32Hex(hash)<<", end="<<toBase32Hex(nsec3->d_nexthash)<<endl);
+ VLOG(log, qname << ": Did not cover us (" << qname << "), start=" << validset.first.first << ", us=" << toBase32Hex(hash) << ", end=" << toBase32Hex(nsec3->d_nexthash) << endl);
}
}
if (nextCloserFound) {
/* RFC 7129 section-5.6 */
if (needWildcardProof && !provesNSEC3NoWildCard(closestEncloser, qtype, validrrsets, &wildcardExists, log, context)) {
if (!isOptOut) {
- VLOG(log, qname << ": But the existence of a wildcard is not denied for "<<qname<<"/"<<QType(qtype)<<endl);
+ VLOG(log, qname << ": But the existence of a wildcard is not denied for " << qname << "/" << QType(qtype) << endl);
return dState::NODENIAL;
}
}
return rfc1982LessThanOrEqual<uint32_t>(sig.d_siginception - g_signatureInceptionSkew, static_cast<uint32_t>(now));
}
-namespace {
+namespace
+{
[[nodiscard]] bool checkSignatureInceptionAndExpiry(const DNSName& qname, time_t now, const RRSIGRecordContent& sig, vState& ede, const OptLog& log)
{
/* rfc4035:
return true;
}
ede = localEDE;
- VLOG(log, qname << ": Signature is "<<(ede == vState::BogusSignatureNotYetValid ? "not yet valid" : "expired")<<" (inception: "<<sig.d_siginception<<", inception skew: "<<g_signatureInceptionSkew<<", expiration: "<<sig.d_sigexpire<<", now: "<<now<<")"<<endl);
+ VLOG(log, qname << ": Signature is " << (ede == vState::BogusSignatureNotYetValid ? "not yet valid" : "expired") << " (inception: " << sig.d_siginception << ", inception skew: " << g_signatureInceptionSkew << ", expiration: " << sig.d_sigexpire << ", now: " << now << ")" << endl);
return false;
}
try {
auto dke = DNSCryptoKeyEngine::makeFromPublicKeyString(key.d_algorithm, key.d_key);
result = dke->verify(msg, sig.d_signature);
- VLOG(log, qname << ": Signature by key with tag "<<sig.d_tag<<" and algorithm "<<DNSSEC::algorithm2name(sig.d_algorithm)<<" was " << (result ? "" : "NOT ")<<"valid"<<endl);
+ VLOG(log, qname << ": Signature by key with tag " << sig.d_tag << " and algorithm " << DNSSEC::algorithm2name(sig.d_algorithm) << " was " << (result ? "" : "NOT ") << "valid" << endl);
if (!result) {
ede = vState::BogusNoValidRRSIG;
}
}
catch (const std::exception& e) {
- VLOG(log, qname << ": Could not make a validator for signature: "<<e.what()<<endl);
+ VLOG(log, qname << ": Could not make a validator for signature: " << e.what() << endl);
ede = vState::BogusUnsupportedDNSKEYAlgo;
}
return result;
}
-vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& toSign, const vector<shared_ptr<const RRSIGRecordContent> >& signatures, const skeyset_t& keys, const OptLog& log, pdns::validation::ValidationContext& context, bool validateAllSigs)
+vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& toSign, const vector<shared_ptr<const RRSIGRecordContent>>& signatures, const skeyset_t& keys, const OptLog& log, pdns::validation::ValidationContext& context, bool validateAllSigs)
{
bool missingKey = false;
bool isValid = false;
for (const auto& signature : signatures) {
unsigned int labelCount = name.countLabels();
if (signature->d_labels > labelCount) {
- VLOG(log, name<<": Discarding invalid RRSIG whose label count is "<<signature->d_labels<<" while the RRset owner name has only "<<labelCount<<endl);
+ VLOG(log, name << ": Discarding invalid RRSIG whose label count is " << signature->d_labels << " while the RRset owner name has only " << labelCount << endl);
continue;
}
vState ede = vState::Indeterminate;
if (!DNSCryptoKeyEngine::isAlgorithmSupported(signature->d_algorithm)) {
- continue;
+ continue;
}
if (!checkSignatureInceptionAndExpiry(name, now, *signature, ede, log)) {
if (isRRSIGIncepted(now, *signature)) {
}
if (g_maxRRSIGsPerRecordToConsider > 0 && signaturesConsidered >= g_maxRRSIGsPerRecordToConsider) {
- VLOG(log, name<<": We have already considered "<<std::to_string(signaturesConsidered)<<" RRSIG"<<addS(signaturesConsidered)<<" for this record, stopping now"<<endl;);
+ VLOG(log, name << ": We have already considered " << std::to_string(signaturesConsidered) << " RRSIG" << addS(signaturesConsidered) << " for this record, stopping now" << endl;);
// possibly going Bogus, the RRSIGs have not been validated so Insecure would be wrong
context.d_limitHit = true;
break;
auto keysMatchingTag = getByTag(keys, signature->d_tag, signature->d_algorithm, log);
if (keysMatchingTag.empty()) {
- VLOG(log, name << ": No key provided for "<<signature->d_tag<<" and algorithm "<<std::to_string(signature->d_algorithm)<<endl;);
+ VLOG(log, name << ": No key provided for " << signature->d_tag << " and algorithm " << std::to_string(signature->d_algorithm) << endl;);
missingKey = true;
continue;
}
uint16_t dnskeysConsidered = 0;
for (const auto& key : keysMatchingTag) {
if (g_maxDNSKEYsToConsider > 0 && dnskeysConsidered >= g_maxDNSKEYsToConsider) {
- VLOG(log, name << ": We have already considered "<<std::to_string(dnskeysConsidered)<<" DNSKEY"<<addS(dnskeysConsidered)<<" for tag "<<std::to_string(signature->d_tag)<<" and algorithm "<<std::to_string(signature->d_algorithm)<<", not considering the remaining ones for this signature"<<endl;);
+ VLOG(log, name << ": We have already considered " << std::to_string(dnskeysConsidered) << " DNSKEY" << addS(dnskeysConsidered) << " for tag " << std::to_string(signature->d_tag) << " and algorithm " << std::to_string(signature->d_algorithm) << ", not considering the remaining ones for this signature" << endl;);
if (!isValid) {
context.d_limitHit = true;
}
if (signIsValid) {
isValid = true;
- VLOG(log, name<< ": Validated "<<name<<"/"<<DNSRecordContent::NumberToType(signature->d_type)<<endl);
+ VLOG(log, name << ": Validated " << name << "/" << DNSRecordContent::NumberToType(signature->d_type) << endl);
// cerr<<"valid"<<endl;
// cerr<<"! validated "<<i->first.first<<"/"<<)<<endl;
}
else {
- VLOG(log, name << ": signature invalid"<<endl);
+ VLOG(log, name << ": signature invalid" << endl);
if (isRRSIGIncepted(now, *signature)) {
noneIncepted = false;
}
return vState::BogusNoValidRRSIG;
}
-bool getTrustAnchor(const map<DNSName,dsset_t>& anchors, const DNSName& zone, dsset_t &res)
+bool getTrustAnchor(const map<DNSName, dsset_t>& anchors, const DNSName& zone, dsset_t& res)
{
const auto& iter = anchors.find(zone);
return true;
}
-bool haveNegativeTrustAnchor(const map<DNSName,std::string>& negAnchors, const DNSName& zone, std::string& reason)
+bool haveNegativeTrustAnchor(const map<DNSName, std::string>& negAnchors, const DNSName& zone, std::string& reason)
{
const auto& iter = negAnchors.find(zone);
return true;
}
-vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsset_t& dsset, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector<shared_ptr<const RRSIGRecordContent> >& sigs, skeyset_t& validkeys, const OptLog& log, pdns::validation::ValidationContext& context) // NOLINT(readability-function-cognitive-complexity)
+vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsset_t& dsset, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector<shared_ptr<const RRSIGRecordContent>>& sigs, skeyset_t& validkeys, const OptLog& log, pdns::validation::ValidationContext& context) // NOLINT(readability-function-cognitive-complexity)
{
/*
* Check all DNSKEY records against all DS records and place all DNSKEY records
uint16_t dssConsidered = 0;
for (const auto& dsrc : dsset) {
if (g_maxDSsToConsider > 0 && dssConsidered > g_maxDSsToConsider) {
- VLOG(log, zone << ": We have already considered "<<std::to_string(dssConsidered)<<" DS"<<addS(dssConsidered)<<", not considering the remaining ones"<<endl;);
+ VLOG(log, zone << ": We have already considered " << std::to_string(dssConsidered) << " DS" << addS(dssConsidered) << ", not considering the remaining ones" << endl;);
return vState::BogusNoValidDNSKEY;
}
++dssConsidered;
DSRecordContent dsrc2;
if (g_maxDNSKEYsToConsider > 0 && dnskeysConsidered >= g_maxDNSKEYsToConsider) {
- VLOG(log, zone << ": We have already considered "<<std::to_string(dnskeysConsidered)<<" DNSKEY"<<addS(dnskeysConsidered)<<" for tag "<<std::to_string(dsrc.d_tag)<<" and algorithm "<<std::to_string(dsrc.d_algorithm)<<", not considering the remaining ones for this DS"<<endl;);
+ VLOG(log, zone << ": We have already considered " << std::to_string(dnskeysConsidered) << " DNSKEY" << addS(dnskeysConsidered) << " for tag " << std::to_string(dsrc.d_tag) << " and algorithm " << std::to_string(dsrc.d_algorithm) << ", not considering the remaining ones for this DS" << endl;);
// we need to break because we can have a partially validated set
// where the KSK signs the ZSK(s), and even if we don't
// we are going to try to get the correct EDE status (revoked, expired, ...)
dsCreated = true;
isValid = dsrc.operator==(dsrc2);
}
- catch (const std::exception &e) {
- VLOG(log, zone << ": Unable to make DS from DNSKey: "<<e.what()<<endl);
+ catch (const std::exception& e) {
+ VLOG(log, zone << ": Unable to make DS from DNSKey: " << e.what() << endl);
}
if (isValid) {
- VLOG(log, zone << ": got valid DNSKEY (it matches the DS) with tag "<<dsrc.d_tag<<" and algorithm "<<std::to_string(dsrc.d_algorithm)<<" for "<<zone<<endl);
+ VLOG(log, zone << ": got valid DNSKEY (it matches the DS) with tag " << dsrc.d_tag << " and algorithm " << std::to_string(dsrc.d_algorithm) << " for " << zone << endl);
validkeys.insert(drc);
}
else {
if (dsCreated) {
- VLOG(log, zone << ": DNSKEY did not match the DS, parent DS: "<<dsrc.getZoneRepresentation() << " ! = "<<dsrc2.getZoneRepresentation()<<endl);
+ VLOG(log, zone << ": DNSKEY did not match the DS, parent DS: " << dsrc.getZoneRepresentation() << " ! = " << dsrc2.getZoneRepresentation() << endl);
}
}
}
}
if (g_maxRRSIGsPerRecordToConsider > 0 && signaturesConsidered >= g_maxRRSIGsPerRecordToConsider) {
- VLOG(log, zone << ": We have already considered "<<std::to_string(signaturesConsidered)<<" RRSIG"<<addS(signaturesConsidered)<<" for this record, stopping now"<<endl;);
+ VLOG(log, zone << ": We have already considered " << std::to_string(signaturesConsidered) << " RRSIG" << addS(signaturesConsidered) << " for this record, stopping now" << endl;);
// possibly going Bogus, the RRSIGs have not been validated so Insecure would be wrong
context.d_limitHit = true;
return vState::BogusNoValidDNSKEY;
uint16_t dnskeysConsidered = 0;
for (const auto& key : bytag) {
if (g_maxDNSKEYsToConsider > 0 && dnskeysConsidered >= g_maxDNSKEYsToConsider) {
- VLOG(log, zone << ": We have already considered "<<std::to_string(dnskeysConsidered)<<" DNSKEY"<<addS(dnskeysConsidered)<<" for tag "<<std::to_string(sig->d_tag)<<" and algorithm "<<std::to_string(sig->d_algorithm)<<", not considering the remaining ones for this signature"<<endl;);
+ VLOG(log, zone << ": We have already considered " << std::to_string(dnskeysConsidered) << " DNSKEY" << addS(dnskeysConsidered) << " for tag " << std::to_string(sig->d_tag) << " and algorithm " << std::to_string(sig->d_algorithm) << ", not considering the remaining ones for this signature" << endl;);
context.d_limitHit = true;
return vState::BogusNoValidDNSKEY;
}
dnskeysConsidered++;
if (g_maxRRSIGsPerRecordToConsider > 0 && signaturesConsidered >= g_maxRRSIGsPerRecordToConsider) {
- VLOG(log, zone << ": We have already considered "<<std::to_string(signaturesConsidered)<<" RRSIG"<<addS(signaturesConsidered)<<" for this record, stopping now"<<endl;);
+ VLOG(log, zone << ": We have already considered " << std::to_string(signaturesConsidered) << " RRSIG" << addS(signaturesConsidered) << " for this record, stopping now" << endl;);
// possibly going Bogus, the RRSIGs have not been validated so Insecure would be wrong
context.d_limitHit = true;
return vState::BogusNoValidDNSKEY;
context.d_validationsCounter++;
if (signIsValid) {
- VLOG(log, zone << ": Validation succeeded - whole DNSKEY set is valid"<<endl);
+ VLOG(log, zone << ": Validation succeeded - whole DNSKEY set is valid" << endl);
validkeys = tkeys;
break;
}
- VLOG(log, zone << ": Validation did not succeed!"<<endl);
+ VLOG(log, zone << ": Validation did not succeed!" << endl);
}
if (validkeys.size() == tkeys.size()) {
bool dnskeyAlgoSupported = false;
bool dsDigestSupported = false;
- for (const auto& dsrc : dsset)
- {
+ for (const auto& dsrc : dsset) {
if (DNSCryptoKeyEngine::isAlgorithmSupported(dsrc.d_algorithm)) {
dnskeyAlgoSupported = true;
if (DNSCryptoKeyEngine::isDigestSupported(dsrc.d_digesttype)) {
bool isSupportedDS(const DSRecordContent& dsrec, const OptLog& log)
{
if (!DNSCryptoKeyEngine::isAlgorithmSupported(dsrec.d_algorithm)) {
- VLOG(log, "Discarding DS "<<dsrec.d_tag<<" because we don't support algorithm number "<<std::to_string(dsrec.d_algorithm)<<endl);
+ VLOG(log, "Discarding DS " << dsrec.d_tag << " because we don't support algorithm number " << std::to_string(dsrec.d_algorithm) << endl);
return false;
}
if (!DNSCryptoKeyEngine::isDigestSupported(dsrec.d_digesttype)) {
- VLOG(log, "Discarding DS "<<dsrec.d_tag<<" because we don't support digest number "<<std::to_string(dsrec.d_digesttype)<<endl);
+ VLOG(log, "Discarding DS " << dsrec.d_tag << " because we don't support digest number " << std::to_string(dsrec.d_digesttype) << endl);
return false;
}
return true;
}
-DNSName getSigner(const std::vector<std::shared_ptr<const RRSIGRecordContent> >& signatures)
+DNSName getSigner(const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures)
{
for (const auto& sig : signatures) {
if (sig) {
const std::string& vStateToString(vState state)
{
- static const std::vector<std::string> vStates = {"Indeterminate", "Insecure", "Secure", "NTA", "TA", "Bogus - No valid DNSKEY", "Bogus - Invalid denial", "Bogus - Unable to get DSs", "Bogus - Unable to get DNSKEYs", "Bogus - Self Signed DS", "Bogus - No RRSIG", "Bogus - No valid RRSIG", "Bogus - Missing negative indication", "Bogus - Signature not yet valid", "Bogus - Signature expired", "Bogus - Unsupported DNSKEY algorithm", "Bogus - Unsupported DS digest type", "Bogus - No zone key bit set", "Bogus - Revoked DNSKEY", "Bogus - Invalid DNSKEY Protocol" };
+ static const std::vector<std::string> vStates = {"Indeterminate", "Insecure", "Secure", "NTA", "TA", "Bogus - No valid DNSKEY", "Bogus - Invalid denial", "Bogus - Unable to get DSs", "Bogus - Unable to get DNSKEYs", "Bogus - Self Signed DS", "Bogus - No RRSIG", "Bogus - No valid RRSIG", "Bogus - Missing negative indication", "Bogus - Signature not yet valid", "Bogus - Signature expired", "Bogus - Unsupported DNSKEY algorithm", "Bogus - Unsupported DS digest type", "Bogus - No zone key bit set", "Bogus - Revoked DNSKEY", "Bogus - Invalid DNSKEY Protocol"};
return vStates.at(static_cast<size_t>(state));
}
-std::ostream& operator<<(std::ostream &ostr, const vState dstate)
+std::ostream& operator<<(std::ostream& ostr, const vState dstate)
{
- ostr<<vStateToString(dstate);
+ ostr << vStateToString(dstate);
return ostr;
}
-std::ostream& operator<<(std::ostream &ostr, const dState dstate)
+std::ostream& operator<<(std::ostream& ostr, const dState dstate)
{
static const std::vector<std::string> dStates = {"no denial", "inconclusive", "nxdomain", "nxqtype", "empty non-terminal", "insecure", "opt-out"};
- ostr<<dStates.at(static_cast<size_t>(dstate));
+ ostr << dStates.at(static_cast<size_t>(dstate));
return ostr;
}