From: Otto Date: Mon, 22 Feb 2021 14:24:35 +0000 (+0100) Subject: Add validation state to protobuf message. X-Git-Tag: dnsdist-1.6.0-alpha2~16^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e6271507a96ebcd354317f62713b6643d9cff37;p=thirdparty%2Fpdns.git Add validation state to protobuf message. Fixes #8587. --- diff --git a/pdns/dnsmessage.proto b/pdns/dnsmessage.proto index e14dda908a..c92254d7e4 100644 --- a/pdns/dnsmessage.proto +++ b/pdns/dnsmessage.proto @@ -45,6 +45,28 @@ message PBDNSMessage { Truncate= 5; // https://tools.ietf.org/html/draft-vixie-dns-rpz-04 3.5 Custom = 6; // https://tools.ietf.org/html/draft-vixie-dns-rpz-04 3.6 } + enum VState { + Indeterminate = 1; + Insecure = 2; + Secure = 3; + NTA = 4; + TA = 5; + BogusNoValidDNSKEY = 6; + BogusInvalidDenial = 7; + BogusUnableToGetDSs = 8; + BogusUnableToGetDNSKEYs = 9; + BogusSelfSignedDS = 10; + BogusNoRRSIG = 11; + BogusNoValidRRSIG = 12; + BogusMissingNegativeIndication = 13; + BogusSignatureNotYetValid = 14; + BogusSignatureExpired = 15; + BogusUnsupportedDNSKEYAlgo = 16; + BogusUnsupportedDSDigestType = 17; + BogusNoZoneKeyBitSet = 18; + BogusRevokedDNSKEY = 19; + BogusInvalidDNSKEYProtocol = 20; + } required Type type = 1; optional bytes messageId = 2; // UUID, shared by the query and the response optional bytes serverIdentity = 3; // ID of the server emitting the protobuf message @@ -83,6 +105,7 @@ message PBDNSMessage { optional string appliedPolicyTrigger = 8; // The RPZ trigger optional string appliedPolicyHit = 9; // The value (qname or IP) that caused the hit optional PolicyKind appliedPolicyKind = 10; // The Kind (RPZ action) applied by the hit + optional VState validationState = 11; // The DNSSEC Validation State } optional DNSResponse response = 13; diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index a6c093204d..9a61ddac21 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -2065,6 +2065,7 @@ static void startDoResolve(void *p) } pbMessage.addPolicyTags(dc->d_policyTags); pbMessage.setInBytes(packet.size()); + pbMessage.setValidationState(sr.getValidationState()); // Take s snap of the current protobuf buffer state to store in the PC pbDataForCache = boost::make_optional(RecursorPacketCache::PBData{ diff --git a/pdns/protozero.hh b/pdns/protozero.hh index a5e3e0e081..53547bf402 100644 --- a/pdns/protozero.hh +++ b/pdns/protozero.hh @@ -35,7 +35,7 @@ namespace pdns { enum class MessageType : int32_t { DNSQueryType = 1, DNSResponseType = 2, DNSOutgoingQueryType = 3, DNSIncomingResponseType = 4 }; enum class Field : protozero::pbf_tag_type { type = 1, messageId = 2, serverIdentity = 3, socketFamily = 4, socketProtocol = 5, from = 6, to = 7, inBytes = 8, timeSec = 9, timeUsec = 10, id = 11, question = 12, response = 13, originalRequestorSubnet = 14, requestorId = 15, initialRequestId = 16, deviceId = 17, newlyObservedDomain = 18, deviceName = 19, fromPort = 20, toPort = 21 }; enum class QuestionField : protozero::pbf_tag_type { qName = 1, qType = 2, qClass = 3}; - enum class ResponseField : protozero::pbf_tag_type { rcode = 1, rrs = 2, appliedPolicy = 3, tags = 4, queryTimeSec = 5, queryTimeUsec = 6, appliedPolicyType = 7, appliedPolicyTrigger = 8, appliedPolicyHit = 9, appliedPolicyKind = 10 }; + enum class ResponseField : protozero::pbf_tag_type { rcode = 1, rrs = 2, appliedPolicy = 3, tags = 4, queryTimeSec = 5, queryTimeUsec = 6, appliedPolicyType = 7, appliedPolicyTrigger = 8, appliedPolicyHit = 9, appliedPolicyKind = 10, validationState = 11 }; enum class RRField : protozero::pbf_tag_type { name = 1, type = 2, class_ = 3, ttl = 4, rdata = 5, udr = 6 }; Message(std::string& buffer): d_buffer(buffer), d_message{d_buffer} diff --git a/pdns/recursordist/rec-protozero.hh b/pdns/recursordist/rec-protozero.hh index 8794c2142a..6bfb9d170b 100644 --- a/pdns/recursordist/rec-protozero.hh +++ b/pdns/recursordist/rec-protozero.hh @@ -24,6 +24,7 @@ #include "protozero.hh" #include "filterpo.hh" +#include "validate.hh" namespace pdns { @@ -170,6 +171,77 @@ namespace ProtoZero d_response.add_uint32(static_cast(ResponseField::appliedPolicyKind), k); } + void setValidationState(const vState state) + { + uint32_t s; + + switch (state) { + case vState::Indeterminate: + s = 1; + break; + case vState::Insecure: + s = 2; + break; + case vState::Secure: + s = 3; + break; + case vState::NTA: + s = 4; + break; + case vState::TA: + s = 5; + break; + case vState::BogusNoValidDNSKEY: + s = 6; + break; + case vState::BogusInvalidDenial: + s = 7; + break; + case vState::BogusUnableToGetDSs: + s = 8; + break; + case vState::BogusUnableToGetDNSKEYs: + s = 9; + break; + case vState::BogusSelfSignedDS: + s = 10; + break; + case vState::BogusNoRRSIG: + s = 11; + break; + case vState::BogusNoValidRRSIG: + s = 12; + break; + case vState::BogusMissingNegativeIndication: + s = 13; + break; + case vState::BogusSignatureNotYetValid: + s = 14; + break; + case vState::BogusSignatureExpired: + s = 15; + break; + case vState::BogusUnsupportedDNSKEYAlgo: + s = 16; + break; + case vState::BogusUnsupportedDSDigestType: + s = 17; + break; + case vState::BogusNoZoneKeyBitSet: + s = 18; + break; + case vState::BogusRevokedDNSKEY: + s = 19; + break; + case vState::BogusInvalidDNSKEYProtocol: + s = 20; + break; + default: + throw std::runtime_error("Unsupported protobuf validation state"); + } + d_response.add_uint32(static_cast(ResponseField::validationState), s); + } + #ifdef NOD_ENABLED void clearUDR(std::string&); #endif diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index e8baee327d..805fab78a1 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -176,11 +176,13 @@ class TestRecursorProtobuf(RecursorTest): self.assertTrue(msg.question.HasField('qName')) self.assertEquals(msg.question.qName, qname) - def checkProtobufResponse(self, msg, protocol, response, initiator='127.0.0.1', receivedSize=None): + def checkProtobufResponse(self, msg, protocol, response, initiator='127.0.0.1', receivedSize=None, vstate=dnsmessage_pb2.PBDNSMessage.VState.Indeterminate): self.assertEquals(msg.type, dnsmessage_pb2.PBDNSMessage.DNSResponseType) self.checkProtobufBase(msg, protocol, response, initiator, receivedSize=receivedSize) self.assertTrue(msg.HasField('response')) self.assertTrue(msg.response.HasField('queryTimeSec')) + self.assertTrue(msg.response.HasField('validationState')) + self.assertEquals(msg.response.validationState, vstate) def checkProtobufResponseRecord(self, record, rclass, rtype, rname, rttl, checkTTL=True): self.assertTrue(record.HasField('class'))