A dnsreq is bogus if any of its netreqs is

This commit is contained in:
Willem Toorop 2017-09-20 14:42:35 +02:00
parent 17d7ee79f2
commit 36943a4380
3 changed files with 44 additions and 28 deletions

View File

@ -3036,6 +3036,17 @@ static inline chain_node *_to_the_root(chain_node *node)
return node; return node;
} }
int _getdns_bogus(getdns_dns_req *dnsreq)
{
getdns_network_req **netreq_p, *netreq;
for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
if (netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
return 1;
}
return 0;
}
static void check_chain_complete(chain_head *chain) static void check_chain_complete(chain_head *chain)
{ {
getdns_dns_req *dnsreq; getdns_dns_req *dnsreq;
@ -3075,22 +3086,13 @@ static void check_chain_complete(chain_head *chain)
} }
} }
#ifdef STUB_NATIVE_DNSSEC #ifdef STUB_NATIVE_DNSSEC
/* Perform validation only on GETDNS_RESOLUTION_STUB (unbound_id == -1) if (context->trust_anchors)
* Or when asked for the validation chain (to identify the RRSIGs that
* signed the RRSETs, so that only those will be included in the
* validation chain)
* In any case we must have a trust anchor.
*/
if (( chain->netreq->unbound_id == -1
|| dnsreq->dnssec_return_validation_chain)
&& context->trust_anchors)
chain_set_netreq_dnssec_status(chain,_getdns_rrset_iter_init(&tas_iter, chain_set_netreq_dnssec_status(chain,_getdns_rrset_iter_init(&tas_iter,
context->trust_anchors, context->trust_anchors_len, context->trust_anchors, context->trust_anchors_len,
SECTION_ANSWER)); SECTION_ANSWER));
#else #else
if (dnsreq->dnssec_return_validation_chain if (context->trust_anchors)
&& context->trust_anchors)
(void) chain_validate_dnssec(priv_getdns_context_mf(context), (void) chain_validate_dnssec(priv_getdns_context_mf(context),
time(NULL), context->dnssec_allowed_skew, time(NULL), context->dnssec_allowed_skew,
@ -3104,13 +3106,14 @@ static void check_chain_complete(chain_head *chain)
node->dnskey.name && *node->dnskey.name == 0) node->dnskey.name && *node->dnskey.name == 0)
_getdns_context_update_root_ksk(context,&node->dnskey); _getdns_context_update_root_ksk(context,&node->dnskey);
} else if (dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) { } else if (_getdns_bogus(dnsreq)) {
DEBUG_ANCHOR("Request was bogus!\n"); DEBUG_ANCHOR("Request was bogus!\n");
if ((head = chain) && (node = _to_the_root(head->parent)) if ((head = chain) && (node = _to_the_root(head->parent))
&& node->dnskey.name && *node->dnskey.name == 0 && node->dnskey.name && *node->dnskey.name == 0
&& node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS){ && node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS){
DEBUG_ANCHOR("ROOT DNSKEY set was bogus!\n"); DEBUG_ANCHOR("root DNSKEY set was bogus!\n");
if (!dnsreq->waiting_for_ta) { if (!dnsreq->waiting_for_ta) {
uint64_t now = 0; uint64_t now = 0;
@ -3143,7 +3146,7 @@ static void check_chain_complete(chain_head *chain)
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
if ( dnsreq->dnssec_roadblock_avoidance if ( dnsreq->dnssec_roadblock_avoidance
&& !dnsreq->avoid_dnssec_roadblocks && !dnsreq->avoid_dnssec_roadblocks
&& dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) { && _getdns_bogus(dnsreq)) {
getdns_network_req **netreq_p, *netreq; getdns_network_req **netreq_p, *netreq;
uint64_t now_ms = 0; uint64_t now_ms = 0;
@ -3381,6 +3384,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
if (dnsreq->avoid_dnssec_roadblocks && chain->lock == 0) if (dnsreq->avoid_dnssec_roadblocks && chain->lock == 0)
; /* pass */ ; /* pass */
else for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) { else for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
if (! netreq->response if (! netreq->response
|| netreq->response_len < GLDNS_HEADER_SIZE || netreq->response_len < GLDNS_HEADER_SIZE
@ -3391,7 +3395,10 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE; netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
continue; continue;
}
} else if (netreq->unbound_id != -1)
netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
add_pkt2val_chain( &dnsreq->my_mf, &chain add_pkt2val_chain( &dnsreq->my_mf, &chain
, netreq->response, netreq->response_len , netreq->response, netreq->response_len
, netreq , netreq

View File

@ -67,6 +67,8 @@ static inline int _dnssec_rdata_to_canonicalize(uint16_t rr_type)
|| rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG; || rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG;
} }
int _getdns_bogus(getdns_dns_req *dns_req);
#endif #endif
/* dnssec.h */ /* dnssec.h */

View File

@ -214,13 +214,15 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
#endif #endif
#ifdef STUB_NATIVE_DNSSEC #ifdef STUB_NATIVE_DNSSEC
|| (dns_req->context->resolution_type == GETDNS_RESOLUTION_STUB || ( dns_req->context->resolution_type == GETDNS_RESOLUTION_STUB
&& !dns_req->avoid_dnssec_roadblocks && !dns_req->avoid_dnssec_roadblocks
&& (dns_req->dnssec_return_status || && (dns_req->dnssec_return_status ||
dns_req->dnssec_return_only_secure || dns_req->dnssec_return_only_secure ||
dns_req->dnssec_return_all_statuses dns_req->dnssec_return_all_statuses
)) ))
#endif #endif
|| ( dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING
&& _getdns_bogus(dns_req))
)) { )) {
/* Reschedule timeout for this DNS request /* Reschedule timeout for this DNS request
*/ */
@ -236,6 +238,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
#if defined(REQ_DEBUG) && REQ_DEBUG #if defined(REQ_DEBUG) && REQ_DEBUG
debug_req("getting validation chain for ", *dns_req->netreqs); debug_req("getting validation chain for ", *dns_req->netreqs);
#endif #endif
DEBUG_ANCHOR("Valchain lookup\n");
_getdns_get_validation_chain(dns_req); _getdns_get_validation_chain(dns_req);
} else } else
_getdns_call_user_callback( _getdns_call_user_callback(
@ -594,22 +597,18 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
_getdns_context_equip_with_anchor(context, &now_ms); _getdns_context_equip_with_anchor(context, &now_ms);
if (context->trust_anchors_source == GETDNS_TASRC_NONE) { if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
_getdns_start_fetching_ta(context, loop); _getdns_start_fetching_ta(context, loop);
if (context->trust_anchors_source
== GETDNS_TASRC_FETCHING
&& context->resolution_type
== GETDNS_RESOLUTION_RECURSING
&& context->resolution_type
!= context->resolution_type_set) {
req->waiting_for_ta = 1;
req->ta_notify = context->ta_notify;
context->ta_notify = req;
return GETDNS_RETURN_GOOD;
}
} }
} }
} }
if (!usenamespaces) { if (!usenamespaces) {
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING
&& context->resolution_type == GETDNS_RESOLUTION_RECURSING
&& context->resolution_type != context->resolution_type_set) {
req->waiting_for_ta = 1;
req->ta_notify = context->ta_notify;
context->ta_notify = req;
return GETDNS_RETURN_GOOD;
}
(void) _getdns_context_prepare_for_resolution(context, 0); (void) _getdns_context_prepare_for_resolution(context, 0);
/* issue all network requests */ /* issue all network requests */
@ -660,6 +659,14 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
} }
#endif /* HAVE_MDNS_SUPPORT */ #endif /* HAVE_MDNS_SUPPORT */
} else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) { } else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) {
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING
&& context->resolution_type == GETDNS_RESOLUTION_RECURSING
&& context->resolution_type != context->resolution_type_set) {
req->waiting_for_ta = 1;
req->ta_notify = context->ta_notify;
context->ta_notify = req;
return GETDNS_RETURN_GOOD;
}
(void) _getdns_context_prepare_for_resolution(context, 0); (void) _getdns_context_prepare_for_resolution(context, 0);
/* TODO: We will get a good return code here even if /* TODO: We will get a good return code here even if