]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/validate-recursor.cc
2 #include "validate-recursor.hh"
6 DNSSECMode g_dnssecmode
{ DNSSECMode :: ProcessNoValidate
};
9 #define LOG(x) if(g_dnssecLOG) { L <<Logger::Warning << x; }
11 class SRRecordOracle
: public DNSRecordOracle
14 SRRecordOracle ( const ResolveContext
& ctx
): d_ctx ( ctx
)
17 vector
< DNSRecord
> get ( const DNSName
& qname
, uint16_t qtype
) override
22 sr
. setId ( MT
-> getTid ());
24 sr
. d_initialRequestId
= d_ctx
. d_initialRequestId
;
27 vector
< DNSRecord
> ret
;
29 if ( qtype
== QType :: DS
|| qtype
== QType :: DNSKEY
|| qtype
== QType :: NS
)
30 sr
. setSkipCNAMECheck ( true );
31 sr
. beginResolve ( qname
, QType ( qtype
), 1 , ret
);
32 d_queries
+= sr
. d_outqueries
;
35 const ResolveContext
& d_ctx
;
39 bool checkDNSSECDisabled () {
40 return warnIfDNSSECDisabled ( "" );
43 bool warnIfDNSSECDisabled ( const string
& msg
) {
44 if ( g_dnssecmode
== DNSSECMode :: Off
) {
46 L
<< Logger :: Warning
<< msg
<< endl
;
52 inline vState
increaseDNSSECStateCounter ( const vState
& state
)
54 g_stats
. dnssecResults
[ state
]++;
59 * This inline possibly sets currentState based on the new state. It will only
60 * set it to Secure iff the newState is Secure and mayUpgradeToSecure == true.
61 * This should be set by the calling function when checking more than one record
62 * and this is not the first record, this way, we can never go *back* to Secure
63 * from an Insecure vState
65 inline void processNewState ( vState
& currentState
, const vState
& newState
, bool & hadNTA
, const bool & mayUpgradeToSecure
)
67 if ( mayUpgradeToSecure
&& newState
== Secure
)
68 currentState
= Secure
;
70 if ( newState
== Insecure
|| newState
== NTA
) // We can never go back to Secure
71 currentState
= Insecure
;
77 vState
validateRecords ( const ResolveContext
& ctx
, const vector
< DNSRecord
>& recs
)
80 return Insecure
; // can't secure nothing
82 g_stats
. dnssecValidations
++;
84 cspmap_t cspmap
= harvestCSPFromRecs ( recs
);
85 LOG ( "Got " << cspmap
. size ()<< " RRSETs: " << endl
);
87 for ( const auto & csp
: cspmap
) {
88 LOG ( "Going to validate: " << csp
. first
. first
<< "/" << DNSRecordContent :: NumberToType ( csp
. first
. second
)<< ": " << csp
. second
. signatures
. size ()<< " sigs for " << csp
. second
. records
. size ()<< " records" << endl
);
89 numsigs
+= csp
. second
. signatures
. size ();
92 set
< DNSKEYRecordContent
> keys
;
95 SRRecordOracle
sro ( ctx
);
97 vState state
= Insecure
;
101 for ( const auto & csp
: cspmap
) {
102 for ( const auto & sig
: csp
. second
. signatures
) {
103 vState newState
= getKeysFor ( sro
, sig
-> d_signer
, keys
); // XXX check validity here
105 if ( newState
== Bogus
) // No hope
106 return increaseDNSSECStateCounter ( Bogus
);
108 processNewState ( state
, newState
, hadNTA
, first
);
112 LOG ( "! state = " << vStates
[ state
]<< ", now have " << keys
. size ()<< " keys" << endl
);
113 for ( const auto & k
: keys
) {
114 LOG ( "Key: " << k
. getZoneRepresentation ()<< " {tag=" << k
. getTag ()<< "}" << endl
);
118 validateWithKeySet ( cspmap
, validrrsets
, keys
);
121 LOG ( "! no sigs, hoping for Insecure status of " << recs
. begin ()-> d_name
<< endl
);
124 for ( const auto & rec
: recs
) {
125 vState newState
= getKeysFor ( sro
, rec
. d_name
, keys
);
127 if ( newState
== Bogus
) // We're done
128 return increaseDNSSECStateCounter ( Bogus
);
130 processNewState ( state
, newState
, hadNTA
, first
);
133 LOG ( "! state = " << vStates
[ state
]<< ", now have " << keys
. size ()<< " keys " << endl
);
135 return increaseDNSSECStateCounter ( state
);
138 LOG ( "Took " << sro
. d_queries
<< " queries" << endl
);
139 if ( validrrsets
. size () == cspmap
. size ()) // shortcut - everything was ok
140 return increaseDNSSECStateCounter ( Secure
);
142 if ( state
== Insecure
|| keys
. empty ()) {
144 increaseDNSSECStateCounter ( NTA
);
147 return increaseDNSSECStateCounter ( Insecure
);
151 cerr
<< "! validated " << validrrsets
. size ()<< " RRsets out of " << cspmap
. size ()<< endl
;
153 cerr
<< "% validated RRs:" << endl
;
154 for ( auto i
= validrrsets
. begin (); i
!= validrrsets
. end (); i
++) {
155 cerr
<< "% " << i
-> first
. first
<< "/" << DNSRecordContent :: NumberToType ( i
-> first
. second
)<< endl
;
156 for ( auto j
= i
-> second
. records
. begin (); j
!= i
-> second
. records
. end (); j
++) {
157 cerr
<< " \t % > " <<(* j
)-> getZoneRepresentation ()<< endl
;
161 // cerr<<"Input to validate: "<<endl;
162 for ( const auto & csp
: cspmap
) {
163 LOG ( csp
. first
. first
<< "|" << DNSRecordContent :: NumberToType ( csp
. first
. second
)<< " with " << csp
. second
. signatures
. size ()<< " signatures" << endl
);
164 if (! csp
. second
. signatures
. empty () && ! validrrsets
. count ( csp
. first
)) {
165 LOG ( "Lacks signature, must have one, signatures: " << csp
. second
. signatures
. size ()<< ", valid rrsets: " << validrrsets
. count ( csp
. first
)<< endl
);
166 return increaseDNSSECStateCounter ( Bogus
);
169 return increaseDNSSECStateCounter ( Insecure
);