and validate them with the new data. Failure to find needed data here is an internal error.
Once we get to the original answer (FREC_DNSSEC_QUERY not set) and it validates,
return it to the original requestor. */
- if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
+ while (forward->dependent)
{
- while (forward->dependent)
+ struct frec *prev = forward->dependent;
+ free_frec(forward);
+ forward = prev;
+ forward->blocking_query = NULL; /* already gone */
+ blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
+ n = forward->stash_len;
+
+ if (status == STAT_SECURE)
{
- struct frec *prev;
+ if (forward->flags & FREC_DNSKEY_QUERY)
+ status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
+ else if (forward->flags & FREC_DS_QUERY)
+ status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
+ else
+ status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class);
- if (status == STAT_SECURE)
+ if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
{
- if (forward->flags & FREC_DNSKEY_QUERY)
- status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
- else if (forward->flags & FREC_DS_QUERY)
- status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
+ my_syslog(LOG_ERR, _("Unexpected missing data for DNSSEC validation"));
+ status = STAT_INSECURE;
}
-
- prev = forward->dependent;
- free_frec(forward);
- forward = prev;
- forward->blocking_query = NULL; /* already gone */
- blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
- n = forward->stash_len;
- }
-
- /* All DNSKEY and DS records done and in cache, now finally validate original
- answer, provided last DNSKEY is OK. */
- if (status == STAT_SECURE)
- status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class);
-
- if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
- {
- my_syslog(LOG_ERR, _("Unexpected missing data for DNSSEC validation"));
- status = STAT_INSECURE;
}
}
if (status == STAT_TRUNCATED)
- header->hb3 |= HB3_TC;
+ header->hb3 |= HB3_TC;
else
log_query(F_KEYTAG | F_SECSTAT, "result", NULL,
status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
}
else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
{
-#ifdef HAVE_DNSSEC
- if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
- (crecp->flags & F_DNSSECOK) &&
- !(crecp->flags & F_NEG) &&
- sec_reqd &&
- option_bool(OPT_DNSSEC_VALID))
+ if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd)
{
- int gotsig = 0;
-
- crecp = NULL;
- while ((crecp = cache_find_by_name(crecp, name, now, F_DS | F_DNSKEY)))
+ if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)))
+ crecp = NULL;
+#ifdef HAVE_DNSSEC
+ else if (crecp->flags & F_DNSSECOK)
{
- if (crecp->addr.sig.type_covered == T_PTR && crecp->uid == C_IN)
+ int gotsig = 0;
+
+ crecp = NULL;
+ while ((crecp = cache_find_by_name(crecp, name, now, F_DS | F_DNSKEY)))
{
- char *sigdata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL);
- gotsig = 1;
-
- if (!dryrun &&
- add_resource_record(header, limit, &trunc, nameoffset, &ansp,
- crecp->ttd - now, &nameoffset,
- T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
- anscount++;
- }
- }
- /* Need to re-run original cache search */
- crecp = gotsig ? cache_find_by_addr(NULL, &addr, now, is_arpa) : NULL;
+ if (crecp->addr.sig.type_covered == T_PTR && crecp->uid == C_IN)
+ {
+ char *sigdata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL);
+ gotsig = 1;
+
+ if (!dryrun &&
+ add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ crecp->ttd - now, &nameoffset,
+ T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
+ anscount++;
+ }
+ }
+ /* Need to re-run original cache search */
+ crecp = gotsig ? cache_find_by_addr(NULL, &addr, now, is_arpa) : NULL;
+ }
}
#endif
crecp = save;
}
-#ifdef HAVE_DNSSEC
- if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
- (crecp->flags & F_DNSSECOK) &&
- !(crecp->flags & F_NEG) &&
- sec_reqd &&
- option_bool(OPT_DNSSEC_VALID))
+ /* If the client asked for DNSSEC and we can't provide RRSIGs, either
+ because we've not doing DNSSEC or the cached answer is signed by negative,
+ don't answer from the cache, forward instead. */
+ if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd)
{
- /* We're returning validated data, need to return the RRSIG too. */
-
- int sigtype = type;
- /* The signature may have expired even though the data is still in cache,
- forward instead of answering from cache if so. */
- int gotsig = 0;
-
- if (crecp->flags & F_CNAME)
- sigtype = T_CNAME;
-
- crecp = NULL;
- while ((crecp = cache_find_by_name(crecp, name, now, F_DS | F_DNSKEY)))
+ if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)))
+ crecp = NULL;
+#ifdef HAVE_DNSSEC
+ else if (crecp->flags & F_DNSSECOK)
{
- if (crecp->addr.sig.type_covered == sigtype && crecp->uid == C_IN)
+ /* We're returning validated data, need to return the RRSIG too. */
+
+ int sigtype = type;
+ /* The signature may have expired even though the data is still in cache,
+ forward instead of answering from cache if so. */
+ int gotsig = 0;
+
+ if (crecp->flags & F_CNAME)
+ sigtype = T_CNAME;
+
+ crecp = NULL;
+ while ((crecp = cache_find_by_name(crecp, name, now, F_DS | F_DNSKEY)))
{
- char *sigdata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL);
- gotsig = 1;
-
- if (!dryrun &&
- add_resource_record(header, limit, &trunc, nameoffset, &ansp,
- crecp->ttd - now, &nameoffset,
- T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
- anscount++;
+ if (crecp->addr.sig.type_covered == sigtype && crecp->uid == C_IN)
+ {
+ char *sigdata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL);
+ gotsig = 1;
+
+ if (!dryrun &&
+ add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ crecp->ttd - now, &nameoffset,
+ T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
+ anscount++;
+ }
}
+ /* Need to re-run original cache search */
+ crecp = gotsig ? cache_find_by_name(NULL, name, now, flag | F_CNAME) : NULL;
}
- /* Need to re-run original cache search */
- crecp = gotsig ? cache_find_by_name(NULL, name, now, flag | F_CNAME) : NULL;
- }
-
+ }
#endif
if (crecp)
do