if (val == STAT_INSECURE)
val = STAT_BOGUS;
- if (val == STAT_NO_SIG)
- return val;
-
p = (unsigned char *)(header+1);
extract_name(header, plen, &p, name, 1, 4);
p += 4; /* qtype, qclass */
if (!(p = skip_section(p, ntohs(header->ancount), header, plen)))
val = STAT_BOGUS;
-
+
+ /* If we return STAT_NO_SIG, name contains the name of the DS query */
+ if (val == STAT_NO_SIG)
+ {
+ *keyname = 0;
+ return val;
+ }
+
/* If the key needed to validate the DS is on the same domain as the DS, we'll
loop getting nowhere. Stop that now. This can happen of the DS answer comes
from the DS's zone, and not the parent zone. */
/* We only cache sigs when we've validated a reply.
Avoid caching a reply with sigs if there's a vaildated break in the
DS chain, so we don't return replies from cache missing sigs. */
- status = STAT_INSECURE_DS;
- else if (status == STAT_NO_NS || status == STAT_NO_SIG)
+ status = STAT_INSECURE_DS;
+ else if (status == STAT_NO_SIG)
+ {
+ if (option_bool(OPT_DNSSEC_NO_SIGN))
+ {
+ status = send_check_sign(forward, now, header, n, daemon->namebuff, daemon->keyname);
+ if (status == STAT_INSECURE)
+ status = STAT_INSECURE_DS;
+ }
+ else
+ status = STAT_INSECURE_DS;
+ }
+ else if (status == STAT_NO_NS)
status = STAT_BOGUS;
}
else if (forward->flags & FREC_CHECK_NOSIGN)
Avoid caching a reply with sigs if there's a vaildated break in the
DS chain, so we don't return replies from cache missing sigs. */
status = STAT_INSECURE_DS;
- else if (status == STAT_NO_NS || status == STAT_NO_SIG)
- status = STAT_BOGUS;
+ else if (status == STAT_NO_SIG)
+ {
+ if (option_bool(OPT_DNSSEC_NO_SIGN))
+ {
+ status = send_check_sign(forward, now, header, n, daemon->namebuff, daemon->keyname);
+ if (status == STAT_INSECURE)
+ status = STAT_INSECURE_DS;
+ }
+ else
+ status = STAT_INSECURE_DS;
+ }
+ else if (status == STAT_NO_NS)
+ status = STAT_BOGUS;
}
else if (forward->flags & FREC_CHECK_NOSIGN)
{
static int do_check_sign(struct frec *forward, int status, time_t now, char *name, char *keyname)
{
/* get domain we're checking back from blockdata store, it's stored on the original query. */
- while (forward->dependent)
+ while (forward->dependent && !forward->orig_domain)
forward = forward->dependent;
blockdata_retrieve(forward->orig_domain, forward->name_len, name);
/* Have entered non-signed part of DNS tree. */
if (status == STAT_NO_DS)
- return STAT_INSECURE;
+ return forward->dependent ? STAT_INSECURE_DS : STAT_INSECURE;
if (status == STAT_BOGUS)
return STAT_BOGUS;
{
if (new_status == STAT_NO_DS)
new_status = STAT_INSECURE_DS;
- else if (new_status == STAT_NO_NS || new_status == STAT_NO_SIG)
+ if (new_status == STAT_NO_SIG)
+ {
+ if (option_bool(OPT_DNSSEC_NO_SIGN))
+ {
+ new_status = tcp_check_for_unsigned_zone(now, header, n, class, name, keyname, server, keycount);
+ if (new_status == STAT_INSECURE)
+ new_status = STAT_INSECURE_DS;
+ }
+ else
+ new_status = STAT_INSECURE_DS;
+ }
+ else if (new_status == STAT_NO_NS)
new_status = STAT_BOGUS;
}
}
{
if (new_status == STAT_NO_DS)
new_status = STAT_INSECURE_DS;
- else if (new_status == STAT_NO_NS || new_status == STAT_NO_SIG)
- new_status = STAT_BOGUS; /* Validated no DS */
+ else if (new_status == STAT_NO_SIG)
+ {
+ if (option_bool(OPT_DNSSEC_NO_SIGN))
+ {
+ new_status = tcp_check_for_unsigned_zone(now, header, n, class, name, keyname, server, keycount);
+ if (new_status == STAT_INSECURE)
+ new_status = STAT_INSECURE_DS;
+ }
+ else
+ new_status = STAT_INSECURE_DS;
+ }
+ else if (new_status == STAT_NO_NS)
+ new_status = STAT_BOGUS;
}
}
else if (status == STAT_CHASE_CNAME)