mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
Add the basic EDE (RFC8914) cases (#604)
This commit is contained in:
parent
b61b0af5d6
commit
0ce36e8289
13
Makefile.in
13
Makefile.in
@ -344,7 +344,18 @@ longcheck: longtest
|
||||
test: unittest$(EXEEXT) testbound$(EXEEXT)
|
||||
./unittest$(EXEEXT)
|
||||
./testbound$(EXEEXT) -s
|
||||
for x in $(srcdir)/testdata/*.rpl; do printf "%s" "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
|
||||
for x in $(srcdir)/testdata/*.rpl; do \
|
||||
printf "%s" "$$x "; \
|
||||
if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then \
|
||||
echo OK; \
|
||||
else \
|
||||
echo failed; \
|
||||
./testbound$(EXEEXT) -p $$x -o -vvvvv; \
|
||||
printf "%s" "$$x "; \
|
||||
echo failed; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
done
|
||||
@echo test OK
|
||||
|
||||
longtest: tests
|
||||
|
212
daemon/worker.c
212
daemon/worker.c
@ -484,6 +484,12 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
return 0;
|
||||
/* TODO store the reason for the bogus reply in cache
|
||||
* and implement in here instead of the hardcoded EDE */
|
||||
if (worker->env.cfg->ede) {
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, "");
|
||||
}
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
&msg->qinfo, id, flags, edns);
|
||||
if(worker->stats.extended) {
|
||||
@ -654,6 +660,12 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
goto bail_out;
|
||||
/* TODO store the reason for the bogus reply in cache
|
||||
* and implement in here instead of the hardcoded EDE */
|
||||
if (worker->env.cfg->ede) {
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, "");
|
||||
}
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
@ -716,15 +728,25 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(!*partial_repp)
|
||||
goto bail_out;
|
||||
}
|
||||
} else if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
|
||||
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
} else {
|
||||
/* We don't check the global ede as this is a warning, not
|
||||
* an error */
|
||||
if (*is_expired_answer == 1 &&
|
||||
worker->env.cfg->ede_serve_expired && worker->env.cfg->ede) {
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_STALE_ANSWER, "");
|
||||
}
|
||||
if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
|
||||
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO),
|
||||
*is_secure_answer)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo,
|
||||
NULL, NULL, LDNS_RCODE_SERVFAIL, edns, repinfo,
|
||||
worker->scratchpad, worker->env.now_tv))
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
}
|
||||
}
|
||||
/* cannot send the reply right now, because blocking network syscall
|
||||
* is bad while holding locks. */
|
||||
@ -1014,7 +1036,7 @@ static int
|
||||
deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
enum acl_access deny, enum acl_access refuse,
|
||||
struct worker* worker, struct comm_reply* repinfo,
|
||||
struct acl_addr* acladdr)
|
||||
struct acl_addr* acladdr, int ede)
|
||||
{
|
||||
if(acl == deny) {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
@ -1027,26 +1049,164 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
worker->stats.unwanted_queries++;
|
||||
return 0;
|
||||
} else if(acl == refuse) {
|
||||
size_t opt_rr_mark;
|
||||
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
log_acl_action("refused", &repinfo->addr,
|
||||
repinfo->addrlen, acl, acladdr);
|
||||
log_buf(VERB_ALGO, "refuse", c->buffer);
|
||||
}
|
||||
|
||||
if(worker->stats.extended)
|
||||
worker->stats.unwanted_queries++;
|
||||
if(worker_check_request(c->buffer, worker) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0; /* discard this */
|
||||
}
|
||||
sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_write_at(c->buffer, 4,
|
||||
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
|
||||
/* worker_check_request() above guarantees that the buffer contains at
|
||||
* least a header and that qdcount == 1
|
||||
*/
|
||||
log_assert(sldns_buffer_limit(c->buffer) >= LDNS_HEADER_SIZE
|
||||
&& LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) == 1);
|
||||
|
||||
sldns_buffer_skip(c->buffer, LDNS_HEADER_SIZE); /* skip header */
|
||||
|
||||
/* check additional section is present and that we respond with EDEs */
|
||||
if(LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) != 1
|
||||
|| !ede) {
|
||||
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!query_dname_len(c->buffer)) {
|
||||
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
/* space available for query type and class? */
|
||||
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
|
||||
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qtype */
|
||||
|
||||
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qclass */
|
||||
|
||||
/* The OPT RR to be returned should come directly after
|
||||
* the query, so mark this spot.
|
||||
*/
|
||||
opt_rr_mark = sldns_buffer_position(c->buffer);
|
||||
|
||||
/* Skip through the RR records */
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)) != 0 ||
|
||||
LDNS_NSCOUNT(sldns_buffer_begin(c->buffer)) != 0) {
|
||||
if(!skip_pkt_rrs(c->buffer,
|
||||
((int)LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)))+
|
||||
((int)LDNS_NSCOUNT(sldns_buffer_begin(c->buffer))))) {
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, opt_rr_mark);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* Do we have a valid OPT RR here? If not return REFUSED (could be a valid TSIG or something so no FORMERR) */
|
||||
/* domain name must be the root of length 1. */
|
||||
if(sldns_buffer_remaining(c->buffer) < 1 || *sldns_buffer_current(c->buffer) != 0) {
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, opt_rr_mark);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
} else {
|
||||
sldns_buffer_skip(c->buffer, 1); /* skip root label */
|
||||
}
|
||||
if(sldns_buffer_remaining(c->buffer) < 2 ||
|
||||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, opt_rr_mark);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
/* Write OPT RR directly after the query,
|
||||
* so without the (possibly skipped) Answer and NS RRs
|
||||
*/
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_clear(c->buffer); /* reset write limit */
|
||||
sldns_buffer_set_position(c->buffer, opt_rr_mark);
|
||||
|
||||
/* Check if OPT record can be written
|
||||
* 17 == root label (1) + RR type (2) + UDP Size (2)
|
||||
* + Fields (4) + rdata len (2) + EDE Option code (2)
|
||||
* + EDE Option length (2) + EDE info-code (2)
|
||||
*/
|
||||
if (sldns_buffer_available(c->buffer, 17) == 0) {
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 1);
|
||||
|
||||
/* root label */
|
||||
sldns_buffer_write_u8(c->buffer, 0);
|
||||
sldns_buffer_write_u16(c->buffer, LDNS_RR_TYPE_OPT);
|
||||
sldns_buffer_write_u16(c->buffer, EDNS_ADVERTISED_SIZE);
|
||||
|
||||
/* write OPT Record TTL Field */
|
||||
sldns_buffer_write_u32(c->buffer, 0);
|
||||
|
||||
/* write rdata len: EDE option + length + info-code */
|
||||
sldns_buffer_write_u16(c->buffer, 6);
|
||||
|
||||
/* write OPTIONS; add EDE option code */
|
||||
sldns_buffer_write_u16(c->buffer, LDNS_EDNS_EDE);
|
||||
|
||||
/* write single EDE option length (for just 1 info-code) */
|
||||
sldns_buffer_write_u16(c->buffer, 2);
|
||||
|
||||
/* write single EDE info-code */
|
||||
sldns_buffer_write_u16(c->buffer, LDNS_EDE_PROHIBITED);
|
||||
|
||||
sldns_buffer_flip(c->buffer);
|
||||
|
||||
verbose(VERB_ALGO, "attached EDE code: %d", LDNS_EDE_PROHIBITED);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -1055,19 +1215,19 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
static int
|
||||
deny_refuse_all(struct comm_point* c, enum acl_access acl,
|
||||
struct worker* worker, struct comm_reply* repinfo,
|
||||
struct acl_addr* acladdr)
|
||||
struct acl_addr* acladdr, int ede)
|
||||
{
|
||||
return deny_refuse(c, acl, acl_deny, acl_refuse, worker, repinfo,
|
||||
acladdr);
|
||||
acladdr, ede);
|
||||
}
|
||||
|
||||
static int
|
||||
deny_refuse_non_local(struct comm_point* c, enum acl_access acl,
|
||||
struct worker* worker, struct comm_reply* repinfo,
|
||||
struct acl_addr* acladdr)
|
||||
struct acl_addr* acladdr, int ede)
|
||||
{
|
||||
return deny_refuse(c, acl, acl_deny_non_local, acl_refuse_non_local,
|
||||
worker, repinfo, acladdr);
|
||||
worker, repinfo, acladdr, ede);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1159,7 +1319,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
|
||||
repinfo->addrlen);
|
||||
acl = acl_get_control(acladdr);
|
||||
if((ret=deny_refuse_all(c, acl, worker, repinfo, acladdr)) != -1)
|
||||
|
||||
if((ret=deny_refuse_all(c, acl, worker, repinfo, acladdr,
|
||||
worker->env.cfg->ede)) != -1)
|
||||
{
|
||||
if(ret == 1)
|
||||
goto send_reply;
|
||||
@ -1379,7 +1541,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
|
||||
/* We've looked in our local zones. If the answer isn't there, we
|
||||
* might need to bail out based on ACLs now. */
|
||||
if((ret=deny_refuse_non_local(c, acl, worker, repinfo, acladdr)) != -1)
|
||||
if((ret=deny_refuse_non_local(c, acl, worker, repinfo, acladdr,
|
||||
worker->env.cfg->ede)) != -1)
|
||||
{
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(ret == 1)
|
||||
@ -1398,12 +1561,17 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
* ACLs allow the snooping. */
|
||||
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
|
||||
acl != acl_allow_snoop ) {
|
||||
if (worker->env.cfg->ede) {
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_NOT_AUTHORITATIVE, "");
|
||||
}
|
||||
error_encode(c->buffer, LDNS_RCODE_REFUSED, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), &edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
|
||||
goto send_reply;
|
||||
}
|
||||
|
||||
@ -1476,6 +1644,7 @@ lookup_cache:
|
||||
< *worker->env.now)
|
||||
leeway = 0;
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
reply_and_prefetch(worker, lookup_qinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
repinfo, leeway,
|
||||
@ -1517,6 +1686,7 @@ lookup_cache:
|
||||
verbose(VERB_ALGO, "answer from the cache failed");
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
if(answer_norec_from_cache(worker, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
|
@ -901,6 +901,14 @@ server:
|
||||
# the number of servers that will be used in the fast server selection.
|
||||
# fast-server-num: 3
|
||||
|
||||
# Enable to attach Extended DNS Error codes (RFC8914) to responses.
|
||||
# ede: no
|
||||
|
||||
# Enable to attach an Extended DNS Error (RFC8914) Code 3 - Stale
|
||||
# Answer as EDNS0 option to expired responses.
|
||||
# Note that the ede option above needs to be enabled for this to work.
|
||||
# ede-serve-expired: no
|
||||
|
||||
# Specific options for ipsecmod. Unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
#
|
||||
|
@ -1780,6 +1780,21 @@ option can be used multiple times. The most specific match will be used.
|
||||
EDNS0 option code for the \fIedns\-client\-string\fR option, from 0 to 65535.
|
||||
A value from the `Reserved for Local/Experimental` range (65001-65534) should
|
||||
be used. Default is 65001.
|
||||
.TP 5
|
||||
.B ede: \fI<yes or no>
|
||||
If enabled, Unbound will respond with Extended DNS Error codes (RFC8914).
|
||||
These EDEs attach informative error messages to a response for various
|
||||
errors. Default is "no".
|
||||
|
||||
When the \fBval-log-level\fR option is also set to \fB2\fR, responses with
|
||||
Extended DNS Errors concerning DNSSEC failures that are not served from cache,
|
||||
will also contain a descriptive text message about the reason for the failure.
|
||||
.TP
|
||||
.B ede\-serve\-expired: \fI<yes or no>
|
||||
If enabled, Unbound will attach an Extended DNS Error (RFC8914) Code 3 - Stale
|
||||
Answer as EDNS0 option to the expired response. Note that this will not attach
|
||||
the EDE code without setting the global \fBede\fR option to "yes" as well.
|
||||
Default is "no".
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
|
@ -132,6 +132,7 @@ msg_create(struct regional* region, struct query_info* qinfo)
|
||||
return NULL;
|
||||
msg->rep->flags = (uint16_t)(BIT_QR | BIT_AA);
|
||||
msg->rep->authoritative = 1;
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->qdcount = 1;
|
||||
/* rrsets is NULL, no rrsets yet */
|
||||
return msg;
|
||||
@ -7785,7 +7786,7 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
auth_zone_log(z->name, VERB_ALGO,
|
||||
"zonemd: verify %s RRset with DNSKEY", typestr);
|
||||
}
|
||||
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus,
|
||||
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL);
|
||||
if(sec == sec_status_secure) {
|
||||
return 1;
|
||||
@ -8128,7 +8129,7 @@ zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
||||
auth_zone_log(z->name, VERB_QUERY,
|
||||
"zonemd: verify DNSKEY RRset with trust anchor");
|
||||
sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
|
||||
anchor->dnskey_rrset, NULL, why_bogus, NULL);
|
||||
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL);
|
||||
regional_free_all(env->scratch);
|
||||
if(sec == sec_status_secure) {
|
||||
/* success */
|
||||
@ -8186,8 +8187,9 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
||||
keystorage->rk.type = htons(LDNS_RR_TYPE_DNSKEY);
|
||||
keystorage->rk.rrset_class = htons(z->dclass);
|
||||
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
|
||||
// @TODO add EDE here? we currently just pass NULL
|
||||
sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg,
|
||||
why_bogus, NULL);
|
||||
why_bogus, NULL, NULL);
|
||||
regional_free_all(env->scratch);
|
||||
if(sec == sec_status_secure) {
|
||||
/* success */
|
||||
|
5
services/cache/dns.c
vendored
5
services/cache/dns.c
vendored
@ -428,6 +428,7 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
return NULL; /* integer overflow protection */
|
||||
msg->rep->flags = BIT_QR; /* with QR, no AA */
|
||||
msg->rep->qdcount = 1;
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->rrsets = (struct ub_packed_rrset_key**)
|
||||
regional_alloc(region,
|
||||
capacity*sizeof(struct ub_packed_rrset_key*));
|
||||
@ -524,6 +525,7 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
|
||||
sizeof(struct reply_info) - sizeof(struct rrset_ref));
|
||||
if(!msg->rep)
|
||||
return NULL;
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
if(num > RR_COUNT_MAX)
|
||||
return NULL; /* integer overflow protection */
|
||||
msg->rep->rrsets = (struct ub_packed_rrset_key**)
|
||||
@ -577,6 +579,7 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
msg->rep->ar_numrrsets = r->ar_numrrsets;
|
||||
msg->rep->rrset_count = r->rrset_count;
|
||||
msg->rep->authoritative = r->authoritative;
|
||||
msg->rep->reason_bogus = r->reason_bogus;
|
||||
if(!rrset_array_lock(r->ref, r->rrset_count, now_control)) {
|
||||
return NULL;
|
||||
}
|
||||
@ -632,6 +635,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
msg->rep->ns_numrrsets = 0;
|
||||
msg->rep->ar_numrrsets = 0;
|
||||
msg->rep->rrset_count = 1;
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now);
|
||||
if(!msg->rep->rrsets[0]) /* copy CNAME */
|
||||
return NULL;
|
||||
@ -670,6 +674,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
msg->rep->ns_numrrsets = 0;
|
||||
msg->rep->ar_numrrsets = 0;
|
||||
msg->rep->rrset_count = 1;
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now);
|
||||
if(!msg->rep->rrsets[0]) /* copy DNAME */
|
||||
return NULL;
|
||||
|
@ -1328,7 +1328,8 @@ local_encode(struct query_info* qinfo, struct module_env* env,
|
||||
static void
|
||||
local_error_encode(struct query_info* qinfo, struct module_env* env,
|
||||
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
|
||||
struct regional* temp, int rcode, int r)
|
||||
struct regional* temp, int rcode, int r, int ede_code,
|
||||
const char* ede_txt)
|
||||
{
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@ -1338,6 +1339,12 @@ local_error_encode(struct query_info* qinfo, struct module_env* env,
|
||||
if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
|
||||
rcode, edns, repinfo, temp, env->now_tv))
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
|
||||
if(ede_code != LDNS_EDE_NONE && env->cfg->ede) {
|
||||
edns_opt_list_append_ede(&edns->opt_list_out, temp,
|
||||
ede_code, ede_txt);
|
||||
}
|
||||
|
||||
error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
}
|
||||
@ -1535,7 +1542,9 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
qinfo->local_alias = NULL;
|
||||
local_error_encode(qinfo, env, edns, repinfo,
|
||||
buf, temp, LDNS_RCODE_YXDOMAIN,
|
||||
(LDNS_RCODE_YXDOMAIN|BIT_AA));
|
||||
(LDNS_RCODE_YXDOMAIN|BIT_AA),
|
||||
LDNS_EDE_OTHER,
|
||||
"DNAME expansion became too large");
|
||||
return 1;
|
||||
}
|
||||
memset(&qinfo->local_alias->rrset->entry, 0,
|
||||
@ -1638,7 +1647,8 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
} else if(lz_type == local_zone_refuse
|
||||
|| lz_type == local_zone_always_refuse) {
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA));
|
||||
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA),
|
||||
LDNS_EDE_NONE, NULL);
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_static ||
|
||||
lz_type == local_zone_redirect ||
|
||||
@ -1663,8 +1673,8 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
if(z != NULL && z->soa && z->soa_negative)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa_negative, 0, rcode);
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
(rcode|BIT_AA));
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
rcode, (rcode|BIT_AA), LDNS_EDE_NONE, NULL);
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_typetransparent
|
||||
|| lz_type == local_zone_always_transparent) {
|
||||
@ -1705,9 +1715,10 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
&lrr, 1, LDNS_RCODE_NOERROR);
|
||||
} else {
|
||||
/* NODATA: No EDE needed */
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf,
|
||||
temp, LDNS_RCODE_NOERROR,
|
||||
(LDNS_RCODE_NOERROR|BIT_AA));
|
||||
(LDNS_RCODE_NOERROR|BIT_AA), -1, NULL);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1720,8 +1731,9 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
if(z != NULL && z->soa && z->soa_negative)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa_negative, 0, rcode);
|
||||
/* NODATA: No EDE needed */
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
(rcode|BIT_AA));
|
||||
(rcode|BIT_AA), LDNS_EDE_NONE, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1239,7 +1239,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
(rep->security <= sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
m->s.env->mesh->ans_bogus++;
|
||||
}
|
||||
if(rep && rep->security == sec_status_secure)
|
||||
@ -1295,6 +1295,36 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
&r->edns, &r->query_reply, m->s.region, &r->start_time))
|
||||
r->edns.opt_list_inplace_cb_out = NULL;
|
||||
}
|
||||
/* Send along EDE BOGUS EDNS0 option when answer is bogus */
|
||||
if(m->s.env->cfg->ede && rcode == LDNS_RCODE_SERVFAIL &&
|
||||
m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
(rep->security <= sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
char *reason = m->s.env->cfg->val_log_level >= 2
|
||||
? errinf_to_str_bogus(&m->s) : NULL;
|
||||
|
||||
/* During validation the EDE code can be received via two
|
||||
* code paths. One code path fills the reply_info EDE, and
|
||||
* the other fills it in the errinf_strlist. These paths
|
||||
* intersect at some points, but where is opaque due to
|
||||
* the complexity of the validator. At the time of writing
|
||||
* we make the choice to prefer the EDE from errinf_strlist
|
||||
* but a compelling reason to do otherwise is just as valid
|
||||
*/
|
||||
sldns_ede_code reason_bogus = errinf_to_reason_bogus(&m->s);
|
||||
if ((reason_bogus == LDNS_EDE_DNSSEC_BOGUS &&
|
||||
rep->reason_bogus != LDNS_EDE_NONE) ||
|
||||
reason_bogus == LDNS_EDE_NONE) {
|
||||
reason_bogus = rep->reason_bogus;
|
||||
}
|
||||
|
||||
if(reason_bogus != LDNS_EDE_NONE) {
|
||||
edns_opt_list_append_ede(&r->edns.opt_list_out,
|
||||
m->s.region, reason_bogus, reason);
|
||||
}
|
||||
free(reason);
|
||||
}
|
||||
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
|
||||
r->qflags, &r->edns);
|
||||
m->reply_list = NULL;
|
||||
@ -1318,6 +1348,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, &r->start_time))
|
||||
r->edns.opt_list_inplace_cb_out = NULL;
|
||||
/* internal server error (probably malloc failure) so no
|
||||
* EDE (RFC8914) needed */
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
&m->s.qinfo, r->qid, r->qflags, &r->edns);
|
||||
}
|
||||
@ -2050,6 +2082,14 @@ mesh_serve_expired_callback(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
/* Add EDE Stale Answer (RCF8914). Ignore global ede as this is
|
||||
* warning instead of an error */
|
||||
if (r->edns.edns_present && qstate->env->cfg->ede_serve_expired &&
|
||||
qstate->env->cfg->ede) {
|
||||
edns_opt_list_append_ede(&r->edns.opt_list_out,
|
||||
mstate->s.region, LDNS_EDE_STALE_ANSWER, NULL);
|
||||
}
|
||||
|
||||
r_buffer = r->query_reply.c->buffer;
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
|
||||
|
@ -97,18 +97,22 @@ extern "C" {
|
||||
#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
|
||||
*/
|
||||
#define LDNS_QDCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF))
|
||||
#define LDNS_QDCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_QDCOUNT_OFF, i))
|
||||
|
||||
/* Counter of the answer section */
|
||||
#define LDNS_ANCOUNT_OFF 6
|
||||
#define LDNS_ANCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF))
|
||||
#define LDNS_ANCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_ANCOUNT_OFF, i))
|
||||
|
||||
/* Counter of the authority section */
|
||||
#define LDNS_NSCOUNT_OFF 8
|
||||
#define LDNS_NSCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF))
|
||||
#define LDNS_NSCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_NSCOUNT_OFF, i))
|
||||
|
||||
/* Counter of the additional section */
|
||||
#define LDNS_ARCOUNT_OFF 10
|
||||
#define LDNS_ARCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF))
|
||||
#define LDNS_ARCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_ARCOUNT_OFF, i))
|
||||
|
||||
/**
|
||||
* The sections of a packet
|
||||
|
@ -435,10 +435,42 @@ enum sldns_enum_edns_option
|
||||
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
|
||||
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
|
||||
LDNS_EDNS_PADDING = 12, /* RFC7830 */
|
||||
LDNS_EDNS_EDE = 15, /* RFC8914 */
|
||||
LDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
|
||||
};
|
||||
typedef enum sldns_enum_edns_option sldns_edns_option;
|
||||
|
||||
enum sldns_enum_ede_code
|
||||
{
|
||||
LDNS_EDE_NONE = -1, /* EDE undefined for internal use */
|
||||
LDNS_EDE_OTHER = 0,
|
||||
LDNS_EDE_UNSUPPORTED_DNSKEY_ALG = 1,
|
||||
LDNS_EDE_UNSUPPORTED_DS_DIGEST = 2,
|
||||
LDNS_EDE_STALE_ANSWER = 3,
|
||||
LDNS_EDE_FORGED_ANSWER = 4,
|
||||
LDNS_EDE_DNSSEC_INDETERMINATE = 5,
|
||||
LDNS_EDE_DNSSEC_BOGUS = 6,
|
||||
LDNS_EDE_SIGNATURE_EXPIRED = 7,
|
||||
LDNS_EDE_SIGNATURE_NOT_YET_VALID = 8,
|
||||
LDNS_EDE_DNSKEY_MISSING = 9,
|
||||
LDNS_EDE_RRSIGS_MISSING = 10,
|
||||
LDNS_EDE_NO_ZONE_KEY_BIT_SET = 11,
|
||||
LDNS_EDE_NSEC_MISSING = 12,
|
||||
LDNS_EDE_CACHED_ERROR = 13,
|
||||
LDNS_EDE_NOT_READY = 14,
|
||||
LDNS_EDE_BLOCKED = 15,
|
||||
LDNS_EDE_CENSORED = 16,
|
||||
LDNS_EDE_FILTERED = 17,
|
||||
LDNS_EDE_PROHIBITED = 18,
|
||||
LDNS_EDE_STALE_NXDOMAIN_ANSWER = 19,
|
||||
LDNS_EDE_NOT_AUTHORITATIVE = 20,
|
||||
LDNS_EDE_NOT_SUPPORTED = 21,
|
||||
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
|
||||
LDNS_EDE_NETWORK_ERROR = 23,
|
||||
LDNS_EDE_INVALID_DATA = 24,
|
||||
};
|
||||
typedef enum sldns_enum_ede_code sldns_ede_code;
|
||||
|
||||
#define LDNS_EDNS_MASK_DO_BIT 0x8000
|
||||
|
||||
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
|
||||
|
@ -194,6 +194,7 @@ static sldns_lookup_table sldns_edns_options_data[] = {
|
||||
{ 8, "edns-client-subnet" },
|
||||
{ 11, "edns-tcp-keepalive"},
|
||||
{ 12, "Padding" },
|
||||
{ 15, "EDE"},
|
||||
{ 0, NULL}
|
||||
};
|
||||
sldns_lookup_table* sldns_edns_options = sldns_edns_options_data;
|
||||
|
@ -128,6 +128,8 @@ static void matchline(char* line, struct entry* e)
|
||||
e->match_answer = 1;
|
||||
} else if(str_keyword(&parse, "subdomain")) {
|
||||
e->match_subdomain = 1;
|
||||
} else if(str_keyword(&parse, "all_noedns")) {
|
||||
e->match_all_noedns = 1;
|
||||
} else if(str_keyword(&parse, "all")) {
|
||||
e->match_all = 1;
|
||||
} else if(str_keyword(&parse, "ttl")) {
|
||||
@ -148,7 +150,22 @@ static void matchline(char* line, struct entry* e)
|
||||
error("expected = or : in MATCH: %s", line);
|
||||
parse++;
|
||||
e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((unsigned char)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
} else if(str_keyword(&parse, "ede")) {
|
||||
e->match_ede = 1;
|
||||
if(*parse != '=' && *parse != ':')
|
||||
error("expected = or : in MATCH: %s", line);
|
||||
parse++;
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
if(str_keyword(&parse, "any")) {
|
||||
e->match_ede_any = 1;
|
||||
} else {
|
||||
e->ede_info_code = (uint16_t)strtol(parse,
|
||||
(char**)&parse, 10);
|
||||
}
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
} else {
|
||||
error("could not parse MATCH: '%s'", parse);
|
||||
@ -266,11 +283,15 @@ static struct entry* new_entry(void)
|
||||
e->match_answer = 0;
|
||||
e->match_subdomain = 0;
|
||||
e->match_all = 0;
|
||||
e->match_all_noedns = 0;
|
||||
e->match_ttl = 0;
|
||||
e->match_do = 0;
|
||||
e->match_noedns = 0;
|
||||
e->match_serial = 0;
|
||||
e->ixfr_soa_serial = 0;
|
||||
e->match_ede = 0;
|
||||
e->match_ede_any = 0;
|
||||
e->ede_info_code = -1;
|
||||
e->match_transport = transport_any;
|
||||
e->reply_list = NULL;
|
||||
e->copy_id = 0;
|
||||
@ -817,7 +838,7 @@ static uint32_t get_serial(uint8_t* p, size_t plen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** get ptr to EDNS OPT record (and remaining length); behind the type u16 */
|
||||
/** get ptr to EDNS OPT record (and remaining length); after the type u16 */
|
||||
static int
|
||||
pkt_find_edns_opt(uint8_t** p, size_t* plen)
|
||||
{
|
||||
@ -884,6 +905,39 @@ get_do_flag(uint8_t* pkt, size_t len)
|
||||
return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
|
||||
}
|
||||
|
||||
/** Snips the EDE option out of the OPT record and returns the EDNS EDE
|
||||
* INFO-CODE if found, else -1 */
|
||||
static int
|
||||
extract_ede(uint8_t* pkt, size_t len)
|
||||
{
|
||||
uint8_t *rdata, *opt_position = pkt;
|
||||
uint16_t rdlen, optlen;
|
||||
size_t remaining = len;
|
||||
int ede_code;
|
||||
if(!pkt_find_edns_opt(&opt_position, &remaining)) return -1;
|
||||
if(remaining < 8) return -1; /* malformed */
|
||||
rdlen = sldns_read_uint16(opt_position+6);
|
||||
rdata = opt_position + 8;
|
||||
while(rdlen > 0) {
|
||||
if(rdlen < 4) return -1; /* malformed */
|
||||
optlen = sldns_read_uint16(rdata+2);
|
||||
if(sldns_read_uint16(rdata) == LDNS_EDNS_EDE) {
|
||||
if(rdlen < 6) return -1; /* malformed */
|
||||
ede_code = sldns_read_uint16(rdata+4);
|
||||
/* snip option from packet; assumes len is correct */
|
||||
memmove(rdata, rdata+4+optlen,
|
||||
(pkt+len)-(rdata+4+optlen));
|
||||
/* update OPT size */
|
||||
sldns_write_uint16(opt_position+6,
|
||||
sldns_read_uint16(opt_position+6)-(4+optlen));
|
||||
return ede_code;
|
||||
}
|
||||
rdlen -= 4 + optlen;
|
||||
rdata += 4 + optlen;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** zero TTLs in packet */
|
||||
static void
|
||||
zerottls(uint8_t* pkt, size_t pktlen)
|
||||
@ -1201,7 +1255,7 @@ match_question(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* remove after answer section, (;; AUTH, ;; ADD, ;; MSG size ..) */
|
||||
/* remove after answer section, (;; ANS, ;; AUTH, ;; ADD ..) */
|
||||
s = strstr(qcmpstr, ";; ANSWER SECTION");
|
||||
if(!s) s = strstr(qcmpstr, ";; AUTHORITY SECTION");
|
||||
if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION");
|
||||
@ -1292,18 +1346,36 @@ match_answer(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
|
||||
return r;
|
||||
}
|
||||
|
||||
/** ignore EDNS lines in the string by overwriting them with what's left or
|
||||
* zero out if at end of the string */
|
||||
static int
|
||||
ignore_edns_lines(char* str) {
|
||||
char* edns = str, *n;
|
||||
size_t str_len = strlen(str);
|
||||
while((edns = strstr(edns, "; EDNS"))) {
|
||||
n = strchr(edns, '\n');
|
||||
if(!n) {
|
||||
/* EDNS at end of string; zero */
|
||||
*edns = 0;
|
||||
break;
|
||||
}
|
||||
memmove(edns, n+1, str_len-(n-str));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** match all of the packet */
|
||||
int
|
||||
match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
int noloc)
|
||||
int noloc, int noedns)
|
||||
{
|
||||
char* qstr, *pstr;
|
||||
uint8_t* qb = q, *pb = p;
|
||||
int r;
|
||||
/* zero TTLs */
|
||||
qb = memdup(q, qlen);
|
||||
pb = memdup(p, plen);
|
||||
if(!qb || !pb) error("out of memory");
|
||||
/* zero TTLs */
|
||||
if(!mttl) {
|
||||
zerottls(qb, qlen);
|
||||
zerottls(pb, plen);
|
||||
@ -1313,6 +1385,11 @@ match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
qstr = sldns_wire2str_pkt(qb, qlen);
|
||||
pstr = sldns_wire2str_pkt(pb, plen);
|
||||
if(!qstr || !pstr) error("cannot pkt2string");
|
||||
/* should we ignore EDNS lines? */
|
||||
if(noedns) {
|
||||
ignore_edns_lines(qstr);
|
||||
ignore_edns_lines(pstr);
|
||||
}
|
||||
r = (strcmp(qstr, pstr) == 0);
|
||||
if(!r) {
|
||||
/* remove ;; MSG SIZE (at end of string) */
|
||||
@ -1321,8 +1398,8 @@ match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
s = strstr(pstr, ";; MSG SIZE");
|
||||
if(s) *s=0;
|
||||
r = (strcmp(qstr, pstr) == 0);
|
||||
if(!r && !noloc) {
|
||||
/* we are going to fail see if it is because of EDNS */
|
||||
if(!r && !noloc && !noedns) {
|
||||
/* we are going to fail, see if the cause is EDNS */
|
||||
char* a = strstr(qstr, "; EDNS");
|
||||
char* b = strstr(pstr, "; EDNS");
|
||||
if( (a&&!b) || (b&&!a) ) {
|
||||
@ -1428,13 +1505,32 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
|
||||
enum transport_type transport)
|
||||
{
|
||||
struct entry* p = entries;
|
||||
uint8_t* reply;
|
||||
size_t rlen;
|
||||
uint8_t* reply, *query_pkt_orig;
|
||||
size_t rlen, query_pkt_orig_len;
|
||||
/* Keep the original packet; it may be modified */
|
||||
query_pkt_orig = memdup(query_pkt, len);
|
||||
query_pkt_orig_len = len;
|
||||
for(p=entries; p; p=p->next) {
|
||||
verbose(3, "comparepkt: ");
|
||||
reply = p->reply_list->reply_pkt;
|
||||
rlen = p->reply_list->reply_len;
|
||||
if(p->match_opcode && get_opcode(query_pkt, len) !=
|
||||
/* Restore the original packet for each entry */
|
||||
memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
|
||||
/* EDE should be first since it may modify the query_pkt */
|
||||
if(p->match_ede) {
|
||||
int info_code = extract_ede(query_pkt, len);
|
||||
if(info_code == -1) {
|
||||
verbose(3, "bad EDE. Expected but not found\n");
|
||||
continue;
|
||||
} else if(!p->match_ede_any &&
|
||||
(uint16_t)info_code != p->ede_info_code) {
|
||||
verbose(3, "bad EDE INFO-CODE. Expected: %d, "
|
||||
"and got: %d\n", (int)p->ede_info_code,
|
||||
info_code);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(p->match_opcode && get_opcode(query_pkt, len) !=
|
||||
get_opcode(reply, rlen)) {
|
||||
verbose(3, "bad opcode\n");
|
||||
continue;
|
||||
@ -1502,14 +1598,25 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
|
||||
verbose(3, "bad transport\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_all_noedns && !match_all(query_pkt, len, reply,
|
||||
rlen, (int)p->match_ttl, 0, 1)) {
|
||||
verbose(3, "bad all_noedns match\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_all && !match_all(query_pkt, len, reply, rlen,
|
||||
(int)p->match_ttl, 0)) {
|
||||
(int)p->match_ttl, 0, 0)) {
|
||||
verbose(3, "bad allmatch\n");
|
||||
continue;
|
||||
}
|
||||
verbose(3, "match!\n");
|
||||
/* Restore the original packet */
|
||||
memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
|
||||
free(query_pkt_orig);
|
||||
return p;
|
||||
}
|
||||
/* Restore the original packet */
|
||||
memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
|
||||
free(query_pkt_orig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -40,20 +40,30 @@ struct sldns_file_parse_state;
|
||||
ENTRY_BEGIN
|
||||
; first give MATCH lines, that say what queries are matched
|
||||
; by this entry.
|
||||
; 'opcode' makes the query match the opcode from the reply
|
||||
; if you leave it out, any opcode matches this entry.
|
||||
; 'qtype' makes the query match the qtype from the reply
|
||||
; 'qname' makes the query match the qname from the reply
|
||||
; 'subdomain' makes the query match subdomains of qname from the reply
|
||||
; 'serial=1023' makes the query match if ixfr serial is 1023.
|
||||
; 'opcode' makes the query match the opcode from the reply;
|
||||
; if you leave it out, any opcode matches this entry.
|
||||
; 'qtype' makes the query match the qtype from the reply.
|
||||
; 'qname' makes the query match the qname from the reply.
|
||||
; 'subdomain' makes the query match subdomains of qname from the reply.
|
||||
; 'serial=1023' makes the query match if ixfr serial is 1023.
|
||||
; 'all' has to match header byte for byte and all rrs in packet.
|
||||
; 'all_noedns' has to match header byte for byte and all rrs in packet;
|
||||
; ignoring EDNS.
|
||||
; 'ttl' used with all, rrs in packet must also have matching TTLs.
|
||||
; 'DO' will match only queries with DO bit set.
|
||||
; 'noedns' matches queries without EDNS OPT records.
|
||||
; 'rcode' makes the query match the rcode from the reply
|
||||
; 'question' makes the query match the question section
|
||||
; 'answer' makes the query match the answer section
|
||||
; 'rcode' makes the query match the rcode from the reply.
|
||||
; 'question' makes the query match the question section.
|
||||
; 'answer' makes the query match the answer section.
|
||||
; 'ednsdata' matches queries to HEX_EDNS section.
|
||||
; 'UDP' matches if the transport is UDP.
|
||||
; 'TCP' matches if the transport is TCP.
|
||||
; 'ede=2' makes the query match if the EDNS EDE info-code is 2.
|
||||
; It also snips the EDE record out of the packet to facilitate
|
||||
; other matches.
|
||||
; 'ede=any' makes the query match any EDNS EDE info-code.
|
||||
; It also snips the EDE record out of the packet to facilitate
|
||||
; other matches.
|
||||
MATCH [opcode] [qtype] [qname] [serial=<value>] [all] [ttl]
|
||||
MATCH [UDP|TCP] DO
|
||||
MATCH ...
|
||||
@ -72,6 +82,12 @@ struct sldns_file_parse_state;
|
||||
; 'sleep=10' sleeps for 10 seconds before giving the answer (TCP is open)
|
||||
ADJUST [sleep=<num>] ; sleep before giving any reply
|
||||
ADJUST [packet_sleep=<num>] ; sleep before this packet in sequence
|
||||
; 'copy_ednsdata_assume_clientsubnet' copies ednsdata to reply, assumes
|
||||
; it is clientsubnet and adjusts scopemask to match sourcemask.
|
||||
ADJUST copy_ednsdata_assume_clientsubnet
|
||||
; 'increment_ecs_scope' increments the ECS scope copied from the
|
||||
; sourcemask by one.
|
||||
ADJUST increment_ecs_scope
|
||||
SECTION QUESTION
|
||||
<RRs, one per line> ; the RRcount is determined automatically.
|
||||
SECTION ANSWER
|
||||
@ -167,11 +183,11 @@ struct entry {
|
||||
/* match */
|
||||
/* How to match an incoming query with this canned reply */
|
||||
/** match query opcode with answer opcode */
|
||||
uint8_t match_opcode;
|
||||
uint8_t match_opcode;
|
||||
/** match qtype with answer qtype */
|
||||
uint8_t match_qtype;
|
||||
uint8_t match_qtype;
|
||||
/** match qname with answer qname */
|
||||
uint8_t match_qname;
|
||||
uint8_t match_qname;
|
||||
/** match rcode with answer rcode */
|
||||
uint8_t match_rcode;
|
||||
/** match question section */
|
||||
@ -179,11 +195,17 @@ struct entry {
|
||||
/** match answer section */
|
||||
uint8_t match_answer;
|
||||
/** match qname as subdomain of answer qname */
|
||||
uint8_t match_subdomain;
|
||||
uint8_t match_subdomain;
|
||||
/** match SOA serial number, from auth section */
|
||||
uint8_t match_serial;
|
||||
uint8_t match_serial;
|
||||
/** match EDNS EDE info-code */
|
||||
uint8_t match_ede;
|
||||
/** match any EDNS EDE info-code */
|
||||
uint8_t match_ede_any;
|
||||
/** match all of the packet */
|
||||
uint8_t match_all;
|
||||
/** match all of the packet; ignore EDNS */
|
||||
uint8_t match_all_noedns;
|
||||
/** match ttls in the packet */
|
||||
uint8_t match_ttl;
|
||||
/** match DO bit */
|
||||
@ -193,9 +215,11 @@ struct entry {
|
||||
/** match edns data field given in hex */
|
||||
uint8_t match_ednsdata_raw;
|
||||
/** match query serial with this value. */
|
||||
uint32_t ixfr_soa_serial;
|
||||
uint32_t ixfr_soa_serial;
|
||||
/** match on UDP/TCP */
|
||||
enum transport_type match_transport;
|
||||
enum transport_type match_transport;
|
||||
/** match EDNS EDE info-code with this value. */
|
||||
uint16_t ede_info_code;
|
||||
|
||||
/** pre canned reply */
|
||||
struct reply_packet *reply_list;
|
||||
@ -260,10 +284,11 @@ struct entry* find_match(struct entry* entries, uint8_t* query_pkt,
|
||||
* @param mttl: if true, ttls must match, if false, ttls do not need to match
|
||||
* @param noloc: if true, rrs may be reordered in their packet-section.
|
||||
* rrs are then matches without location of the rr being important.
|
||||
* @param noedns: if true, edns is not compared, if false, edns must match.
|
||||
* @return true if matched.
|
||||
*/
|
||||
int match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
int noloc);
|
||||
int noloc, int noedns);
|
||||
|
||||
/**
|
||||
* copy & adjust packet, mallocs a copy.
|
||||
|
@ -137,7 +137,7 @@ test_buffers(sldns_buffer* pkt, sldns_buffer* out)
|
||||
/* compare packets */
|
||||
unit_assert(match_all(sldns_buffer_begin(pkt), sldns_buffer_limit(pkt),
|
||||
sldns_buffer_begin(out), sldns_buffer_limit(out), 1,
|
||||
matches_nolocation));
|
||||
matches_nolocation, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
}
|
||||
setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
|
||||
/* ok to give null as qstate here, won't be used for answer section. */
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason,
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL);
|
||||
if(vsig) {
|
||||
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
|
||||
|
4
testdata/autotrust_init_fail.rpl
vendored
4
testdata/autotrust_init_fail.rpl
vendored
@ -4,6 +4,8 @@ server:
|
||||
log-time-ascii: yes
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
@ -150,7 +152,7 @@ ENTRY_END
|
||||
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
4
testdata/autotrust_init_failsig.rpl
vendored
4
testdata/autotrust_init_failsig.rpl
vendored
@ -5,6 +5,8 @@ server:
|
||||
log-time-ascii: yes
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
@ -138,7 +140,7 @@ ENTRY_END
|
||||
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
4
testdata/autotrust_probefail.rpl
vendored
4
testdata/autotrust_probefail.rpl
vendored
@ -4,6 +4,8 @@ server:
|
||||
log-time-ascii: yes
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
@ -155,7 +157,7 @@ ENTRY_END
|
||||
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
4
testdata/autotrust_probefailsig.rpl
vendored
4
testdata/autotrust_probefailsig.rpl
vendored
@ -4,6 +4,8 @@ server:
|
||||
log-time-ascii: yes
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
@ -155,7 +157,7 @@ ENTRY_END
|
||||
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
5
testdata/black_ds_entry.rpl
vendored
5
testdata/black_ds_entry.rpl
vendored
@ -6,6 +6,7 @@ server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -578,7 +579,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
@ -595,7 +596,7 @@ ENTRY_END
|
||||
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ftp.sub.example.com. IN A
|
||||
|
5
testdata/black_key_entry.rpl
vendored
5
testdata/black_key_entry.rpl
vendored
@ -6,6 +6,7 @@ server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -560,7 +561,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
@ -577,7 +578,7 @@ ENTRY_END
|
||||
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ftp.sub.example.com. IN A
|
||||
|
5
testdata/black_prime_entry.rpl
vendored
5
testdata/black_prime_entry.rpl
vendored
@ -7,6 +7,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -285,7 +286,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
@ -304,7 +305,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ftp.example.com. IN A
|
||||
|
1
testdata/ede.tdir/bogus/clean.sh
vendored
Executable file
1
testdata/ede.tdir/bogus/clean.sh
vendored
Executable file
@ -0,0 +1 @@
|
||||
rm -f K* piece1 base expired notyetincepted trust-anchors dnssec-failures.test.signed dnskey-failures.test.signed nsec-failures.test.signed rrsig-failures.test.signed
|
10
testdata/ede.tdir/bogus/dnskey-failures.test
vendored
Normal file
10
testdata/ede.tdir/bogus/dnskey-failures.test
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
$ORIGIN dnskey-failures.test.
|
||||
|
||||
@ SOA ns hostmaster (
|
||||
1 ; serial
|
||||
14400 ; refresh (4 hours)
|
||||
1800 ; retry (30 minutes)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
A 192.0.2.1
|
15
testdata/ede.tdir/bogus/dnssec-failures.test
vendored
Normal file
15
testdata/ede.tdir/bogus/dnssec-failures.test
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
$ORIGIN dnssec-failures.test.
|
||||
|
||||
@ SOA ns hostmaster (
|
||||
1 ; serial
|
||||
14400 ; refresh (4 hours)
|
||||
1800 ; retry (30 minutes)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
NS ns
|
||||
ns A 192.0.2.1
|
||||
notyetincepted TXT "Not yet incepted"
|
||||
expired TXT "Expired"
|
||||
sigsinvalid TXT "Signatures invalid"
|
||||
missingrrsigs TXT "Signatures missing"
|
67
testdata/ede.tdir/bogus/make-broken-zone.sh
vendored
Executable file
67
testdata/ede.tdir/bogus/make-broken-zone.sh
vendored
Executable file
@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# create oudated zones
|
||||
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom dnssec-failures.test`
|
||||
echo $CSK
|
||||
|
||||
echo ". IN DS 20326 8 2 e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d" | \
|
||||
cat $CSK.ds - > bogus/trust-anchors
|
||||
|
||||
# differentiate for MacOS with "gdate"
|
||||
DATE=date
|
||||
which gdate > /dev/null && DATE=gdate
|
||||
|
||||
ONEMONTHAGO=`$DATE -d 'now - 1 month' +%Y%m%d`
|
||||
YESTERDAY=`$DATE -d 'now - 2 days' +%Y%m%d`
|
||||
TOMORROW=`$DATE -d 'now + 2 days' +%Y%m%d`
|
||||
|
||||
ldns-signzone -i $YESTERDAY -f - bogus/dnssec-failures.test $CSK | \
|
||||
grep -v '^missingrrsigs\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' | \
|
||||
sed 's/Signatures invalid/Signatures INVALID/g' | \
|
||||
grep -v '^notyetincepted\.dnssec-failures\.test\..*IN.*TXT' | \
|
||||
grep -v '^notyetincepted\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' | \
|
||||
grep -v '^expired\.dnssec-failures\.test\..*IN.*TXT' | \
|
||||
grep -v '^expired\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' > base
|
||||
ldns-signzone -i $ONEMONTHAGO -e $YESTERDAY -f - bogus/dnssec-failures.test $CSK | \
|
||||
grep -v '[ ]NSEC[ ]' | \
|
||||
grep '^expired\.dnssec-failures\.test\..*IN.*TXT' > expired
|
||||
ldns-signzone -i $TOMORROW -f - bogus/dnssec-failures.test $CSK | \
|
||||
grep -v '[ ]NSEC[ ]' | \
|
||||
grep '^notyetincepted\.dnssec-failures\.test\..*IN.*TXT' > notyetincepted
|
||||
|
||||
cat base expired notyetincepted > bogus/dnssec-failures.test.signed
|
||||
|
||||
# cleanup old zone keys
|
||||
rm -f $CSK.*
|
||||
# create zone with DNSKEY missing
|
||||
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom dnskey-failures.test`
|
||||
echo $CSK
|
||||
cat $CSK.ds >> bogus/trust-anchors
|
||||
|
||||
ldns-signzone -f tmp.signed bogus/dnskey-failures.test $CSK
|
||||
grep -v ' DNSKEY ' tmp.signed > bogus/dnskey-failures.test.signed
|
||||
|
||||
|
||||
# cleanup old zone keys
|
||||
rm -f $CSK.*
|
||||
# create zone with NSEC missing
|
||||
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom nsec-failures.test`
|
||||
echo $CSK
|
||||
cat $CSK.ds >> bogus/trust-anchors
|
||||
|
||||
ldns-signzone -f tmp.signed bogus/nsec-failures.test $CSK
|
||||
grep -v ' NSEC ' tmp.signed > bogus/nsec-failures.test.signed
|
||||
|
||||
|
||||
# cleanup old zone keys
|
||||
rm -f $CSK.*
|
||||
# create zone with RRSIGs missing
|
||||
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom rrsig-failures.test`
|
||||
echo $CSK
|
||||
cat $CSK.ds >> bogus/trust-anchors
|
||||
|
||||
ldns-signzone -f tmp.signed bogus/rrsig-failures.test $CSK
|
||||
grep -v ' RRSIG ' tmp.signed > bogus/rrsig-failures.test.signed
|
||||
|
||||
# cleanup
|
||||
rm -f base expired notyetincepted tmp.signed $CSK.*
|
10
testdata/ede.tdir/bogus/nsec-failures.test
vendored
Normal file
10
testdata/ede.tdir/bogus/nsec-failures.test
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
$ORIGIN nsec-failures.test.
|
||||
|
||||
@ SOA ns hostmaster (
|
||||
1 ; serial
|
||||
14400 ; refresh (4 hours)
|
||||
1800 ; retry (30 minutes)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
A 192.0.2.1
|
10
testdata/ede.tdir/bogus/rrsig-failures.test
vendored
Normal file
10
testdata/ede.tdir/bogus/rrsig-failures.test
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
$ORIGIN rrsig-failures.test.
|
||||
|
||||
@ SOA ns hostmaster (
|
||||
1 ; serial
|
||||
14400 ; refresh (4 hours)
|
||||
1800 ; retry (30 minutes)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
A 192.0.2.1
|
25
testdata/ede.tdir/ede-auth.conf
vendored
Normal file
25
testdata/ede.tdir/ede-auth.conf
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
server:
|
||||
verbosity: 1
|
||||
use-syslog: no
|
||||
chroot: ""
|
||||
username: ""
|
||||
directory: ""
|
||||
local-zone: test nodefault
|
||||
port: @PORT2@
|
||||
|
||||
auth-zone:
|
||||
name: "dnssec-failures.test"
|
||||
zonefile: "bogus/dnssec-failures.test.signed"
|
||||
|
||||
auth-zone:
|
||||
name: "dnskey-failures.test"
|
||||
zonefile: "bogus/dnskey-failures.test.signed"
|
||||
|
||||
auth-zone:
|
||||
name: "nsec-failures.test"
|
||||
zonefile: "bogus/nsec-failures.test.signed"
|
||||
|
||||
auth-zone:
|
||||
name: "rrsig-failures.test"
|
||||
zonefile: "bogus/rrsig-failures.test.signed"
|
||||
|
49
testdata/ede.tdir/ede.conf
vendored
Normal file
49
testdata/ede.tdir/ede.conf
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
server:
|
||||
verbosity: 2
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: .
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
directory: ""
|
||||
val-log-level: 2
|
||||
|
||||
trust-anchor-file: "bogus/trust-anchors"
|
||||
|
||||
module-config: "respip validator iterator"
|
||||
|
||||
ede: yes
|
||||
access-control: 127.0.0.2/32 refuse
|
||||
access-control: 127.0.0.3/32 allow
|
||||
|
||||
local-zone: hopsa.kidee. always_refuse
|
||||
local-data: "hopsa.kidee. TXT hela hola"
|
||||
|
||||
local-zone: nlnetlabs.nl transparent
|
||||
local-data: "hopsa.nlnetlabs.nl. TXT hela hola"
|
||||
|
||||
local-zone: uva.nl. always_null
|
||||
|
||||
local-zone: example.com redirect
|
||||
local-data: "example.com CNAME *.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa."
|
||||
|
||||
local-zone: test nodefault
|
||||
do-not-query-localhost: no
|
||||
|
||||
forward-zone:
|
||||
name: "dnssec-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
name: "dnskey-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
name: "nsec-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
name: "rrsig-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
16
testdata/ede.tdir/ede.dsc
vendored
Normal file
16
testdata/ede.tdir/ede.dsc
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
BaseName: ede
|
||||
Version: 1.0
|
||||
Description: Test Extended DNS Errors (rfc8914)
|
||||
CreationDate: Fri Aug 20 15:42:11 UTC 2021
|
||||
Maintainer: Tom Carpay
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: ede.pre
|
||||
Post: ede.post
|
||||
Test: ede.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
10
testdata/ede.tdir/ede.post
vendored
Normal file
10
testdata/ede.tdir/ede.post
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# #-- ede.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
# teardown
|
||||
. ../common.sh
|
||||
kill_pid $UNBOUND_PID
|
||||
kill_pid $UNBOUND_PID2
|
37
testdata/ede.tdir/ede.pre
vendored
Normal file
37
testdata/ede.tdir/ede.pre
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
# #-- ede.pre --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
UNBOUND_PORT2=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "UNBOUND_PORT2=$UNBOUND_PORT2" >> .tpkg.var.test
|
||||
|
||||
# rewrite config file with created ports
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' < ede.conf > temp.conf
|
||||
sed -e 's/@PORT2\@/'$UNBOUND_PORT2'/' < temp.conf > ub.conf
|
||||
sed -e 's/@PORT2\@/'$UNBOUND_PORT2'/' < ede-auth.conf > ub2.conf
|
||||
|
||||
# create broken dnssec zone
|
||||
bogus/make-broken-zone.sh
|
||||
|
||||
# start unbound in the background
|
||||
PRE="../.."
|
||||
$PRE/unbound -d -c ub.conf > unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
|
||||
# start authoritative unbound in the background
|
||||
$PRE/unbound -d -c ub2.conf > unbound2.log 2>&1 &
|
||||
UNBOUND_PID2=$!
|
||||
echo "UNBOUND_PID2=$UNBOUND_PID2" >> .tpkg.var.test
|
||||
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_unbound_up unbound.log
|
||||
wait_unbound_up unbound2.log
|
||||
|
72
testdata/ede.tdir/ede.test
vendored
Normal file
72
testdata/ede.tdir/ede.test
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
# #-- ede.test --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
|
||||
# DNSSEC failure: Signature Expired or DNSKEY Missing (depending on the servfail configuration)
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT servfail.nl > servfail.txt
|
||||
|
||||
# DNSSEC failure: key not incepted
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT notyetincepted.dnssec-failures.test. TXT +dnssec > sig_notyetincepted.txt
|
||||
|
||||
if ! grep -q -e "OPT=15: 00 08" -e "EDE: 8" sig_notyetincepted.txt
|
||||
then
|
||||
echo "Signature not yet valid does not return EDE Signature Not Yet Valid"
|
||||
cat sig_notyetincepted.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# DNSSEC failure: key expired
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT expired.dnssec-failures.test. TXT +dnssec > sig_expired.txt
|
||||
|
||||
if ! grep -q -e "OPT=15: 00 07" -e "EDE: 7" sig_expired.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE Signature expired"
|
||||
cat sig_expired.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# DNSSEC failure: missing rrsigs
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT missingrrsigs.dnssec-failures.test. TXT +dnssec > missingrrsigs.txt
|
||||
|
||||
if ! grep -q -e "OPT=15: 00 0a" -e "EDE: 10" missingrrsigs.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE RRSIGs missing"
|
||||
cat missingrrsigs.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# signed zone with DNSKEY missing
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT dnskey-failures.test > dnskey-failure.txt
|
||||
|
||||
if ! grep -q -e "OPT=15: 00 09" -e "EDE: 9" dnskey-failure.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE DNSKEY missing"
|
||||
cat dnskey-failure.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# signed zone with RRSIGs missing
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT rrsig-failures.test > rrsig-failure.txt
|
||||
|
||||
if ! grep -q -e "OPT=15: 00 0a" -e "EDE: 10" rrsig-failure.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE RRSIGs missing"
|
||||
cat rrsig-failure.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# signed zone with NSEC missing
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT abc.nsec-failures.test > nsec-failure.txt
|
||||
|
||||
if ! grep -q -e "OPT=15: 00 0c" -e "EDE: 12" nsec-failure.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE NSEC missing"
|
||||
cat nsec-failure.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# @TODO DNSSEC indeterminate when implemented
|
35
testdata/ede_acl_refused.rpl
vendored
Normal file
35
testdata/ede_acl_refused.rpl
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
; config options
|
||||
server:
|
||||
access-control: 127.0.0.0/8 refuse
|
||||
ede: yes
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test ede-acl-refused
|
||||
; Scenario overview:
|
||||
; - query for example.com. A record with EDNS
|
||||
; - check that we get a refused answer with EDE (RFC8914) code 18 - Prohibited
|
||||
|
||||
; Query without RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got ede 18
|
||||
STEP 2 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=18
|
||||
REPLY QR RD REFUSED
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
33
testdata/ede_cache_snoop_noth_auth.rpl
vendored
Normal file
33
testdata/ede_cache_snoop_noth_auth.rpl
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
; config options
|
||||
server:
|
||||
ede: yes
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test ede-cache-snoop-not-authoritative
|
||||
; Scenario overview:
|
||||
; - query for example.com. A record with EDNS without the RD bit
|
||||
; - check that we get a refused answer with EDE (RFC8914) code 20 - Not Authoritative
|
||||
|
||||
; Query without RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got ede 20
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=20
|
||||
REPLY QR RA REFUSED
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
37
testdata/ede_localzone_dname_expansion.rpl
vendored
Normal file
37
testdata/ede_localzone_dname_expansion.rpl
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
; config options
|
||||
server:
|
||||
local-zone: example.com redirect
|
||||
local-data: "example.com CNAME *.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa."
|
||||
ede: yes
|
||||
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test ede-localzone-dname-expansion
|
||||
; Scenario overview:
|
||||
; - query for www.qhqwer.qwer.qwer.h.example.com. (a large Qname) A record with EDNS
|
||||
; - check that we get a YXDOMAIN answer with EDE (RFC8914) code 0 - Other (which adds a DNAME expansion message)
|
||||
|
||||
; Query with RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.qhqwer.qwer.qwer.h.example.com A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer (should be cached)
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=0
|
||||
REPLY QR AA RD RA YXDOMAIN
|
||||
SECTION QUESTION
|
||||
www.qhqwer.qwer.qwer.h.example.com A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
6
testdata/edns_keepalive.rpl
vendored
6
testdata/edns_keepalive.rpl
vendored
@ -47,14 +47,10 @@ STEP 1 QUERY
|
||||
STEP 10 CHECK_ANSWER
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH TCP ednsdata
|
||||
MATCH TCP
|
||||
REPLY RD FORMERR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; Empty
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY
|
||||
|
3
testdata/nsid_bogus.rpl
vendored
3
testdata/nsid_bogus.rpl
vendored
@ -9,6 +9,7 @@ server:
|
||||
trust-anchor-signaling: no
|
||||
minimal-responses: no
|
||||
nsid: "ascii_hopsa kidee"
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -157,7 +158,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
5
testdata/root_key_sentinel.rpl
vendored
5
testdata/root_key_sentinel.rpl
vendored
@ -4,6 +4,7 @@ server:
|
||||
val-override-date: "20180423171826"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -138,7 +139,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 22 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
root-key-sentinel-not-ta-19036. IN A
|
||||
@ -154,7 +155,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 33 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
root-key-sentinel-is-ta-20326. IN A
|
||||
|
7
testdata/serve_expired.rpl
vendored
7
testdata/serve_expired.rpl
vendored
@ -5,6 +5,8 @@ server:
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
access-control: 127.0.0.1/32 allow_snoop
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
@ -78,6 +80,7 @@ STEP 11 TIME_PASSES ELAPSE 3601
|
||||
; Query again without RD bit
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY DO
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
@ -85,8 +88,8 @@ ENTRY_END
|
||||
; Check that we got a stale answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
8
testdata/serve_expired_client_timeout.rpl
vendored
8
testdata/serve_expired_client_timeout.rpl
vendored
@ -6,6 +6,8 @@ server:
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 1
|
||||
serve-expired-reply-ttl: 123
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
@ -83,7 +85,7 @@ STEP 11 TIME_PASSES ELAPSE 3600
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
@ -94,8 +96,8 @@ STEP 31 TIME_PASSES ELAPSE 1
|
||||
; Check that we got a stale answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
8
testdata/serve_expired_reply_ttl.rpl
vendored
8
testdata/serve_expired_reply_ttl.rpl
vendored
@ -5,6 +5,8 @@ server:
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-reply-ttl: 123
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
@ -77,7 +79,7 @@ STEP 11 TIME_PASSES ELAPSE 3601
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
@ -85,8 +87,8 @@ ENTRY_END
|
||||
; Check that we got a stale answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
8
testdata/serve_expired_servfail.rpl
vendored
8
testdata/serve_expired_servfail.rpl
vendored
@ -7,6 +7,8 @@ server:
|
||||
serve-expired-client-timeout: 1800
|
||||
serve-expired-reply-ttl: 123
|
||||
log-servfail: yes
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
|
||||
stub-zone:
|
||||
@ -94,7 +96,7 @@ STEP 11 TIME_PASSES ELAPSE 3601
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
@ -102,8 +104,8 @@ ENTRY_END
|
||||
; Check that we got a stale answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
8
testdata/serve_expired_zerottl.rpl
vendored
8
testdata/serve_expired_zerottl.rpl
vendored
@ -5,6 +5,8 @@ server:
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-reply-ttl: 123
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
@ -128,7 +130,7 @@ STEP 30 TIME_PASSES ELAPSE 11
|
||||
; Query with RD flag
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
@ -136,8 +138,8 @@ ENTRY_END
|
||||
; Check that we got the correct answer
|
||||
STEP 49 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
8
testdata/serve_original_ttl.rpl
vendored
8
testdata/serve_original_ttl.rpl
vendored
@ -9,6 +9,8 @@ server:
|
||||
cache-min-ttl: 20
|
||||
serve-expired: yes
|
||||
serve-expired-reply-ttl: 123
|
||||
ede: yes
|
||||
ede-serve-expired: yes
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
@ -110,7 +112,7 @@ STEP 31 TIME_PASSES ELAPSE 3601
|
||||
; Query again
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY
|
||||
REPLY DO
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
@ -118,8 +120,8 @@ ENTRY_END
|
||||
; Check that we got a stale answer with the original TTL
|
||||
STEP 50 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RA NOERROR
|
||||
MATCH all ttl ede=3
|
||||
REPLY QR RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
|
3
testdata/val_cnametocloser_nosig.rpl
vendored
3
testdata/val_cnametocloser_nosig.rpl
vendored
@ -5,6 +5,7 @@ server:
|
||||
val-override-date: "20091113091234"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
forward-zone:
|
||||
name: "."
|
||||
@ -88,7 +89,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN AAAA
|
||||
|
4
testdata/val_cnametonodata_nonsec.rpl
vendored
4
testdata/val_cnametonodata_nonsec.rpl
vendored
@ -8,6 +8,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -254,12 +255,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
5
testdata/val_cnametoposnowc.rpl
vendored
5
testdata/val_cnametoposnowc.rpl
vendored
@ -8,6 +8,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -253,13 +254,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
3
testdata/val_deleg_nons.rpl
vendored
3
testdata/val_deleg_nons.rpl
vendored
@ -7,6 +7,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -261,7 +262,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
foo.www.example.com. IN A
|
||||
|
5
testdata/val_dnamewc.rpl
vendored
5
testdata/val_dnamewc.rpl
vendored
@ -8,6 +8,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -256,13 +257,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
4
testdata/val_ds_cname.rpl
vendored
4
testdata/val_ds_cname.rpl
vendored
@ -7,6 +7,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -195,11 +196,10 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
3
testdata/val_faildnskey.rpl
vendored
3
testdata/val_faildnskey.rpl
vendored
@ -7,6 +7,7 @@ server:
|
||||
# test that default value of harden-dnssec-stripped is still yes.
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -160,7 +161,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
5
testdata/val_nodata_failsig.rpl
vendored
5
testdata/val_nodata_failsig.rpl
vendored
@ -7,6 +7,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -154,13 +155,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
6
testdata/val_nodata_failwc.rpl
vendored
6
testdata/val_nodata_failwc.rpl
vendored
@ -7,6 +7,8 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "nsecwc.nlnetlabs.nl"
|
||||
stub-addr: "185.49.140.60"
|
||||
@ -60,13 +62,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
_25._tcp.mail.nsecwc.nlnetlabs.nl. IN TLSA
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
3
testdata/val_nokeyprime.rpl
vendored
3
testdata/val_nokeyprime.rpl
vendored
@ -6,6 +6,7 @@ server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -153,7 +154,7 @@ ENTRY_END
|
||||
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
4
testdata/val_nsec3_b1_nameerror_nowc.rpl
vendored
4
testdata/val_nsec3_b1_nameerror_nowc.rpl
vendored
@ -6,6 +6,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -133,7 +134,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
a.c.x.w.example. IN A
|
||||
@ -145,7 +146,6 @@ SECTION AUTHORITY
|
||||
; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
|
||||
; b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
|
||||
; b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
5
testdata/val_nsec3_b2_nodata_nons.rpl
vendored
5
testdata/val_nsec3_b2_nodata_nons.rpl
vendored
@ -5,6 +5,7 @@ server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -127,13 +128,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=12
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ns1.example. IN MX
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
@ -6,6 +6,7 @@ server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -186,13 +187,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ent.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
5
testdata/val_nsec3_nods_badsig.rpl
vendored
5
testdata/val_nsec3_nods_badsig.rpl
vendored
@ -7,6 +7,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -226,13 +227,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
6
testdata/val_nx_failwc.rpl
vendored
6
testdata/val_nx_failwc.rpl
vendored
@ -7,6 +7,8 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "nsecwc.nlnetlabs.nl"
|
||||
stub-addr: "185.49.140.60"
|
||||
@ -58,13 +60,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
a.nsecwc.nlnetlabs.nl. IN TXT
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
5
testdata/val_nx_overreach.rpl
vendored
5
testdata/val_nx_overreach.rpl
vendored
@ -7,6 +7,7 @@ server:
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -154,13 +155,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
3
testdata/val_secds_nosig.rpl
vendored
3
testdata/val_secds_nosig.rpl
vendored
@ -6,6 +6,7 @@ server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -223,7 +224,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
|
3
testdata/val_ta_algo_missing.rpl
vendored
3
testdata/val_ta_algo_missing.rpl
vendored
@ -10,6 +10,7 @@ server:
|
||||
harden-algo-downgrade: yes
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
@ -165,7 +166,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
@ -268,6 +268,7 @@ config_create(void)
|
||||
cfg->serve_expired_ttl_reset = 0;
|
||||
cfg->serve_expired_reply_ttl = 30;
|
||||
cfg->serve_expired_client_timeout = 0;
|
||||
cfg->ede_serve_expired = 0;
|
||||
cfg->serve_original_ttl = 0;
|
||||
cfg->zonemd_permissive_mode = 0;
|
||||
cfg->add_holddown = 30*24*3600;
|
||||
@ -376,6 +377,7 @@ config_create(void)
|
||||
cfg->ipset_name_v4 = NULL;
|
||||
cfg->ipset_name_v6 = NULL;
|
||||
#endif
|
||||
cfg->ede = 0;
|
||||
return cfg;
|
||||
error_exit:
|
||||
config_delete(cfg);
|
||||
@ -670,6 +672,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else if(strcmp(opt, "serve-expired-reply-ttl:") == 0)
|
||||
{ IS_NUMBER_OR_ZERO; cfg->serve_expired_reply_ttl = atoi(val); SERVE_EXPIRED_REPLY_TTL=(time_t)cfg->serve_expired_reply_ttl;}
|
||||
else S_NUMBER_OR_ZERO("serve-expired-client-timeout:", serve_expired_client_timeout)
|
||||
else S_YNO("ede:", ede)
|
||||
else S_YNO("ede_serve-expired:", ede_serve_expired)
|
||||
else S_YNO("serve-original-ttl:", serve_original_ttl)
|
||||
else S_STR("val-nsec3-keysize-iterations:", val_nsec3_key_iterations)
|
||||
else S_YNO("zonemd-permissive-mode:", zonemd_permissive_mode)
|
||||
@ -1111,6 +1115,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_YNO(opt, "serve-expired-ttl-reset", serve_expired_ttl_reset)
|
||||
else O_DEC(opt, "serve-expired-reply-ttl", serve_expired_reply_ttl)
|
||||
else O_DEC(opt, "serve-expired-client-timeout", serve_expired_client_timeout)
|
||||
else O_YNO(opt, "ede", ede)
|
||||
else O_YNO(opt, "ede-serve-expired", ede_serve_expired)
|
||||
else O_YNO(opt, "serve-original-ttl", serve_original_ttl)
|
||||
else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations)
|
||||
else O_YNO(opt, "zonemd-permissive-mode", zonemd_permissive_mode)
|
||||
@ -2486,7 +2492,7 @@ char* cfg_ptr_reverse(char* str)
|
||||
while(*ip_end && isspace((unsigned char)*ip_end))
|
||||
ip_end++;
|
||||
if(name>ip_end) {
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%.*s",
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%.*s",
|
||||
(int)(name-ip_end), ip_end);
|
||||
}
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), " PTR %s", name);
|
||||
@ -2557,126 +2563,6 @@ void w_config_adjust_directory(struct config_file* cfg)
|
||||
}
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
|
||||
void errinf(struct module_qstate* qstate, const char* str)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str)
|
||||
return;
|
||||
p = (struct config_strlist*)regional_alloc(qstate->region, sizeof(*p));
|
||||
if(!p) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
p->next = NULL;
|
||||
p->str = regional_strdup(qstate->region, str);
|
||||
if(!p->str) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
/* add at end */
|
||||
if(qstate->errinf) {
|
||||
struct config_strlist* q = qstate->errinf;
|
||||
while(q->next)
|
||||
q = q->next;
|
||||
q->next = p;
|
||||
} else qstate->errinf = p;
|
||||
}
|
||||
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin)
|
||||
{
|
||||
struct sock_list* p;
|
||||
if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
|
||||
return;
|
||||
for(p=origin; p; p=p->next) {
|
||||
char buf[256];
|
||||
if(p == origin)
|
||||
snprintf(buf, sizeof(buf), "from ");
|
||||
else snprintf(buf, sizeof(buf), "and ");
|
||||
if(p->len == 0)
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf),
|
||||
"cache");
|
||||
else
|
||||
addr_to_str(&p->addr, p->len, buf+strlen(buf),
|
||||
sizeof(buf)-strlen(buf));
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
}
|
||||
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct config_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct config_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr)
|
||||
{
|
||||
char buf[1024];
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !rr)
|
||||
return;
|
||||
sldns_wire2str_type_buf(ntohs(rr->rk.type), t, sizeof(t));
|
||||
sldns_wire2str_class_buf(ntohs(rr->rk.rrset_class), c, sizeof(c));
|
||||
dname_str(rr->rk.dname, dname);
|
||||
snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c);
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname)
|
||||
{
|
||||
char b[1024];
|
||||
char buf[LDNS_MAX_DOMAINLEN+1];
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str || !dname)
|
||||
return;
|
||||
dname_str(dname, buf);
|
||||
snprintf(b, sizeof(b), "%s %s", str, buf);
|
||||
errinf(qstate, b);
|
||||
}
|
||||
|
||||
int options_remote_is_address(struct config_file* cfg)
|
||||
{
|
||||
if(!cfg->remote_control_enable) return 0;
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#ifndef UTIL_CONFIG_FILE_H
|
||||
#define UTIL_CONFIG_FILE_H
|
||||
#include "sldns/rrdef.h"
|
||||
struct config_stub;
|
||||
struct config_auth;
|
||||
struct config_view;
|
||||
@ -406,6 +407,8 @@ struct config_file {
|
||||
/** serve expired entries only after trying to update the entries and this
|
||||
* timeout (in milliseconds) is reached */
|
||||
int serve_expired_client_timeout;
|
||||
/** serve EDE code 3 - Stale Answer (RFC8914) for expired entries */
|
||||
int ede_serve_expired;
|
||||
/** serve original TTLs rather than decrementing ones */
|
||||
int serve_original_ttl;
|
||||
/** nsec3 maximum iterations per key size, string */
|
||||
@ -679,6 +682,8 @@ struct config_file {
|
||||
char* ipset_name_v4;
|
||||
char* ipset_name_v6;
|
||||
#endif
|
||||
/** respond with Extended DNS Errors (RFC8914) */
|
||||
int ede;
|
||||
};
|
||||
|
||||
/** from cfg username, after daemonize setup performed */
|
||||
@ -1241,56 +1246,6 @@ char* fname_after_chroot(const char* fname, struct config_file* cfg,
|
||||
*/
|
||||
char* cfg_ptr_reverse(char* str);
|
||||
|
||||
/**
|
||||
* Append text to the error info for validation.
|
||||
* @param qstate: query state.
|
||||
* @param str: copied into query region and appended.
|
||||
* Failures to allocate are logged.
|
||||
*/
|
||||
void errinf(struct module_qstate* qstate, const char* str);
|
||||
|
||||
/**
|
||||
* Append text to error info: from 1.2.3.4
|
||||
* @param qstate: query state.
|
||||
* @param origin: sock list with origin of trouble.
|
||||
* Every element added.
|
||||
* If NULL: nothing is added.
|
||||
* if 0len element: 'from cache' is added.
|
||||
*/
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin);
|
||||
|
||||
/**
|
||||
* Append text to error info: for RRset name type class
|
||||
* @param qstate: query state.
|
||||
* @param rr: rrset_key.
|
||||
*/
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr);
|
||||
|
||||
/**
|
||||
* Append text to error info: str dname
|
||||
* @param qstate: query state.
|
||||
* @param str: explanation string
|
||||
* @param dname: the dname.
|
||||
*/
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str,
|
||||
uint8_t* dname);
|
||||
|
||||
/**
|
||||
* Create error info in string. For validation failures.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Create error info in string. For other servfails.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Used during options parsing
|
||||
*/
|
||||
|
6001
util/configlexer.c
6001
util/configlexer.c
File diff suppressed because it is too large
Load Diff
@ -402,6 +402,7 @@ serve-expired-ttl{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_TTL) }
|
||||
serve-expired-ttl-reset{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_TTL_RESET) }
|
||||
serve-expired-reply-ttl{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_REPLY_TTL) }
|
||||
serve-expired-client-timeout{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_CLIENT_TIMEOUT) }
|
||||
ede-serve-expired{COLON} { YDVAR(1, VAR_EDE_SERVE_EXPIRED) }
|
||||
serve-original-ttl{COLON} { YDVAR(1, VAR_SERVE_ORIGINAL_TTL) }
|
||||
fake-dsa{COLON} { YDVAR(1, VAR_FAKE_DSA) }
|
||||
fake-sha1{COLON} { YDVAR(1, VAR_FAKE_SHA1) }
|
||||
@ -553,6 +554,7 @@ tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
|
||||
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
|
||||
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
|
||||
nsid{COLON} { YDVAR(1, VAR_NSID ) }
|
||||
ede{COLON} { YDVAR(1, VAR_EDE ) }
|
||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||
|
||||
/* Quoted strings. Strip leading and ending quotes */
|
||||
|
9080
util/configparser.c
9080
util/configparser.c
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,14 @@
|
||||
/* A Bison parser, made by GNU Bison 3.7.6. */
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
|
||||
Inc.
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -16,7 +16,9 @@
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
@ -31,359 +33,339 @@
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
|
||||
especially those whose name start with YY_ or yy_. They are
|
||||
private implementation details that can be changed or removed. */
|
||||
|
||||
#ifndef YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
|
||||
# define YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
|
||||
/* Token kinds. */
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
YYEMPTY = -2,
|
||||
YYEOF = 0, /* "end of file" */
|
||||
YYerror = 256, /* error */
|
||||
YYUNDEF = 257, /* "invalid token" */
|
||||
SPACE = 258, /* SPACE */
|
||||
LETTER = 259, /* LETTER */
|
||||
NEWLINE = 260, /* NEWLINE */
|
||||
COMMENT = 261, /* COMMENT */
|
||||
COLON = 262, /* COLON */
|
||||
ANY = 263, /* ANY */
|
||||
ZONESTR = 264, /* ZONESTR */
|
||||
STRING_ARG = 265, /* STRING_ARG */
|
||||
VAR_FORCE_TOPLEVEL = 266, /* VAR_FORCE_TOPLEVEL */
|
||||
VAR_SERVER = 267, /* VAR_SERVER */
|
||||
VAR_VERBOSITY = 268, /* VAR_VERBOSITY */
|
||||
VAR_NUM_THREADS = 269, /* VAR_NUM_THREADS */
|
||||
VAR_PORT = 270, /* VAR_PORT */
|
||||
VAR_OUTGOING_RANGE = 271, /* VAR_OUTGOING_RANGE */
|
||||
VAR_INTERFACE = 272, /* VAR_INTERFACE */
|
||||
VAR_PREFER_IP4 = 273, /* VAR_PREFER_IP4 */
|
||||
VAR_DO_IP4 = 274, /* VAR_DO_IP4 */
|
||||
VAR_DO_IP6 = 275, /* VAR_DO_IP6 */
|
||||
VAR_PREFER_IP6 = 276, /* VAR_PREFER_IP6 */
|
||||
VAR_DO_UDP = 277, /* VAR_DO_UDP */
|
||||
VAR_DO_TCP = 278, /* VAR_DO_TCP */
|
||||
VAR_TCP_MSS = 279, /* VAR_TCP_MSS */
|
||||
VAR_OUTGOING_TCP_MSS = 280, /* VAR_OUTGOING_TCP_MSS */
|
||||
VAR_TCP_IDLE_TIMEOUT = 281, /* VAR_TCP_IDLE_TIMEOUT */
|
||||
VAR_EDNS_TCP_KEEPALIVE = 282, /* VAR_EDNS_TCP_KEEPALIVE */
|
||||
VAR_EDNS_TCP_KEEPALIVE_TIMEOUT = 283, /* VAR_EDNS_TCP_KEEPALIVE_TIMEOUT */
|
||||
VAR_CHROOT = 284, /* VAR_CHROOT */
|
||||
VAR_USERNAME = 285, /* VAR_USERNAME */
|
||||
VAR_DIRECTORY = 286, /* VAR_DIRECTORY */
|
||||
VAR_LOGFILE = 287, /* VAR_LOGFILE */
|
||||
VAR_PIDFILE = 288, /* VAR_PIDFILE */
|
||||
VAR_MSG_CACHE_SIZE = 289, /* VAR_MSG_CACHE_SIZE */
|
||||
VAR_MSG_CACHE_SLABS = 290, /* VAR_MSG_CACHE_SLABS */
|
||||
VAR_NUM_QUERIES_PER_THREAD = 291, /* VAR_NUM_QUERIES_PER_THREAD */
|
||||
VAR_RRSET_CACHE_SIZE = 292, /* VAR_RRSET_CACHE_SIZE */
|
||||
VAR_RRSET_CACHE_SLABS = 293, /* VAR_RRSET_CACHE_SLABS */
|
||||
VAR_OUTGOING_NUM_TCP = 294, /* VAR_OUTGOING_NUM_TCP */
|
||||
VAR_INFRA_HOST_TTL = 295, /* VAR_INFRA_HOST_TTL */
|
||||
VAR_INFRA_LAME_TTL = 296, /* VAR_INFRA_LAME_TTL */
|
||||
VAR_INFRA_CACHE_SLABS = 297, /* VAR_INFRA_CACHE_SLABS */
|
||||
VAR_INFRA_CACHE_NUMHOSTS = 298, /* VAR_INFRA_CACHE_NUMHOSTS */
|
||||
VAR_INFRA_CACHE_LAME_SIZE = 299, /* VAR_INFRA_CACHE_LAME_SIZE */
|
||||
VAR_NAME = 300, /* VAR_NAME */
|
||||
VAR_STUB_ZONE = 301, /* VAR_STUB_ZONE */
|
||||
VAR_STUB_HOST = 302, /* VAR_STUB_HOST */
|
||||
VAR_STUB_ADDR = 303, /* VAR_STUB_ADDR */
|
||||
VAR_TARGET_FETCH_POLICY = 304, /* VAR_TARGET_FETCH_POLICY */
|
||||
VAR_HARDEN_SHORT_BUFSIZE = 305, /* VAR_HARDEN_SHORT_BUFSIZE */
|
||||
VAR_HARDEN_LARGE_QUERIES = 306, /* VAR_HARDEN_LARGE_QUERIES */
|
||||
VAR_FORWARD_ZONE = 307, /* VAR_FORWARD_ZONE */
|
||||
VAR_FORWARD_HOST = 308, /* VAR_FORWARD_HOST */
|
||||
VAR_FORWARD_ADDR = 309, /* VAR_FORWARD_ADDR */
|
||||
VAR_DO_NOT_QUERY_ADDRESS = 310, /* VAR_DO_NOT_QUERY_ADDRESS */
|
||||
VAR_HIDE_IDENTITY = 311, /* VAR_HIDE_IDENTITY */
|
||||
VAR_HIDE_VERSION = 312, /* VAR_HIDE_VERSION */
|
||||
VAR_IDENTITY = 313, /* VAR_IDENTITY */
|
||||
VAR_VERSION = 314, /* VAR_VERSION */
|
||||
VAR_HARDEN_GLUE = 315, /* VAR_HARDEN_GLUE */
|
||||
VAR_MODULE_CONF = 316, /* VAR_MODULE_CONF */
|
||||
VAR_TRUST_ANCHOR_FILE = 317, /* VAR_TRUST_ANCHOR_FILE */
|
||||
VAR_TRUST_ANCHOR = 318, /* VAR_TRUST_ANCHOR */
|
||||
VAR_VAL_OVERRIDE_DATE = 319, /* VAR_VAL_OVERRIDE_DATE */
|
||||
VAR_BOGUS_TTL = 320, /* VAR_BOGUS_TTL */
|
||||
VAR_VAL_CLEAN_ADDITIONAL = 321, /* VAR_VAL_CLEAN_ADDITIONAL */
|
||||
VAR_VAL_PERMISSIVE_MODE = 322, /* VAR_VAL_PERMISSIVE_MODE */
|
||||
VAR_INCOMING_NUM_TCP = 323, /* VAR_INCOMING_NUM_TCP */
|
||||
VAR_MSG_BUFFER_SIZE = 324, /* VAR_MSG_BUFFER_SIZE */
|
||||
VAR_KEY_CACHE_SIZE = 325, /* VAR_KEY_CACHE_SIZE */
|
||||
VAR_KEY_CACHE_SLABS = 326, /* VAR_KEY_CACHE_SLABS */
|
||||
VAR_TRUSTED_KEYS_FILE = 327, /* VAR_TRUSTED_KEYS_FILE */
|
||||
VAR_VAL_NSEC3_KEYSIZE_ITERATIONS = 328, /* VAR_VAL_NSEC3_KEYSIZE_ITERATIONS */
|
||||
VAR_USE_SYSLOG = 329, /* VAR_USE_SYSLOG */
|
||||
VAR_OUTGOING_INTERFACE = 330, /* VAR_OUTGOING_INTERFACE */
|
||||
VAR_ROOT_HINTS = 331, /* VAR_ROOT_HINTS */
|
||||
VAR_DO_NOT_QUERY_LOCALHOST = 332, /* VAR_DO_NOT_QUERY_LOCALHOST */
|
||||
VAR_CACHE_MAX_TTL = 333, /* VAR_CACHE_MAX_TTL */
|
||||
VAR_HARDEN_DNSSEC_STRIPPED = 334, /* VAR_HARDEN_DNSSEC_STRIPPED */
|
||||
VAR_ACCESS_CONTROL = 335, /* VAR_ACCESS_CONTROL */
|
||||
VAR_LOCAL_ZONE = 336, /* VAR_LOCAL_ZONE */
|
||||
VAR_LOCAL_DATA = 337, /* VAR_LOCAL_DATA */
|
||||
VAR_INTERFACE_AUTOMATIC = 338, /* VAR_INTERFACE_AUTOMATIC */
|
||||
VAR_STATISTICS_INTERVAL = 339, /* VAR_STATISTICS_INTERVAL */
|
||||
VAR_DO_DAEMONIZE = 340, /* VAR_DO_DAEMONIZE */
|
||||
VAR_USE_CAPS_FOR_ID = 341, /* VAR_USE_CAPS_FOR_ID */
|
||||
VAR_STATISTICS_CUMULATIVE = 342, /* VAR_STATISTICS_CUMULATIVE */
|
||||
VAR_OUTGOING_PORT_PERMIT = 343, /* VAR_OUTGOING_PORT_PERMIT */
|
||||
VAR_OUTGOING_PORT_AVOID = 344, /* VAR_OUTGOING_PORT_AVOID */
|
||||
VAR_DLV_ANCHOR_FILE = 345, /* VAR_DLV_ANCHOR_FILE */
|
||||
VAR_DLV_ANCHOR = 346, /* VAR_DLV_ANCHOR */
|
||||
VAR_NEG_CACHE_SIZE = 347, /* VAR_NEG_CACHE_SIZE */
|
||||
VAR_HARDEN_REFERRAL_PATH = 348, /* VAR_HARDEN_REFERRAL_PATH */
|
||||
VAR_PRIVATE_ADDRESS = 349, /* VAR_PRIVATE_ADDRESS */
|
||||
VAR_PRIVATE_DOMAIN = 350, /* VAR_PRIVATE_DOMAIN */
|
||||
VAR_REMOTE_CONTROL = 351, /* VAR_REMOTE_CONTROL */
|
||||
VAR_CONTROL_ENABLE = 352, /* VAR_CONTROL_ENABLE */
|
||||
VAR_CONTROL_INTERFACE = 353, /* VAR_CONTROL_INTERFACE */
|
||||
VAR_CONTROL_PORT = 354, /* VAR_CONTROL_PORT */
|
||||
VAR_SERVER_KEY_FILE = 355, /* VAR_SERVER_KEY_FILE */
|
||||
VAR_SERVER_CERT_FILE = 356, /* VAR_SERVER_CERT_FILE */
|
||||
VAR_CONTROL_KEY_FILE = 357, /* VAR_CONTROL_KEY_FILE */
|
||||
VAR_CONTROL_CERT_FILE = 358, /* VAR_CONTROL_CERT_FILE */
|
||||
VAR_CONTROL_USE_CERT = 359, /* VAR_CONTROL_USE_CERT */
|
||||
VAR_TCP_REUSE_TIMEOUT = 360, /* VAR_TCP_REUSE_TIMEOUT */
|
||||
VAR_MAX_REUSE_TCP_QUERIES = 361, /* VAR_MAX_REUSE_TCP_QUERIES */
|
||||
VAR_EXTENDED_STATISTICS = 362, /* VAR_EXTENDED_STATISTICS */
|
||||
VAR_LOCAL_DATA_PTR = 363, /* VAR_LOCAL_DATA_PTR */
|
||||
VAR_JOSTLE_TIMEOUT = 364, /* VAR_JOSTLE_TIMEOUT */
|
||||
VAR_STUB_PRIME = 365, /* VAR_STUB_PRIME */
|
||||
VAR_UNWANTED_REPLY_THRESHOLD = 366, /* VAR_UNWANTED_REPLY_THRESHOLD */
|
||||
VAR_LOG_TIME_ASCII = 367, /* VAR_LOG_TIME_ASCII */
|
||||
VAR_DOMAIN_INSECURE = 368, /* VAR_DOMAIN_INSECURE */
|
||||
VAR_PYTHON = 369, /* VAR_PYTHON */
|
||||
VAR_PYTHON_SCRIPT = 370, /* VAR_PYTHON_SCRIPT */
|
||||
VAR_VAL_SIG_SKEW_MIN = 371, /* VAR_VAL_SIG_SKEW_MIN */
|
||||
VAR_VAL_SIG_SKEW_MAX = 372, /* VAR_VAL_SIG_SKEW_MAX */
|
||||
VAR_VAL_MAX_RESTART = 373, /* VAR_VAL_MAX_RESTART */
|
||||
VAR_CACHE_MIN_TTL = 374, /* VAR_CACHE_MIN_TTL */
|
||||
VAR_VAL_LOG_LEVEL = 375, /* VAR_VAL_LOG_LEVEL */
|
||||
VAR_AUTO_TRUST_ANCHOR_FILE = 376, /* VAR_AUTO_TRUST_ANCHOR_FILE */
|
||||
VAR_KEEP_MISSING = 377, /* VAR_KEEP_MISSING */
|
||||
VAR_ADD_HOLDDOWN = 378, /* VAR_ADD_HOLDDOWN */
|
||||
VAR_DEL_HOLDDOWN = 379, /* VAR_DEL_HOLDDOWN */
|
||||
VAR_SO_RCVBUF = 380, /* VAR_SO_RCVBUF */
|
||||
VAR_EDNS_BUFFER_SIZE = 381, /* VAR_EDNS_BUFFER_SIZE */
|
||||
VAR_PREFETCH = 382, /* VAR_PREFETCH */
|
||||
VAR_PREFETCH_KEY = 383, /* VAR_PREFETCH_KEY */
|
||||
VAR_SO_SNDBUF = 384, /* VAR_SO_SNDBUF */
|
||||
VAR_SO_REUSEPORT = 385, /* VAR_SO_REUSEPORT */
|
||||
VAR_HARDEN_BELOW_NXDOMAIN = 386, /* VAR_HARDEN_BELOW_NXDOMAIN */
|
||||
VAR_IGNORE_CD_FLAG = 387, /* VAR_IGNORE_CD_FLAG */
|
||||
VAR_LOG_QUERIES = 388, /* VAR_LOG_QUERIES */
|
||||
VAR_LOG_REPLIES = 389, /* VAR_LOG_REPLIES */
|
||||
VAR_LOG_LOCAL_ACTIONS = 390, /* VAR_LOG_LOCAL_ACTIONS */
|
||||
VAR_TCP_UPSTREAM = 391, /* VAR_TCP_UPSTREAM */
|
||||
VAR_SSL_UPSTREAM = 392, /* VAR_SSL_UPSTREAM */
|
||||
VAR_TCP_AUTH_QUERY_TIMEOUT = 393, /* VAR_TCP_AUTH_QUERY_TIMEOUT */
|
||||
VAR_SSL_SERVICE_KEY = 394, /* VAR_SSL_SERVICE_KEY */
|
||||
VAR_SSL_SERVICE_PEM = 395, /* VAR_SSL_SERVICE_PEM */
|
||||
VAR_SSL_PORT = 396, /* VAR_SSL_PORT */
|
||||
VAR_FORWARD_FIRST = 397, /* VAR_FORWARD_FIRST */
|
||||
VAR_STUB_SSL_UPSTREAM = 398, /* VAR_STUB_SSL_UPSTREAM */
|
||||
VAR_FORWARD_SSL_UPSTREAM = 399, /* VAR_FORWARD_SSL_UPSTREAM */
|
||||
VAR_TLS_CERT_BUNDLE = 400, /* VAR_TLS_CERT_BUNDLE */
|
||||
VAR_STUB_TCP_UPSTREAM = 401, /* VAR_STUB_TCP_UPSTREAM */
|
||||
VAR_FORWARD_TCP_UPSTREAM = 402, /* VAR_FORWARD_TCP_UPSTREAM */
|
||||
VAR_HTTPS_PORT = 403, /* VAR_HTTPS_PORT */
|
||||
VAR_HTTP_ENDPOINT = 404, /* VAR_HTTP_ENDPOINT */
|
||||
VAR_HTTP_MAX_STREAMS = 405, /* VAR_HTTP_MAX_STREAMS */
|
||||
VAR_HTTP_QUERY_BUFFER_SIZE = 406, /* VAR_HTTP_QUERY_BUFFER_SIZE */
|
||||
VAR_HTTP_RESPONSE_BUFFER_SIZE = 407, /* VAR_HTTP_RESPONSE_BUFFER_SIZE */
|
||||
VAR_HTTP_NODELAY = 408, /* VAR_HTTP_NODELAY */
|
||||
VAR_HTTP_NOTLS_DOWNSTREAM = 409, /* VAR_HTTP_NOTLS_DOWNSTREAM */
|
||||
VAR_STUB_FIRST = 410, /* VAR_STUB_FIRST */
|
||||
VAR_MINIMAL_RESPONSES = 411, /* VAR_MINIMAL_RESPONSES */
|
||||
VAR_RRSET_ROUNDROBIN = 412, /* VAR_RRSET_ROUNDROBIN */
|
||||
VAR_MAX_UDP_SIZE = 413, /* VAR_MAX_UDP_SIZE */
|
||||
VAR_DELAY_CLOSE = 414, /* VAR_DELAY_CLOSE */
|
||||
VAR_UDP_CONNECT = 415, /* VAR_UDP_CONNECT */
|
||||
VAR_UNBLOCK_LAN_ZONES = 416, /* VAR_UNBLOCK_LAN_ZONES */
|
||||
VAR_INSECURE_LAN_ZONES = 417, /* VAR_INSECURE_LAN_ZONES */
|
||||
VAR_INFRA_CACHE_MIN_RTT = 418, /* VAR_INFRA_CACHE_MIN_RTT */
|
||||
VAR_INFRA_KEEP_PROBING = 419, /* VAR_INFRA_KEEP_PROBING */
|
||||
VAR_DNS64_PREFIX = 420, /* VAR_DNS64_PREFIX */
|
||||
VAR_DNS64_SYNTHALL = 421, /* VAR_DNS64_SYNTHALL */
|
||||
VAR_DNS64_IGNORE_AAAA = 422, /* VAR_DNS64_IGNORE_AAAA */
|
||||
VAR_DNSTAP = 423, /* VAR_DNSTAP */
|
||||
VAR_DNSTAP_ENABLE = 424, /* VAR_DNSTAP_ENABLE */
|
||||
VAR_DNSTAP_SOCKET_PATH = 425, /* VAR_DNSTAP_SOCKET_PATH */
|
||||
VAR_DNSTAP_IP = 426, /* VAR_DNSTAP_IP */
|
||||
VAR_DNSTAP_TLS = 427, /* VAR_DNSTAP_TLS */
|
||||
VAR_DNSTAP_TLS_SERVER_NAME = 428, /* VAR_DNSTAP_TLS_SERVER_NAME */
|
||||
VAR_DNSTAP_TLS_CERT_BUNDLE = 429, /* VAR_DNSTAP_TLS_CERT_BUNDLE */
|
||||
VAR_DNSTAP_TLS_CLIENT_KEY_FILE = 430, /* VAR_DNSTAP_TLS_CLIENT_KEY_FILE */
|
||||
VAR_DNSTAP_TLS_CLIENT_CERT_FILE = 431, /* VAR_DNSTAP_TLS_CLIENT_CERT_FILE */
|
||||
VAR_DNSTAP_SEND_IDENTITY = 432, /* VAR_DNSTAP_SEND_IDENTITY */
|
||||
VAR_DNSTAP_SEND_VERSION = 433, /* VAR_DNSTAP_SEND_VERSION */
|
||||
VAR_DNSTAP_BIDIRECTIONAL = 434, /* VAR_DNSTAP_BIDIRECTIONAL */
|
||||
VAR_DNSTAP_IDENTITY = 435, /* VAR_DNSTAP_IDENTITY */
|
||||
VAR_DNSTAP_VERSION = 436, /* VAR_DNSTAP_VERSION */
|
||||
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 437, /* VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES */
|
||||
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 438, /* VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES */
|
||||
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 439, /* VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES */
|
||||
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 440, /* VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES */
|
||||
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 441, /* VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES */
|
||||
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 442, /* VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES */
|
||||
VAR_RESPONSE_IP_TAG = 443, /* VAR_RESPONSE_IP_TAG */
|
||||
VAR_RESPONSE_IP = 444, /* VAR_RESPONSE_IP */
|
||||
VAR_RESPONSE_IP_DATA = 445, /* VAR_RESPONSE_IP_DATA */
|
||||
VAR_HARDEN_ALGO_DOWNGRADE = 446, /* VAR_HARDEN_ALGO_DOWNGRADE */
|
||||
VAR_IP_TRANSPARENT = 447, /* VAR_IP_TRANSPARENT */
|
||||
VAR_IP_DSCP = 448, /* VAR_IP_DSCP */
|
||||
VAR_DISABLE_DNSSEC_LAME_CHECK = 449, /* VAR_DISABLE_DNSSEC_LAME_CHECK */
|
||||
VAR_IP_RATELIMIT = 450, /* VAR_IP_RATELIMIT */
|
||||
VAR_IP_RATELIMIT_SLABS = 451, /* VAR_IP_RATELIMIT_SLABS */
|
||||
VAR_IP_RATELIMIT_SIZE = 452, /* VAR_IP_RATELIMIT_SIZE */
|
||||
VAR_RATELIMIT = 453, /* VAR_RATELIMIT */
|
||||
VAR_RATELIMIT_SLABS = 454, /* VAR_RATELIMIT_SLABS */
|
||||
VAR_RATELIMIT_SIZE = 455, /* VAR_RATELIMIT_SIZE */
|
||||
VAR_OUTBOUND_MSG_RETRY = 456, /* VAR_OUTBOUND_MSG_RETRY */
|
||||
VAR_RATELIMIT_FOR_DOMAIN = 457, /* VAR_RATELIMIT_FOR_DOMAIN */
|
||||
VAR_RATELIMIT_BELOW_DOMAIN = 458, /* VAR_RATELIMIT_BELOW_DOMAIN */
|
||||
VAR_IP_RATELIMIT_FACTOR = 459, /* VAR_IP_RATELIMIT_FACTOR */
|
||||
VAR_RATELIMIT_FACTOR = 460, /* VAR_RATELIMIT_FACTOR */
|
||||
VAR_IP_RATELIMIT_BACKOFF = 461, /* VAR_IP_RATELIMIT_BACKOFF */
|
||||
VAR_RATELIMIT_BACKOFF = 462, /* VAR_RATELIMIT_BACKOFF */
|
||||
VAR_SEND_CLIENT_SUBNET = 463, /* VAR_SEND_CLIENT_SUBNET */
|
||||
VAR_CLIENT_SUBNET_ZONE = 464, /* VAR_CLIENT_SUBNET_ZONE */
|
||||
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 465, /* VAR_CLIENT_SUBNET_ALWAYS_FORWARD */
|
||||
VAR_CLIENT_SUBNET_OPCODE = 466, /* VAR_CLIENT_SUBNET_OPCODE */
|
||||
VAR_MAX_CLIENT_SUBNET_IPV4 = 467, /* VAR_MAX_CLIENT_SUBNET_IPV4 */
|
||||
VAR_MAX_CLIENT_SUBNET_IPV6 = 468, /* VAR_MAX_CLIENT_SUBNET_IPV6 */
|
||||
VAR_MIN_CLIENT_SUBNET_IPV4 = 469, /* VAR_MIN_CLIENT_SUBNET_IPV4 */
|
||||
VAR_MIN_CLIENT_SUBNET_IPV6 = 470, /* VAR_MIN_CLIENT_SUBNET_IPV6 */
|
||||
VAR_MAX_ECS_TREE_SIZE_IPV4 = 471, /* VAR_MAX_ECS_TREE_SIZE_IPV4 */
|
||||
VAR_MAX_ECS_TREE_SIZE_IPV6 = 472, /* VAR_MAX_ECS_TREE_SIZE_IPV6 */
|
||||
VAR_CAPS_WHITELIST = 473, /* VAR_CAPS_WHITELIST */
|
||||
VAR_CACHE_MAX_NEGATIVE_TTL = 474, /* VAR_CACHE_MAX_NEGATIVE_TTL */
|
||||
VAR_PERMIT_SMALL_HOLDDOWN = 475, /* VAR_PERMIT_SMALL_HOLDDOWN */
|
||||
VAR_QNAME_MINIMISATION = 476, /* VAR_QNAME_MINIMISATION */
|
||||
VAR_QNAME_MINIMISATION_STRICT = 477, /* VAR_QNAME_MINIMISATION_STRICT */
|
||||
VAR_IP_FREEBIND = 478, /* VAR_IP_FREEBIND */
|
||||
VAR_DEFINE_TAG = 479, /* VAR_DEFINE_TAG */
|
||||
VAR_LOCAL_ZONE_TAG = 480, /* VAR_LOCAL_ZONE_TAG */
|
||||
VAR_ACCESS_CONTROL_TAG = 481, /* VAR_ACCESS_CONTROL_TAG */
|
||||
VAR_LOCAL_ZONE_OVERRIDE = 482, /* VAR_LOCAL_ZONE_OVERRIDE */
|
||||
VAR_ACCESS_CONTROL_TAG_ACTION = 483, /* VAR_ACCESS_CONTROL_TAG_ACTION */
|
||||
VAR_ACCESS_CONTROL_TAG_DATA = 484, /* VAR_ACCESS_CONTROL_TAG_DATA */
|
||||
VAR_VIEW = 485, /* VAR_VIEW */
|
||||
VAR_ACCESS_CONTROL_VIEW = 486, /* VAR_ACCESS_CONTROL_VIEW */
|
||||
VAR_VIEW_FIRST = 487, /* VAR_VIEW_FIRST */
|
||||
VAR_SERVE_EXPIRED = 488, /* VAR_SERVE_EXPIRED */
|
||||
VAR_SERVE_EXPIRED_TTL = 489, /* VAR_SERVE_EXPIRED_TTL */
|
||||
VAR_SERVE_EXPIRED_TTL_RESET = 490, /* VAR_SERVE_EXPIRED_TTL_RESET */
|
||||
VAR_SERVE_EXPIRED_REPLY_TTL = 491, /* VAR_SERVE_EXPIRED_REPLY_TTL */
|
||||
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 492, /* VAR_SERVE_EXPIRED_CLIENT_TIMEOUT */
|
||||
VAR_SERVE_ORIGINAL_TTL = 493, /* VAR_SERVE_ORIGINAL_TTL */
|
||||
VAR_FAKE_DSA = 494, /* VAR_FAKE_DSA */
|
||||
VAR_FAKE_SHA1 = 495, /* VAR_FAKE_SHA1 */
|
||||
VAR_LOG_IDENTITY = 496, /* VAR_LOG_IDENTITY */
|
||||
VAR_HIDE_TRUSTANCHOR = 497, /* VAR_HIDE_TRUSTANCHOR */
|
||||
VAR_HIDE_HTTP_USER_AGENT = 498, /* VAR_HIDE_HTTP_USER_AGENT */
|
||||
VAR_HTTP_USER_AGENT = 499, /* VAR_HTTP_USER_AGENT */
|
||||
VAR_TRUST_ANCHOR_SIGNALING = 500, /* VAR_TRUST_ANCHOR_SIGNALING */
|
||||
VAR_AGGRESSIVE_NSEC = 501, /* VAR_AGGRESSIVE_NSEC */
|
||||
VAR_USE_SYSTEMD = 502, /* VAR_USE_SYSTEMD */
|
||||
VAR_SHM_ENABLE = 503, /* VAR_SHM_ENABLE */
|
||||
VAR_SHM_KEY = 504, /* VAR_SHM_KEY */
|
||||
VAR_ROOT_KEY_SENTINEL = 505, /* VAR_ROOT_KEY_SENTINEL */
|
||||
VAR_DNSCRYPT = 506, /* VAR_DNSCRYPT */
|
||||
VAR_DNSCRYPT_ENABLE = 507, /* VAR_DNSCRYPT_ENABLE */
|
||||
VAR_DNSCRYPT_PORT = 508, /* VAR_DNSCRYPT_PORT */
|
||||
VAR_DNSCRYPT_PROVIDER = 509, /* VAR_DNSCRYPT_PROVIDER */
|
||||
VAR_DNSCRYPT_SECRET_KEY = 510, /* VAR_DNSCRYPT_SECRET_KEY */
|
||||
VAR_DNSCRYPT_PROVIDER_CERT = 511, /* VAR_DNSCRYPT_PROVIDER_CERT */
|
||||
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 512, /* VAR_DNSCRYPT_PROVIDER_CERT_ROTATED */
|
||||
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 513, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE */
|
||||
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 514, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS */
|
||||
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 515, /* VAR_DNSCRYPT_NONCE_CACHE_SIZE */
|
||||
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 516, /* VAR_DNSCRYPT_NONCE_CACHE_SLABS */
|
||||
VAR_PAD_RESPONSES = 517, /* VAR_PAD_RESPONSES */
|
||||
VAR_PAD_RESPONSES_BLOCK_SIZE = 518, /* VAR_PAD_RESPONSES_BLOCK_SIZE */
|
||||
VAR_PAD_QUERIES = 519, /* VAR_PAD_QUERIES */
|
||||
VAR_PAD_QUERIES_BLOCK_SIZE = 520, /* VAR_PAD_QUERIES_BLOCK_SIZE */
|
||||
VAR_IPSECMOD_ENABLED = 521, /* VAR_IPSECMOD_ENABLED */
|
||||
VAR_IPSECMOD_HOOK = 522, /* VAR_IPSECMOD_HOOK */
|
||||
VAR_IPSECMOD_IGNORE_BOGUS = 523, /* VAR_IPSECMOD_IGNORE_BOGUS */
|
||||
VAR_IPSECMOD_MAX_TTL = 524, /* VAR_IPSECMOD_MAX_TTL */
|
||||
VAR_IPSECMOD_WHITELIST = 525, /* VAR_IPSECMOD_WHITELIST */
|
||||
VAR_IPSECMOD_STRICT = 526, /* VAR_IPSECMOD_STRICT */
|
||||
VAR_CACHEDB = 527, /* VAR_CACHEDB */
|
||||
VAR_CACHEDB_BACKEND = 528, /* VAR_CACHEDB_BACKEND */
|
||||
VAR_CACHEDB_SECRETSEED = 529, /* VAR_CACHEDB_SECRETSEED */
|
||||
VAR_CACHEDB_REDISHOST = 530, /* VAR_CACHEDB_REDISHOST */
|
||||
VAR_CACHEDB_REDISPORT = 531, /* VAR_CACHEDB_REDISPORT */
|
||||
VAR_CACHEDB_REDISTIMEOUT = 532, /* VAR_CACHEDB_REDISTIMEOUT */
|
||||
VAR_CACHEDB_REDISEXPIRERECORDS = 533, /* VAR_CACHEDB_REDISEXPIRERECORDS */
|
||||
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 534, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */
|
||||
VAR_FOR_UPSTREAM = 535, /* VAR_FOR_UPSTREAM */
|
||||
VAR_AUTH_ZONE = 536, /* VAR_AUTH_ZONE */
|
||||
VAR_ZONEFILE = 537, /* VAR_ZONEFILE */
|
||||
VAR_MASTER = 538, /* VAR_MASTER */
|
||||
VAR_URL = 539, /* VAR_URL */
|
||||
VAR_FOR_DOWNSTREAM = 540, /* VAR_FOR_DOWNSTREAM */
|
||||
VAR_FALLBACK_ENABLED = 541, /* VAR_FALLBACK_ENABLED */
|
||||
VAR_TLS_ADDITIONAL_PORT = 542, /* VAR_TLS_ADDITIONAL_PORT */
|
||||
VAR_LOW_RTT = 543, /* VAR_LOW_RTT */
|
||||
VAR_LOW_RTT_PERMIL = 544, /* VAR_LOW_RTT_PERMIL */
|
||||
VAR_FAST_SERVER_PERMIL = 545, /* VAR_FAST_SERVER_PERMIL */
|
||||
VAR_FAST_SERVER_NUM = 546, /* VAR_FAST_SERVER_NUM */
|
||||
VAR_ALLOW_NOTIFY = 547, /* VAR_ALLOW_NOTIFY */
|
||||
VAR_TLS_WIN_CERT = 548, /* VAR_TLS_WIN_CERT */
|
||||
VAR_TCP_CONNECTION_LIMIT = 549, /* VAR_TCP_CONNECTION_LIMIT */
|
||||
VAR_FORWARD_NO_CACHE = 550, /* VAR_FORWARD_NO_CACHE */
|
||||
VAR_STUB_NO_CACHE = 551, /* VAR_STUB_NO_CACHE */
|
||||
VAR_LOG_SERVFAIL = 552, /* VAR_LOG_SERVFAIL */
|
||||
VAR_DENY_ANY = 553, /* VAR_DENY_ANY */
|
||||
VAR_UNKNOWN_SERVER_TIME_LIMIT = 554, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */
|
||||
VAR_LOG_TAG_QUERYREPLY = 555, /* VAR_LOG_TAG_QUERYREPLY */
|
||||
VAR_STREAM_WAIT_SIZE = 556, /* VAR_STREAM_WAIT_SIZE */
|
||||
VAR_TLS_CIPHERS = 557, /* VAR_TLS_CIPHERS */
|
||||
VAR_TLS_CIPHERSUITES = 558, /* VAR_TLS_CIPHERSUITES */
|
||||
VAR_TLS_USE_SNI = 559, /* VAR_TLS_USE_SNI */
|
||||
VAR_IPSET = 560, /* VAR_IPSET */
|
||||
VAR_IPSET_NAME_V4 = 561, /* VAR_IPSET_NAME_V4 */
|
||||
VAR_IPSET_NAME_V6 = 562, /* VAR_IPSET_NAME_V6 */
|
||||
VAR_TLS_SESSION_TICKET_KEYS = 563, /* VAR_TLS_SESSION_TICKET_KEYS */
|
||||
VAR_RPZ = 564, /* VAR_RPZ */
|
||||
VAR_TAGS = 565, /* VAR_TAGS */
|
||||
VAR_RPZ_ACTION_OVERRIDE = 566, /* VAR_RPZ_ACTION_OVERRIDE */
|
||||
VAR_RPZ_CNAME_OVERRIDE = 567, /* VAR_RPZ_CNAME_OVERRIDE */
|
||||
VAR_RPZ_LOG = 568, /* VAR_RPZ_LOG */
|
||||
VAR_RPZ_LOG_NAME = 569, /* VAR_RPZ_LOG_NAME */
|
||||
VAR_DYNLIB = 570, /* VAR_DYNLIB */
|
||||
VAR_DYNLIB_FILE = 571, /* VAR_DYNLIB_FILE */
|
||||
VAR_EDNS_CLIENT_STRING = 572, /* VAR_EDNS_CLIENT_STRING */
|
||||
VAR_EDNS_CLIENT_STRING_OPCODE = 573, /* VAR_EDNS_CLIENT_STRING_OPCODE */
|
||||
VAR_NSID = 574, /* VAR_NSID */
|
||||
VAR_ZONEMD_PERMISSIVE_MODE = 575, /* VAR_ZONEMD_PERMISSIVE_MODE */
|
||||
VAR_ZONEMD_CHECK = 576, /* VAR_ZONEMD_CHECK */
|
||||
VAR_ZONEMD_REJECT_ABSENCE = 577, /* VAR_ZONEMD_REJECT_ABSENCE */
|
||||
VAR_RPZ_SIGNAL_NXDOMAIN_RA = 578, /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */
|
||||
VAR_INTERFACE_AUTOMATIC_PORTS = 579 /* VAR_INTERFACE_AUTOMATIC_PORTS */
|
||||
};
|
||||
typedef enum yytokentype yytoken_kind_t;
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
SPACE = 258,
|
||||
LETTER = 259,
|
||||
NEWLINE = 260,
|
||||
COMMENT = 261,
|
||||
COLON = 262,
|
||||
ANY = 263,
|
||||
ZONESTR = 264,
|
||||
STRING_ARG = 265,
|
||||
VAR_FORCE_TOPLEVEL = 266,
|
||||
VAR_SERVER = 267,
|
||||
VAR_VERBOSITY = 268,
|
||||
VAR_NUM_THREADS = 269,
|
||||
VAR_PORT = 270,
|
||||
VAR_OUTGOING_RANGE = 271,
|
||||
VAR_INTERFACE = 272,
|
||||
VAR_PREFER_IP4 = 273,
|
||||
VAR_DO_IP4 = 274,
|
||||
VAR_DO_IP6 = 275,
|
||||
VAR_PREFER_IP6 = 276,
|
||||
VAR_DO_UDP = 277,
|
||||
VAR_DO_TCP = 278,
|
||||
VAR_TCP_MSS = 279,
|
||||
VAR_OUTGOING_TCP_MSS = 280,
|
||||
VAR_TCP_IDLE_TIMEOUT = 281,
|
||||
VAR_EDNS_TCP_KEEPALIVE = 282,
|
||||
VAR_EDNS_TCP_KEEPALIVE_TIMEOUT = 283,
|
||||
VAR_CHROOT = 284,
|
||||
VAR_USERNAME = 285,
|
||||
VAR_DIRECTORY = 286,
|
||||
VAR_LOGFILE = 287,
|
||||
VAR_PIDFILE = 288,
|
||||
VAR_MSG_CACHE_SIZE = 289,
|
||||
VAR_MSG_CACHE_SLABS = 290,
|
||||
VAR_NUM_QUERIES_PER_THREAD = 291,
|
||||
VAR_RRSET_CACHE_SIZE = 292,
|
||||
VAR_RRSET_CACHE_SLABS = 293,
|
||||
VAR_OUTGOING_NUM_TCP = 294,
|
||||
VAR_INFRA_HOST_TTL = 295,
|
||||
VAR_INFRA_LAME_TTL = 296,
|
||||
VAR_INFRA_CACHE_SLABS = 297,
|
||||
VAR_INFRA_CACHE_NUMHOSTS = 298,
|
||||
VAR_INFRA_CACHE_LAME_SIZE = 299,
|
||||
VAR_NAME = 300,
|
||||
VAR_STUB_ZONE = 301,
|
||||
VAR_STUB_HOST = 302,
|
||||
VAR_STUB_ADDR = 303,
|
||||
VAR_TARGET_FETCH_POLICY = 304,
|
||||
VAR_HARDEN_SHORT_BUFSIZE = 305,
|
||||
VAR_HARDEN_LARGE_QUERIES = 306,
|
||||
VAR_FORWARD_ZONE = 307,
|
||||
VAR_FORWARD_HOST = 308,
|
||||
VAR_FORWARD_ADDR = 309,
|
||||
VAR_DO_NOT_QUERY_ADDRESS = 310,
|
||||
VAR_HIDE_IDENTITY = 311,
|
||||
VAR_HIDE_VERSION = 312,
|
||||
VAR_IDENTITY = 313,
|
||||
VAR_VERSION = 314,
|
||||
VAR_HARDEN_GLUE = 315,
|
||||
VAR_MODULE_CONF = 316,
|
||||
VAR_TRUST_ANCHOR_FILE = 317,
|
||||
VAR_TRUST_ANCHOR = 318,
|
||||
VAR_VAL_OVERRIDE_DATE = 319,
|
||||
VAR_BOGUS_TTL = 320,
|
||||
VAR_VAL_CLEAN_ADDITIONAL = 321,
|
||||
VAR_VAL_PERMISSIVE_MODE = 322,
|
||||
VAR_INCOMING_NUM_TCP = 323,
|
||||
VAR_MSG_BUFFER_SIZE = 324,
|
||||
VAR_KEY_CACHE_SIZE = 325,
|
||||
VAR_KEY_CACHE_SLABS = 326,
|
||||
VAR_TRUSTED_KEYS_FILE = 327,
|
||||
VAR_VAL_NSEC3_KEYSIZE_ITERATIONS = 328,
|
||||
VAR_USE_SYSLOG = 329,
|
||||
VAR_OUTGOING_INTERFACE = 330,
|
||||
VAR_ROOT_HINTS = 331,
|
||||
VAR_DO_NOT_QUERY_LOCALHOST = 332,
|
||||
VAR_CACHE_MAX_TTL = 333,
|
||||
VAR_HARDEN_DNSSEC_STRIPPED = 334,
|
||||
VAR_ACCESS_CONTROL = 335,
|
||||
VAR_LOCAL_ZONE = 336,
|
||||
VAR_LOCAL_DATA = 337,
|
||||
VAR_INTERFACE_AUTOMATIC = 338,
|
||||
VAR_STATISTICS_INTERVAL = 339,
|
||||
VAR_DO_DAEMONIZE = 340,
|
||||
VAR_USE_CAPS_FOR_ID = 341,
|
||||
VAR_STATISTICS_CUMULATIVE = 342,
|
||||
VAR_OUTGOING_PORT_PERMIT = 343,
|
||||
VAR_OUTGOING_PORT_AVOID = 344,
|
||||
VAR_DLV_ANCHOR_FILE = 345,
|
||||
VAR_DLV_ANCHOR = 346,
|
||||
VAR_NEG_CACHE_SIZE = 347,
|
||||
VAR_HARDEN_REFERRAL_PATH = 348,
|
||||
VAR_PRIVATE_ADDRESS = 349,
|
||||
VAR_PRIVATE_DOMAIN = 350,
|
||||
VAR_REMOTE_CONTROL = 351,
|
||||
VAR_CONTROL_ENABLE = 352,
|
||||
VAR_CONTROL_INTERFACE = 353,
|
||||
VAR_CONTROL_PORT = 354,
|
||||
VAR_SERVER_KEY_FILE = 355,
|
||||
VAR_SERVER_CERT_FILE = 356,
|
||||
VAR_CONTROL_KEY_FILE = 357,
|
||||
VAR_CONTROL_CERT_FILE = 358,
|
||||
VAR_CONTROL_USE_CERT = 359,
|
||||
VAR_TCP_REUSE_TIMEOUT = 360,
|
||||
VAR_MAX_REUSE_TCP_QUERIES = 361,
|
||||
VAR_EXTENDED_STATISTICS = 362,
|
||||
VAR_LOCAL_DATA_PTR = 363,
|
||||
VAR_JOSTLE_TIMEOUT = 364,
|
||||
VAR_STUB_PRIME = 365,
|
||||
VAR_UNWANTED_REPLY_THRESHOLD = 366,
|
||||
VAR_LOG_TIME_ASCII = 367,
|
||||
VAR_DOMAIN_INSECURE = 368,
|
||||
VAR_PYTHON = 369,
|
||||
VAR_PYTHON_SCRIPT = 370,
|
||||
VAR_VAL_SIG_SKEW_MIN = 371,
|
||||
VAR_VAL_SIG_SKEW_MAX = 372,
|
||||
VAR_VAL_MAX_RESTART = 373,
|
||||
VAR_CACHE_MIN_TTL = 374,
|
||||
VAR_VAL_LOG_LEVEL = 375,
|
||||
VAR_AUTO_TRUST_ANCHOR_FILE = 376,
|
||||
VAR_KEEP_MISSING = 377,
|
||||
VAR_ADD_HOLDDOWN = 378,
|
||||
VAR_DEL_HOLDDOWN = 379,
|
||||
VAR_SO_RCVBUF = 380,
|
||||
VAR_EDNS_BUFFER_SIZE = 381,
|
||||
VAR_PREFETCH = 382,
|
||||
VAR_PREFETCH_KEY = 383,
|
||||
VAR_SO_SNDBUF = 384,
|
||||
VAR_SO_REUSEPORT = 385,
|
||||
VAR_HARDEN_BELOW_NXDOMAIN = 386,
|
||||
VAR_IGNORE_CD_FLAG = 387,
|
||||
VAR_LOG_QUERIES = 388,
|
||||
VAR_LOG_REPLIES = 389,
|
||||
VAR_LOG_LOCAL_ACTIONS = 390,
|
||||
VAR_TCP_UPSTREAM = 391,
|
||||
VAR_SSL_UPSTREAM = 392,
|
||||
VAR_TCP_AUTH_QUERY_TIMEOUT = 393,
|
||||
VAR_SSL_SERVICE_KEY = 394,
|
||||
VAR_SSL_SERVICE_PEM = 395,
|
||||
VAR_SSL_PORT = 396,
|
||||
VAR_FORWARD_FIRST = 397,
|
||||
VAR_STUB_SSL_UPSTREAM = 398,
|
||||
VAR_FORWARD_SSL_UPSTREAM = 399,
|
||||
VAR_TLS_CERT_BUNDLE = 400,
|
||||
VAR_STUB_TCP_UPSTREAM = 401,
|
||||
VAR_FORWARD_TCP_UPSTREAM = 402,
|
||||
VAR_HTTPS_PORT = 403,
|
||||
VAR_HTTP_ENDPOINT = 404,
|
||||
VAR_HTTP_MAX_STREAMS = 405,
|
||||
VAR_HTTP_QUERY_BUFFER_SIZE = 406,
|
||||
VAR_HTTP_RESPONSE_BUFFER_SIZE = 407,
|
||||
VAR_HTTP_NODELAY = 408,
|
||||
VAR_HTTP_NOTLS_DOWNSTREAM = 409,
|
||||
VAR_STUB_FIRST = 410,
|
||||
VAR_MINIMAL_RESPONSES = 411,
|
||||
VAR_RRSET_ROUNDROBIN = 412,
|
||||
VAR_MAX_UDP_SIZE = 413,
|
||||
VAR_DELAY_CLOSE = 414,
|
||||
VAR_UDP_CONNECT = 415,
|
||||
VAR_UNBLOCK_LAN_ZONES = 416,
|
||||
VAR_INSECURE_LAN_ZONES = 417,
|
||||
VAR_INFRA_CACHE_MIN_RTT = 418,
|
||||
VAR_INFRA_KEEP_PROBING = 419,
|
||||
VAR_DNS64_PREFIX = 420,
|
||||
VAR_DNS64_SYNTHALL = 421,
|
||||
VAR_DNS64_IGNORE_AAAA = 422,
|
||||
VAR_DNSTAP = 423,
|
||||
VAR_DNSTAP_ENABLE = 424,
|
||||
VAR_DNSTAP_SOCKET_PATH = 425,
|
||||
VAR_DNSTAP_IP = 426,
|
||||
VAR_DNSTAP_TLS = 427,
|
||||
VAR_DNSTAP_TLS_SERVER_NAME = 428,
|
||||
VAR_DNSTAP_TLS_CERT_BUNDLE = 429,
|
||||
VAR_DNSTAP_TLS_CLIENT_KEY_FILE = 430,
|
||||
VAR_DNSTAP_TLS_CLIENT_CERT_FILE = 431,
|
||||
VAR_DNSTAP_SEND_IDENTITY = 432,
|
||||
VAR_DNSTAP_SEND_VERSION = 433,
|
||||
VAR_DNSTAP_BIDIRECTIONAL = 434,
|
||||
VAR_DNSTAP_IDENTITY = 435,
|
||||
VAR_DNSTAP_VERSION = 436,
|
||||
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 437,
|
||||
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 438,
|
||||
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 439,
|
||||
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 440,
|
||||
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 441,
|
||||
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 442,
|
||||
VAR_RESPONSE_IP_TAG = 443,
|
||||
VAR_RESPONSE_IP = 444,
|
||||
VAR_RESPONSE_IP_DATA = 445,
|
||||
VAR_HARDEN_ALGO_DOWNGRADE = 446,
|
||||
VAR_IP_TRANSPARENT = 447,
|
||||
VAR_IP_DSCP = 448,
|
||||
VAR_DISABLE_DNSSEC_LAME_CHECK = 449,
|
||||
VAR_IP_RATELIMIT = 450,
|
||||
VAR_IP_RATELIMIT_SLABS = 451,
|
||||
VAR_IP_RATELIMIT_SIZE = 452,
|
||||
VAR_RATELIMIT = 453,
|
||||
VAR_RATELIMIT_SLABS = 454,
|
||||
VAR_RATELIMIT_SIZE = 455,
|
||||
VAR_OUTBOUND_MSG_RETRY = 456,
|
||||
VAR_RATELIMIT_FOR_DOMAIN = 457,
|
||||
VAR_RATELIMIT_BELOW_DOMAIN = 458,
|
||||
VAR_IP_RATELIMIT_FACTOR = 459,
|
||||
VAR_RATELIMIT_FACTOR = 460,
|
||||
VAR_IP_RATELIMIT_BACKOFF = 461,
|
||||
VAR_RATELIMIT_BACKOFF = 462,
|
||||
VAR_SEND_CLIENT_SUBNET = 463,
|
||||
VAR_CLIENT_SUBNET_ZONE = 464,
|
||||
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 465,
|
||||
VAR_CLIENT_SUBNET_OPCODE = 466,
|
||||
VAR_MAX_CLIENT_SUBNET_IPV4 = 467,
|
||||
VAR_MAX_CLIENT_SUBNET_IPV6 = 468,
|
||||
VAR_MIN_CLIENT_SUBNET_IPV4 = 469,
|
||||
VAR_MIN_CLIENT_SUBNET_IPV6 = 470,
|
||||
VAR_MAX_ECS_TREE_SIZE_IPV4 = 471,
|
||||
VAR_MAX_ECS_TREE_SIZE_IPV6 = 472,
|
||||
VAR_CAPS_WHITELIST = 473,
|
||||
VAR_CACHE_MAX_NEGATIVE_TTL = 474,
|
||||
VAR_PERMIT_SMALL_HOLDDOWN = 475,
|
||||
VAR_QNAME_MINIMISATION = 476,
|
||||
VAR_QNAME_MINIMISATION_STRICT = 477,
|
||||
VAR_IP_FREEBIND = 478,
|
||||
VAR_DEFINE_TAG = 479,
|
||||
VAR_LOCAL_ZONE_TAG = 480,
|
||||
VAR_ACCESS_CONTROL_TAG = 481,
|
||||
VAR_LOCAL_ZONE_OVERRIDE = 482,
|
||||
VAR_ACCESS_CONTROL_TAG_ACTION = 483,
|
||||
VAR_ACCESS_CONTROL_TAG_DATA = 484,
|
||||
VAR_VIEW = 485,
|
||||
VAR_ACCESS_CONTROL_VIEW = 486,
|
||||
VAR_VIEW_FIRST = 487,
|
||||
VAR_SERVE_EXPIRED = 488,
|
||||
VAR_SERVE_EXPIRED_TTL = 489,
|
||||
VAR_SERVE_EXPIRED_TTL_RESET = 490,
|
||||
VAR_SERVE_EXPIRED_REPLY_TTL = 491,
|
||||
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 492,
|
||||
VAR_EDE_SERVE_EXPIRED = 493,
|
||||
VAR_SERVE_ORIGINAL_TTL = 494,
|
||||
VAR_FAKE_DSA = 495,
|
||||
VAR_FAKE_SHA1 = 496,
|
||||
VAR_LOG_IDENTITY = 497,
|
||||
VAR_HIDE_TRUSTANCHOR = 498,
|
||||
VAR_HIDE_HTTP_USER_AGENT = 499,
|
||||
VAR_HTTP_USER_AGENT = 500,
|
||||
VAR_TRUST_ANCHOR_SIGNALING = 501,
|
||||
VAR_AGGRESSIVE_NSEC = 502,
|
||||
VAR_USE_SYSTEMD = 503,
|
||||
VAR_SHM_ENABLE = 504,
|
||||
VAR_SHM_KEY = 505,
|
||||
VAR_ROOT_KEY_SENTINEL = 506,
|
||||
VAR_DNSCRYPT = 507,
|
||||
VAR_DNSCRYPT_ENABLE = 508,
|
||||
VAR_DNSCRYPT_PORT = 509,
|
||||
VAR_DNSCRYPT_PROVIDER = 510,
|
||||
VAR_DNSCRYPT_SECRET_KEY = 511,
|
||||
VAR_DNSCRYPT_PROVIDER_CERT = 512,
|
||||
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 513,
|
||||
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 514,
|
||||
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 515,
|
||||
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 516,
|
||||
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 517,
|
||||
VAR_PAD_RESPONSES = 518,
|
||||
VAR_PAD_RESPONSES_BLOCK_SIZE = 519,
|
||||
VAR_PAD_QUERIES = 520,
|
||||
VAR_PAD_QUERIES_BLOCK_SIZE = 521,
|
||||
VAR_IPSECMOD_ENABLED = 522,
|
||||
VAR_IPSECMOD_HOOK = 523,
|
||||
VAR_IPSECMOD_IGNORE_BOGUS = 524,
|
||||
VAR_IPSECMOD_MAX_TTL = 525,
|
||||
VAR_IPSECMOD_WHITELIST = 526,
|
||||
VAR_IPSECMOD_STRICT = 527,
|
||||
VAR_CACHEDB = 528,
|
||||
VAR_CACHEDB_BACKEND = 529,
|
||||
VAR_CACHEDB_SECRETSEED = 530,
|
||||
VAR_CACHEDB_REDISHOST = 531,
|
||||
VAR_CACHEDB_REDISPORT = 532,
|
||||
VAR_CACHEDB_REDISTIMEOUT = 533,
|
||||
VAR_CACHEDB_REDISEXPIRERECORDS = 534,
|
||||
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 535,
|
||||
VAR_FOR_UPSTREAM = 536,
|
||||
VAR_AUTH_ZONE = 537,
|
||||
VAR_ZONEFILE = 538,
|
||||
VAR_MASTER = 539,
|
||||
VAR_URL = 540,
|
||||
VAR_FOR_DOWNSTREAM = 541,
|
||||
VAR_FALLBACK_ENABLED = 542,
|
||||
VAR_TLS_ADDITIONAL_PORT = 543,
|
||||
VAR_LOW_RTT = 544,
|
||||
VAR_LOW_RTT_PERMIL = 545,
|
||||
VAR_FAST_SERVER_PERMIL = 546,
|
||||
VAR_FAST_SERVER_NUM = 547,
|
||||
VAR_ALLOW_NOTIFY = 548,
|
||||
VAR_TLS_WIN_CERT = 549,
|
||||
VAR_TCP_CONNECTION_LIMIT = 550,
|
||||
VAR_FORWARD_NO_CACHE = 551,
|
||||
VAR_STUB_NO_CACHE = 552,
|
||||
VAR_LOG_SERVFAIL = 553,
|
||||
VAR_DENY_ANY = 554,
|
||||
VAR_UNKNOWN_SERVER_TIME_LIMIT = 555,
|
||||
VAR_LOG_TAG_QUERYREPLY = 556,
|
||||
VAR_STREAM_WAIT_SIZE = 557,
|
||||
VAR_TLS_CIPHERS = 558,
|
||||
VAR_TLS_CIPHERSUITES = 559,
|
||||
VAR_TLS_USE_SNI = 560,
|
||||
VAR_IPSET = 561,
|
||||
VAR_IPSET_NAME_V4 = 562,
|
||||
VAR_IPSET_NAME_V6 = 563,
|
||||
VAR_TLS_SESSION_TICKET_KEYS = 564,
|
||||
VAR_RPZ = 565,
|
||||
VAR_TAGS = 566,
|
||||
VAR_RPZ_ACTION_OVERRIDE = 567,
|
||||
VAR_RPZ_CNAME_OVERRIDE = 568,
|
||||
VAR_RPZ_LOG = 569,
|
||||
VAR_RPZ_LOG_NAME = 570,
|
||||
VAR_DYNLIB = 571,
|
||||
VAR_DYNLIB_FILE = 572,
|
||||
VAR_EDNS_CLIENT_STRING = 573,
|
||||
VAR_EDNS_CLIENT_STRING_OPCODE = 574,
|
||||
VAR_NSID = 575,
|
||||
VAR_ZONEMD_PERMISSIVE_MODE = 576,
|
||||
VAR_ZONEMD_CHECK = 577,
|
||||
VAR_ZONEMD_REJECT_ABSENCE = 578,
|
||||
VAR_RPZ_SIGNAL_NXDOMAIN_RA = 579,
|
||||
VAR_INTERFACE_AUTOMATIC_PORTS = 580,
|
||||
VAR_EDE = 581
|
||||
};
|
||||
#endif
|
||||
/* Token kinds. */
|
||||
#define YYEMPTY -2
|
||||
#define YYEOF 0
|
||||
#define YYerror 256
|
||||
#define YYUNDEF 257
|
||||
/* Tokens. */
|
||||
#define SPACE 258
|
||||
#define LETTER 259
|
||||
#define NEWLINE 260
|
||||
@ -619,113 +601,112 @@ extern int yydebug;
|
||||
#define VAR_SERVE_EXPIRED_TTL_RESET 490
|
||||
#define VAR_SERVE_EXPIRED_REPLY_TTL 491
|
||||
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 492
|
||||
#define VAR_SERVE_ORIGINAL_TTL 493
|
||||
#define VAR_FAKE_DSA 494
|
||||
#define VAR_FAKE_SHA1 495
|
||||
#define VAR_LOG_IDENTITY 496
|
||||
#define VAR_HIDE_TRUSTANCHOR 497
|
||||
#define VAR_HIDE_HTTP_USER_AGENT 498
|
||||
#define VAR_HTTP_USER_AGENT 499
|
||||
#define VAR_TRUST_ANCHOR_SIGNALING 500
|
||||
#define VAR_AGGRESSIVE_NSEC 501
|
||||
#define VAR_USE_SYSTEMD 502
|
||||
#define VAR_SHM_ENABLE 503
|
||||
#define VAR_SHM_KEY 504
|
||||
#define VAR_ROOT_KEY_SENTINEL 505
|
||||
#define VAR_DNSCRYPT 506
|
||||
#define VAR_DNSCRYPT_ENABLE 507
|
||||
#define VAR_DNSCRYPT_PORT 508
|
||||
#define VAR_DNSCRYPT_PROVIDER 509
|
||||
#define VAR_DNSCRYPT_SECRET_KEY 510
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT 511
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 512
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 513
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 514
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 515
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 516
|
||||
#define VAR_PAD_RESPONSES 517
|
||||
#define VAR_PAD_RESPONSES_BLOCK_SIZE 518
|
||||
#define VAR_PAD_QUERIES 519
|
||||
#define VAR_PAD_QUERIES_BLOCK_SIZE 520
|
||||
#define VAR_IPSECMOD_ENABLED 521
|
||||
#define VAR_IPSECMOD_HOOK 522
|
||||
#define VAR_IPSECMOD_IGNORE_BOGUS 523
|
||||
#define VAR_IPSECMOD_MAX_TTL 524
|
||||
#define VAR_IPSECMOD_WHITELIST 525
|
||||
#define VAR_IPSECMOD_STRICT 526
|
||||
#define VAR_CACHEDB 527
|
||||
#define VAR_CACHEDB_BACKEND 528
|
||||
#define VAR_CACHEDB_SECRETSEED 529
|
||||
#define VAR_CACHEDB_REDISHOST 530
|
||||
#define VAR_CACHEDB_REDISPORT 531
|
||||
#define VAR_CACHEDB_REDISTIMEOUT 532
|
||||
#define VAR_CACHEDB_REDISEXPIRERECORDS 533
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 534
|
||||
#define VAR_FOR_UPSTREAM 535
|
||||
#define VAR_AUTH_ZONE 536
|
||||
#define VAR_ZONEFILE 537
|
||||
#define VAR_MASTER 538
|
||||
#define VAR_URL 539
|
||||
#define VAR_FOR_DOWNSTREAM 540
|
||||
#define VAR_FALLBACK_ENABLED 541
|
||||
#define VAR_TLS_ADDITIONAL_PORT 542
|
||||
#define VAR_LOW_RTT 543
|
||||
#define VAR_LOW_RTT_PERMIL 544
|
||||
#define VAR_FAST_SERVER_PERMIL 545
|
||||
#define VAR_FAST_SERVER_NUM 546
|
||||
#define VAR_ALLOW_NOTIFY 547
|
||||
#define VAR_TLS_WIN_CERT 548
|
||||
#define VAR_TCP_CONNECTION_LIMIT 549
|
||||
#define VAR_FORWARD_NO_CACHE 550
|
||||
#define VAR_STUB_NO_CACHE 551
|
||||
#define VAR_LOG_SERVFAIL 552
|
||||
#define VAR_DENY_ANY 553
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 554
|
||||
#define VAR_LOG_TAG_QUERYREPLY 555
|
||||
#define VAR_STREAM_WAIT_SIZE 556
|
||||
#define VAR_TLS_CIPHERS 557
|
||||
#define VAR_TLS_CIPHERSUITES 558
|
||||
#define VAR_TLS_USE_SNI 559
|
||||
#define VAR_IPSET 560
|
||||
#define VAR_IPSET_NAME_V4 561
|
||||
#define VAR_IPSET_NAME_V6 562
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 563
|
||||
#define VAR_RPZ 564
|
||||
#define VAR_TAGS 565
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 566
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 567
|
||||
#define VAR_RPZ_LOG 568
|
||||
#define VAR_RPZ_LOG_NAME 569
|
||||
#define VAR_DYNLIB 570
|
||||
#define VAR_DYNLIB_FILE 571
|
||||
#define VAR_EDNS_CLIENT_STRING 572
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 573
|
||||
#define VAR_NSID 574
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 575
|
||||
#define VAR_ZONEMD_CHECK 576
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 577
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 578
|
||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 579
|
||||
#define VAR_EDE_SERVE_EXPIRED 493
|
||||
#define VAR_SERVE_ORIGINAL_TTL 494
|
||||
#define VAR_FAKE_DSA 495
|
||||
#define VAR_FAKE_SHA1 496
|
||||
#define VAR_LOG_IDENTITY 497
|
||||
#define VAR_HIDE_TRUSTANCHOR 498
|
||||
#define VAR_HIDE_HTTP_USER_AGENT 499
|
||||
#define VAR_HTTP_USER_AGENT 500
|
||||
#define VAR_TRUST_ANCHOR_SIGNALING 501
|
||||
#define VAR_AGGRESSIVE_NSEC 502
|
||||
#define VAR_USE_SYSTEMD 503
|
||||
#define VAR_SHM_ENABLE 504
|
||||
#define VAR_SHM_KEY 505
|
||||
#define VAR_ROOT_KEY_SENTINEL 506
|
||||
#define VAR_DNSCRYPT 507
|
||||
#define VAR_DNSCRYPT_ENABLE 508
|
||||
#define VAR_DNSCRYPT_PORT 509
|
||||
#define VAR_DNSCRYPT_PROVIDER 510
|
||||
#define VAR_DNSCRYPT_SECRET_KEY 511
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT 512
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 513
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 514
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 515
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 516
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 517
|
||||
#define VAR_PAD_RESPONSES 518
|
||||
#define VAR_PAD_RESPONSES_BLOCK_SIZE 519
|
||||
#define VAR_PAD_QUERIES 520
|
||||
#define VAR_PAD_QUERIES_BLOCK_SIZE 521
|
||||
#define VAR_IPSECMOD_ENABLED 522
|
||||
#define VAR_IPSECMOD_HOOK 523
|
||||
#define VAR_IPSECMOD_IGNORE_BOGUS 524
|
||||
#define VAR_IPSECMOD_MAX_TTL 525
|
||||
#define VAR_IPSECMOD_WHITELIST 526
|
||||
#define VAR_IPSECMOD_STRICT 527
|
||||
#define VAR_CACHEDB 528
|
||||
#define VAR_CACHEDB_BACKEND 529
|
||||
#define VAR_CACHEDB_SECRETSEED 530
|
||||
#define VAR_CACHEDB_REDISHOST 531
|
||||
#define VAR_CACHEDB_REDISPORT 532
|
||||
#define VAR_CACHEDB_REDISTIMEOUT 533
|
||||
#define VAR_CACHEDB_REDISEXPIRERECORDS 534
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 535
|
||||
#define VAR_FOR_UPSTREAM 536
|
||||
#define VAR_AUTH_ZONE 537
|
||||
#define VAR_ZONEFILE 538
|
||||
#define VAR_MASTER 539
|
||||
#define VAR_URL 540
|
||||
#define VAR_FOR_DOWNSTREAM 541
|
||||
#define VAR_FALLBACK_ENABLED 542
|
||||
#define VAR_TLS_ADDITIONAL_PORT 543
|
||||
#define VAR_LOW_RTT 544
|
||||
#define VAR_LOW_RTT_PERMIL 545
|
||||
#define VAR_FAST_SERVER_PERMIL 546
|
||||
#define VAR_FAST_SERVER_NUM 547
|
||||
#define VAR_ALLOW_NOTIFY 548
|
||||
#define VAR_TLS_WIN_CERT 549
|
||||
#define VAR_TCP_CONNECTION_LIMIT 550
|
||||
#define VAR_FORWARD_NO_CACHE 551
|
||||
#define VAR_STUB_NO_CACHE 552
|
||||
#define VAR_LOG_SERVFAIL 553
|
||||
#define VAR_DENY_ANY 554
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 555
|
||||
#define VAR_LOG_TAG_QUERYREPLY 556
|
||||
#define VAR_STREAM_WAIT_SIZE 557
|
||||
#define VAR_TLS_CIPHERS 558
|
||||
#define VAR_TLS_CIPHERSUITES 559
|
||||
#define VAR_TLS_USE_SNI 560
|
||||
#define VAR_IPSET 561
|
||||
#define VAR_IPSET_NAME_V4 562
|
||||
#define VAR_IPSET_NAME_V6 563
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 564
|
||||
#define VAR_RPZ 565
|
||||
#define VAR_TAGS 566
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 567
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 568
|
||||
#define VAR_RPZ_LOG 569
|
||||
#define VAR_RPZ_LOG_NAME 570
|
||||
#define VAR_DYNLIB 571
|
||||
#define VAR_DYNLIB_FILE 572
|
||||
#define VAR_EDNS_CLIENT_STRING 573
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 574
|
||||
#define VAR_NSID 575
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 576
|
||||
#define VAR_ZONEMD_CHECK 577
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 578
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 579
|
||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 580
|
||||
#define VAR_EDE 581
|
||||
|
||||
|
||||
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
union YYSTYPE
|
||||
{
|
||||
typedef union YYSTYPE
|
||||
#line 66 "./util/configparser.y"
|
||||
|
||||
{
|
||||
char* str;
|
||||
|
||||
#line 719 "util/configparser.h"
|
||||
|
||||
};
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
}
|
||||
/* Line 1529 of yacc.c. */
|
||||
#line 705 "util/configparser.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
int yyparse (void);
|
||||
|
||||
#endif /* !YY_YY_UTIL_CONFIGPARSER_H_INCLUDED */
|
||||
|
@ -155,7 +155,8 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
|
||||
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_SERVE_EXPIRED_TTL
|
||||
%token VAR_SERVE_EXPIRED_TTL_RESET VAR_SERVE_EXPIRED_REPLY_TTL
|
||||
%token VAR_SERVE_EXPIRED_CLIENT_TIMEOUT VAR_SERVE_ORIGINAL_TTL VAR_FAKE_DSA
|
||||
%token VAR_SERVE_EXPIRED_CLIENT_TIMEOUT VAR_EDE_SERVE_EXPIRED
|
||||
%token VAR_SERVE_ORIGINAL_TTL VAR_FAKE_DSA
|
||||
%token VAR_FAKE_SHA1 VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR
|
||||
%token VAR_HIDE_HTTP_USER_AGENT VAR_HTTP_USER_AGENT
|
||||
%token VAR_TRUST_ANCHOR_SIGNALING VAR_AGGRESSIVE_NSEC VAR_USE_SYSTEMD
|
||||
@ -188,7 +189,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING
|
||||
%token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID
|
||||
%token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE
|
||||
%token VAR_RPZ_SIGNAL_NXDOMAIN_RA VAR_INTERFACE_AUTOMATIC_PORTS
|
||||
%token VAR_RPZ_SIGNAL_NXDOMAIN_RA VAR_INTERFACE_AUTOMATIC_PORTS VAR_EDE
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@ -292,7 +293,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_serve_expired |
|
||||
server_serve_expired_ttl | server_serve_expired_ttl_reset |
|
||||
server_serve_expired_reply_ttl | server_serve_expired_client_timeout |
|
||||
server_serve_original_ttl | server_fake_dsa |
|
||||
server_ede_serve_expired | server_serve_original_ttl | server_fake_dsa |
|
||||
server_log_identity | server_use_systemd |
|
||||
server_response_ip_tag | server_response_ip | server_response_ip_data |
|
||||
server_shm_enable | server_shm_key | server_fake_sha1 |
|
||||
@ -312,7 +313,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_edns_client_string_opcode | server_nsid |
|
||||
server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
|
||||
server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
|
||||
server_interface_automatic_ports
|
||||
server_interface_automatic_ports | server_ede
|
||||
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
@ -2034,6 +2035,15 @@ server_serve_expired_client_timeout: VAR_SERVE_EXPIRED_CLIENT_TIMEOUT STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_ede_serve_expired: VAR_EDE_SERVE_EXPIRED STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ede_serve_expired:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->ede_serve_expired = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_serve_original_ttl: VAR_SERVE_ORIGINAL_TTL STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_serve_original_ttl:%s)\n", $2));
|
||||
@ -2731,7 +2741,15 @@ server_edns_client_string_opcode: VAR_EDNS_CLIENT_STRING_OPCODE STRING_ARG
|
||||
yyerror("option code must be in interval [0, 65535]");
|
||||
else cfg_parser->cfg->edns_client_string_opcode = atoi($2);
|
||||
free($2);
|
||||
|
||||
}
|
||||
;
|
||||
server_ede: VAR_EDE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ede:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->ede = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
stub_name: VAR_NAME STRING_ARG
|
||||
|
@ -1157,7 +1157,7 @@ skip_pkt_rr(sldns_buffer* pkt)
|
||||
}
|
||||
|
||||
/** skip RRs from packet */
|
||||
static int
|
||||
int
|
||||
skip_pkt_rrs(sldns_buffer* pkt, int num)
|
||||
{
|
||||
int i;
|
||||
@ -1235,3 +1235,4 @@ log_edns_opt_list(enum verbosity_value level, const char* info_str,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,6 +293,15 @@ int parse_packet(struct sldns_buffer* pkt, struct msg_parse* msg,
|
||||
int parse_extract_edns_from_response_msg(struct msg_parse* msg,
|
||||
struct edns_data* edns, struct regional* region);
|
||||
|
||||
/**
|
||||
* Skip RRs from packet
|
||||
* @param pkt: the packet. position at start must be right after the query
|
||||
* section. At end, right after EDNS data or no movement if failed.
|
||||
* @param num: Limit of the number of records we want to parse.
|
||||
* @return: 0 on success, 1 on failure.
|
||||
*/
|
||||
int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
|
||||
|
||||
/**
|
||||
* If EDNS data follows a query section, extract it and initialize edns struct.
|
||||
* @param pkt: the packet. position at start must be right after the query
|
||||
|
@ -117,6 +117,7 @@ construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
|
||||
rep->ar_numrrsets = ar;
|
||||
rep->rrset_count = total;
|
||||
rep->security = sec;
|
||||
rep->reason_bogus = LDNS_EDE_NONE;
|
||||
rep->authoritative = 0;
|
||||
/* array starts after the refs */
|
||||
if(region)
|
||||
@ -989,6 +990,36 @@ parse_reply_in_temp_region(sldns_buffer* pkt, struct regional* region,
|
||||
return rep;
|
||||
}
|
||||
|
||||
int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
|
||||
sldns_ede_code code, const char *txt)
|
||||
{
|
||||
struct edns_option** prevp;
|
||||
struct edns_option* opt;
|
||||
size_t txt_len = txt ? strlen(txt) : 0;
|
||||
|
||||
/* allocate new element */
|
||||
opt = (struct edns_option*)regional_alloc(region, sizeof(*opt));
|
||||
if(!opt)
|
||||
return 0;
|
||||
opt->next = NULL;
|
||||
opt->opt_code = LDNS_EDNS_EDE;
|
||||
opt->opt_len = txt_len + sizeof(uint16_t);
|
||||
opt->opt_data = regional_alloc(region, txt_len + sizeof(uint16_t));
|
||||
if(!opt->opt_data)
|
||||
return 0;
|
||||
sldns_write_uint16(opt->opt_data, (uint16_t)code);
|
||||
if (txt_len)
|
||||
memmove(opt->opt_data + 2, txt, txt_len);
|
||||
|
||||
/* append at end of list */
|
||||
prevp = list;
|
||||
while(*prevp != NULL)
|
||||
prevp = &((*prevp)->next);
|
||||
verbose(VERB_ALGO, "attached EDE code: %d with message: %s", code, txt);
|
||||
*prevp = opt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
uint8_t* data, struct regional* region)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@
|
||||
#define UTIL_DATA_MSGREPLY_H
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct sldns_buffer;
|
||||
struct comm_reply;
|
||||
struct alloc_cache;
|
||||
@ -167,6 +168,11 @@ struct reply_info {
|
||||
*/
|
||||
enum sec_status security;
|
||||
|
||||
/**
|
||||
* EDE (rfc8914) code with reason for DNSSEC bogus status.
|
||||
*/
|
||||
sldns_ede_code reason_bogus;
|
||||
|
||||
/**
|
||||
* Number of RRsets in each section.
|
||||
* The answer section. Add up the RRs in every RRset to calculate
|
||||
@ -528,7 +534,38 @@ void log_query_info(enum verbosity_value v, const char* str,
|
||||
* @return false on failure.
|
||||
*/
|
||||
int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
uint8_t* data, struct regional* region);
|
||||
uint8_t* data, struct regional* region);
|
||||
|
||||
/**
|
||||
* Append edns EDE option to edns options list
|
||||
* @param LIST: the edns option list to append the edns option to.
|
||||
* @param REGION: region to allocate the new edns option.
|
||||
* @param CODE: the EDE code.
|
||||
* @param TXT: Additional text for the option
|
||||
*/
|
||||
#define EDNS_OPT_LIST_APPEND_EDE(LIST, REGION, CODE, TXT) \
|
||||
do { \
|
||||
struct { \
|
||||
uint16_t code; \
|
||||
char text[sizeof(TXT) - 1]; \
|
||||
} ede = { htons(CODE), TXT }; \
|
||||
verbose(VERB_ALGO, "attached EDE code: %d with" \
|
||||
" message: %s", CODE, TXT); \
|
||||
edns_opt_list_append((LIST), LDNS_EDNS_EDE, \
|
||||
sizeof(uint16_t) + sizeof(TXT) - 1, \
|
||||
(void *)&ede, (REGION)); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Append edns EDE option to edns options list
|
||||
* @param list: the edns option list to append the edns option to.
|
||||
* @param region: region to allocate the new edns option.
|
||||
* @param code: the EDE code.
|
||||
* @param txt: Additional text for the option
|
||||
* @return false on failure.
|
||||
*/
|
||||
int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
|
||||
sldns_ede_code code, const char *txt);
|
||||
|
||||
/**
|
||||
* Remove any option found on the edns option list that matches the code.
|
||||
|
142
util/module.c
142
util/module.c
@ -40,6 +40,10 @@
|
||||
#include "config.h"
|
||||
#include "util/module.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/net_help.h"
|
||||
|
||||
const char*
|
||||
strextstate(enum module_ext_state s)
|
||||
@ -71,6 +75,144 @@ strmodulevent(enum module_ev e)
|
||||
return "bad_event_value";
|
||||
}
|
||||
|
||||
void errinf(struct module_qstate* qstate, const char* str)
|
||||
{
|
||||
errinf_ede(qstate, str, LDNS_EDE_NONE);
|
||||
}
|
||||
|
||||
void errinf_ede(struct module_qstate* qstate,
|
||||
const char* str, sldns_ede_code reason_bogus)
|
||||
{
|
||||
struct errinf_strlist* p;
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str)
|
||||
return;
|
||||
p = (struct errinf_strlist*)regional_alloc(qstate->region, sizeof(*p));
|
||||
if(!p) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
p->next = NULL;
|
||||
p->str = regional_strdup(qstate->region, str);
|
||||
p->reason_bogus = reason_bogus;
|
||||
if(!p->str) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
/* add at end */
|
||||
if(qstate->errinf) {
|
||||
struct errinf_strlist* q = qstate->errinf;
|
||||
while(q->next)
|
||||
q = q->next;
|
||||
q->next = p;
|
||||
} else qstate->errinf = p;
|
||||
}
|
||||
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin)
|
||||
{
|
||||
struct sock_list* p;
|
||||
if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
|
||||
return;
|
||||
for(p=origin; p; p=p->next) {
|
||||
char buf[256];
|
||||
if(p == origin)
|
||||
snprintf(buf, sizeof(buf), "from ");
|
||||
else snprintf(buf, sizeof(buf), "and ");
|
||||
if(p->len == 0)
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf),
|
||||
"cache");
|
||||
else
|
||||
addr_to_str(&p->addr, p->len, buf+strlen(buf),
|
||||
sizeof(buf)-strlen(buf));
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
}
|
||||
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct errinf_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate)
|
||||
{
|
||||
struct errinf_strlist* s;
|
||||
for(s=qstate->errinf; s; s=s->next) {
|
||||
if (s->reason_bogus != LDNS_EDE_NONE) {
|
||||
return s->reason_bogus;
|
||||
}
|
||||
}
|
||||
return LDNS_EDE_NONE;
|
||||
}
|
||||
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct errinf_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr)
|
||||
{
|
||||
char buf[1024];
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !rr)
|
||||
return;
|
||||
sldns_wire2str_type_buf(ntohs(rr->rk.type), t, sizeof(t));
|
||||
sldns_wire2str_class_buf(ntohs(rr->rk.rrset_class), c, sizeof(c));
|
||||
dname_str(rr->rk.dname, dname);
|
||||
snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c);
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname)
|
||||
{
|
||||
char b[1024];
|
||||
char buf[LDNS_MAX_DOMAINLEN+1];
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str || !dname)
|
||||
return;
|
||||
dname_str(dname, buf);
|
||||
snprintf(b, sizeof(b), "%s %s", str, buf);
|
||||
errinf(qstate, b);
|
||||
}
|
||||
|
||||
int
|
||||
edns_known_options_init(struct module_env* env)
|
||||
{
|
||||
|
@ -187,6 +187,15 @@ struct respip_addr_info;
|
||||
/** Maximum number of known edns options */
|
||||
#define MAX_KNOWN_EDNS_OPTS 256
|
||||
|
||||
struct errinf_strlist {
|
||||
/** next item in list */
|
||||
struct errinf_strlist* next;
|
||||
/** config option string */
|
||||
char* str;
|
||||
/** EDE code companion to the error str */
|
||||
int reason_bogus;
|
||||
};
|
||||
|
||||
enum inplace_cb_list_type {
|
||||
/* Inplace callbacks for when a resolved reply is ready to be sent to the
|
||||
* front.*/
|
||||
@ -624,8 +633,7 @@ struct module_qstate {
|
||||
/** region for this query. Cleared when query process finishes. */
|
||||
struct regional* region;
|
||||
/** failure reason information if val-log-level is high */
|
||||
struct config_strlist* errinf;
|
||||
|
||||
struct errinf_strlist* errinf;
|
||||
/** which module is executing */
|
||||
int curmod;
|
||||
/** module states */
|
||||
@ -761,6 +769,65 @@ const char* strextstate(enum module_ext_state s);
|
||||
*/
|
||||
const char* strmodulevent(enum module_ev e);
|
||||
|
||||
/**
|
||||
* Append text to the error info for validation.
|
||||
* @param qstate: query state.
|
||||
* @param str: copied into query region and appended.
|
||||
* Failures to allocate are logged.
|
||||
*/
|
||||
void errinf(struct module_qstate* qstate, const char* str);
|
||||
void errinf_ede(struct module_qstate* qstate, const char* str,
|
||||
sldns_ede_code reason_bogus);
|
||||
|
||||
/**
|
||||
* Append text to error info: from 1.2.3.4
|
||||
* @param qstate: query state.
|
||||
* @param origin: sock list with origin of trouble.
|
||||
* Every element added.
|
||||
* If NULL: nothing is added.
|
||||
* if 0len element: 'from cache' is added.
|
||||
*/
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin);
|
||||
|
||||
/**
|
||||
* Append text to error info: for RRset name type class
|
||||
* @param qstate: query state.
|
||||
* @param rr: rrset_key.
|
||||
*/
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr);
|
||||
|
||||
/**
|
||||
* Append text to error info: str dname
|
||||
* @param qstate: query state.
|
||||
* @param str: explanation string
|
||||
* @param dname: the dname.
|
||||
*/
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str,
|
||||
uint8_t* dname);
|
||||
|
||||
/**
|
||||
* Create error info in string. For validation failures.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate);
|
||||
/**
|
||||
* Check the sldns_ede_code of the qstate.
|
||||
* @param qstate: query state.
|
||||
* @return LDNS_EDE_DNSSEC_BOGUS by default, or the first explicitly set
|
||||
* sldns_ede_code.
|
||||
*/
|
||||
sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Create error info in string. For other servfails.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Initialize the edns known options by allocating the required space.
|
||||
* @param env: the module environment.
|
||||
|
@ -1263,7 +1263,7 @@ verify_dnskey(struct module_env* env, struct val_env* ve,
|
||||
int downprot = env->cfg->harden_algo_downgrade;
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset,
|
||||
tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason,
|
||||
qstate);
|
||||
NULL, qstate);
|
||||
/* sigalg is ignored, it returns algorithms signalled to exist, but
|
||||
* in 5011 there are no other rrsets to check. if downprot is
|
||||
* enabled, then it checks that the DNSKEY is signed with all
|
||||
@ -1312,7 +1312,7 @@ rr_is_selfsigned_revoked(struct module_env* env, struct val_env* ve,
|
||||
/* no algorithm downgrade protection necessary, if it is selfsigned
|
||||
* revoked it can be removed. */
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset, i,
|
||||
&reason, LDNS_SECTION_ANSWER, qstate);
|
||||
&reason, NULL, LDNS_SECTION_ANSWER, qstate);
|
||||
return (sec == sec_status_secure);
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,7 @@ key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey,
|
||||
qstate->env->cfg->val_log_level >= 2) {
|
||||
/* on malloc failure there is simply no reason string */
|
||||
key_entry_set_reason(k, errinf_to_str_bogus(qstate));
|
||||
key_entry_set_reason_bogus(k, errinf_to_reason_bogus(qstate));
|
||||
}
|
||||
key_entry_hash(k);
|
||||
slabhash_insert(kcache->slab, k->entry.hash, &k->entry,
|
||||
|
@ -244,6 +244,15 @@ key_entry_set_reason(struct key_entry_key* kkey, char* reason)
|
||||
d->reason = reason;
|
||||
}
|
||||
|
||||
void
|
||||
key_entry_set_reason_bogus(struct key_entry_key* kkey, sldns_ede_code ede)
|
||||
{
|
||||
struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
|
||||
if (ede != LDNS_EDE_NONE) { /* reason_bogus init is LDNS_EDE_NONE already */
|
||||
d->reason_bogus = ede;
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
key_entry_get_reason(struct key_entry_key* kkey)
|
||||
{
|
||||
@ -251,6 +260,14 @@ key_entry_get_reason(struct key_entry_key* kkey)
|
||||
return d->reason;
|
||||
}
|
||||
|
||||
sldns_ede_code
|
||||
key_entry_get_reason_bogus(struct key_entry_key* kkey)
|
||||
{
|
||||
struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
|
||||
return d->reason_bogus;
|
||||
|
||||
}
|
||||
|
||||
/** setup key entry in region */
|
||||
static int
|
||||
key_entry_setup(struct regional* region,
|
||||
@ -286,6 +303,7 @@ key_entry_create_null(struct regional* region,
|
||||
d->ttl = now + ttl;
|
||||
d->isbad = 0;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->rrset_type = LDNS_RR_TYPE_DNSKEY;
|
||||
d->rrset_data = NULL;
|
||||
d->algo = NULL;
|
||||
@ -306,6 +324,7 @@ key_entry_create_rrset(struct regional* region,
|
||||
d->ttl = rd->ttl + now;
|
||||
d->isbad = 0;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->rrset_type = ntohs(rrset->rk.type);
|
||||
d->rrset_data = (struct packed_rrset_data*)regional_alloc_init(region,
|
||||
rd, packed_rrset_sizeof(rd));
|
||||
@ -332,6 +351,7 @@ key_entry_create_bad(struct regional* region,
|
||||
d->ttl = now + ttl;
|
||||
d->isbad = 1;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->rrset_type = LDNS_RR_TYPE_DNSKEY;
|
||||
d->rrset_data = NULL;
|
||||
d->algo = NULL;
|
||||
|
@ -45,6 +45,7 @@ struct packed_rrset_data;
|
||||
struct regional;
|
||||
struct ub_packed_rrset_key;
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "sldns/rrdef.h"
|
||||
|
||||
/**
|
||||
* A key entry for the validator.
|
||||
@ -80,6 +81,8 @@ struct key_entry_data {
|
||||
struct packed_rrset_data* rrset_data;
|
||||
/** not NULL sometimes to give reason why bogus */
|
||||
char* reason;
|
||||
/** not NULL to give reason why bogus */
|
||||
sldns_ede_code reason_bogus;
|
||||
/** list of algorithms signalled, ends with 0, or NULL */
|
||||
uint8_t* algo;
|
||||
/** DNS RR type of the rrset data (host order) */
|
||||
@ -150,6 +153,15 @@ int key_entry_isbad(struct key_entry_key* kkey);
|
||||
*/
|
||||
void key_entry_set_reason(struct key_entry_key* kkey, char* reason);
|
||||
|
||||
/**
|
||||
* Set the EDE (RFC8914) code why the key is bad, if it
|
||||
* exists (so not LDNS_EDE_NONE).
|
||||
* @param kkey: bad key.
|
||||
* @param ede: EDE code to attach to this key.
|
||||
*/
|
||||
void key_entry_set_reason_bogus(struct key_entry_key* kkey, sldns_ede_code ede);
|
||||
|
||||
|
||||
/**
|
||||
* Get reason why a key is bad.
|
||||
* @param kkey: bad key
|
||||
@ -158,6 +170,13 @@ void key_entry_set_reason(struct key_entry_key* kkey, char* reason);
|
||||
*/
|
||||
char* key_entry_get_reason(struct key_entry_key* kkey);
|
||||
|
||||
/**
|
||||
* Get the EDE (RFC8914) code why a key is bad. Can return LDNS_EDE_NONE.
|
||||
* @param kkey: bad key
|
||||
* @return the ede code.
|
||||
*/
|
||||
sldns_ede_code key_entry_get_reason_bogus(struct key_entry_key* kkey);
|
||||
|
||||
/**
|
||||
* Create a null entry, in the given region.
|
||||
* @param region: where to allocate
|
||||
|
@ -187,7 +187,7 @@ nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
if(d->security == sec_status_secure)
|
||||
return 1;
|
||||
d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason,
|
||||
LDNS_SECTION_AUTHORITY, qstate);
|
||||
NULL, LDNS_SECTION_AUTHORITY, qstate);
|
||||
if(d->security == sec_status_secure) {
|
||||
rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
|
||||
return 1;
|
||||
|
@ -1289,7 +1289,8 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
|
||||
static int
|
||||
list_is_secure(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key** list, size_t num,
|
||||
struct key_entry_key* kkey, char** reason, struct module_qstate* qstate)
|
||||
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
struct packed_rrset_data* d;
|
||||
size_t i;
|
||||
@ -1303,7 +1304,7 @@ list_is_secure(struct module_env* env, struct val_env* ve,
|
||||
if(d->security == sec_status_secure)
|
||||
continue;
|
||||
d->security = val_verify_rrset_entry(env, ve, list[i], kkey,
|
||||
reason, LDNS_SECTION_AUTHORITY, qstate);
|
||||
reason, reason_bogus, LDNS_SECTION_AUTHORITY, qstate);
|
||||
if(d->security != sec_status_secure) {
|
||||
verbose(VERB_ALGO, "NSEC3 did not verify");
|
||||
return 0;
|
||||
@ -1317,7 +1318,7 @@ enum sec_status
|
||||
nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key** list, size_t num,
|
||||
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
rbtree_type ct;
|
||||
struct nsec3_filter flt;
|
||||
@ -1330,8 +1331,10 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
*reason = "no valid NSEC3s";
|
||||
return sec_status_bogus; /* no valid NSEC3s, bogus */
|
||||
}
|
||||
if(!list_is_secure(env, ve, list, num, kkey, reason, qstate))
|
||||
if(!list_is_secure(env, ve, list, num, kkey, reason, reason_bogus, qstate)) {
|
||||
*reason = "not all NSEC3 records secure";
|
||||
return sec_status_bogus; /* not all NSEC3 records secure */
|
||||
}
|
||||
rbtree_init(&ct, &nsec3_hash_cmp); /* init names-to-hash cache */
|
||||
filter_init(&flt, list, num, qinfo); /* init RR iterator */
|
||||
if(!flt.zone) {
|
||||
|
@ -68,6 +68,7 @@
|
||||
#define VALIDATOR_VAL_NSEC3_H
|
||||
#include "util/rbtree.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct val_env;
|
||||
struct regional;
|
||||
struct module_env;
|
||||
@ -186,6 +187,7 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
|
||||
* @param qinfo: query that is verified for.
|
||||
* @param kkey: key entry that signed the NSEC3s.
|
||||
* @param reason: string for bogus result.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return:
|
||||
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
|
||||
@ -197,7 +199,7 @@ enum sec_status
|
||||
nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key** list, size_t num,
|
||||
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Prove NXDOMAIN or NODATA.
|
||||
|
@ -525,11 +525,19 @@ int algo_needs_missing(struct algo_needs* n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum sec_status
|
||||
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
enum sec_status
|
||||
dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num;
|
||||
@ -543,6 +551,8 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "rrset failed to verify due to a lack of "
|
||||
"signatures");
|
||||
*reason = "no signatures";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -551,12 +561,15 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
if(algo_needs_num_missing(&needs) == 0) {
|
||||
verbose(VERB_QUERY, "zone has no known algorithms");
|
||||
*reason = "zone has no known algorithms";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
|
||||
return sec_status_insecure;
|
||||
}
|
||||
}
|
||||
for(i=0; i<num; i++) {
|
||||
sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset,
|
||||
dnskey, i, &sortree, reason, section, qstate);
|
||||
dnskey, i, &sortree, reason, reason_bogus,
|
||||
section, qstate);
|
||||
/* see which algorithm has been fixed up */
|
||||
if(sec == sec_status_secure) {
|
||||
if(!sigalg)
|
||||
@ -597,8 +610,8 @@ void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s)
|
||||
enum sec_status
|
||||
dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num, numchecked = 0;
|
||||
@ -612,6 +625,8 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "rrset failed to verify due to a lack of "
|
||||
"signatures");
|
||||
*reason = "no signatures";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
for(i=0; i<num; i++) {
|
||||
@ -620,10 +635,10 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
tag != rrset_get_sig_keytag(rrset, i))
|
||||
continue;
|
||||
buf_canon = 0;
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
env->scratch_buffer, ve, *env->now, rrset,
|
||||
dnskey, dnskey_idx, i, &sortree, &buf_canon, reason,
|
||||
section, qstate);
|
||||
reason_bogus, section, qstate);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
numchecked ++;
|
||||
@ -633,12 +648,13 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
static enum sec_status
|
||||
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
/* find matching keys and check them */
|
||||
enum sec_status sec = sec_status_bogus;
|
||||
@ -649,10 +665,12 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
int buf_canon = 0;
|
||||
verbose(VERB_ALGO, "verify sig %d %d", (int)tag, algo);
|
||||
if(!dnskey_algo_id_is_supported(algo)) {
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
|
||||
verbose(VERB_QUERY, "verify sig: unknown algorithm");
|
||||
return sec_status_insecure;
|
||||
}
|
||||
|
||||
|
||||
for(i=0; i<num; i++) {
|
||||
/* see if key matches keytag and algo */
|
||||
if(algo != dnskey_get_algo(dnskey, i) ||
|
||||
@ -661,14 +679,17 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
numchecked ++;
|
||||
|
||||
/* see if key verifies */
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
env->scratch_buffer, ve, now, rrset, dnskey, i,
|
||||
sig_idx, sortree, &buf_canon, reason, section, qstate);
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
env->scratch_buffer, ve, now, rrset, dnskey, i,
|
||||
sig_idx, sortree, &buf_canon, reason, reason_bogus,
|
||||
section, qstate);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
}
|
||||
if(numchecked == 0) {
|
||||
*reason = "signatures from unknown keys";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
verbose(VERB_QUERY, "verify: could not find appropriate key");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
@ -1361,8 +1382,8 @@ subtract_1982(uint32_t a, uint32_t b)
|
||||
|
||||
/** check rrsig dates */
|
||||
static int
|
||||
check_dates(struct val_env* ve, uint32_t unow,
|
||||
uint8_t* expi_p, uint8_t* incep_p, char** reason)
|
||||
check_dates(struct val_env* ve, uint32_t unow, uint8_t* expi_p,
|
||||
uint8_t* incep_p, char** reason, sldns_ede_code *reason_bogus)
|
||||
{
|
||||
/* read out the dates */
|
||||
uint32_t expi, incep, now;
|
||||
@ -1386,6 +1407,14 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: inception after expiration, "
|
||||
"signature bad", expi, incep, now);
|
||||
*reason = "signature inception after expiration";
|
||||
if(reason_bogus){
|
||||
/* from RFC8914 on Signature Not Yet Valid: The resolver
|
||||
* attempted to perform DNSSEC validation, but no
|
||||
* signatures are presently valid and at least some are
|
||||
* not yet valid. */
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_NOT_YET_VALID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
if(compare_1982(incep, now) > 0) {
|
||||
@ -1397,6 +1426,8 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: signature bad, current time is"
|
||||
" before inception date", expi, incep, now);
|
||||
*reason = "signature before inception date";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_NOT_YET_VALID;
|
||||
return 0;
|
||||
}
|
||||
sigdate_error("verify warning suspicious signature inception "
|
||||
@ -1410,6 +1441,8 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: signature expired", expi,
|
||||
incep, now);
|
||||
*reason = "signature expired";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_EXPIRED;
|
||||
return 0;
|
||||
}
|
||||
sigdate_error("verify warning suspicious signature expiration "
|
||||
@ -1473,7 +1506,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
struct val_env* ve, time_t now,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon, char** reason,
|
||||
struct rbtree_type** sortree, int* buf_canon,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
@ -1492,12 +1526,16 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(siglen < 2+20) {
|
||||
verbose(VERB_QUERY, "verify: signature too short");
|
||||
*reason = "signature too short";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
if(!(dnskey_get_flags(dnskey, dnskey_idx) & DNSKEY_BIT_ZSK)) {
|
||||
verbose(VERB_QUERY, "verify: dnskey without ZSK flag");
|
||||
*reason = "dnskey without ZSK flag";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_NO_ZONE_KEY_BIT_SET;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1505,6 +1543,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
/* RFC 4034 says DNSKEY PROTOCOL MUST be 3 */
|
||||
verbose(VERB_QUERY, "verify: dnskey has wrong key protocol");
|
||||
*reason = "dnskey has wrong protocolnumber";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1514,17 +1554,23 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(!signer_len) {
|
||||
verbose(VERB_QUERY, "verify: malformed signer name");
|
||||
*reason = "signer name malformed";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* signer name invalid */
|
||||
}
|
||||
if(!dname_subdomain_c(rrset->rk.dname, signer)) {
|
||||
verbose(VERB_QUERY, "verify: signer name is off-tree");
|
||||
*reason = "signer name off-tree";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* signer name offtree */
|
||||
}
|
||||
sigblock = (unsigned char*)signer+signer_len;
|
||||
if(siglen < 2+18+signer_len+1) {
|
||||
verbose(VERB_QUERY, "verify: too short, no signature data");
|
||||
*reason = "signature too short, no signature data";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* sig rdf is < 1 byte */
|
||||
}
|
||||
sigblock_len = (unsigned int)(siglen - 2 - 18 - signer_len);
|
||||
@ -1537,6 +1583,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
log_nametypeclass(VERB_QUERY, "the key name is",
|
||||
dnskey->rk.dname, 0, 0);
|
||||
*reason = "signer name mismatches key name";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1545,18 +1593,24 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(memcmp(sig+2, &rrset->rk.type, 2) != 0) {
|
||||
verbose(VERB_QUERY, "verify: wrong type covered");
|
||||
*reason = "signature covers wrong type";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
/* verify keytag and sig algo (possibly again) */
|
||||
if((int)sig[2+2] != dnskey_get_algo(dnskey, dnskey_idx)) {
|
||||
verbose(VERB_QUERY, "verify: wrong algorithm");
|
||||
*reason = "signature has wrong algorithm";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
ktag = htons(dnskey_calc_keytag(dnskey, dnskey_idx));
|
||||
if(memcmp(sig+2+16, &ktag, 2) != 0) {
|
||||
verbose(VERB_QUERY, "verify: wrong keytag");
|
||||
*reason = "signature has wrong keytag";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1564,6 +1618,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if((int)sig[2+3] > dname_signame_label_count(rrset->rk.dname)) {
|
||||
verbose(VERB_QUERY, "verify: labelcount out of range");
|
||||
*reason = "signature labelcount out of range";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1598,7 +1654,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
/* verify inception, expiration dates
|
||||
* Do this last so that if you ignore expired-sigs the
|
||||
* rest is sure to be OK. */
|
||||
if(!check_dates(ve, now, sig+2+8, sig+2+12, reason)) {
|
||||
if(!check_dates(ve, now, sig+2+8, sig+2+12,
|
||||
reason, reason_bogus)) {
|
||||
return sec_status_bogus;
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define VALIDATOR_VAL_SIGCRYPT_H
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct val_env;
|
||||
struct module_env;
|
||||
struct module_qstate;
|
||||
@ -256,6 +257,7 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
|
||||
* @param sigalg: if nonNULL provide downgrade protection otherwise one
|
||||
* algorithm is enough.
|
||||
* @param reason: if bogus, a string returned, fixed or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return SECURE if one key in the set verifies one rrsig.
|
||||
@ -264,9 +266,11 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
|
||||
*/
|
||||
enum sec_status dnskeyset_verify_rrset(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg, char** reason,
|
||||
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
|
||||
/**
|
||||
* verify rrset against one specific dnskey (from rrset)
|
||||
* @param env: module environment, scratch space is used.
|
||||
@ -275,38 +279,17 @@ enum sec_status dnskeyset_verify_rrset(struct module_env* env,
|
||||
* @param dnskey: DNSKEY rrset, keyset.
|
||||
* @param dnskey_idx: which key from the rrset to try.
|
||||
* @param reason: if bogus, a string returned, fixed or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return secure if *this* key signs any of the signatures on rrset.
|
||||
* unchecked on error or and bogus on bad signature.
|
||||
*/
|
||||
enum sec_status dnskey_verify_rrset(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, char** reason,
|
||||
enum sec_status dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* verify rrset, with dnskey rrset, for a specific rrsig in rrset
|
||||
* @param env: module environment, scratch space is used.
|
||||
* @param ve: validator environment, date settings.
|
||||
* @param now: current time for validation (can be overridden).
|
||||
* @param rrset: to be validated.
|
||||
* @param dnskey: DNSKEY rrset, keyset to try.
|
||||
* @param sig_idx: which signature to try to validate.
|
||||
* @param sortree: reused sorted order. Stored in region. Pass NULL at start,
|
||||
* and for a new rrset.
|
||||
* @param reason: if bogus, a string returned, fixed or alloced in scratch.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return secure if any key signs *this* signature. bogus if no key signs it,
|
||||
* or unchecked on error.
|
||||
*/
|
||||
enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
|
||||
struct val_env* ve, time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* verify rrset, with specific dnskey(from set), for a specific rrsig
|
||||
* @param region: scratch region used for temporary allocation.
|
||||
@ -323,17 +306,19 @@ enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
|
||||
* pass false at start. pass old value only for same rrset and same
|
||||
* signature (but perhaps different key) for reuse.
|
||||
* @param reason: if bogus, a string returned, fixed or alloced in scratch.
|
||||
* @param reason_bogus: EDE (8914) code paired with the reason of failure.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return secure if this key signs this signature. unchecked on error or
|
||||
* bogus if it did not validate.
|
||||
*/
|
||||
enum sec_status dnskey_verify_rrset_sig(struct regional* region,
|
||||
struct sldns_buffer* buf, struct val_env* ve, time_t now,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon, char** reason,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
enum sec_status dnskey_verify_rrset_sig(struct regional* region,
|
||||
struct sldns_buffer* buf, struct val_env* ve, time_t now,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* canonical compare for two tree entries
|
||||
|
@ -332,11 +332,11 @@ rrset_get_ttl(struct ub_packed_rrset_key* rrset)
|
||||
return d->ttl;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
static enum sec_status
|
||||
val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
|
||||
@ -359,7 +359,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname,
|
||||
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason,
|
||||
section, qstate);
|
||||
reason_bogus, section, qstate);
|
||||
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
|
||||
regional_free_all(env->scratch);
|
||||
|
||||
@ -392,7 +392,8 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
enum sec_status
|
||||
val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey,
|
||||
char** reason, sldns_pkt_section section, struct module_qstate* qstate)
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
/* temporary dnskey rrset-key */
|
||||
struct ub_packed_rrset_key dnskey;
|
||||
@ -406,16 +407,16 @@ val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
|
||||
dnskey.entry.key = &dnskey;
|
||||
dnskey.entry.data = kd->rrset_data;
|
||||
sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason,
|
||||
section, qstate);
|
||||
reason_bogus, section, qstate);
|
||||
return sec;
|
||||
}
|
||||
|
||||
/** verify that a DS RR hashes to a key and that key signs the set */
|
||||
static enum sec_status
|
||||
verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec = sec_status_bogus;
|
||||
size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
|
||||
@ -450,8 +451,8 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||
|
||||
/* Otherwise, we have a match! Make sure that the DNSKEY
|
||||
* verifies *with this key* */
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset,
|
||||
dnskey_rrset, i, reason, LDNS_SECTION_ANSWER, qstate);
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset,
|
||||
i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
return sec;
|
||||
}
|
||||
@ -488,11 +489,12 @@ int val_favorite_ds_algo(struct ub_packed_rrset_key* ds_rrset)
|
||||
return digest_algo;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
// @TODO change the use of this function to _ede function in authzone.c:8111
|
||||
enum sec_status
|
||||
val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
/* as long as this is false, we can consider this DS rrset to be
|
||||
* equivalent to no DS rrset. */
|
||||
@ -529,7 +531,7 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
}
|
||||
|
||||
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
||||
ds_rrset, i, reason, qstate);
|
||||
ds_rrset, i, reason, reason_bogus, qstate);
|
||||
if(sec == sec_status_insecure)
|
||||
continue;
|
||||
|
||||
@ -571,15 +573,16 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
struct key_entry_key*
|
||||
struct key_entry_key*
|
||||
val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve,
|
||||
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason, qstate);
|
||||
enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve,
|
||||
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason,
|
||||
reason_bogus, qstate);
|
||||
|
||||
if(sec == sec_status_secure) {
|
||||
return key_entry_create_rrset(region,
|
||||
@ -597,12 +600,12 @@ val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
||||
BOGUS_KEY_TTL, *env->now);
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
enum sec_status
|
||||
val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
/* as long as this is false, we can consider this anchor to be
|
||||
* equivalent to no anchor. */
|
||||
@ -617,6 +620,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "DNSKEY RRset did not match DS RRset "
|
||||
"by name");
|
||||
*reason = "DNSKEY RRset did not match DS RRset by name";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
if(ta_dnskey && (dnskey_rrset->rk.dname_len != ta_dnskey->rk.dname_len
|
||||
@ -625,6 +630,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "DNSKEY RRset did not match anchor RRset "
|
||||
"by name");
|
||||
*reason = "DNSKEY RRset did not match anchor RRset by name";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -648,7 +655,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
continue;
|
||||
|
||||
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
||||
ta_ds, i, reason, qstate);
|
||||
ta_ds, i, reason, reason_bogus, qstate);
|
||||
if(sec == sec_status_insecure)
|
||||
continue;
|
||||
|
||||
@ -688,7 +695,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
has_useful_ta = 1;
|
||||
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset,
|
||||
ta_dnskey, i, reason, LDNS_SECTION_ANSWER, qstate);
|
||||
ta_dnskey, i, reason, NULL, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
if(!sigalg || algo_needs_set_secure(&needs,
|
||||
(uint8_t)dnskey_get_algo(ta_dnskey, i))) {
|
||||
@ -723,24 +730,24 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
|
||||
struct key_entry_key*
|
||||
val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||
char** reason, struct module_qstate* qstate)
|
||||
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve,
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve,
|
||||
dnskey_rrset, ta_ds_rrset, ta_dnskey_rrset,
|
||||
downprot?sigalg:NULL, reason, qstate);
|
||||
downprot?sigalg:NULL, reason, reason_bogus, qstate);
|
||||
|
||||
if(sec == sec_status_secure) {
|
||||
return key_entry_create_rrset(region,
|
||||
return key_entry_create_rrset(region,
|
||||
dnskey_rrset->rk.dname, dnskey_rrset->rk.dname_len,
|
||||
ntohs(dnskey_rrset->rk.rrset_class), dnskey_rrset,
|
||||
downprot?sigalg:NULL, *env->now);
|
||||
} else if(sec == sec_status_insecure) {
|
||||
return key_entry_create_null(region, dnskey_rrset->rk.dname,
|
||||
dnskey_rrset->rk.dname_len,
|
||||
dnskey_rrset->rk.dname_len,
|
||||
ntohs(dnskey_rrset->rk.rrset_class),
|
||||
rrset_get_ttl(dnskey_rrset), *env->now);
|
||||
}
|
||||
@ -749,7 +756,7 @@ val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
|
||||
BOGUS_KEY_TTL, *env->now);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset)
|
||||
{
|
||||
size_t i;
|
||||
@ -776,6 +783,7 @@ val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset)
|
||||
if(lt) snprintf(aerr, sizeof(aerr), "%s", lt->name);
|
||||
else snprintf(aerr, sizeof(aerr), "%d",
|
||||
(int)ds_get_key_algo(ds_rrset, 0));
|
||||
|
||||
verbose(VERB_ALGO, "DS unsupported, hash %s %s, "
|
||||
"key algorithm %s %s", herr,
|
||||
(ds_digest_algo_is_supported(ds_rrset, 0)?
|
||||
|
@ -43,6 +43,7 @@
|
||||
#define VALIDATOR_VAL_UTILS_H
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct query_info;
|
||||
struct reply_info;
|
||||
struct val_env;
|
||||
@ -113,24 +114,6 @@ void val_find_signer(enum val_classification subtype,
|
||||
struct query_info* qinf, struct reply_info* rep,
|
||||
size_t cname_skip, uint8_t** signer_name, size_t* signer_len);
|
||||
|
||||
/**
|
||||
* Verify RRset with keys
|
||||
* @param env: module environment (scratch buffer)
|
||||
* @param ve: validator environment (verification settings)
|
||||
* @param rrset: what to verify
|
||||
* @param keys: dnskey rrset to verify with.
|
||||
* @param sigalg: if nonNULL provide downgrade protection otherwise one
|
||||
* algorithm is enough. Algo list is constructed in here.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return security status of verification.
|
||||
*/
|
||||
enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify RRset with keys from a keyset.
|
||||
* @param env: module environment (scratch buffer)
|
||||
@ -138,14 +121,15 @@ enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
* @param rrset: what to verify
|
||||
* @param kkey: key_entry to verify with.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return security status of verification.
|
||||
*/
|
||||
enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct key_entry_key* kkey, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but
|
||||
@ -158,15 +142,16 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||
* algorithm is enough. The list of signalled algorithms is returned,
|
||||
* must have enough space for ALGO_NEEDS_MAX+1.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return: sec_status_secure if a DS matches.
|
||||
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
||||
* sec_status_bogus if it fails.
|
||||
*/
|
||||
enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS
|
||||
@ -180,16 +165,17 @@ enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
||||
* algorithm is enough. The list of signalled algorithms is returned,
|
||||
* must have enough space for ALGO_NEEDS_MAX+1.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return: sec_status_secure if a DS matches.
|
||||
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
||||
* sec_status_bogus if it fails.
|
||||
*/
|
||||
enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify new DNSKEYs with DS rrset. The DS contains hash values that should
|
||||
@ -204,6 +190,7 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||
* @param downprot: if true provide downgrade protection otherwise one
|
||||
* algorithm is enough.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return a KeyEntry. This will either contain the now trusted
|
||||
* dnskey_rrset, a "null" key entry indicating that this DS
|
||||
@ -215,12 +202,11 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||
* rrset.
|
||||
* if downprot is set, a key entry with an algo list is made.
|
||||
*/
|
||||
struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify rrset with trust anchor: DS and DNSKEY rrset.
|
||||
@ -234,6 +220,7 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||
* @param downprot: if true provide downgrade protection otherwise one
|
||||
* algorithm is enough.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return a KeyEntry. This will either contain the now trusted
|
||||
* dnskey_rrset, a "null" key entry indicating that this DS
|
||||
@ -246,11 +233,11 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||
* if downprot is set, a key entry with an algo list is made.
|
||||
*/
|
||||
struct key_entry_key* val_verify_new_DNSKEYs_with_ta(struct regional* region,
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset,
|
||||
int downprot, char** reason, struct module_qstate* qstate);
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Determine if DS rrset is usable for validator or not.
|
||||
|
@ -69,6 +69,20 @@ static void process_ds_response(struct module_qstate* qstate,
|
||||
struct val_qstate* vq, int id, int rcode, struct dns_msg* msg,
|
||||
struct query_info* qinfo, struct sock_list* origin);
|
||||
|
||||
|
||||
/* Updates the suplied EDE (RFC8914) code selectively so we don't loose
|
||||
* a more specific code
|
||||
*/
|
||||
static void
|
||||
update_reason_bogus(struct reply_info* rep, sldns_ede_code reason_bogus)
|
||||
{
|
||||
if (rep->reason_bogus == LDNS_EDE_DNSSEC_BOGUS ||
|
||||
rep->reason_bogus == LDNS_EDE_NONE) {
|
||||
rep->reason_bogus = reason_bogus;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** fill up nsec3 key iterations config entry */
|
||||
static int
|
||||
fill_nsec3_iter(struct val_env* ve, char* s, int c)
|
||||
@ -230,6 +244,7 @@ val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
|
||||
vq->orig_msg->rep->flags = (uint16_t)(qstate->return_rcode&0xf)
|
||||
|BIT_QR|BIT_RA|(qstate->query_flags|(BIT_CD|BIT_RD));
|
||||
vq->orig_msg->rep->qdcount = 1;
|
||||
vq->orig_msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
} else {
|
||||
vq->orig_msg = qstate->return_msg;
|
||||
}
|
||||
@ -592,6 +607,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
enum sec_status sec;
|
||||
int dname_seen = 0;
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
|
||||
/* validate the ANSWER section */
|
||||
for(i=0; i<chase_reply->an_numrrsets; i++) {
|
||||
@ -613,20 +629,22 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
|
||||
/* Verify the answer rrset */
|
||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||
LDNS_SECTION_ANSWER, qstate);
|
||||
&reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
/* If the (answer) rrset failed to validate, then this
|
||||
* message is BAD. */
|
||||
if(sec != sec_status_secure) {
|
||||
log_nametypeclass(VERB_QUERY, "validator: response "
|
||||
"has failed ANSWER rrset:", s->rk.dname,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME)
|
||||
errinf(qstate, "for CNAME");
|
||||
else if(ntohs(s->rk.type) == LDNS_RR_TYPE_DNAME)
|
||||
errinf(qstate, "for DNAME");
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, reason_bogus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -643,17 +661,18 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
chase_reply->ns_numrrsets; i++) {
|
||||
s = chase_reply->rrsets[i];
|
||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||
LDNS_SECTION_AUTHORITY, qstate);
|
||||
&reason_bogus, LDNS_SECTION_AUTHORITY, qstate);
|
||||
/* If anything in the authority section fails to be secure,
|
||||
* we have a bad message. */
|
||||
if(sec != sec_status_secure) {
|
||||
log_nametypeclass(VERB_QUERY, "validator: response "
|
||||
"has failed AUTHORITY rrset:", s->rk.dname,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
errinf_rrset(qstate, s);
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, reason_bogus);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -669,9 +688,10 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
/* only validate rrs that have signatures with the key */
|
||||
/* leave others unchecked, those get removed later on too */
|
||||
val_find_rrset_signer(s, &sname, &slen);
|
||||
|
||||
if(sname && query_dname_compare(sname, key_entry->name)==0)
|
||||
(void)val_verify_rrset_entry(env, ve, s, key_entry,
|
||||
&reason, LDNS_SECTION_ADDITIONAL, qstate);
|
||||
&reason, NULL, LDNS_SECTION_ADDITIONAL, qstate);
|
||||
/* the additional section can fail to be secure,
|
||||
* it is optional, check signature in case we need
|
||||
* to clean the additional section later. */
|
||||
@ -804,6 +824,7 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
"inconsistent wildcard sigs:", s->rk.dname,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
if(wc && !wc_cached && env->cfg->aggressive_nsec) {
|
||||
@ -861,6 +882,7 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
"expansion and did not prove original data "
|
||||
"did not exist");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -959,6 +981,7 @@ validate_nodata_response(struct module_env* env, struct val_env* ve,
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("Failed NODATA", qchase, chase_reply);
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1045,6 +1068,7 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "NameError response has failed to prove: "
|
||||
"qname does not exist");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
/* Be lenient with RCODE in NSEC NameError responses */
|
||||
validate_nodata_response(env, ve, qchase, chase_reply, kkey);
|
||||
if (chase_reply->security == sec_status_secure)
|
||||
@ -1056,6 +1080,7 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "NameError response has failed to prove: "
|
||||
"covering wildcard does not exist");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
/* Be lenient with RCODE in NSEC NameError responses */
|
||||
validate_nodata_response(env, ve, qchase, chase_reply, kkey);
|
||||
if (chase_reply->security == sec_status_secure)
|
||||
@ -1138,6 +1163,7 @@ validate_any_response(struct module_env* env, struct val_env* ve,
|
||||
if(qchase->qtype != LDNS_RR_TYPE_ANY) {
|
||||
log_err("internal error: ANY validation called for non-ANY");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1154,6 +1180,7 @@ validate_any_response(struct module_env* env, struct val_env* ve,
|
||||
s->rk.dname, ntohs(s->rk.type),
|
||||
ntohs(s->rk.rrset_class));
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1208,6 +1235,7 @@ validate_any_response(struct module_env* env, struct val_env* ve,
|
||||
"expansion and did not prove original data "
|
||||
"did not exist");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1255,6 +1283,7 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
"inconsistent wildcard sigs:", s->rk.dname,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1267,6 +1296,7 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
"wildcarded DNAME:", s->rk.dname,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1324,6 +1354,7 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
"expansion and did not prove original data "
|
||||
"did not exist");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1424,6 +1455,7 @@ validate_cname_noanswer_response(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "CNAMEchain to noanswer proves that name "
|
||||
"exists and not exists, bogus");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
if(!nodata_valid_nsec && !nxdomain_valid_nsec && nsec3s_seen) {
|
||||
@ -1449,6 +1481,7 @@ validate_cname_noanswer_response(struct module_env* env, struct val_env* ve,
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("Failed CNAMEnoanswer", qchase, chase_reply);
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1492,6 +1525,10 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
verbose(VERB_ALGO, "restart count exceeded");
|
||||
return val_error(qstate, id);
|
||||
}
|
||||
|
||||
/* correctly initialize reason_bogus */
|
||||
update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
|
||||
verbose(VERB_ALGO, "validator classification %s",
|
||||
val_classification_to_string(subtype));
|
||||
if(subtype == VAL_CLASS_REFERRAL &&
|
||||
@ -1557,6 +1594,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
verbose(VERB_QUERY, "unsigned parent zone denies"
|
||||
" trust anchor, indeterminate");
|
||||
vq->chase_reply->security = sec_status_indeterminate;
|
||||
update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_INDETERMINATE);
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
@ -1588,6 +1626,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
if(vq->key_entry == NULL && anchor == NULL) {
|
||||
/*response isn't under a trust anchor, so we cannot validate.*/
|
||||
vq->chase_reply->security = sec_status_indeterminate;
|
||||
update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_INDETERMINATE);
|
||||
/* go to finished state to cache this result */
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
@ -1633,16 +1672,25 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
} else if(key_entry_isbad(vq->key_entry)) {
|
||||
sldns_ede_code ede = LDNS_EDE_DNSSEC_BOGUS;
|
||||
|
||||
/* the key could have a more spefic EDE than just bogus */
|
||||
if(key_entry_get_reason_bogus(vq->key_entry) != LDNS_EDE_NONE) {
|
||||
ede = key_entry_get_reason_bogus(vq->key_entry);
|
||||
}
|
||||
|
||||
/* key is bad, chain is bad, reply is bogus */
|
||||
errinf_dname(qstate, "key for validation", vq->key_entry->name);
|
||||
errinf(qstate, "is marked as invalid");
|
||||
errinf_ede(qstate, "is marked as invalid", ede);
|
||||
if(key_entry_get_reason(vq->key_entry)) {
|
||||
errinf(qstate, "because of a previous");
|
||||
errinf(qstate, key_entry_get_reason(vq->key_entry));
|
||||
}
|
||||
|
||||
/* no retries, stop bothering the authority until timeout */
|
||||
vq->restart_count = ve->max_restart;
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(vq->chase_reply, ede);
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
@ -1713,9 +1761,10 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
|
||||
vq->empty_DS_name) == 0) {
|
||||
/* do not query for empty_DS_name again */
|
||||
verbose(VERB_ALGO, "Cannot retrieve DS for signature");
|
||||
errinf(qstate, "no signatures");
|
||||
errinf_ede(qstate, "no signatures", LDNS_EDE_RRSIGS_MISSING);
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(vq->chase_reply, LDNS_EDE_RRSIGS_MISSING);
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
@ -1848,7 +1897,10 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
"of trust to keys for", vq->key_entry->name,
|
||||
LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
errinf(qstate, "while building chain of trust");
|
||||
|
||||
update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSKEY_MISSING);
|
||||
errinf_ede(qstate, "while building chain of trust",
|
||||
LDNS_EDE_DNSKEY_MISSING);
|
||||
if(vq->restart_count >= ve->max_restart)
|
||||
key_cache_insert(ve->kcache, vq->key_entry, qstate);
|
||||
return 1;
|
||||
@ -1861,9 +1913,10 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
"signer name", &vq->qchase);
|
||||
verbose(VERB_DETAIL, "Could not establish validation of "
|
||||
"INSECURE status of unsigned response.");
|
||||
errinf(qstate, "no signatures");
|
||||
errinf_ede(qstate, "no signatures", LDNS_EDE_RRSIGS_MISSING);
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(vq->chase_reply, LDNS_EDE_RRSIGS_MISSING);
|
||||
return 1;
|
||||
}
|
||||
subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
|
||||
@ -2001,17 +2054,20 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
vq->orig_msg->rep, vq->rrset_skip);
|
||||
|
||||
/* store overall validation result in orig_msg */
|
||||
if(vq->rrset_skip == 0)
|
||||
if(vq->rrset_skip == 0) {
|
||||
vq->orig_msg->rep->security = vq->chase_reply->security;
|
||||
else if(subtype != VAL_CLASS_REFERRAL ||
|
||||
update_reason_bogus(vq->orig_msg->rep, vq->chase_reply->reason_bogus);
|
||||
} else if(subtype != VAL_CLASS_REFERRAL ||
|
||||
vq->rrset_skip < vq->orig_msg->rep->an_numrrsets +
|
||||
vq->orig_msg->rep->ns_numrrsets) {
|
||||
/* ignore sec status of additional section if a referral
|
||||
* type message skips there and
|
||||
* use the lowest security status as end result. */
|
||||
if(vq->chase_reply->security < vq->orig_msg->rep->security)
|
||||
if(vq->chase_reply->security < vq->orig_msg->rep->security) {
|
||||
vq->orig_msg->rep->security =
|
||||
vq->chase_reply->security;
|
||||
update_reason_bogus(vq->orig_msg->rep, vq->chase_reply->reason_bogus);
|
||||
}
|
||||
}
|
||||
|
||||
if(subtype == VAL_CLASS_REFERRAL) {
|
||||
@ -2034,6 +2090,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
&vq->rrset_skip)) {
|
||||
verbose(VERB_ALGO, "validator: failed to chase CNAME");
|
||||
vq->orig_msg->rep->security = sec_status_bogus;
|
||||
update_reason_bogus(vq->orig_msg->rep, LDNS_EDE_DNSSEC_BOGUS);
|
||||
} else {
|
||||
/* restart process for new qchase at rrset_skip */
|
||||
log_query_info(VERB_ALGO, "validator: chased to",
|
||||
@ -2247,9 +2304,11 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
* queries. If we get here, it is bogus or an internal error */
|
||||
if(qstate->qinfo.qclass == LDNS_RR_CLASS_ANY) {
|
||||
verbose(VERB_ALGO, "cannot validate classANY: bogus");
|
||||
if(qstate->return_msg)
|
||||
if(qstate->return_msg) {
|
||||
qstate->return_msg->rep->security =
|
||||
sec_status_bogus;
|
||||
update_reason_bogus(qstate->return_msg->rep, LDNS_EDE_DNSSEC_BOGUS);
|
||||
}
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
@ -2304,6 +2363,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct key_entry_key* kkey = NULL;
|
||||
enum sec_status sec = sec_status_unchecked;
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
int downprot = qstate->env->cfg->harden_algo_downgrade;
|
||||
|
||||
if(!dnskey_rrset) {
|
||||
@ -2311,7 +2371,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
"could not fetch DNSKEY rrset",
|
||||
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
|
||||
if(qstate->env->cfg->harden_dnssec_stripped) {
|
||||
errinf(qstate, "no DNSKEY rrset");
|
||||
errinf_ede(qstate, "no DNSKEY rrset", LDNS_EDE_DNSKEY_MISSING);
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
||||
*qstate->env->now);
|
||||
@ -2327,7 +2387,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
/* attempt to verify with trust anchor DS and DNSKEY */
|
||||
kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve,
|
||||
dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot,
|
||||
&reason, qstate);
|
||||
&reason, &reason_bogus, qstate);
|
||||
if(!kkey) {
|
||||
log_err("out of memory: verifying prime TA");
|
||||
return NULL;
|
||||
@ -2346,7 +2406,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
/* NOTE: in this case, we should probably reject the trust
|
||||
* anchor for longer, perhaps forever. */
|
||||
if(qstate->env->cfg->harden_dnssec_stripped) {
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
||||
*qstate->env->now);
|
||||
@ -2389,6 +2449,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
{
|
||||
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
enum val_classification subtype;
|
||||
if(rcode != LDNS_RCODE_NOERROR) {
|
||||
char rc[16];
|
||||
@ -2397,7 +2458,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* errors here pretty much break validation */
|
||||
verbose(VERB_DETAIL, "DS response was error, thus bogus");
|
||||
errinf(qstate, rc);
|
||||
errinf(qstate, "no DS");
|
||||
errinf_ede(qstate, "no DS", LDNS_EDE_NETWORK_ERROR);
|
||||
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
@ -2411,17 +2473,17 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
if(!ds) {
|
||||
log_warn("internal error: POSITIVE DS response was "
|
||||
"missing DS.");
|
||||
errinf(qstate, "no DS record");
|
||||
errinf_ede(qstate, "no DS record", LDNS_EDE_DNSSEC_BOGUS);
|
||||
goto return_bogus;
|
||||
}
|
||||
/* Verify only returns BOGUS or SECURE. If the rrset is
|
||||
* bogus, then we are done. */
|
||||
sec = val_verify_rrset_entry(qstate->env, ve, ds,
|
||||
vq->key_entry, &reason, LDNS_SECTION_ANSWER, qstate);
|
||||
sec = val_verify_rrset_entry(qstate->env, ve, ds,
|
||||
vq->key_entry, &reason, &reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec != sec_status_secure) {
|
||||
verbose(VERB_DETAIL, "DS rrset in DS response did "
|
||||
"not verify");
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
@ -2430,6 +2492,9 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
if(!val_dsset_isusable(ds)) {
|
||||
/* If they aren't usable, then we treat it like
|
||||
* there was no DS. */
|
||||
|
||||
// @TODO add EDE Unsupported DS Digest Type
|
||||
|
||||
*ke = key_entry_create_null(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len, qinfo->qclass,
|
||||
ub_packed_rrset_ttl(ds), *qstate->env->now);
|
||||
@ -2452,7 +2517,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* make sure there are NSECs or NSEC3s with signatures */
|
||||
if(!val_has_signed_nsecs(msg->rep, &reason)) {
|
||||
verbose(VERB_ALGO, "no NSECs: %s", reason);
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, LDNS_EDE_NSEC_MISSING);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
@ -2493,7 +2558,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
sec = nsec3_prove_nods(qstate->env, ve,
|
||||
msg->rep->rrsets + msg->rep->an_numrrsets,
|
||||
msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason,
|
||||
qstate);
|
||||
&reason_bogus, qstate);
|
||||
switch(sec) {
|
||||
case sec_status_insecure:
|
||||
/* case insecure also continues to unsigned
|
||||
@ -2515,7 +2580,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
case sec_status_bogus:
|
||||
verbose(VERB_DETAIL, "NSEC3s for the "
|
||||
"referral did not prove no DS.");
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
case sec_status_unchecked:
|
||||
default:
|
||||
@ -2554,7 +2619,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
goto return_bogus;
|
||||
}
|
||||
sec = val_verify_rrset_entry(qstate->env, ve, cname,
|
||||
vq->key_entry, &reason, LDNS_SECTION_ANSWER, qstate);
|
||||
vq->key_entry, &reason, NULL, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
verbose(VERB_ALGO, "CNAME validated, "
|
||||
"proof that DS does not exist");
|
||||
@ -2685,6 +2750,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct ub_packed_rrset_key* dnskey = NULL;
|
||||
int downprot;
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
|
||||
if(rcode == LDNS_RCODE_NOERROR)
|
||||
dnskey = reply_find_answer_rrset(qinfo, msg->rep);
|
||||
@ -2693,6 +2759,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* bad response */
|
||||
verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to "
|
||||
"DNSKEY query.");
|
||||
|
||||
if(vq->restart_count < ve->max_restart) {
|
||||
val_blacklist(&vq->chain_blacklist, qstate->region,
|
||||
origin, 1);
|
||||
@ -2707,7 +2774,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
log_err("alloc failure in missing dnskey response");
|
||||
/* key_entry is NULL for failure in Validate */
|
||||
}
|
||||
errinf(qstate, "No DNSKEY record");
|
||||
errinf_ede(qstate, "No DNSKEY record", LDNS_EDE_DNSKEY_MISSING);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for key", qinfo->qname);
|
||||
vq->state = VAL_VALIDATE_STATE;
|
||||
@ -2721,7 +2788,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
}
|
||||
downprot = qstate->env->cfg->harden_algo_downgrade;
|
||||
vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env,
|
||||
ve, dnskey, vq->ds_rrset, downprot, &reason, qstate);
|
||||
ve, dnskey, vq->ds_rrset, downprot, &reason, &reason_bogus, qstate);
|
||||
|
||||
if(!vq->key_entry) {
|
||||
log_err("out of memory in verify new DNSKEYs");
|
||||
@ -2742,7 +2809,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
}
|
||||
verbose(VERB_DETAIL, "Did not match a DS to a DNSKEY, "
|
||||
"thus bogus.");
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for key", qinfo->qname);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user