mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-10-18 06:17:20 +02:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7366fa0c02 | ||
|
|
bdc787104c | ||
|
|
dfaf5ce5dc | ||
|
|
f830ee89e3 |
@@ -17,9 +17,7 @@ You can learn more about Unbound by reading our
|
||||
## Compiling
|
||||
|
||||
Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
|
||||
installed.
|
||||
If building from the repository source you also need flex and bison installed.
|
||||
Unbound can be compiled and installed using:
|
||||
installed. Unbound can be compiled and installed using:
|
||||
|
||||
```
|
||||
./configure && make && make install
|
||||
@@ -29,7 +27,7 @@ You can use libevent if you want. libevent is useful when using many (10000)
|
||||
outgoing ports. By default max 256 ports are opened at the same time and the
|
||||
builtin alternative is equally capable and a little faster.
|
||||
|
||||
Use the `--with-libevent` configure option to compile Unbound with libevent
|
||||
Use the `--with-libevent=dir` configure option to compile Unbound with libevent
|
||||
support.
|
||||
|
||||
## Unbound configuration
|
||||
|
||||
@@ -815,11 +815,6 @@ cachedb_handle_response(struct module_qstate* qstate,
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
if(qstate->env->cfg->cachedb_no_store) {
|
||||
/* do not store the item in the external cache */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the item into the backend cache */
|
||||
cachedb_extcache_store(qstate, ie);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.19.2.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.18.1.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
||||
#
|
||||
@@ -591,8 +591,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.19.2'
|
||||
PACKAGE_STRING='unbound 1.19.2'
|
||||
PACKAGE_VERSION='1.18.1'
|
||||
PACKAGE_STRING='unbound 1.18.1'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1477,7 +1477,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.19.2 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.18.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1543,7 +1543,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.19.2:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.18.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1785,7 +1785,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.19.2
|
||||
unbound configure 1.18.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2494,7 +2494,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.19.2, which was
|
||||
It was created by unbound $as_me 1.18.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2844,13 +2844,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=19
|
||||
UNBOUND_VERSION_MINOR=18
|
||||
|
||||
UNBOUND_VERSION_MICRO=2
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=25
|
||||
LIBUNBOUND_REVISION=23
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -2940,9 +2940,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.17.0 had 9:20:1
|
||||
# 1.17.1 had 9:21:1
|
||||
# 1.18.0 had 9:22:1
|
||||
# 1.19.0 had 9:23:1
|
||||
# 1.19.1 had 9:24:1
|
||||
# 1.19.2 had 9:25:1
|
||||
# 1.18.1 had 9:23:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -21342,7 +21340,7 @@ if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "The protobuf-c library was not found. Please install the development libraries for protobuf-c!" "$LINENO" 5
|
||||
as_fn_error $? "The protobuf-c library was not found. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
@@ -21896,7 +21894,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.19.2
|
||||
version=1.18.1
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@@ -22415,7 +22413,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.19.2, which was
|
||||
This file was extended by unbound $as_me 1.18.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -22481,7 +22479,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.19.2
|
||||
unbound config.status 1.18.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+4
-6
@@ -10,15 +10,15 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[19])
|
||||
m4_define([VERSION_MICRO],[2])
|
||||
m4_define([VERSION_MINOR],[18])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=25
|
||||
LIBUNBOUND_REVISION=23
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -108,9 +108,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.17.0 had 9:20:1
|
||||
# 1.17.1 had 9:21:1
|
||||
# 1.18.0 had 9:22:1
|
||||
# 1.19.0 had 9:23:1
|
||||
# 1.19.1 had 9:24:1
|
||||
# 1.19.2 had 9:25:1
|
||||
# 1.18.1 had 9:23:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ AC_DEFUN([dt_DNSTAP],
|
||||
fi
|
||||
])
|
||||
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
|
||||
AC_MSG_ERROR([The protobuf-c library was not found. Please install the development libraries for protobuf-c!]))
|
||||
AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!]))
|
||||
$2
|
||||
else
|
||||
$3
|
||||
|
||||
+1
-35
@@ -1,37 +1,3 @@
|
||||
2 November 2023: Wouter
|
||||
- Set version number to 1.19.0.
|
||||
- Tag for 1.19.0rc1 release.
|
||||
|
||||
1 November 2023: George
|
||||
- Mention flex and bison in README.md when building from repository
|
||||
source.
|
||||
|
||||
1 November 2023: Wouter
|
||||
- Fix SSL compile failure for definition in log_crypto_err_io_code_arg.
|
||||
- Fix SSL compile failure for other missing definitions in
|
||||
log_crypto_err_io_code_arg.
|
||||
- Fix compilation without openssl, remove unused function warning.
|
||||
|
||||
31 October 2023: George
|
||||
- Fix #941: dnscrypt doesn't work after upgrade to 1.18 with
|
||||
suggestion by dukeartem to also fix the udp_ancil with dnscrypt.
|
||||
|
||||
30 October 2023: George
|
||||
- Merge #930 from Stuart Henderson: add void to
|
||||
log_ident_revert_to_default declaration.
|
||||
|
||||
30 October 2023: Wouter
|
||||
- autoconf.
|
||||
|
||||
24 October 2023: George
|
||||
- Clearer configure text for missing protobuf-c development libraries.
|
||||
|
||||
20 October 2023: Wouter
|
||||
- Merge #951: Cachedb no store. The cachedb-no-store: yes option is
|
||||
used to stop cachedb from writing messages to the backend storage.
|
||||
It reads messages when data is available from the backend. The
|
||||
default is no.
|
||||
|
||||
19 October 2023: Wouter
|
||||
- Fix to print detailed errors when an SSL IO routine fails via
|
||||
SSL_get_error.
|
||||
@@ -4899,7 +4865,7 @@
|
||||
- Fix that with openssl 1.1 control-use-cert: no uses less cpu, by
|
||||
using no encryption over the unix socket.
|
||||
|
||||
22 November 2016: Ralph
|
||||
22 Novenber 2016: Ralph
|
||||
- Make access-control-tag-data RDATA absolute. This makes the RDATA
|
||||
origin consistent between local-data and access-control-tag-data.
|
||||
- Fix NSEC ENT wildcard check. Matching wildcard does not have to be a
|
||||
|
||||
@@ -1226,8 +1226,6 @@ remote-control:
|
||||
# backend: "testframe"
|
||||
# # secret seed string to calculate hashed keys
|
||||
# secret-seed: "default"
|
||||
# # if the backend should be read from, but not written to.
|
||||
# cachedb-no-store: no
|
||||
#
|
||||
# # For "redis" backend:
|
||||
# # (to enable, use --with-libhiredis to configure before compiling)
|
||||
|
||||
@@ -2681,11 +2681,6 @@ operationally.
|
||||
If the backend database is shared by multiple Unbound instances,
|
||||
all instances must use the same secret seed.
|
||||
This option defaults to "default".
|
||||
.TP
|
||||
.B cachedb-no-store: \fI<yes or no>\fR
|
||||
If the backend should be read from, but not written to. This makes this
|
||||
instance not store dns messages in the backend. But if data is available it
|
||||
is retrieved. The default is no.
|
||||
.P
|
||||
The following
|
||||
.B cachedb
|
||||
|
||||
+122
-25
@@ -6345,6 +6345,16 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
|
||||
/* get master addr */
|
||||
if(xfr->task_probe->scan_addr) {
|
||||
/* parse the host string to get the auth name for scan_addr */
|
||||
if(xfr->task_probe->scan_specific &&
|
||||
xfr->task_probe->scan_specific->host &&
|
||||
!authextstrtoaddr(xfr->task_probe->scan_specific->host, &addr, &addrlen, &auth_name)) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
log_err("%s: failed lookup, cannot probe to master %s",
|
||||
zname, master->host);
|
||||
return 0;
|
||||
}
|
||||
addrlen = xfr->task_probe->scan_addr->addrlen;
|
||||
memmove(&addr, &xfr->task_probe->scan_addr->addr, addrlen);
|
||||
} else {
|
||||
@@ -6358,18 +6368,6 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
zname, master->host);
|
||||
return 0;
|
||||
}
|
||||
if (auth_name != NULL) {
|
||||
if (addr.ss_family == AF_INET
|
||||
&& (int)ntohs(((struct sockaddr_in *)&addr)->sin_port)
|
||||
== env->cfg->ssl_port)
|
||||
((struct sockaddr_in *)&addr)->sin_port
|
||||
= htons((uint16_t)env->cfg->port);
|
||||
else if (addr.ss_family == AF_INET6
|
||||
&& (int)ntohs(((struct sockaddr_in6 *)&addr)->sin6_port)
|
||||
== env->cfg->ssl_port)
|
||||
((struct sockaddr_in6 *)&addr)->sin6_port
|
||||
= htons((uint16_t)env->cfg->port);
|
||||
}
|
||||
}
|
||||
|
||||
/* create packet */
|
||||
@@ -6379,11 +6377,12 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
xfr->task_probe->id = GET_RANDOM_ID(env->rnd);
|
||||
xfr_create_soa_probe_packet(xfr, env->scratch_buffer,
|
||||
xfr->task_probe->id);
|
||||
/* we need to remove the cp if we have a different ip4/ip6 type now */
|
||||
/* we need to remove the cp if we have a different ip4/ip6 type now.
|
||||
* And also for tls probes to get a new tcp commpoint. */
|
||||
if(xfr->task_probe->cp &&
|
||||
((xfr->task_probe->cp_is_ip6 && !addr_is_ip6(&addr, addrlen)) ||
|
||||
(!xfr->task_probe->cp_is_ip6 && addr_is_ip6(&addr, addrlen)))
|
||||
) {
|
||||
(!xfr->task_probe->cp_is_ip6 && addr_is_ip6(&addr, addrlen)) ||
|
||||
auth_name != NULL)) {
|
||||
comm_point_delete(xfr->task_probe->cp);
|
||||
xfr->task_probe->cp = NULL;
|
||||
}
|
||||
@@ -6391,14 +6390,19 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
if(addr_is_ip6(&addr, addrlen))
|
||||
xfr->task_probe->cp_is_ip6 = 1;
|
||||
else xfr->task_probe->cp_is_ip6 = 0;
|
||||
xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet,
|
||||
auth_xfer_probe_udp_callback, xfr, &addr, addrlen);
|
||||
if(auth_name != NULL)
|
||||
xfr->task_probe->cp = outnet_comm_point_for_tcp(env->outnet,
|
||||
auth_xfer_probe_tcp_callback, xfr, &addr, addrlen, env->scratch_buffer, -1, auth_name != NULL, auth_name);
|
||||
else
|
||||
xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet,
|
||||
auth_xfer_probe_udp_callback, xfr, &addr, addrlen);
|
||||
if(!xfr->task_probe->cp) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "cannot create udp cp for "
|
||||
"probe %s to %s", zname, as);
|
||||
verbose(VERB_ALGO, "cannot create %s cp for "
|
||||
"probe %s to %s", (auth_name?"tcp":"udp"),
|
||||
zname, as);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -6411,8 +6415,9 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
}
|
||||
}
|
||||
|
||||
/* send udp packet */
|
||||
if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer,
|
||||
/* send udp packet, for an UDP commpoint. */
|
||||
if(auth_name == NULL &&
|
||||
!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer,
|
||||
(struct sockaddr*)&addr, addrlen, 0)) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
@@ -6421,13 +6426,18 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
zname, as);
|
||||
return 0;
|
||||
}
|
||||
/* for a TCP commpoint, the packet is waiting to be sent in the
|
||||
* TCP commpoint buffer. The callback returns when there is a reply. */
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
|
||||
as);
|
||||
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s%s%s",
|
||||
zname, as, (auth_name?"#":""),
|
||||
(auth_name?auth_name:""));
|
||||
}
|
||||
if(auth_name != NULL)
|
||||
timeout *= 10; /* TCP and TLS get a longer timeout */
|
||||
xfr->task_probe->timeout = timeout;
|
||||
#ifndef S_SPLINT_S
|
||||
t.tv_sec = timeout/1000;
|
||||
@@ -6565,6 +6575,94 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** callback for task_probe tcp replies */
|
||||
int
|
||||
auth_xfer_probe_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* ATTR_UNUSED(repinfo))
|
||||
{
|
||||
struct auth_xfer* xfr = (struct auth_xfer*)arg;
|
||||
struct module_env* env;
|
||||
log_assert(xfr->task_probe);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_probe->env;
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return 0; /* stop on quit */
|
||||
}
|
||||
/* stop the timer */
|
||||
comm_timer_disable(xfr->task_probe->timer);
|
||||
|
||||
/* see if we got a reply and what that means */
|
||||
if(err == NETEVENT_NOERROR) {
|
||||
uint32_t serial = 0;
|
||||
if(check_packet_ok(c->buffer, LDNS_RR_TYPE_SOA, xfr,
|
||||
&serial)) {
|
||||
/* successful lookup */
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char buf[256];
|
||||
dname_str(xfr->name, buf);
|
||||
verbose(VERB_ALGO, "auth zone %s: soa probe "
|
||||
"serial is %u", buf, (unsigned)serial);
|
||||
}
|
||||
/* see if this serial indicates that the zone has
|
||||
* to be updated */
|
||||
if(xfr_serial_means_update(xfr, serial)) {
|
||||
/* if updated, start the transfer task, if needed */
|
||||
verbose(VERB_ALGO, "auth_zone updated, start transfer");
|
||||
if(xfr->task_transfer->worker == NULL) {
|
||||
struct auth_master* master =
|
||||
xfr_probe_current_master(xfr);
|
||||
/* if we have download URLs use them
|
||||
* in preference to this master we
|
||||
* just probed the SOA from */
|
||||
if(xfr->task_transfer->masters &&
|
||||
xfr->task_transfer->masters->http)
|
||||
master = NULL;
|
||||
xfr_probe_disown(xfr);
|
||||
xfr_start_transfer(xfr, env, master);
|
||||
return 0;
|
||||
|
||||
}
|
||||
/* other tasks are running, we don't do this anymore */
|
||||
xfr_probe_disown(xfr);
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
/* return, we don't sent a reply to this udp packet,
|
||||
* and we setup the tasks to do next */
|
||||
return 0;
|
||||
} else {
|
||||
verbose(VERB_ALGO, "auth_zone master reports unchanged soa serial");
|
||||
/* we if cannot find updates amongst the
|
||||
* masters, this means we then have a new lease
|
||||
* on the zone */
|
||||
xfr->task_probe->have_new_lease = 1;
|
||||
}
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char buf[256];
|
||||
dname_str(xfr->name, buf);
|
||||
verbose(VERB_ALGO, "auth zone %s: bad reply to soa probe", buf);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char buf[256];
|
||||
dname_str(xfr->name, buf);
|
||||
verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* failed lookup or not an update */
|
||||
/* delete commpoint so a new one is created, with a fresh port nr */
|
||||
comm_point_delete(xfr->task_probe->cp);
|
||||
xfr->task_probe->cp = NULL;
|
||||
|
||||
/* if the result was not a successful probe, we need
|
||||
* to send the next one */
|
||||
xfr_probe_nextmaster(xfr);
|
||||
xfr_probe_send_or_end(xfr, env);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** lookup a host name for its addresses, if needed */
|
||||
static int
|
||||
xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
@@ -7774,7 +7872,6 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
enum sec_status sec;
|
||||
struct val_env* ve;
|
||||
int m;
|
||||
int verified = 0;
|
||||
m = modstack_find(mods, "validator");
|
||||
if(m == -1) {
|
||||
auth_zone_log(z->name, VERB_ALGO, "zonemd dnssec verify: have "
|
||||
@@ -7798,7 +7895,7 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
"zonemd: verify %s RRset with DNSKEY", typestr);
|
||||
}
|
||||
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
||||
LDNS_SECTION_ANSWER, NULL);
|
||||
if(sec == sec_status_secure) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -678,6 +678,9 @@ void auth_xfer_timer(void* arg);
|
||||
/** callback for commpoint udp replies to task_probe */
|
||||
int auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
/** callback for commpoint tcp replies to task_probe */
|
||||
int auth_xfer_probe_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
/** callback for task_transfer tcp connections */
|
||||
int auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
|
||||
Vendored
-22
@@ -690,28 +690,6 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
return msg;
|
||||
}
|
||||
|
||||
struct dns_msg*
|
||||
dns_msg_deepcopy_region(struct dns_msg* origin, struct regional* region)
|
||||
{
|
||||
size_t i;
|
||||
struct dns_msg* res = NULL;
|
||||
res = gen_dns_msg(region, &origin->qinfo, origin->rep->rrset_count);
|
||||
if(!res) return NULL;
|
||||
*res->rep = *origin->rep;
|
||||
if(origin->rep->reason_bogus_str) {
|
||||
res->rep->reason_bogus_str = regional_strdup(region,
|
||||
origin->rep->reason_bogus_str);
|
||||
}
|
||||
for(i=0; i<res->rep->rrset_count; i++) {
|
||||
res->rep->rrsets[i] = packed_rrset_copy_region(
|
||||
origin->rep->rrsets[i], region, 0);
|
||||
if(!res->rep->rrsets[i]) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** synthesize RRset-only response from cached RRset item */
|
||||
static struct dns_msg*
|
||||
rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
|
||||
Vendored
-9
@@ -164,15 +164,6 @@ struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
|
||||
struct reply_info* r, struct regional* region, time_t now,
|
||||
int allow_expired, struct regional* scratch);
|
||||
|
||||
/**
|
||||
* Deep copy a dns_msg to a region.
|
||||
* @param origin: the dns_msg to copy.
|
||||
* @param region: the region to copy all the data to.
|
||||
* @return the new dns_msg or NULL on malloc error.
|
||||
*/
|
||||
struct dns_msg* dns_msg_deepcopy_region(struct dns_msg* origin,
|
||||
struct regional* region);
|
||||
|
||||
/**
|
||||
* Find cached message
|
||||
* @param env: module environment with the DNS cache.
|
||||
|
||||
@@ -180,7 +180,6 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
enum sec_status sec;
|
||||
char* reason = NULL;
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
int verified = 0;
|
||||
if(vsig) {
|
||||
log_nametypeclass(VERB_QUERY, "verify of rrset",
|
||||
rrset->rk.dname, ntohs(rrset->rk.type),
|
||||
@@ -189,7 +188,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, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
||||
LDNS_SECTION_ANSWER, NULL);
|
||||
if(vsig) {
|
||||
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
|
||||
reason?reason:"");
|
||||
@@ -443,9 +442,9 @@ nsec3_hash_test_entry(struct entry* e, rbtree_type* ct,
|
||||
|
||||
ret = nsec3_hash_name(ct, region, buf, nsec3, 0, qname,
|
||||
qinfo.qname_len, &hash);
|
||||
if(ret < 1) {
|
||||
if(ret != 1) {
|
||||
printf("Bad nsec3_hash_name retcode %d\n", ret);
|
||||
unit_assert(ret == 1 || ret == 2);
|
||||
unit_assert(ret == 1);
|
||||
}
|
||||
unit_assert(hash->dname && hash->hash && hash->hash_len &&
|
||||
hash->b32 && hash->b32_len);
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
server:
|
||||
verbosity: 7
|
||||
# num-threads: 1
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
use-caps-for-id: no
|
||||
tls-cert-bundle: "unbound_server.pem"
|
||||
auth-zone:
|
||||
name: "example.com"
|
||||
for-upstream: yes
|
||||
for-downstream: yes
|
||||
master: "127.0.0.1@@TOPORT@#unbound"
|
||||
# if queries escape, send them to localhost
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: 127.0.0.1@@PORT@
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
server:
|
||||
verbosity: 5
|
||||
logfile: "/dev/stderr"
|
||||
xfrdfile: "xfrd.state"
|
||||
zonesdir: ""
|
||||
username: ""
|
||||
chroot: ""
|
||||
pidfile: "nsd.pid"
|
||||
database: ""
|
||||
zonelistfile: "zone.list"
|
||||
interface: 127.0.0.1@@AUTH_PORT@
|
||||
tls-service-key: "unbound_server.key"
|
||||
tls-service-pem: "unbound_server.pem"
|
||||
tls-port: @AUTH_PORT@
|
||||
|
||||
zone:
|
||||
name: "example.com"
|
||||
zonefile: "example.com.zone"
|
||||
provide-xfr: 127.0.0.0/8 NOKEY
|
||||
provide-xfr: ::1 NOKEY
|
||||
provide-xfr: ::ffff:127.0.0.1 NOKEY
|
||||
notify: 127.0.0.1@@PORT@ NOKEY
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
BaseName: auth_axfr_tls
|
||||
Version: 1.0
|
||||
Description: Perform AXFR for authority zone using TLS
|
||||
CreationDate: Thu 19 Oct 09:25:40 CEST 2023
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: auth_axfr_tls.pre
|
||||
Post: auth_axfr_tls.post
|
||||
Test: auth_axfr_tls.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
# #-- auth_axfr_tls.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# source the test var file when it's there
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
#
|
||||
# do your teardown here
|
||||
. ../common.sh
|
||||
kill_pid $AUTH_PID
|
||||
kill_pid $UNBOUND_PID
|
||||
if test -f nsd.log; then
|
||||
cat nsd.log
|
||||
fi
|
||||
if test -f unbound.log; then
|
||||
cat unbound.log
|
||||
fi
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# #-- auth_axfr_tls.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
|
||||
# see if we have NSD as an auth server to serve xfr over tls.
|
||||
NSD=nsd
|
||||
if which nsd 2>/dev/null; then
|
||||
echo "NSD=$NSD"
|
||||
else
|
||||
NSD=""
|
||||
for d in ".." "../.." "../../.." "../../../.." ; do
|
||||
if test -z "$NSD" -o ! -f "$NSD"; then
|
||||
if test -d "$d/nsd" && test -f "$d/nsd/nsd"; then
|
||||
NSD="$d/nsd/nsd"
|
||||
break;
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test -z "$NSD"; then
|
||||
skip_test "Need nsd for auth server, skip test"
|
||||
fi
|
||||
echo "NSD=$NSD" >> .tpkg.var.test
|
||||
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
AUTH_PORT=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "AUTH_PORT=$AUTH_PORT" >> .tpkg.var.test
|
||||
|
||||
# start auth server
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@AUTH_PORT\@/'$AUTH_PORT'/' < auth_axfr_tls.conf2 > nsd.conf
|
||||
$NSD -d -c nsd.conf >nsd.log 2>&1 &
|
||||
AUTH_PID=$!
|
||||
echo "AUTH_PID=$AUTH_PID" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$AUTH_PORT'/' < auth_axfr_tls.conf > ub.conf
|
||||
# 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
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_nsd_up nsd.log
|
||||
wait_unbound_up unbound.log
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
# #-- auth_axfr_tls.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
|
||||
|
||||
. ../common.sh
|
||||
PRE="../.."
|
||||
# do the test
|
||||
echo "> dig www.example.com."
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
# try again if it needs time to do the zone transfer.
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
echo "> check answer"
|
||||
if grep "1.2.3.4" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# update the zone
|
||||
mv example.com.zone example.com.zone.old
|
||||
mv example.com.zone2 example.com.zone
|
||||
touch example.com.zone
|
||||
kill -1 $AUTH_PID
|
||||
#it would need to wait for the line to appear twice.
|
||||
#wait_server_up nsd.log "zone example.com read with success"
|
||||
echo "> auth server updated"
|
||||
|
||||
echo "> dig www.example.com."
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
# try again if it needs time to do the zone transfer.
|
||||
if grep SERVFAIL outfile || grep "1.2.3.4" outfile; then
|
||||
echo "> try again"
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile || grep "1.2.3.4" outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile || grep "1.2.3.4" outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile || grep "1.2.3.4" outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
echo "> check answer"
|
||||
if grep "1.2.3.5" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep "auth zone example.com. soa probe sent to 127.0.0.1#unbound" unbound.log; then
|
||||
echo "SOA sent over TLS"
|
||||
else
|
||||
echo "SOA not sent over TLS"
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,2 @@
|
||||
example.com. IN SOA nibbler.example.com. leela.example.com. 4 3600 3600 7200 300
|
||||
www.example.com. IN A 1.2.3.4
|
||||
@@ -0,0 +1,2 @@
|
||||
example.com. IN SOA nibbler.example.com. leela.example.com. 8 3600 3600 7200 300
|
||||
www.example.com. IN A 1.2.3.5
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIG4gIBAAKCAYEAstEp+Pyh8XGrtZ77A4FhYjvbeB3dMa7Q2rGWxobzlA9przhA
|
||||
1aChAvUtCOAuM+rB6NTNB8YWfZJbQHawyMNpmC77cg6vXLYCGUQHZyAqidN049RJ
|
||||
F5T7j4N8Vniv17LiRdr0S6swy4PRvEnIPPV43EQHZqC5jVvHsKkhIfmBF/Dj5TXR
|
||||
ypeawWV/m5jeU6/4HRYMfytBZdO1mPXuWLh0lgbQ4SCbgrOUVD3rniMk1yZIbQOm
|
||||
vlDHYqekjDb/vOW2KxUQLG04aZMJ1mWfdbwG0CKQkSjISEDZ1l76vhM6mTM0fwXb
|
||||
IvyFZ9yPPCle1mF5aSlxS2cmGuGVSRQaw8XF9fe3a9ACJJTr33HdSpyaZkKRAUzL
|
||||
cKqLCl323daKv3NwwAT03Tj4iQM416ASMoiyfFa/2GWTKQVjddu8Crar7tGaf5xr
|
||||
lig4DBmrBvdYA3njy72/RD71hLwmlRoCGU7dRuDr9O6KASUm1Ri91ONZ/qdjMvov
|
||||
15l2vj4GV+KXR00dAgMBAAECggGAHepIL1N0dEQkCdpy+/8lH54L9WhpnOo2HqAf
|
||||
LU9eaKK7d4jdr9+TkD8cLaPzltPrZNxVALvu/0sA4SP6J1wpyj/x6P7z73qzly5+
|
||||
Xo5PD4fEwmi9YaiW/UduAblnEZrnp/AddptJKoL/D5T4XtpiQddPtael4zQ7kB57
|
||||
YIexRSQTvEDovA/o3/nvA0TrzOxfgd4ycQP3iOWGN/TMzyLsvjydrUwbOB567iz9
|
||||
whL3Etdgvnwh5Sz2blbFfH+nAR8ctvFFz+osPvuIVR21VMEI6wm7kTpSNnQ6sh/c
|
||||
lrLb/bTADn4g7z/LpIZJ+MrLvyEcoqValrLYeFBhM9CV8woPxvkO2P3pU47HVGax
|
||||
tC7GV6a/kt5RoKFd/TNdiA3OC7NGZtaeXv9VkPf4fVwBtSO9d5ZZXTGEynDD/rUQ
|
||||
U4KFJe6OD23APjse08HiiKqTPhsOneOONU67iqoaTdIkT2R4EdlkVEDpXVtWb+G9
|
||||
Q+IqYzVljlzuyHrhWXLJw/FMa2aBAoHBAOnZbi4gGpH+P6886WDWVgIlTccuXoyc
|
||||
Mg9QQYk9UDeXxL0AizR5bZy49Sduegz9vkHpAiZARQsUnizHjZ8YlRcrmn4t6tx3
|
||||
ahTIKAjdprnxJfYINM580j8CGbXvX5LhIlm3O267D0Op+co3+7Ujy+cjsIuFQrP+
|
||||
1MqMgXSeBjzC1APivmps7HeFE+4w0k2PfN5wSMDNCzLo99PZuUG5XZ93OVOS5dpN
|
||||
b+WskdcD8NOoJy/X/5A08veEI/jYO/DyqQKBwQDDwUQCOWf41ecvJLtBHKmEnHDz
|
||||
ftzHino9DRKG8a9XaN4rmetnoWEaM2vHGX3pf3mwH+dAe8vJdAQueDhBKYeEpm6C
|
||||
TYNOpou1+Zs5s99BilCTNYo8fkMOAyqwRwmz9zgHS6QxXuPwsghKefLJGt6o6RFF
|
||||
tfWVTfLlYJ+I3GQe3ySsk3wjVz4oUTKiyiq5+KzD+HhEkS7u+RQ7Z0ZI2xd2cF8Y
|
||||
aN2hjKDpcOiFf3CDoqka5D1qMNLgIHO52AHww1UCgcA1h7o7AMpURRka6hyaODY0
|
||||
A4oMYEbwdQjYjIyT998W+rzkbu1us6UtzQEBZ760npkgyU/epbOoV63lnkCC/MOU
|
||||
LD0PST+L/CHiY/cWIHb79YG1EifUZKpUFg0Aoq0EGFkepF0MefGCkbRGYA5UZr9U
|
||||
R80wAu9D+L+JJiS0J0BSRF74DL196zUuHt5zFeXuLzxsRtPAnq9DliS08BACRYZy
|
||||
7H3I7cWD9Vn5/0jbKWHFcaaWwyETR6uekTcSzZzbCRECgcBeoE3/xUA9SSk34Mmj
|
||||
7/cB4522Ft0imA3+9RK/qJTZ7Bd5fC4PKjOGNtUiqW/0L2rjeIiQ40bfWvWqgPKw
|
||||
jSK1PL6uvkl6+4cNsFsYyZpiVDoe7wKju2UuoNlB3RUTqa2r2STFuNj2wRjA57I1
|
||||
BIgdnox65jqQsd14g/yaa+75/WP9CE45xzKEyrtvdcqxm0Pod3OrsYK+gikFjiar
|
||||
kT0GQ8u0QPzh2tjt/2ZnIfOBrl+QYERP0MofDZDjhUdq2wECgcB0Lu841+yP5cdR
|
||||
qbJhXO4zJNh7oWNcJlOuQp3ZMNFrA1oHpe9pmLukiROOy01k9WxIMQDzU5GSqRv3
|
||||
VLkYOIcbhJ3kClKAcM3j95SkKbU2H5/RENb3Ck52xtl4pNU1x/3PnVFZfDVuuHO9
|
||||
MZ9YBcIeK98MyP2jr5JtFKnOyPE7xKq0IHIhXadpbc2wjje5FtZ1cUtMyEECCXNa
|
||||
C1TpXebHGyXGpY9WdWXhjdE/1jPvfS+uO5WyuDpYPr339gsdq1g=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDszCCAhsCFGD5193whHQ2bVdzbaQfdf1gc4SkMA0GCSqGSIb3DQEBCwUAMBIx
|
||||
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjMwWhcNNDAwMzI1MTMzMjMw
|
||||
WjAaMRgwFgYDVQQDDA91bmJvdW5kLWNvbnRyb2wwggGiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBjwAwggGKAoIBgQCy0Sn4/KHxcau1nvsDgWFiO9t4Hd0xrtDasZbGhvOUD2mv
|
||||
OEDVoKEC9S0I4C4z6sHo1M0HxhZ9kltAdrDIw2mYLvtyDq9ctgIZRAdnICqJ03Tj
|
||||
1EkXlPuPg3xWeK/XsuJF2vRLqzDLg9G8Scg89XjcRAdmoLmNW8ewqSEh+YEX8OPl
|
||||
NdHKl5rBZX+bmN5Tr/gdFgx/K0Fl07WY9e5YuHSWBtDhIJuCs5RUPeueIyTXJkht
|
||||
A6a+UMdip6SMNv+85bYrFRAsbThpkwnWZZ91vAbQIpCRKMhIQNnWXvq+EzqZMzR/
|
||||
Bdsi/IVn3I88KV7WYXlpKXFLZyYa4ZVJFBrDxcX197dr0AIklOvfcd1KnJpmQpEB
|
||||
TMtwqosKXfbd1oq/c3DABPTdOPiJAzjXoBIyiLJ8Vr/YZZMpBWN127wKtqvu0Zp/
|
||||
nGuWKDgMGasG91gDeePLvb9EPvWEvCaVGgIZTt1G4Ov07ooBJSbVGL3U41n+p2My
|
||||
+i/XmXa+PgZX4pdHTR0CAwEAATANBgkqhkiG9w0BAQsFAAOCAYEAd++Wen6l8Ifj
|
||||
4h3p/y16PhSsWJWuJ4wdNYy3/GM84S26wGjzlEEwiW76HpH6VJzPOiBAeWnFKE83
|
||||
hFyetEIxgJeIPbcs9ZP/Uoh8GZH9tRISBSN9Hgk2Slr9llo4t1H0g/XTgA5HqMQU
|
||||
9YydlBh43G7Vw3FVwh09OM6poNOGQKNc/tq2/QdKeUMtyBbLWpRmjH5XcCT35fbn
|
||||
ZiVOUldqSHD4kKrFO4nJYXZyipRbcXybsLiX9GP0GLemc3IgIvOXyJ2RPp06o/SJ
|
||||
pzlMlkcAfLJaSuEW57xRakhuNK7m051TKKzJzIEX+NFYOVdafFHS8VwGrYsdrFvD
|
||||
72tMfu+Fu55y3awdWWGc6YlaGogZiuMnJkvQphwgn+5qE/7CGEckoKEsH601rqIZ
|
||||
muaIc85+nEcHJeijd/ZlBN9zeltjFoMuqTUENgmv8+tUAdVm/UMY9Vjme6b43ydP
|
||||
uv6DS02+k9z8toxXworLiPr94BGaiGV1NxgwZKLZigYJt/Fi2Qte
|
||||
-----END CERTIFICATE-----
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIG5AIBAAKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI
|
||||
0x41iG32a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+Nqq
|
||||
GRS7XVQ24vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Z
|
||||
uh9MDgotaBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8K
|
||||
WaBe1ca4TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5
|
||||
FzUReSXZuTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xP
|
||||
q6O9UPj4+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XL
|
||||
A5UoZgRzXgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP
|
||||
7kFZSngxdy1+A/bNAgMBAAECggGBALpTOIqQwVg4CFBylL/a8K1IWJTI/I65sklf
|
||||
XxYL7G7SB2HlEJ//z+E+F0+S4Vlao1vyLQ5QkgE82pAUB8FoMWvY1qF0Y8A5wtm6
|
||||
iZSGk4OLK488ZbT8Ii9i+AGKgPe2XbVxsJwj8N4k7Zooqec9hz73Up8ATEWJkRz7
|
||||
2u7oMGG4z91E0PULA64dOi3l/vOQe5w/Aa+CwVbAWtI05o7kMvQEBMDJn6C7CByo
|
||||
MB5op9wueJMnz7PM7hns+U7Dy6oE4ljuolJUy51bDzFWwoM54cRoQqLFNHd8JVQj
|
||||
WxldCkbfF43iyprlsEcUrTyUjtdA+ZeiG39vg/mtdmgNpGmdupHJZQvSuG8IcVlz
|
||||
O+eMSeQS1QXPD6Ik8UK4SU0h+zOl8xIWtRrsxQuh4fnTN40udm/YUWl/6gOebsBI
|
||||
IrVLlKGqJSfB3tMjpCRqdTzJ0dA9keVpkqm2ugZkxEf1+/efq/rFIQ2pUBLCqNTN
|
||||
qpNqruK8y8FphP30I2uI4Ej2UIB8AQKBwQDd2Yptj2FyDyaXCycsyde0wYkNyzGU
|
||||
dRnzdibfHnMZwjgTjwAwgIUBVIS8H0/z7ZJQKN7osJfddMrtjJtYYUk9g/dCpHXs
|
||||
bNh2QSoWah3FdzNGuWd0iRf9+LFxhjAAMo/FS8zFJAJKrFsBdCGTfFUMdsLC0bjr
|
||||
YjiWBuvV72uKf8XIZX5KIZruKdWBBcWukcb21R1UDyFYyXRBsly5XHaIYKZql3km
|
||||
7pV7MKWO0IYgHbHIqGUqPQlzZ/lkunS1jKECgcEA23wHffD6Ou9/x3okPx2AWpTr
|
||||
gh8rgqbyo6hQkBW5Y90Wz824cqaYebZDaBR/xlVx/YwjKkohv8Bde2lpH/ZxRZ1Z
|
||||
5Sk2s6GJ/vU0L9RsJZgCgj4L6Coal1NMxuZtCXAlnOpiCdxSZgfqbshbTVz30KsG
|
||||
ZJG361Cua1ScdAHxlZBxT52/1Sm0zRC2hnxL7h4qo7Idmtzs40LAJvYOKekR0pPN
|
||||
oWeJfra7vgx/jVNvMFWoOoSLpidVO4g+ot4ery6tAoHAdW3rCic1C2zdnmH28Iw+
|
||||
s50l8Lk3mz+I5wgJd1zkzCO0DxZIoWPGA3g7cmCYr6N3KRsZMs4W9NAXgjpFGDkW
|
||||
zYsG3K21BdpvkdjYcFjnPVjlOXB2RIc0vehf9Jl02wXoeCSxVUDEPcaRvWk9RJYx
|
||||
ZpGOchUU7vNkxHURbIJ4yCzuAi9G8/Jp0dsu+kaV5tufF5SjG5WOrzKjaQsCbdN1
|
||||
oqaWMCHRrTvov/Z2C+xwsptFOdN5CSyZzg6hQiI4GMlBAoHAXyb6KINcOEi0YMp3
|
||||
BFXJ23tMTnEs78tozcKeipigcsbaqORK3omS+NEnj+uzKUzJyl4CsMbKstK2tFYS
|
||||
mSTCHqgE3PBtIpsZtEqhgUraR8IK9GPpzZDTTl9ynZgwFTNlWw3RyuyVXF56J+T8
|
||||
kCGJ3hEHCHqT/ZRQyX85BKIDFhA0z4tYKxWVqIFiYBNq56R0X9tMMmMs36mEnF93
|
||||
7Ht6mowxTZQRa7nU0qOgeKh/P7ki4Zus3y+WJ+T9IqahLtlRAoHBAIhqMrcxSAB8
|
||||
RpB9jukJlAnidw2jCMPgrFE8tP0khhVvGrXMldxAUsMKntDIo8dGCnG1KTcWDI0O
|
||||
jepvSPHSsxVLFugL79h0eVIS5z4huW48i9xgU8VlHdgAcgEPIAOFcOw2BCu/s0Vp
|
||||
O+MM/EyUOdo3NsibB3qc/GJI6iNBYS7AljYEVo6rXo5V/MZvZUF4vClen6Obzsre
|
||||
MTTb+4sJjfqleWuvr1XNMeu2mBfXBQkWGZP1byBK0MvD/aQ2PWq92A==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDqzCCAhMCFBHWXeQ6ZIa9QcQbXLFfC6tj+KA+MA0GCSqGSIb3DQEBCwUAMBIx
|
||||
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjI5WhcNNDAwMzI1MTMzMjI5
|
||||
WjASMRAwDgYDVQQDDAd1bmJvdW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
|
||||
igKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI0x41iG32
|
||||
a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+NqqGRS7XVQ2
|
||||
4vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Zuh9MDgot
|
||||
aBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8KWaBe1ca4
|
||||
TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5FzUReSXZ
|
||||
uTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xPq6O9UPj4
|
||||
+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XLA5UoZgRz
|
||||
XgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP7kFZSngx
|
||||
dy1+A/bNAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABunf93MKaCUHiZgnoOTinsW
|
||||
84/EgInrgtKzAyH+BhnKkJOhhR0kkIAx5d9BpDlaSiRTACFon9moWCgDIIsK/Ar7
|
||||
JE0Kln9cV//wiiNoFU0O4mnzyGUIMvlaEX6QHMJJQYvL05+w/3AAcf5XmMJtR5ca
|
||||
fJ8FqvGC34b2WxX9lTQoyT52sRt+1KnQikiMEnEyAdKktMG+MwKsFDdOwDXyZhZg
|
||||
XZhRrfX3/NVJolqB6EahjWIGXDeKuSSKZVtCyib6LskyeMzN5lcRfvubKDdlqFVF
|
||||
qlD7rHBsKhQUWK/IO64mGf7y/de+CgHtED5vDvr/p2uj/9sABATfbrOQR3W/Of25
|
||||
sLBj4OEfrJ7lX8hQgFaxkMI3x6VFT3W8dTCp7xnQgb6bgROWB5fNEZ9jk/gjSRmD
|
||||
yIU+r0UbKe5kBk/CmZVFXL2TyJ92V5NYEQh8V4DGy19qZ6u/XKYyNJL4ocs35GGe
|
||||
CA8SBuyrmdhx38h1RHErR2Skzadi1S7MwGf1y431fQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,29 +0,0 @@
|
||||
server:
|
||||
verbosity: 4
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
module-config: "cachedb iterator"
|
||||
do-not-query-localhost: no
|
||||
qname-minimisation: no
|
||||
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: 127.0.0.1@@TOPORT@
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 127.0.0.1@@TOPORT@
|
||||
|
||||
remote-control:
|
||||
control-enable: yes
|
||||
control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@
|
||||
control-use-cert: no
|
||||
|
||||
cachedb:
|
||||
backend: "testframe"
|
||||
secret-seed: "testvalue"
|
||||
@@ -1,16 +0,0 @@
|
||||
BaseName: cachedb_no_store
|
||||
Version: 1.0
|
||||
Description: cachedb test the cachedb-no-store option
|
||||
CreationDate: Wed 11 Oct 11:00:00 CEST 2023
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: cachedb_no_store.pre
|
||||
Post: cachedb_no_store.post
|
||||
Test: cachedb_no_store.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
@@ -1,20 +0,0 @@
|
||||
# #-- cachedb_no_store.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# source the test var file when it's there
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
#
|
||||
# do your teardown here
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
if test -f fwd2.log; then cat fwd2.log; else echo "no fwd2.log"; fi
|
||||
if test -f fwd3.log; then cat fwd3.log; else echo "no fwd3.log"; fi
|
||||
if test -f fwd4.log; then cat fwd4.log; else echo "no fwd4.log"; fi
|
||||
cat unbound.log
|
||||
if test -f unbound2.log; then cat unbound2.log; else echo "no unbound2.log"; fi
|
||||
kill_pid $FWD_PID
|
||||
kill_pid `cat unbound.pid`
|
||||
rm -f $CONTROL_PATH/controlpipe.$CONTROL_PID
|
||||
@@ -1,36 +0,0 @@
|
||||
# #-- cachedb_no_store.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
|
||||
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
if grep "define USE_CACHEDB 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
|
||||
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
FWD_PORT=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||
|
||||
# start forwarder
|
||||
get_ldns_testns
|
||||
$LDNS_TESTNS -p $FWD_PORT cachedb_no_store.testns >fwd.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
CONTROL_PATH=/tmp
|
||||
CONTROL_PID=$$
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < cachedb_no_store.conf > ub.conf
|
||||
# start unbound in the background
|
||||
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
echo "CONTROL_PATH=$CONTROL_PATH" >> .tpkg.var.test
|
||||
echo "CONTROL_PID=$CONTROL_PID" >> .tpkg.var.test
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_ldns_testns_up fwd.log
|
||||
wait_unbound_up unbound.log
|
||||
@@ -1,8 +0,0 @@
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR AA SERVFAIL
|
||||
SECTION QUESTION
|
||||
txt1.example.com. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
@@ -1,132 +0,0 @@
|
||||
# #-- cachedb_no_store.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
|
||||
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
|
||||
# do the test
|
||||
get_ldns_testns
|
||||
|
||||
# query for a text record that is stored by unbound's cache and cachedb
|
||||
# in the testframe cache.
|
||||
echo "> dig txt1.example.com."
|
||||
dig @localhost -p $UNBOUND_PORT txt1.example.com. TXT | tee outfile
|
||||
if grep "example text message" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# stop the forwarder with servfail, to check the answer came from the cache
|
||||
echo "> stop ldns-testns"
|
||||
kill_pid $FWD_PID
|
||||
echo "> start ldns-testns with servfails"
|
||||
$LDNS_TESTNS -p $FWD_PORT cachedb_no_store.servfail.testns >fwd2.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
wait_ldns_testns_up fwd2.log
|
||||
|
||||
echo "> dig txt1.example.com. from unbound cache"
|
||||
dig @localhost -p $UNBOUND_PORT txt1.example.com. TXT | tee outfile
|
||||
if grep "example text message" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# clear the cache of unbound, but not cachedb testframe cache
|
||||
echo "> unbound-control flush"
|
||||
$PRE/unbound-control -c ub.conf flush_type txt1.example.com. TXT
|
||||
if test $? -ne 0; then
|
||||
echo "wrong exit value."
|
||||
exit 1
|
||||
else
|
||||
echo "exit value: OK"
|
||||
fi
|
||||
|
||||
echo "> dig txt1.example.com. from cachedb"
|
||||
dig @localhost -p $UNBOUND_PORT txt1.example.com. TXT | tee outfile
|
||||
if grep "example text message" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# start the forwarder again.
|
||||
echo "> stop ldns-testns"
|
||||
kill_pid $FWD_PID
|
||||
echo "> start ldns-testns"
|
||||
$LDNS_TESTNS -p $FWD_PORT cachedb_no_store.testns >fwd3.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
wait_ldns_testns_up fwd3.log
|
||||
|
||||
# stop unbound to flush the cachedb cache
|
||||
echo "> stop unbound"
|
||||
kill_pid `cat unbound.pid`
|
||||
|
||||
echo ""
|
||||
echo "> config unbound with cachedb-no-store: yes"
|
||||
echo "cachedb: cachedb-no-store: yes" >> ub.conf
|
||||
|
||||
# start unbound again.
|
||||
echo "> start unbound"
|
||||
$PRE/unbound -d -c ub.conf >unbound2.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
wait_unbound_up unbound2.log
|
||||
|
||||
echo ""
|
||||
echo "> dig txt1.example.com."
|
||||
dig @localhost -p $UNBOUND_PORT txt1.example.com. TXT | tee outfile
|
||||
if grep "example text message" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# stop the forwarder with servfail, to check the answer came from the cache
|
||||
echo "> stop ldns-testns"
|
||||
kill_pid $FWD_PID
|
||||
echo "> start ldns-testns with servfails"
|
||||
$LDNS_TESTNS -p $FWD_PORT cachedb_no_store.servfail.testns >fwd4.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
wait_ldns_testns_up fwd4.log
|
||||
|
||||
echo "> dig txt1.example.com. from unbound cache"
|
||||
dig @localhost -p $UNBOUND_PORT txt1.example.com. TXT | tee outfile
|
||||
if grep "example text message" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# clear the cache of unbound, but not cachedb testframe cache
|
||||
echo "> unbound-control flush"
|
||||
$PRE/unbound-control -c ub.conf flush_type txt1.example.com. TXT
|
||||
if test $? -ne 0; then
|
||||
echo "wrong exit value."
|
||||
exit 1
|
||||
else
|
||||
echo "exit value: OK"
|
||||
fi
|
||||
|
||||
echo "> dig txt1.example.com. from cachedb, but that has no message stored"
|
||||
dig @localhost -p $UNBOUND_PORT txt1.example.com. TXT | tee outfile
|
||||
if grep "SERVFAIL" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,9 +0,0 @@
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
txt1.example.com. IN TXT
|
||||
SECTION ANSWER
|
||||
txt1.example.com. IN TXT "example text message"
|
||||
ENTRY_END
|
||||
Vendored
-3
@@ -162,9 +162,6 @@ SECTION QUESTION
|
||||
example.com. IN ANY
|
||||
ENTRY_END
|
||||
|
||||
; Allow validation resuming for the RRSIGs
|
||||
STEP 2 TIME_PASSES ELAPSE 0.05
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
|
||||
Vendored
-3
@@ -164,9 +164,6 @@ SECTION QUESTION
|
||||
example.com. IN ANY
|
||||
ENTRY_END
|
||||
|
||||
; Allow validation resuming for the RRSIGs
|
||||
STEP 2 TIME_PASSES ELAPSE 0.05
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
|
||||
Vendored
-3
@@ -199,9 +199,6 @@ SECTION QUESTION
|
||||
example.com. IN ANY
|
||||
ENTRY_END
|
||||
|
||||
; Allow validation resuming for the RRSIGs
|
||||
STEP 21 TIME_PASSES ELAPSE 0.05
|
||||
|
||||
; recursion happens here.
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
|
||||
Vendored
-3
@@ -156,9 +156,6 @@ SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Allow validation resuming for NSEC3 hash calculations
|
||||
STEP 2 TIME_PASSES ELAPSE 0.05
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
|
||||
@@ -382,7 +382,6 @@ config_create(void)
|
||||
#ifdef USE_CACHEDB
|
||||
if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit;
|
||||
if(!(cfg->cachedb_secret = strdup("default"))) goto error_exit;
|
||||
cfg->cachedb_no_store = 0;
|
||||
#ifdef USE_REDIS
|
||||
if(!(cfg->redis_server_host = strdup("127.0.0.1"))) goto error_exit;
|
||||
cfg->redis_server_path = NULL;
|
||||
@@ -823,9 +822,6 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
{ IS_NUMBER_OR_ZERO; cfg->ipsecmod_max_ttl = atoi(val); }
|
||||
else S_YNO("ipsecmod-strict:", ipsecmod_strict)
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
else S_YNO("cachedb-no-store:", cachedb_no_store)
|
||||
#endif /* USE_CACHEDB */
|
||||
else if(strcmp(opt, "define-tag:") ==0) {
|
||||
return config_add_tag(cfg, val);
|
||||
/* val_sig_skew_min, max and val_max_restart are copied into val_env
|
||||
@@ -1314,7 +1310,6 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
#ifdef USE_CACHEDB
|
||||
else O_STR(opt, "backend", cachedb_backend)
|
||||
else O_STR(opt, "secret-seed", cachedb_secret)
|
||||
else O_YNO(opt, "cachedb-no-store", cachedb_no_store)
|
||||
#ifdef USE_REDIS
|
||||
else O_STR(opt, "redis-server-host", redis_server_host)
|
||||
else O_DEC(opt, "redis-server-port", redis_server_port)
|
||||
|
||||
@@ -701,8 +701,6 @@ struct config_file {
|
||||
char* cachedb_backend;
|
||||
/** secret seed for hash key calculation */
|
||||
char* cachedb_secret;
|
||||
/** cachedb that does not store, but only reads from database, if on */
|
||||
int cachedb_no_store;
|
||||
#ifdef USE_REDIS
|
||||
/** redis server's IP address or host name */
|
||||
char* redis_server_host;
|
||||
|
||||
@@ -558,7 +558,6 @@ ipsecmod-strict{COLON} { YDVAR(1, VAR_IPSECMOD_STRICT) }
|
||||
cachedb{COLON} { YDVAR(0, VAR_CACHEDB) }
|
||||
backend{COLON} { YDVAR(1, VAR_CACHEDB_BACKEND) }
|
||||
secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) }
|
||||
cachedb-no-store{COLON} { YDVAR(1, VAR_CACHEDB_NO_STORE) }
|
||||
redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) }
|
||||
redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) }
|
||||
redis-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISPATH) }
|
||||
|
||||
+2
-15
@@ -199,7 +199,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_INTERFACE_ACTION VAR_INTERFACE_VIEW VAR_INTERFACE_TAG
|
||||
%token VAR_INTERFACE_TAG_ACTION VAR_INTERFACE_TAG_DATA
|
||||
%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
|
||||
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
|
||||
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@@ -3712,7 +3712,7 @@ contents_cachedb: contents_cachedb content_cachedb
|
||||
content_cachedb: cachedb_backend_name | cachedb_secret_seed |
|
||||
redis_server_host | redis_server_port | redis_timeout |
|
||||
redis_expire_records | redis_server_path | redis_server_password |
|
||||
cachedb_no_store | redis_logical_db
|
||||
redis_logical_db
|
||||
;
|
||||
cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
|
||||
{
|
||||
@@ -3738,19 +3738,6 @@ cachedb_secret_seed: VAR_CACHEDB_SECRETSEED STRING_ARG
|
||||
#endif
|
||||
}
|
||||
;
|
||||
cachedb_no_store: VAR_CACHEDB_NO_STORE STRING_ARG
|
||||
{
|
||||
#ifdef USE_CACHEDB
|
||||
OUTYY(("P(cachedb_no_store:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->cachedb_no_store = (strcmp($2, "yes")==0);
|
||||
#else
|
||||
OUTYY(("P(Compiled without cachedb, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
redis_server_host: VAR_CACHEDB_REDISHOST STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
|
||||
@@ -886,9 +886,6 @@ ede_trim_text(struct edns_option** list)
|
||||
curr->opt_len = 2;
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
} else {
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
} else {
|
||||
/* continue */
|
||||
|
||||
+1
-1
@@ -108,6 +108,7 @@ fptr_whitelist_comm_point(comm_point_callback_type *fptr)
|
||||
else if(fptr == &outnet_tcp_cb) return 1;
|
||||
else if(fptr == &tube_handle_listen) return 1;
|
||||
else if(fptr == &auth_xfer_probe_udp_callback) return 1;
|
||||
else if(fptr == &auth_xfer_probe_tcp_callback) return 1;
|
||||
else if(fptr == &auth_xfer_transfer_tcp_callback) return 1;
|
||||
else if(fptr == &auth_xfer_transfer_http_callback) return 1;
|
||||
return 0;
|
||||
@@ -131,7 +132,6 @@ fptr_whitelist_comm_timer(void (*fptr)(void*))
|
||||
else if(fptr == &pending_udp_timer_delay_cb) return 1;
|
||||
else if(fptr == &worker_stat_timer_cb) return 1;
|
||||
else if(fptr == &worker_probe_timer_cb) return 1;
|
||||
else if(fptr == &validate_suspend_timer_cb) return 1;
|
||||
#ifdef UB_ON_WINDOWS
|
||||
else if(fptr == &wsvc_cron_cb) return 1;
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ void log_ident_set_default(const char* id)
|
||||
default_ident = id;
|
||||
}
|
||||
|
||||
void log_ident_revert_to_default(void)
|
||||
void log_ident_revert_to_default()
|
||||
{
|
||||
ident = default_ident;
|
||||
}
|
||||
|
||||
+7
-8
@@ -952,11 +952,11 @@ void log_crypto_err_code(const char* str, unsigned long err)
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
/** Print crypt erro with SSL_get_error want code and err_get_error code */
|
||||
static void log_crypto_err_io_code_arg(const char* str, int r,
|
||||
unsigned long err, int err_present)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
int print_errno = 0, print_crypto_err = 0;
|
||||
const char* inf = NULL;
|
||||
|
||||
@@ -982,21 +982,15 @@ static void log_crypto_err_io_code_arg(const char* str, int r,
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
inf = "want X509 lookup";
|
||||
break;
|
||||
#ifdef SSL_ERROR_WANT_ASYNC
|
||||
case SSL_ERROR_WANT_ASYNC:
|
||||
inf = "want async";
|
||||
break;
|
||||
#endif
|
||||
#ifdef SSL_ERROR_WANT_ASYNC_JOB
|
||||
case SSL_ERROR_WANT_ASYNC_JOB:
|
||||
inf = "want async job";
|
||||
break;
|
||||
#endif
|
||||
#ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB
|
||||
case SSL_ERROR_WANT_CLIENT_HELLO_CB:
|
||||
inf = "want client hello cb";
|
||||
break;
|
||||
#endif
|
||||
case SSL_ERROR_SYSCALL:
|
||||
print_errno = 1;
|
||||
inf = "syscall";
|
||||
@@ -1033,8 +1027,13 @@ static void log_crypto_err_io_code_arg(const char* str, int r,
|
||||
log_err("str: %s", inf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)str;
|
||||
(void)r;
|
||||
(void)err;
|
||||
(void)err_present;
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
|
||||
void log_crypto_err_io(const char* str, int r)
|
||||
{
|
||||
|
||||
+1
-7
@@ -1070,13 +1070,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
||||
fptr_ok(fptr_whitelist_comm_point(rep.c->callback));
|
||||
if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) {
|
||||
/* send back immediate reply */
|
||||
struct sldns_buffer *buffer;
|
||||
#ifdef USE_DNSCRYPT
|
||||
buffer = rep.c->dnscrypt_buffer;
|
||||
#else
|
||||
buffer = rep.c->buffer;
|
||||
#endif
|
||||
(void)comm_point_send_udp_msg_if(rep.c, buffer,
|
||||
(void)comm_point_send_udp_msg_if(rep.c, rep.c->buffer,
|
||||
(struct sockaddr*)&rep.remote_addr,
|
||||
rep.remote_addrlen, &rep);
|
||||
}
|
||||
|
||||
@@ -181,7 +181,6 @@ nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
nsec->entry.data;
|
||||
int verified = 0;
|
||||
if(!d) return 0;
|
||||
if(d->security == sec_status_secure)
|
||||
return 1;
|
||||
@@ -189,7 +188,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,
|
||||
reason_bogus, LDNS_SECTION_AUTHORITY, qstate, &verified);
|
||||
reason_bogus, LDNS_SECTION_AUTHORITY, qstate);
|
||||
if(d->security == sec_status_secure) {
|
||||
rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
|
||||
return 1;
|
||||
|
||||
+70
-246
@@ -57,19 +57,6 @@
|
||||
/* we include nsec.h for the bitmap_has_type function */
|
||||
#include "validator/val_nsec.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
/**
|
||||
* Max number of NSEC3 calculations at once, suspend query for later.
|
||||
* 8 is low enough and allows for cases where multiple proofs are needed.
|
||||
*/
|
||||
#define MAX_NSEC3_CALCULATIONS 8
|
||||
/**
|
||||
* When all allowed NSEC3 calculations at once resulted in error treat as
|
||||
* bogus. NSEC3 hash errors are not cached and this helps breaks loops with
|
||||
* erroneous data.
|
||||
*/
|
||||
#define MAX_NSEC3_ERRORS -1
|
||||
|
||||
/**
|
||||
* This function we get from ldns-compat or from base system
|
||||
@@ -545,17 +532,6 @@ nsec3_hash_cmp(const void* c1, const void* c2)
|
||||
return memcmp(s1, s2, s1len);
|
||||
}
|
||||
|
||||
int
|
||||
nsec3_cache_table_init(struct nsec3_cache_table* ct, struct regional* region)
|
||||
{
|
||||
if(ct->ct) return 1;
|
||||
ct->ct = (rbtree_type*)regional_alloc(region, sizeof(*ct->ct));
|
||||
if(!ct->ct) return 0;
|
||||
ct->region = region;
|
||||
rbtree_init(ct->ct, &nsec3_hash_cmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
nsec3_get_hashed(sldns_buffer* buf, uint8_t* nm, size_t nmlen, int algo,
|
||||
size_t iter, uint8_t* salt, size_t saltlen, uint8_t* res, size_t max)
|
||||
@@ -670,7 +646,7 @@ nsec3_hash_name(rbtree_type* table, struct regional* region, sldns_buffer* buf,
|
||||
c = (struct nsec3_cached_hash*)rbtree_search(table, &looki);
|
||||
if(c) {
|
||||
*hash = c;
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
/* create a new entry */
|
||||
c = (struct nsec3_cached_hash*)regional_alloc(region, sizeof(*c));
|
||||
@@ -682,10 +658,10 @@ nsec3_hash_name(rbtree_type* table, struct regional* region, sldns_buffer* buf,
|
||||
c->dname_len = dname_len;
|
||||
r = nsec3_calc_hash(region, buf, c);
|
||||
if(r != 1)
|
||||
return r; /* returns -1 or 0 */
|
||||
return r;
|
||||
r = nsec3_calc_b32(region, buf, c);
|
||||
if(r != 1)
|
||||
return r; /* returns 0 */
|
||||
return r;
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#else
|
||||
@@ -728,7 +704,6 @@ nsec3_hash_matches_owner(struct nsec3_filter* flt,
|
||||
struct nsec3_cached_hash* hash, struct ub_packed_rrset_key* s)
|
||||
{
|
||||
uint8_t* nm = s->rk.dname;
|
||||
if(!hash) return 0; /* please clang */
|
||||
/* compare, does hash of name based on params in this NSEC3
|
||||
* match the owner name of this NSEC3?
|
||||
* name must be: <hashlength>base32 . zone name
|
||||
@@ -755,50 +730,34 @@ nsec3_hash_matches_owner(struct nsec3_filter* flt,
|
||||
* @param nmlen: length of name.
|
||||
* @param rrset: nsec3 that matches is returned here.
|
||||
* @param rr: rr number in nsec3 rrset that matches.
|
||||
* @param calculations: current hash calculations.
|
||||
* @return true if a matching NSEC3 is found, false if not.
|
||||
*/
|
||||
static int
|
||||
find_matching_nsec3(struct module_env* env, struct nsec3_filter* flt,
|
||||
struct nsec3_cache_table* ct, uint8_t* nm, size_t nmlen,
|
||||
struct ub_packed_rrset_key** rrset, int* rr,
|
||||
int* calculations)
|
||||
rbtree_type* ct, uint8_t* nm, size_t nmlen,
|
||||
struct ub_packed_rrset_key** rrset, int* rr)
|
||||
{
|
||||
size_t i_rs;
|
||||
int i_rr;
|
||||
struct ub_packed_rrset_key* s;
|
||||
struct nsec3_cached_hash* hash = NULL;
|
||||
int r;
|
||||
int calc_errors = 0;
|
||||
|
||||
/* this loop skips other-zone and unknown NSEC3s, also non-NSEC3 RRs */
|
||||
for(s=filter_first(flt, &i_rs, &i_rr); s;
|
||||
s=filter_next(flt, &i_rs, &i_rr)) {
|
||||
/* check if we are allowed more calculations */
|
||||
if(*calculations >= MAX_NSEC3_CALCULATIONS) {
|
||||
if(calc_errors == *calculations) {
|
||||
*calculations = MAX_NSEC3_ERRORS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* get name hashed for this NSEC3 RR */
|
||||
r = nsec3_hash_name(ct->ct, ct->region, env->scratch_buffer,
|
||||
r = nsec3_hash_name(ct, env->scratch, env->scratch_buffer,
|
||||
s, i_rr, nm, nmlen, &hash);
|
||||
if(r == 0) {
|
||||
log_err("nsec3: malloc failure");
|
||||
break; /* alloc failure */
|
||||
} else if(r < 0) {
|
||||
/* malformed NSEC3 */
|
||||
calc_errors++;
|
||||
(*calculations)++;
|
||||
continue;
|
||||
} else {
|
||||
if(r == 1) (*calculations)++;
|
||||
if(nsec3_hash_matches_owner(flt, hash, s)) {
|
||||
*rrset = s; /* rrset with this name */
|
||||
*rr = i_rr; /* matches hash with these parameters */
|
||||
return 1;
|
||||
}
|
||||
} else if(r != 1)
|
||||
continue; /* malformed NSEC3 */
|
||||
else if(nsec3_hash_matches_owner(flt, hash, s)) {
|
||||
*rrset = s; /* rrset with this name */
|
||||
*rr = i_rr; /* matches hash with these parameters */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
*rrset = NULL;
|
||||
@@ -816,7 +775,6 @@ nsec3_covers(uint8_t* zone, struct nsec3_cached_hash* hash,
|
||||
if(!nsec3_get_nextowner(rrset, rr, &next, &nextlen))
|
||||
return 0; /* malformed RR proves nothing */
|
||||
|
||||
if(!hash) return 0; /* please clang */
|
||||
/* check the owner name is a hashed value . apex
|
||||
* base32 encoded values must have equal length.
|
||||
* hash_value and next hash value must have equal length. */
|
||||
@@ -865,51 +823,35 @@ nsec3_covers(uint8_t* zone, struct nsec3_cached_hash* hash,
|
||||
* @param nmlen: length of name.
|
||||
* @param rrset: covering NSEC3 rrset is returned here.
|
||||
* @param rr: rr of cover is returned here.
|
||||
* @param calculations: current hash calculations.
|
||||
* @return true if a covering NSEC3 is found, false if not.
|
||||
*/
|
||||
static int
|
||||
find_covering_nsec3(struct module_env* env, struct nsec3_filter* flt,
|
||||
struct nsec3_cache_table* ct, uint8_t* nm, size_t nmlen,
|
||||
struct ub_packed_rrset_key** rrset, int* rr,
|
||||
int* calculations)
|
||||
rbtree_type* ct, uint8_t* nm, size_t nmlen,
|
||||
struct ub_packed_rrset_key** rrset, int* rr)
|
||||
{
|
||||
size_t i_rs;
|
||||
int i_rr;
|
||||
struct ub_packed_rrset_key* s;
|
||||
struct nsec3_cached_hash* hash = NULL;
|
||||
int r;
|
||||
int calc_errors = 0;
|
||||
|
||||
/* this loop skips other-zone and unknown NSEC3s, also non-NSEC3 RRs */
|
||||
for(s=filter_first(flt, &i_rs, &i_rr); s;
|
||||
s=filter_next(flt, &i_rs, &i_rr)) {
|
||||
/* check if we are allowed more calculations */
|
||||
if(*calculations >= MAX_NSEC3_CALCULATIONS) {
|
||||
if(calc_errors == *calculations) {
|
||||
*calculations = MAX_NSEC3_ERRORS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* get name hashed for this NSEC3 RR */
|
||||
r = nsec3_hash_name(ct->ct, ct->region, env->scratch_buffer,
|
||||
r = nsec3_hash_name(ct, env->scratch, env->scratch_buffer,
|
||||
s, i_rr, nm, nmlen, &hash);
|
||||
if(r == 0) {
|
||||
log_err("nsec3: malloc failure");
|
||||
break; /* alloc failure */
|
||||
} else if(r < 0) {
|
||||
/* malformed NSEC3 */
|
||||
calc_errors++;
|
||||
(*calculations)++;
|
||||
continue;
|
||||
} else {
|
||||
if(r == 1) (*calculations)++;
|
||||
if(nsec3_covers(flt->zone, hash, s, i_rr,
|
||||
env->scratch_buffer)) {
|
||||
*rrset = s; /* rrset with this name */
|
||||
*rr = i_rr; /* covers hash with these parameters */
|
||||
return 1;
|
||||
}
|
||||
} else if(r != 1)
|
||||
continue; /* malformed NSEC3 */
|
||||
else if(nsec3_covers(flt->zone, hash, s, i_rr,
|
||||
env->scratch_buffer)) {
|
||||
*rrset = s; /* rrset with this name */
|
||||
*rr = i_rr; /* covers hash with these parameters */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
*rrset = NULL;
|
||||
@@ -927,13 +869,11 @@ find_covering_nsec3(struct module_env* env, struct nsec3_filter* flt,
|
||||
* @param ct: cached hashes table.
|
||||
* @param qinfo: query that is verified for.
|
||||
* @param ce: closest encloser information is returned in here.
|
||||
* @param calculations: current hash calculations.
|
||||
* @return true if a closest encloser candidate is found, false if not.
|
||||
*/
|
||||
static int
|
||||
nsec3_find_closest_encloser(struct module_env* env, struct nsec3_filter* flt,
|
||||
struct nsec3_cache_table* ct, struct query_info* qinfo,
|
||||
struct ce_response* ce, int* calculations)
|
||||
nsec3_find_closest_encloser(struct module_env* env, struct nsec3_filter* flt,
|
||||
rbtree_type* ct, struct query_info* qinfo, struct ce_response* ce)
|
||||
{
|
||||
uint8_t* nm = qinfo->qname;
|
||||
size_t nmlen = qinfo->qname_len;
|
||||
@@ -948,12 +888,8 @@ nsec3_find_closest_encloser(struct module_env* env, struct nsec3_filter* flt,
|
||||
* may be the case. */
|
||||
|
||||
while(dname_subdomain_c(nm, flt->zone)) {
|
||||
if(*calculations >= MAX_NSEC3_CALCULATIONS ||
|
||||
*calculations == MAX_NSEC3_ERRORS) {
|
||||
return 0;
|
||||
}
|
||||
if(find_matching_nsec3(env, flt, ct, nm, nmlen,
|
||||
&ce->ce_rrset, &ce->ce_rr, calculations)) {
|
||||
&ce->ce_rrset, &ce->ce_rr)) {
|
||||
ce->ce = nm;
|
||||
ce->ce_len = nmlen;
|
||||
return 1;
|
||||
@@ -997,38 +933,22 @@ next_closer(uint8_t* qname, size_t qnamelen, uint8_t* ce,
|
||||
* If set true, and the return value is true, then you can be
|
||||
* certain that the ce.nc_rrset and ce.nc_rr are set properly.
|
||||
* @param ce: closest encloser information is returned in here.
|
||||
* @param calculations: pointer to the current NSEC3 hash calculations.
|
||||
* @return bogus if no closest encloser could be proven.
|
||||
* secure if a closest encloser could be proven, ce is set.
|
||||
* insecure if the closest-encloser candidate turns out to prove
|
||||
* that an insecure delegation exists above the qname.
|
||||
* unchecked if no more hash calculations are allowed at this point.
|
||||
*/
|
||||
static enum sec_status
|
||||
nsec3_prove_closest_encloser(struct module_env* env, struct nsec3_filter* flt,
|
||||
struct nsec3_cache_table* ct, struct query_info* qinfo,
|
||||
int prove_does_not_exist, struct ce_response* ce, int* calculations)
|
||||
nsec3_prove_closest_encloser(struct module_env* env, struct nsec3_filter* flt,
|
||||
rbtree_type* ct, struct query_info* qinfo, int prove_does_not_exist,
|
||||
struct ce_response* ce)
|
||||
{
|
||||
uint8_t* nc;
|
||||
size_t nc_len;
|
||||
/* robust: clean out ce, in case it gets abused later */
|
||||
memset(ce, 0, sizeof(*ce));
|
||||
|
||||
if(!nsec3_find_closest_encloser(env, flt, ct, qinfo, ce, calculations)) {
|
||||
if(*calculations == MAX_NSEC3_ERRORS) {
|
||||
verbose(VERB_ALGO, "nsec3 proveClosestEncloser: could "
|
||||
"not find a candidate for the closest "
|
||||
"encloser; all attempted hash calculations "
|
||||
"were erroneous; bogus");
|
||||
return sec_status_bogus;
|
||||
} else if(*calculations >= MAX_NSEC3_CALCULATIONS) {
|
||||
verbose(VERB_ALGO, "nsec3 proveClosestEncloser: could "
|
||||
"not find a candidate for the closest "
|
||||
"encloser; reached MAX_NSEC3_CALCULATIONS "
|
||||
"(%d); unchecked still",
|
||||
MAX_NSEC3_CALCULATIONS);
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
if(!nsec3_find_closest_encloser(env, flt, ct, qinfo, ce)) {
|
||||
verbose(VERB_ALGO, "nsec3 proveClosestEncloser: could "
|
||||
"not find a candidate for the closest encloser.");
|
||||
return sec_status_bogus;
|
||||
@@ -1069,23 +989,9 @@ nsec3_prove_closest_encloser(struct module_env* env, struct nsec3_filter* flt,
|
||||
/* Otherwise, we need to show that the next closer name is covered. */
|
||||
next_closer(qinfo->qname, qinfo->qname_len, ce->ce, &nc, &nc_len);
|
||||
if(!find_covering_nsec3(env, flt, ct, nc, nc_len,
|
||||
&ce->nc_rrset, &ce->nc_rr, calculations)) {
|
||||
if(*calculations == MAX_NSEC3_ERRORS) {
|
||||
verbose(VERB_ALGO, "nsec3: Could not find proof that the "
|
||||
"candidate encloser was the closest encloser; "
|
||||
"all attempted hash calculations were "
|
||||
"erroneous; bogus");
|
||||
return sec_status_bogus;
|
||||
} else if(*calculations >= MAX_NSEC3_CALCULATIONS) {
|
||||
verbose(VERB_ALGO, "nsec3: Could not find proof that the "
|
||||
"candidate encloser was the closest encloser; "
|
||||
"reached MAX_NSEC3_CALCULATIONS (%d); "
|
||||
"unchecked still",
|
||||
MAX_NSEC3_CALCULATIONS);
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
&ce->nc_rrset, &ce->nc_rr)) {
|
||||
verbose(VERB_ALGO, "nsec3: Could not find proof that the "
|
||||
"candidate encloser was the closest encloser");
|
||||
"candidate encloser was the closest encloser");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
return sec_status_secure;
|
||||
@@ -1113,8 +1019,8 @@ nsec3_ce_wildcard(struct regional* region, uint8_t* ce, size_t celen,
|
||||
|
||||
/** Do the name error proof */
|
||||
static enum sec_status
|
||||
nsec3_do_prove_nameerror(struct module_env* env, struct nsec3_filter* flt,
|
||||
struct nsec3_cache_table* ct, struct query_info* qinfo, int* calc)
|
||||
nsec3_do_prove_nameerror(struct module_env* env, struct nsec3_filter* flt,
|
||||
rbtree_type* ct, struct query_info* qinfo)
|
||||
{
|
||||
struct ce_response ce;
|
||||
uint8_t* wc;
|
||||
@@ -1126,15 +1032,11 @@ nsec3_do_prove_nameerror(struct module_env* env, struct nsec3_filter* flt,
|
||||
/* First locate and prove the closest encloser to qname. We will
|
||||
* use the variant that fails if the closest encloser turns out
|
||||
* to be qname. */
|
||||
sec = nsec3_prove_closest_encloser(env, flt, ct, qinfo, 1, &ce, calc);
|
||||
sec = nsec3_prove_closest_encloser(env, flt, ct, qinfo, 1, &ce);
|
||||
if(sec != sec_status_secure) {
|
||||
if(sec == sec_status_bogus)
|
||||
verbose(VERB_ALGO, "nsec3 nameerror proof: failed "
|
||||
"to prove a closest encloser");
|
||||
else if(sec == sec_status_unchecked)
|
||||
verbose(VERB_ALGO, "nsec3 nameerror proof: will "
|
||||
"continue proving closest encloser after "
|
||||
"suspend");
|
||||
else verbose(VERB_ALGO, "nsec3 nameerror proof: closest "
|
||||
"nsec3 is an insecure delegation");
|
||||
return sec;
|
||||
@@ -1144,27 +1046,9 @@ nsec3_do_prove_nameerror(struct module_env* env, struct nsec3_filter* flt,
|
||||
/* At this point, we know that qname does not exist. Now we need
|
||||
* to prove that the wildcard does not exist. */
|
||||
log_assert(ce.ce);
|
||||
wc = nsec3_ce_wildcard(ct->region, ce.ce, ce.ce_len, &wclen);
|
||||
if(!wc) {
|
||||
verbose(VERB_ALGO, "nsec3 nameerror proof: could not prove "
|
||||
"that the applicable wildcard did not exist.");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
if(!find_covering_nsec3(env, flt, ct, wc, wclen, &wc_rrset, &wc_rr, calc)) {
|
||||
if(*calc == MAX_NSEC3_ERRORS) {
|
||||
verbose(VERB_ALGO, "nsec3 nameerror proof: could not prove "
|
||||
"that the applicable wildcard did not exist; "
|
||||
"all attempted hash calculations were "
|
||||
"erroneous; bogus");
|
||||
return sec_status_bogus;
|
||||
} else if(*calc >= MAX_NSEC3_CALCULATIONS) {
|
||||
verbose(VERB_ALGO, "nsec3 nameerror proof: could not prove "
|
||||
"that the applicable wildcard did not exist; "
|
||||
"reached MAX_NSEC3_CALCULATIONS (%d); "
|
||||
"unchecked still",
|
||||
MAX_NSEC3_CALCULATIONS);
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
wc = nsec3_ce_wildcard(env->scratch, ce.ce, ce.ce_len, &wclen);
|
||||
if(!wc || !find_covering_nsec3(env, flt, ct, wc, wclen,
|
||||
&wc_rrset, &wc_rr)) {
|
||||
verbose(VERB_ALGO, "nsec3 nameerror proof: could not prove "
|
||||
"that the applicable wildcard did not exist.");
|
||||
return sec_status_bogus;
|
||||
@@ -1180,13 +1064,14 @@ nsec3_do_prove_nameerror(struct module_env* env, struct nsec3_filter* flt,
|
||||
enum sec_status
|
||||
nsec3_prove_nameerror(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,
|
||||
struct nsec3_cache_table* ct, int* calc)
|
||||
struct query_info* qinfo, struct key_entry_key* kkey)
|
||||
{
|
||||
rbtree_type ct;
|
||||
struct nsec3_filter flt;
|
||||
|
||||
if(!list || num == 0 || !kkey || !key_entry_isgood(kkey))
|
||||
return sec_status_bogus; /* no valid NSEC3s, bogus */
|
||||
rbtree_init(&ct, &nsec3_hash_cmp); /* init names-to-hash cache */
|
||||
filter_init(&flt, list, num, qinfo); /* init RR iterator */
|
||||
if(!flt.zone)
|
||||
return sec_status_bogus; /* no RRs */
|
||||
@@ -1194,7 +1079,7 @@ nsec3_prove_nameerror(struct module_env* env, struct val_env* ve,
|
||||
return sec_status_insecure; /* iteration count too high */
|
||||
log_nametypeclass(VERB_ALGO, "start nsec3 nameerror proof, zone",
|
||||
flt.zone, 0, 0);
|
||||
return nsec3_do_prove_nameerror(env, &flt, ct, qinfo, calc);
|
||||
return nsec3_do_prove_nameerror(env, &flt, &ct, qinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1204,9 +1089,8 @@ nsec3_prove_nameerror(struct module_env* env, struct val_env* ve,
|
||||
|
||||
/** Do the nodata proof */
|
||||
static enum sec_status
|
||||
nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt,
|
||||
struct nsec3_cache_table* ct, struct query_info* qinfo,
|
||||
int* calc)
|
||||
nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt,
|
||||
rbtree_type* ct, struct query_info* qinfo)
|
||||
{
|
||||
struct ce_response ce;
|
||||
uint8_t* wc;
|
||||
@@ -1216,7 +1100,7 @@ nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt,
|
||||
enum sec_status sec;
|
||||
|
||||
if(find_matching_nsec3(env, flt, ct, qinfo->qname, qinfo->qname_len,
|
||||
&rrset, &rr, calc)) {
|
||||
&rrset, &rr)) {
|
||||
/* cases 1 and 2 */
|
||||
if(nsec3_has_type(rrset, rr, qinfo->qtype)) {
|
||||
verbose(VERB_ALGO, "proveNodata: Matching NSEC3 "
|
||||
@@ -1260,23 +1144,11 @@ nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt,
|
||||
}
|
||||
return sec_status_secure;
|
||||
}
|
||||
if(*calc == MAX_NSEC3_ERRORS) {
|
||||
verbose(VERB_ALGO, "proveNodata: all attempted hash "
|
||||
"calculations were erroneous while finding a matching "
|
||||
"NSEC3, bogus");
|
||||
return sec_status_bogus;
|
||||
} else if(*calc >= MAX_NSEC3_CALCULATIONS) {
|
||||
verbose(VERB_ALGO, "proveNodata: reached "
|
||||
"MAX_NSEC3_CALCULATIONS (%d) while finding a "
|
||||
"matching NSEC3; unchecked still",
|
||||
MAX_NSEC3_CALCULATIONS);
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
|
||||
/* For cases 3 - 5, we need the proven closest encloser, and it
|
||||
* can't match qname. Although, at this point, we know that it
|
||||
* won't since we just checked that. */
|
||||
sec = nsec3_prove_closest_encloser(env, flt, ct, qinfo, 1, &ce, calc);
|
||||
sec = nsec3_prove_closest_encloser(env, flt, ct, qinfo, 1, &ce);
|
||||
if(sec == sec_status_bogus) {
|
||||
verbose(VERB_ALGO, "proveNodata: did not match qname, "
|
||||
"nor found a proven closest encloser.");
|
||||
@@ -1285,17 +1157,14 @@ nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt,
|
||||
verbose(VERB_ALGO, "proveNodata: closest nsec3 is insecure "
|
||||
"delegation.");
|
||||
return sec_status_insecure;
|
||||
} else if(sec==sec_status_unchecked) {
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
|
||||
/* Case 3: removed */
|
||||
|
||||
/* Case 4: */
|
||||
log_assert(ce.ce);
|
||||
wc = nsec3_ce_wildcard(ct->region, ce.ce, ce.ce_len, &wclen);
|
||||
if(wc && find_matching_nsec3(env, flt, ct, wc, wclen, &rrset, &rr,
|
||||
calc)) {
|
||||
wc = nsec3_ce_wildcard(env->scratch, ce.ce, ce.ce_len, &wclen);
|
||||
if(wc && find_matching_nsec3(env, flt, ct, wc, wclen, &rrset, &rr)) {
|
||||
/* found wildcard */
|
||||
if(nsec3_has_type(rrset, rr, qinfo->qtype)) {
|
||||
verbose(VERB_ALGO, "nsec3 nodata proof: matching "
|
||||
@@ -1326,18 +1195,6 @@ nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt,
|
||||
}
|
||||
return sec_status_secure;
|
||||
}
|
||||
if(*calc == MAX_NSEC3_ERRORS) {
|
||||
verbose(VERB_ALGO, "nsec3 nodata proof: all attempted hash "
|
||||
"calculations were erroneous while matching "
|
||||
"wildcard, bogus");
|
||||
return sec_status_bogus;
|
||||
} else if(*calc >= MAX_NSEC3_CALCULATIONS) {
|
||||
verbose(VERB_ALGO, "nsec3 nodata proof: reached "
|
||||
"MAX_NSEC3_CALCULATIONS (%d) while matching "
|
||||
"wildcard, unchecked still",
|
||||
MAX_NSEC3_CALCULATIONS);
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
|
||||
/* Case 5: */
|
||||
/* Due to forwarders, cnames, and other collating effects, we
|
||||
@@ -1366,27 +1223,28 @@ nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt,
|
||||
enum sec_status
|
||||
nsec3_prove_nodata(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,
|
||||
struct nsec3_cache_table* ct, int* calc)
|
||||
struct query_info* qinfo, struct key_entry_key* kkey)
|
||||
{
|
||||
rbtree_type ct;
|
||||
struct nsec3_filter flt;
|
||||
|
||||
if(!list || num == 0 || !kkey || !key_entry_isgood(kkey))
|
||||
return sec_status_bogus; /* no valid NSEC3s, bogus */
|
||||
rbtree_init(&ct, &nsec3_hash_cmp); /* init names-to-hash cache */
|
||||
filter_init(&flt, list, num, qinfo); /* init RR iterator */
|
||||
if(!flt.zone)
|
||||
return sec_status_bogus; /* no RRs */
|
||||
if(nsec3_iteration_count_high(ve, &flt, kkey))
|
||||
return sec_status_insecure; /* iteration count too high */
|
||||
return nsec3_do_prove_nodata(env, &flt, ct, qinfo, calc);
|
||||
return nsec3_do_prove_nodata(env, &flt, &ct, qinfo);
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
nsec3_prove_wildcard(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, uint8_t* wc,
|
||||
struct nsec3_cache_table* ct, int* calc)
|
||||
struct query_info* qinfo, struct key_entry_key* kkey, uint8_t* wc)
|
||||
{
|
||||
rbtree_type ct;
|
||||
struct nsec3_filter flt;
|
||||
struct ce_response ce;
|
||||
uint8_t* nc;
|
||||
@@ -1396,6 +1254,7 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
|
||||
|
||||
if(!list || num == 0 || !kkey || !key_entry_isgood(kkey))
|
||||
return sec_status_bogus; /* no valid NSEC3s, bogus */
|
||||
rbtree_init(&ct, &nsec3_hash_cmp); /* init names-to-hash cache */
|
||||
filter_init(&flt, list, num, qinfo); /* init RR iterator */
|
||||
if(!flt.zone)
|
||||
return sec_status_bogus; /* no RRs */
|
||||
@@ -1413,22 +1272,8 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
|
||||
/* Now we still need to prove that the original data did not exist.
|
||||
* Otherwise, we need to show that the next closer name is covered. */
|
||||
next_closer(qinfo->qname, qinfo->qname_len, ce.ce, &nc, &nc_len);
|
||||
if(!find_covering_nsec3(env, &flt, ct, nc, nc_len,
|
||||
&ce.nc_rrset, &ce.nc_rr, calc)) {
|
||||
if(*calc == MAX_NSEC3_ERRORS) {
|
||||
verbose(VERB_ALGO, "proveWildcard: did not find a "
|
||||
"covering NSEC3 that covered the next closer "
|
||||
"name; all attempted hash calculations were "
|
||||
"erroneous; bogus");
|
||||
return sec_status_bogus;
|
||||
} else if(*calc >= MAX_NSEC3_CALCULATIONS) {
|
||||
verbose(VERB_ALGO, "proveWildcard: did not find a "
|
||||
"covering NSEC3 that covered the next closer "
|
||||
"name; reached MAX_NSEC3_CALCULATIONS "
|
||||
"(%d); unchecked still",
|
||||
MAX_NSEC3_CALCULATIONS);
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
if(!find_covering_nsec3(env, &flt, &ct, nc, nc_len,
|
||||
&ce.nc_rrset, &ce.nc_rr)) {
|
||||
verbose(VERB_ALGO, "proveWildcard: did not find a covering "
|
||||
"NSEC3 that covered the next closer name.");
|
||||
return sec_status_bogus;
|
||||
@@ -1449,7 +1294,6 @@ list_is_secure(struct module_env* env, struct val_env* ve,
|
||||
{
|
||||
struct packed_rrset_data* d;
|
||||
size_t i;
|
||||
int verified = 0;
|
||||
for(i=0; i<num; i++) {
|
||||
d = (struct packed_rrset_data*)list[i]->entry.data;
|
||||
if(list[i]->rk.type != htons(LDNS_RR_TYPE_NSEC3))
|
||||
@@ -1460,8 +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, reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
|
||||
&verified);
|
||||
reason, reason_bogus, LDNS_SECTION_AUTHORITY, qstate);
|
||||
if(d->security != sec_status_secure) {
|
||||
verbose(VERB_ALGO, "NSEC3 did not verify");
|
||||
return 0;
|
||||
@@ -1475,16 +1318,13 @@ 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,
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
|
||||
struct nsec3_cache_table* ct)
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
rbtree_type ct;
|
||||
struct nsec3_filter flt;
|
||||
struct ce_response ce;
|
||||
struct ub_packed_rrset_key* rrset;
|
||||
int rr;
|
||||
int calc = 0;
|
||||
enum sec_status sec;
|
||||
|
||||
log_assert(qinfo->qtype == LDNS_RR_TYPE_DS);
|
||||
|
||||
if(!list || num == 0 || !kkey || !key_entry_isgood(kkey)) {
|
||||
@@ -1495,6 +1335,7 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
*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) {
|
||||
*reason = "no NSEC3 records";
|
||||
@@ -1505,8 +1346,8 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
|
||||
/* Look for a matching NSEC3 to qname -- this is the normal
|
||||
* NODATA case. */
|
||||
if(find_matching_nsec3(env, &flt, ct, qinfo->qname, qinfo->qname_len,
|
||||
&rrset, &rr, &calc)) {
|
||||
if(find_matching_nsec3(env, &flt, &ct, qinfo->qname, qinfo->qname_len,
|
||||
&rrset, &rr)) {
|
||||
/* If the matching NSEC3 has the SOA bit set, it is from
|
||||
* the wrong zone (the child instead of the parent). If
|
||||
* it has the DS bit set, then we were lied to. */
|
||||
@@ -1529,24 +1370,10 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
/* Otherwise, this proves no DS. */
|
||||
return sec_status_secure;
|
||||
}
|
||||
if(calc == MAX_NSEC3_ERRORS) {
|
||||
verbose(VERB_ALGO, "nsec3 provenods: all attempted hash "
|
||||
"calculations were erroneous while finding a matching "
|
||||
"NSEC3, bogus");
|
||||
return sec_status_bogus;
|
||||
} else if(calc >= MAX_NSEC3_CALCULATIONS) {
|
||||
verbose(VERB_ALGO, "nsec3 provenods: reached "
|
||||
"MAX_NSEC3_CALCULATIONS (%d) while finding a "
|
||||
"matching NSEC3, unchecked still",
|
||||
MAX_NSEC3_CALCULATIONS);
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
|
||||
/* Otherwise, we are probably in the opt-out case. */
|
||||
sec = nsec3_prove_closest_encloser(env, &flt, ct, qinfo, 1, &ce, &calc);
|
||||
if(sec == sec_status_unchecked) {
|
||||
return sec_status_unchecked;
|
||||
} else if(sec != sec_status_secure) {
|
||||
if(nsec3_prove_closest_encloser(env, &flt, &ct, qinfo, 1, &ce)
|
||||
!= sec_status_secure) {
|
||||
/* an insecure delegation *above* the qname does not prove
|
||||
* anything about this qname exactly, and bogus is bogus */
|
||||
verbose(VERB_ALGO, "nsec3 provenods: did not match qname, "
|
||||
@@ -1580,16 +1407,17 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
|
||||
enum sec_status
|
||||
nsec3_prove_nxornodata(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, int* nodata,
|
||||
struct nsec3_cache_table* ct, int* calc)
|
||||
struct ub_packed_rrset_key** list, size_t num,
|
||||
struct query_info* qinfo, struct key_entry_key* kkey, int* nodata)
|
||||
{
|
||||
enum sec_status sec, secnx;
|
||||
rbtree_type ct;
|
||||
struct nsec3_filter flt;
|
||||
*nodata = 0;
|
||||
|
||||
if(!list || num == 0 || !kkey || !key_entry_isgood(kkey))
|
||||
return sec_status_bogus; /* no valid NSEC3s, bogus */
|
||||
rbtree_init(&ct, &nsec3_hash_cmp); /* init names-to-hash cache */
|
||||
filter_init(&flt, list, num, qinfo); /* init RR iterator */
|
||||
if(!flt.zone)
|
||||
return sec_status_bogus; /* no RRs */
|
||||
@@ -1599,20 +1427,16 @@ nsec3_prove_nxornodata(struct module_env* env, struct val_env* ve,
|
||||
/* try nxdomain and nodata after another, while keeping the
|
||||
* hash cache intact */
|
||||
|
||||
secnx = nsec3_do_prove_nameerror(env, &flt, ct, qinfo, calc);
|
||||
secnx = nsec3_do_prove_nameerror(env, &flt, &ct, qinfo);
|
||||
if(secnx==sec_status_secure)
|
||||
return sec_status_secure;
|
||||
else if(secnx == sec_status_unchecked)
|
||||
return sec_status_unchecked;
|
||||
sec = nsec3_do_prove_nodata(env, &flt, ct, qinfo, calc);
|
||||
sec = nsec3_do_prove_nodata(env, &flt, &ct, qinfo);
|
||||
if(sec==sec_status_secure) {
|
||||
*nodata = 1;
|
||||
} else if(sec == sec_status_insecure) {
|
||||
*nodata = 1;
|
||||
} else if(secnx == sec_status_insecure) {
|
||||
sec = sec_status_insecure;
|
||||
} else if(sec == sec_status_unchecked) {
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
return sec;
|
||||
}
|
||||
|
||||
+12
-48
@@ -98,15 +98,6 @@ struct sldns_buffer;
|
||||
/** The SHA1 hash algorithm for NSEC3 */
|
||||
#define NSEC3_HASH_SHA1 0x01
|
||||
|
||||
/**
|
||||
* Cache table for NSEC3 hashes.
|
||||
* It keeps a *pointer* to the region its items are allocated.
|
||||
*/
|
||||
struct nsec3_cache_table {
|
||||
rbtree_type* ct;
|
||||
struct regional* region;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine if the set of NSEC3 records provided with a response prove NAME
|
||||
* ERROR. This means that the NSEC3s prove a) the closest encloser exists,
|
||||
@@ -119,18 +110,14 @@ struct nsec3_cache_table {
|
||||
* @param num: number of RRsets in the array to examine.
|
||||
* @param qinfo: query that is verified for.
|
||||
* @param kkey: key entry that signed the NSEC3s.
|
||||
* @param ct: cached hashes table.
|
||||
* @param calc: current hash calculations.
|
||||
* @return:
|
||||
* sec_status SECURE of the Name Error is proven by the NSEC3 RRs,
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored,
|
||||
* UNCHECKED if no more hash calculations are allowed at this point.
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored.
|
||||
*/
|
||||
enum sec_status
|
||||
nsec3_prove_nameerror(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,
|
||||
struct nsec3_cache_table* ct, int* calc);
|
||||
struct query_info* qinfo, struct key_entry_key* kkey);
|
||||
|
||||
/**
|
||||
* Determine if the NSEC3s provided in a response prove the NOERROR/NODATA
|
||||
@@ -157,18 +144,15 @@ nsec3_prove_nameerror(struct module_env* env, struct val_env* ve,
|
||||
* @param num: number of RRsets in the array to examine.
|
||||
* @param qinfo: query that is verified for.
|
||||
* @param kkey: key entry that signed the NSEC3s.
|
||||
* @param ct: cached hashes table.
|
||||
* @param calc: current hash calculations.
|
||||
* @return:
|
||||
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored,
|
||||
* UNCHECKED if no more hash calculations are allowed at this point.
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored.
|
||||
*/
|
||||
enum sec_status
|
||||
nsec3_prove_nodata(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,
|
||||
struct nsec3_cache_table* ct, int* calc);
|
||||
struct query_info* qinfo, struct key_entry_key* kkey);
|
||||
|
||||
|
||||
/**
|
||||
* Prove that a positive wildcard match was appropriate (no direct match
|
||||
@@ -182,18 +166,14 @@ nsec3_prove_nodata(struct module_env* env, struct val_env* ve,
|
||||
* @param kkey: key entry that signed the NSEC3s.
|
||||
* @param wc: The purported wildcard that matched. This is the wildcard name
|
||||
* as *.wildcard.name., with the *. label already removed.
|
||||
* @param ct: cached hashes table.
|
||||
* @param calc: current hash calculations.
|
||||
* @return:
|
||||
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored,
|
||||
* UNCHECKED if no more hash calculations are allowed at this point.
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored.
|
||||
*/
|
||||
enum sec_status
|
||||
nsec3_prove_wildcard(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, uint8_t* wc,
|
||||
struct nsec3_cache_table* ct, int* calc);
|
||||
struct query_info* qinfo, struct key_entry_key* kkey, uint8_t* wc);
|
||||
|
||||
/**
|
||||
* Prove that a DS response either had no DS, or wasn't a delegation point.
|
||||
@@ -209,20 +189,17 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
|
||||
* @param reason: string for bogus result.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @param ct: cached hashes table.
|
||||
* @return:
|
||||
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored.
|
||||
* or if there was no DS in an insecure (i.e., opt-in) way,
|
||||
* INDETERMINATE if it was clear that this wasn't a delegation point,
|
||||
* UNCHECKED if no more hash calculations are allowed at this point.
|
||||
* INDETERMINATE if it was clear that this wasn't a delegation point.
|
||||
*/
|
||||
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,
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
|
||||
struct nsec3_cache_table* ct);
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Prove NXDOMAIN or NODATA.
|
||||
@@ -235,18 +212,14 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
* @param kkey: key entry that signed the NSEC3s.
|
||||
* @param nodata: if return value is secure, this indicates if nodata or
|
||||
* nxdomain was proven.
|
||||
* @param ct: cached hashes table.
|
||||
* @param calc: current hash calculations.
|
||||
* @return:
|
||||
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored,
|
||||
* UNCHECKED if no more hash calculations are allowed at this point.
|
||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored.
|
||||
*/
|
||||
enum sec_status
|
||||
nsec3_prove_nxornodata(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, int* nodata,
|
||||
struct nsec3_cache_table* ct, int* calc);
|
||||
struct query_info* qinfo, struct key_entry_key* kkey, int* nodata);
|
||||
|
||||
/**
|
||||
* The NSEC3 hash result storage.
|
||||
@@ -283,14 +256,6 @@ struct nsec3_cached_hash {
|
||||
*/
|
||||
int nsec3_hash_cmp(const void* c1, const void* c2);
|
||||
|
||||
/**
|
||||
* Initialise the NSEC3 cache table.
|
||||
* @param ct: the nsec3 cache table.
|
||||
* @param region: the region where allocations for the table will happen.
|
||||
* @return true on success, false on malloc error.
|
||||
*/
|
||||
int nsec3_cache_table_init(struct nsec3_cache_table* ct, struct regional* region);
|
||||
|
||||
/**
|
||||
* Obtain the hash of an owner name.
|
||||
* Used internally by the nsec3 proof functions in this file.
|
||||
@@ -307,8 +272,7 @@ int nsec3_cache_table_init(struct nsec3_cache_table* ct, struct regional* region
|
||||
* @param dname_len: the length of the name.
|
||||
* @param hash: the hash node is returned on success.
|
||||
* @return:
|
||||
* 2 on success, hash from cache is returned.
|
||||
* 1 on success, newly computed hash is returned.
|
||||
* 1 on success, either from cache or newly hashed hash is returned.
|
||||
* 0 on a malloc failure.
|
||||
* -1 if the NSEC3 rr was badly formatted (i.e. formerr).
|
||||
*/
|
||||
|
||||
@@ -79,9 +79,6 @@
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
|
||||
/** Maximum number of RRSIG validations for an RRset. */
|
||||
#define MAX_VALIDATE_RRSIGS 8
|
||||
|
||||
/** return number of rrs in an rrset */
|
||||
static size_t
|
||||
rrset_get_count(struct ub_packed_rrset_key* rrset)
|
||||
@@ -545,8 +542,6 @@ int algo_needs_missing(struct algo_needs* n)
|
||||
* @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.
|
||||
* @param numverified: incremented when the number of RRSIG validations
|
||||
* increases.
|
||||
* @return secure if any key signs *this* signature. bogus if no key signs it,
|
||||
* unchecked on error, or indeterminate if all keys are not supported by
|
||||
* the crypto library (openssl3+ only).
|
||||
@@ -557,8 +552,7 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
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,
|
||||
int* numverified)
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
/* find matching keys and check them */
|
||||
enum sec_status sec = sec_status_bogus;
|
||||
@@ -582,7 +576,6 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
tag != dnskey_calc_keytag(dnskey, i))
|
||||
continue;
|
||||
numchecked ++;
|
||||
(*numverified)++;
|
||||
|
||||
/* see if key verifies */
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
@@ -593,13 +586,6 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
return sec;
|
||||
else if(sec == sec_status_indeterminate)
|
||||
numindeterminate ++;
|
||||
if(*numverified > MAX_VALIDATE_RRSIGS) {
|
||||
*reason = "too many RRSIG validations";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
verbose(VERB_ALGO, "verify sig: too many RRSIG validations");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
}
|
||||
if(numchecked == 0) {
|
||||
*reason = "signatures from unknown keys";
|
||||
@@ -623,7 +609,7 @@ 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_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate, int* verified)
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num;
|
||||
@@ -631,7 +617,6 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
/* make sure that for all DNSKEY algorithms there are valid sigs */
|
||||
struct algo_needs needs;
|
||||
int alg;
|
||||
*verified = 0;
|
||||
|
||||
num = rrset_get_sigcount(rrset);
|
||||
if(num == 0) {
|
||||
@@ -656,7 +641,7 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
for(i=0; i<num; i++) {
|
||||
sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset,
|
||||
dnskey, i, &sortree, reason, reason_bogus,
|
||||
section, qstate, verified);
|
||||
section, qstate);
|
||||
/* see which algorithm has been fixed up */
|
||||
if(sec == sec_status_secure) {
|
||||
if(!sigalg)
|
||||
@@ -668,13 +653,6 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
algo_needs_set_bogus(&needs,
|
||||
(uint8_t)rrset_get_sig_algo(rrset, i));
|
||||
}
|
||||
if(*verified > MAX_VALIDATE_RRSIGS) {
|
||||
verbose(VERB_QUERY, "rrset failed to verify, too many RRSIG validations");
|
||||
*reason = "too many RRSIG validations";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
}
|
||||
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
|
||||
verbose(VERB_ALGO, "rrset failed to verify: "
|
||||
@@ -713,7 +691,6 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
int buf_canon = 0;
|
||||
uint16_t tag = dnskey_calc_keytag(dnskey, dnskey_idx);
|
||||
int algo = dnskey_get_algo(dnskey, dnskey_idx);
|
||||
int numverified = 0;
|
||||
|
||||
num = rrset_get_sigcount(rrset);
|
||||
if(num == 0) {
|
||||
@@ -737,16 +714,8 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
numchecked ++;
|
||||
numverified ++;
|
||||
if(sec == sec_status_indeterminate)
|
||||
numindeterminate ++;
|
||||
if(numverified > MAX_VALIDATE_RRSIGS) {
|
||||
verbose(VERB_QUERY, "rrset failed to verify, too many RRSIG validations");
|
||||
*reason = "too many RRSIG validations";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
}
|
||||
verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus");
|
||||
if(!numchecked) {
|
||||
|
||||
@@ -260,7 +260,6 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
|
||||
* @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.
|
||||
* @param verified: if not NULL the number of RRSIG validations is returned.
|
||||
* @return SECURE if one key in the set verifies one rrsig.
|
||||
* UNCHECKED on allocation errors, unsupported algorithms, malformed data,
|
||||
* and BOGUS on verification failures (no keys match any signatures).
|
||||
@@ -269,7 +268,7 @@ 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_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate, int* verified);
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+4
-18
@@ -58,10 +58,6 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/parseutil.h"
|
||||
|
||||
/** Maximum allowed digest match failures per DS, for DNSKEYs with the same
|
||||
* properties */
|
||||
#define MAX_DS_MATCH_FAILURES 4
|
||||
|
||||
enum val_classification
|
||||
val_classify_response(uint16_t query_flags, struct query_info* origqinf,
|
||||
struct query_info* qinf, struct reply_info* rep, size_t skip)
|
||||
@@ -340,8 +336,7 @@ 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_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate,
|
||||
int *verified)
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
|
||||
@@ -351,7 +346,6 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
log_nametypeclass(VERB_ALGO, "verify rrset cached",
|
||||
rrset->rk.dname, ntohs(rrset->rk.type),
|
||||
ntohs(rrset->rk.rrset_class));
|
||||
*verified = 0;
|
||||
return d->security;
|
||||
}
|
||||
/* check in the cache if verification has already been done */
|
||||
@@ -360,13 +354,12 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
log_nametypeclass(VERB_ALGO, "verify rrset from cache",
|
||||
rrset->rk.dname, ntohs(rrset->rk.type),
|
||||
ntohs(rrset->rk.rrset_class));
|
||||
*verified = 0;
|
||||
return d->security;
|
||||
}
|
||||
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,
|
||||
reason_bogus, section, qstate, verified);
|
||||
reason_bogus, section, qstate);
|
||||
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
|
||||
regional_free_all(env->scratch);
|
||||
|
||||
@@ -400,8 +393,7 @@ 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_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate,
|
||||
int* verified)
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
/* temporary dnskey rrset-key */
|
||||
struct ub_packed_rrset_key dnskey;
|
||||
@@ -415,7 +407,7 @@ 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,
|
||||
reason_bogus, section, qstate, verified);
|
||||
reason_bogus, section, qstate);
|
||||
return sec;
|
||||
}
|
||||
|
||||
@@ -447,12 +439,6 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||
if(!ds_digest_match_dnskey(env, dnskey_rrset, i, ds_rrset,
|
||||
ds_idx)) {
|
||||
verbose(VERB_ALGO, "DS match attempt failed");
|
||||
if(numchecked > numhashok + MAX_DS_MATCH_FAILURES) {
|
||||
verbose(VERB_ALGO, "DS match attempt reached "
|
||||
"MAX_DS_MATCH_FAILURES (%d); bogus",
|
||||
MAX_DS_MATCH_FAILURES);
|
||||
return sec_status_bogus;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
numhashok++;
|
||||
|
||||
@@ -124,14 +124,12 @@ void val_find_signer(enum val_classification subtype,
|
||||
* @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.
|
||||
* @param verified: if not NULL, the number of RRSIG validations is returned.
|
||||
* @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_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate,
|
||||
int* verified);
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but
|
||||
|
||||
+75
-424
@@ -64,15 +64,10 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
/** Max number of RRSIGs to validate at once, suspend query for later. */
|
||||
#define MAX_VALIDATE_AT_ONCE 8
|
||||
/** Max number of validation suspends allowed, error out otherwise. */
|
||||
#define MAX_VALIDATION_SUSPENDS 16
|
||||
|
||||
/* forward decl for cache response and normal super inform calls of a DS */
|
||||
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, int* suspend);
|
||||
struct query_info* qinfo, struct sock_list* origin);
|
||||
|
||||
|
||||
/* Updates the suplied EDE (RFC8914) code selectively so we don't lose
|
||||
@@ -297,21 +292,6 @@ val_new(struct module_qstate* qstate, int id)
|
||||
return val_new_getmsg(qstate, vq);
|
||||
}
|
||||
|
||||
/** reset validator query state for query restart */
|
||||
static void
|
||||
val_restart(struct val_qstate* vq)
|
||||
{
|
||||
struct comm_timer* temp_timer;
|
||||
int restart_count;
|
||||
if(!vq) return;
|
||||
temp_timer = vq->suspend_timer;
|
||||
restart_count = vq->restart_count+1;
|
||||
memset(vq, 0, sizeof(*vq));
|
||||
vq->suspend_timer = temp_timer;
|
||||
vq->restart_count = restart_count;
|
||||
vq->state = VAL_INIT_STATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit validation with an error status
|
||||
*
|
||||
@@ -618,42 +598,30 @@ prime_trust_anchor(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
* completed.
|
||||
*
|
||||
* @param qstate: query state.
|
||||
* @param vq: validator query state.
|
||||
* @param env: module env for verify.
|
||||
* @param ve: validator env for verify.
|
||||
* @param qchase: query that was made.
|
||||
* @param chase_reply: answer to validate.
|
||||
* @param key_entry: the key entry, which is trusted, and which matches
|
||||
* the signer of the answer. The key entry isgood().
|
||||
* @param suspend: returned true if the task takes too long and needs to
|
||||
* suspend to continue the effort later.
|
||||
* @return false if any of the rrsets in the an or ns sections of the message
|
||||
* fail to verify. The message is then set to bogus.
|
||||
*/
|
||||
static int
|
||||
validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct module_env* env, struct val_env* ve, struct query_info* qchase,
|
||||
struct reply_info* chase_reply, struct key_entry_key* key_entry,
|
||||
int* suspend)
|
||||
validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
struct val_env* ve, struct query_info* qchase,
|
||||
struct reply_info* chase_reply, struct key_entry_key* key_entry)
|
||||
{
|
||||
uint8_t* sname;
|
||||
size_t i, slen;
|
||||
struct ub_packed_rrset_key* s;
|
||||
enum sec_status sec;
|
||||
int dname_seen = 0, num_verifies = 0, verified, have_state = 0;
|
||||
int dname_seen = 0;
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
*suspend = 0;
|
||||
if(vq->msg_signatures_state) {
|
||||
/* Pick up the state, and reset it, may not be needed now. */
|
||||
vq->msg_signatures_state = 0;
|
||||
have_state = 1;
|
||||
}
|
||||
|
||||
/* validate the ANSWER section */
|
||||
for(i=0; i<chase_reply->an_numrrsets; i++) {
|
||||
if(have_state && i <= vq->msg_signatures_index)
|
||||
continue;
|
||||
s = chase_reply->rrsets[i];
|
||||
/* Skip the CNAME following a (validated) DNAME.
|
||||
* Because of the normalization routines in the iterator,
|
||||
@@ -672,7 +640,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
|
||||
/* Verify the answer rrset */
|
||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||
&reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified);
|
||||
&reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
/* If the (answer) rrset failed to validate, then this
|
||||
* message is BAD. */
|
||||
if(sec != sec_status_secure) {
|
||||
@@ -697,33 +665,14 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
ntohs(s->rk.type) == LDNS_RR_TYPE_DNAME) {
|
||||
dname_seen = 1;
|
||||
}
|
||||
num_verifies += verified;
|
||||
if(num_verifies > MAX_VALIDATE_AT_ONCE &&
|
||||
i+1 < (env->cfg->val_clean_additional?
|
||||
chase_reply->an_numrrsets+chase_reply->ns_numrrsets:
|
||||
chase_reply->rrset_count)) {
|
||||
/* If the number of RRSIGs exceeds the maximum in
|
||||
* one go, suspend. Only suspend if there is a next
|
||||
* rrset to verify, i+1<loopmax. Store where to
|
||||
* continue later. */
|
||||
*suspend = 1;
|
||||
vq->msg_signatures_state = 1;
|
||||
vq->msg_signatures_index = i;
|
||||
verbose(VERB_ALGO, "msg signature validation "
|
||||
"suspended");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* validate the AUTHORITY section */
|
||||
for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+
|
||||
chase_reply->ns_numrrsets; i++) {
|
||||
if(have_state && i <= vq->msg_signatures_index)
|
||||
continue;
|
||||
s = chase_reply->rrsets[i];
|
||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||
&reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
|
||||
&verified);
|
||||
&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) {
|
||||
@@ -737,18 +686,6 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
update_reason_bogus(chase_reply, reason_bogus);
|
||||
return 0;
|
||||
}
|
||||
num_verifies += verified;
|
||||
if(num_verifies > MAX_VALIDATE_AT_ONCE &&
|
||||
i+1 < (env->cfg->val_clean_additional?
|
||||
chase_reply->an_numrrsets+chase_reply->ns_numrrsets:
|
||||
chase_reply->rrset_count)) {
|
||||
*suspend = 1;
|
||||
vq->msg_signatures_state = 1;
|
||||
vq->msg_signatures_index = i;
|
||||
verbose(VERB_ALGO, "msg signature validation "
|
||||
"suspended");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If set, the validator should clean the additional section of
|
||||
@@ -758,103 +695,22 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* attempt to validate the ADDITIONAL section rrsets */
|
||||
for(i=chase_reply->an_numrrsets+chase_reply->ns_numrrsets;
|
||||
i<chase_reply->rrset_count; i++) {
|
||||
if(have_state && i <= vq->msg_signatures_index)
|
||||
continue;
|
||||
s = chase_reply->rrsets[i];
|
||||
/* 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);
|
||||
|
||||
verified = 0;
|
||||
if(sname && query_dname_compare(sname, key_entry->name)==0)
|
||||
(void)val_verify_rrset_entry(env, ve, s, key_entry,
|
||||
&reason, NULL, LDNS_SECTION_ADDITIONAL, qstate,
|
||||
&verified);
|
||||
&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. */
|
||||
num_verifies += verified;
|
||||
if(num_verifies > MAX_VALIDATE_AT_ONCE &&
|
||||
i+1 < chase_reply->rrset_count) {
|
||||
*suspend = 1;
|
||||
vq->msg_signatures_state = 1;
|
||||
vq->msg_signatures_index = i;
|
||||
verbose(VERB_ALGO, "msg signature validation "
|
||||
"suspended");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
validate_suspend_timer_cb(void* arg)
|
||||
{
|
||||
struct module_qstate* qstate = (struct module_qstate*)arg;
|
||||
verbose(VERB_ALGO, "validate_suspend timer, continue");
|
||||
mesh_run(qstate->env->mesh, qstate->mesh_info, module_event_pass,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/** Setup timer to continue validation of msg signatures later */
|
||||
static int
|
||||
validate_suspend_setup_timer(struct module_qstate* qstate,
|
||||
struct val_qstate* vq, int id, enum val_state resume_state)
|
||||
{
|
||||
struct timeval tv;
|
||||
int usec, slack, base;
|
||||
if(vq->suspend_count >= MAX_VALIDATION_SUSPENDS) {
|
||||
verbose(VERB_ALGO, "validate_suspend timer: "
|
||||
"reached MAX_VALIDATION_SUSPENDS (%d); error out",
|
||||
MAX_VALIDATION_SUSPENDS);
|
||||
errinf(qstate, "max validation suspends reached, "
|
||||
"too many RRSIG validations");
|
||||
return 0;
|
||||
}
|
||||
verbose(VERB_ALGO, "validate_suspend timer, set for suspend");
|
||||
vq->state = resume_state;
|
||||
qstate->ext_state[id] = module_wait_reply;
|
||||
if(!vq->suspend_timer) {
|
||||
vq->suspend_timer = comm_timer_create(
|
||||
qstate->env->worker_base,
|
||||
validate_suspend_timer_cb, qstate);
|
||||
if(!vq->suspend_timer) {
|
||||
log_err("validate_suspend_setup_timer: "
|
||||
"out of memory for comm_timer_create");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* The timer is activated later, after other events in the event
|
||||
* loop have been processed. The query state can also be deleted,
|
||||
* when the list is full and query states are dropped. */
|
||||
/* Extend wait time if there are a lot of queries or if this one
|
||||
* is taking long, to keep around cpu time for ordinary queries. */
|
||||
usec = 50000; /* 50 msec */
|
||||
slack = 0;
|
||||
if(qstate->env->mesh->all.count >= qstate->env->mesh->max_reply_states)
|
||||
slack += 3;
|
||||
else if(qstate->env->mesh->all.count >= qstate->env->mesh->max_reply_states/2)
|
||||
slack += 2;
|
||||
else if(qstate->env->mesh->all.count >= qstate->env->mesh->max_reply_states/4)
|
||||
slack += 1;
|
||||
if(vq->suspend_count > 3)
|
||||
slack += 3;
|
||||
else if(vq->suspend_count > 0)
|
||||
slack += vq->suspend_count;
|
||||
if(slack != 0 && slack <= 12 /* No numeric overflow. */) {
|
||||
usec = usec << slack;
|
||||
}
|
||||
/* Spread such timeouts within 90%-100% of the original timer. */
|
||||
base = usec * 9/10;
|
||||
usec = base + ub_random_max(qstate->env->rnd, usec-base);
|
||||
tv.tv_usec = (usec % 1000000);
|
||||
tv.tv_sec = (usec / 1000000);
|
||||
vq->suspend_count ++;
|
||||
comm_timer_set(vq->suspend_timer, &tv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect wrong truncated response (say from BIND 9.6.1 that is forwarding
|
||||
* and saw the NS record without signatures from a referral).
|
||||
@@ -953,17 +809,11 @@ remove_spurious_authority(struct reply_info* chase_reply,
|
||||
* @param chase_reply: answer to that query to validate.
|
||||
* @param kkey: the key entry, which is trusted, and which matches
|
||||
* the signer of the answer. The key entry isgood().
|
||||
* @param qstate: query state for the region.
|
||||
* @param vq: validator state for the nsec3 cache table.
|
||||
* @param nsec3_calculations: current nsec3 hash calculations.
|
||||
* @param suspend: returned true if the task takes too long and needs to
|
||||
* suspend to continue the effort later.
|
||||
*/
|
||||
static void
|
||||
validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qchase, struct reply_info* chase_reply,
|
||||
struct key_entry_key* kkey, struct module_qstate* qstate,
|
||||
struct val_qstate* vq, int* nsec3_calculations, int* suspend)
|
||||
struct key_entry_key* kkey)
|
||||
{
|
||||
uint8_t* wc = NULL;
|
||||
size_t wl;
|
||||
@@ -972,7 +822,6 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
int nsec3s_seen = 0;
|
||||
size_t i;
|
||||
struct ub_packed_rrset_key* s;
|
||||
*suspend = 0;
|
||||
|
||||
/* validate the ANSWER section - this will be the answer itself */
|
||||
for(i=0; i<chase_reply->an_numrrsets; i++) {
|
||||
@@ -1024,23 +873,17 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
/* If this was a positive wildcard response that we haven't already
|
||||
* proven, and we have NSEC3 records, try to prove it using the NSEC3
|
||||
* records. */
|
||||
if(wc != NULL && !wc_NSEC_ok && nsec3s_seen &&
|
||||
nsec3_cache_table_init(&vq->nsec3_cache_table, qstate->region)) {
|
||||
enum sec_status sec = nsec3_prove_wildcard(env, ve,
|
||||
if(wc != NULL && !wc_NSEC_ok && nsec3s_seen) {
|
||||
enum sec_status sec = nsec3_prove_wildcard(env, ve,
|
||||
chase_reply->rrsets+chase_reply->an_numrrsets,
|
||||
chase_reply->ns_numrrsets, qchase, kkey, wc,
|
||||
&vq->nsec3_cache_table, nsec3_calculations);
|
||||
chase_reply->ns_numrrsets, qchase, kkey, wc);
|
||||
if(sec == sec_status_insecure) {
|
||||
verbose(VERB_ALGO, "Positive wildcard response is "
|
||||
"insecure");
|
||||
chase_reply->security = sec_status_insecure;
|
||||
return;
|
||||
} else if(sec == sec_status_secure) {
|
||||
} else if(sec == sec_status_secure)
|
||||
wc_NSEC_ok = 1;
|
||||
} else if(sec == sec_status_unchecked) {
|
||||
*suspend = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If after all this, we still haven't proven the positive wildcard
|
||||
@@ -1072,17 +915,11 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
* @param chase_reply: answer to that query to validate.
|
||||
* @param kkey: the key entry, which is trusted, and which matches
|
||||
* the signer of the answer. The key entry isgood().
|
||||
* @param qstate: query state for the region.
|
||||
* @param vq: validator state for the nsec3 cache table.
|
||||
* @param nsec3_calculations: current nsec3 hash calculations.
|
||||
* @param suspend: returned true if the task takes too long and needs to
|
||||
* suspend to continue the effort later.
|
||||
*/
|
||||
static void
|
||||
validate_nodata_response(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qchase, struct reply_info* chase_reply,
|
||||
struct key_entry_key* kkey, struct module_qstate* qstate,
|
||||
struct val_qstate* vq, int* nsec3_calculations, int* suspend)
|
||||
struct key_entry_key* kkey)
|
||||
{
|
||||
/* Since we are here, there must be nothing in the ANSWER section to
|
||||
* validate. */
|
||||
@@ -1099,7 +936,6 @@ validate_nodata_response(struct module_env* env, struct val_env* ve,
|
||||
int nsec3s_seen = 0; /* nsec3s seen */
|
||||
struct ub_packed_rrset_key* s;
|
||||
size_t i;
|
||||
*suspend = 0;
|
||||
|
||||
for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+
|
||||
chase_reply->ns_numrrsets; i++) {
|
||||
@@ -1138,23 +974,16 @@ validate_nodata_response(struct module_env* env, struct val_env* ve,
|
||||
}
|
||||
}
|
||||
|
||||
if(!has_valid_nsec && nsec3s_seen &&
|
||||
nsec3_cache_table_init(&vq->nsec3_cache_table, qstate->region)) {
|
||||
if(!has_valid_nsec && nsec3s_seen) {
|
||||
enum sec_status sec = nsec3_prove_nodata(env, ve,
|
||||
chase_reply->rrsets+chase_reply->an_numrrsets,
|
||||
chase_reply->ns_numrrsets, qchase, kkey,
|
||||
&vq->nsec3_cache_table, nsec3_calculations);
|
||||
chase_reply->ns_numrrsets, qchase, kkey);
|
||||
if(sec == sec_status_insecure) {
|
||||
verbose(VERB_ALGO, "NODATA response is insecure");
|
||||
chase_reply->security = sec_status_insecure;
|
||||
return;
|
||||
} else if(sec == sec_status_secure) {
|
||||
} else if(sec == sec_status_secure)
|
||||
has_valid_nsec = 1;
|
||||
} else if(sec == sec_status_unchecked) {
|
||||
/* check is incomplete; suspend */
|
||||
*suspend = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(!has_valid_nsec) {
|
||||
@@ -1186,18 +1015,11 @@ validate_nodata_response(struct module_env* env, struct val_env* ve,
|
||||
* @param kkey: the key entry, which is trusted, and which matches
|
||||
* the signer of the answer. The key entry isgood().
|
||||
* @param rcode: adjusted RCODE, in case of RCODE/proof mismatch leniency.
|
||||
* @param qstate: query state for the region.
|
||||
* @param vq: validator state for the nsec3 cache table.
|
||||
* @param nsec3_calculations: current nsec3 hash calculations.
|
||||
* @param suspend: returned true if the task takes too long and needs to
|
||||
* suspend to continue the effort later.
|
||||
*/
|
||||
static void
|
||||
validate_nameerror_response(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qchase, struct reply_info* chase_reply,
|
||||
struct key_entry_key* kkey, int* rcode,
|
||||
struct module_qstate* qstate, struct val_qstate* vq,
|
||||
int* nsec3_calculations, int* suspend)
|
||||
struct key_entry_key* kkey, int* rcode)
|
||||
{
|
||||
int has_valid_nsec = 0;
|
||||
int has_valid_wnsec = 0;
|
||||
@@ -1207,7 +1029,6 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve,
|
||||
uint8_t* ce;
|
||||
int ce_labs = 0;
|
||||
int prev_ce_labs = 0;
|
||||
*suspend = 0;
|
||||
|
||||
for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+
|
||||
chase_reply->ns_numrrsets; i++) {
|
||||
@@ -1237,18 +1058,13 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve,
|
||||
nsec3s_seen = 1;
|
||||
}
|
||||
|
||||
if((!has_valid_nsec || !has_valid_wnsec) && nsec3s_seen &&
|
||||
nsec3_cache_table_init(&vq->nsec3_cache_table, qstate->region)) {
|
||||
if((!has_valid_nsec || !has_valid_wnsec) && nsec3s_seen) {
|
||||
/* use NSEC3 proof, both answer and auth rrsets, in case
|
||||
* NSEC3s end up in the answer (due to qtype=NSEC3 or so) */
|
||||
chase_reply->security = nsec3_prove_nameerror(env, ve,
|
||||
chase_reply->rrsets, chase_reply->an_numrrsets+
|
||||
chase_reply->ns_numrrsets, qchase, kkey,
|
||||
&vq->nsec3_cache_table, nsec3_calculations);
|
||||
if(chase_reply->security == sec_status_unchecked) {
|
||||
*suspend = 1;
|
||||
return;
|
||||
} else if(chase_reply->security != sec_status_secure) {
|
||||
chase_reply->ns_numrrsets, qchase, kkey);
|
||||
if(chase_reply->security != sec_status_secure) {
|
||||
verbose(VERB_QUERY, "NameError response failed nsec, "
|
||||
"nsec3 proof was %s", sec_status_to_string(
|
||||
chase_reply->security));
|
||||
@@ -1260,34 +1076,26 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve,
|
||||
|
||||
/* If the message fails to prove either condition, it is bogus. */
|
||||
if(!has_valid_nsec) {
|
||||
validate_nodata_response(env, ve, qchase, chase_reply, kkey,
|
||||
qstate, vq, nsec3_calculations, suspend);
|
||||
if(*suspend) return;
|
||||
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 */
|
||||
if(chase_reply->security == sec_status_secure) {
|
||||
validate_nodata_response(env, ve, qchase, chase_reply, kkey);
|
||||
if (chase_reply->security == sec_status_secure)
|
||||
*rcode = LDNS_RCODE_NOERROR;
|
||||
} else {
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!has_valid_wnsec) {
|
||||
validate_nodata_response(env, ve, qchase, chase_reply, kkey,
|
||||
qstate, vq, nsec3_calculations, suspend);
|
||||
if(*suspend) return;
|
||||
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 */
|
||||
if (chase_reply->security == sec_status_secure) {
|
||||
validate_nodata_response(env, ve, qchase, chase_reply, kkey);
|
||||
if (chase_reply->security == sec_status_secure)
|
||||
*rcode = LDNS_RCODE_NOERROR;
|
||||
} else {
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1347,17 +1155,11 @@ validate_referral_response(struct reply_info* chase_reply)
|
||||
* @param chase_reply: answer to that query to validate.
|
||||
* @param kkey: the key entry, which is trusted, and which matches
|
||||
* the signer of the answer. The key entry isgood().
|
||||
* @param qstate: query state for the region.
|
||||
* @param vq: validator state for the nsec3 cache table.
|
||||
* @param nsec3_calculations: current nsec3 hash calculations.
|
||||
* @param suspend: returned true if the task takes too long and needs to
|
||||
* suspend to continue the effort later.
|
||||
*/
|
||||
static void
|
||||
validate_any_response(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qchase, struct reply_info* chase_reply,
|
||||
struct key_entry_key* kkey, struct module_qstate* qstate,
|
||||
struct val_qstate* vq, int* nsec3_calculations, int* suspend)
|
||||
struct key_entry_key* kkey)
|
||||
{
|
||||
/* all answer and auth rrsets already verified */
|
||||
/* but check if a wildcard response is given, then check NSEC/NSEC3
|
||||
@@ -1368,7 +1170,6 @@ validate_any_response(struct module_env* env, struct val_env* ve,
|
||||
int nsec3s_seen = 0;
|
||||
size_t i;
|
||||
struct ub_packed_rrset_key* s;
|
||||
*suspend = 0;
|
||||
|
||||
if(qchase->qtype != LDNS_RR_TYPE_ANY) {
|
||||
log_err("internal error: ANY validation called for non-ANY");
|
||||
@@ -1423,25 +1224,19 @@ validate_any_response(struct module_env* env, struct val_env* ve,
|
||||
/* If this was a positive wildcard response that we haven't already
|
||||
* proven, and we have NSEC3 records, try to prove it using the NSEC3
|
||||
* records. */
|
||||
if(wc != NULL && !wc_NSEC_ok && nsec3s_seen &&
|
||||
nsec3_cache_table_init(&vq->nsec3_cache_table, qstate->region)) {
|
||||
if(wc != NULL && !wc_NSEC_ok && nsec3s_seen) {
|
||||
/* look both in answer and auth section for NSEC3s */
|
||||
enum sec_status sec = nsec3_prove_wildcard(env, ve,
|
||||
enum sec_status sec = nsec3_prove_wildcard(env, ve,
|
||||
chase_reply->rrsets,
|
||||
chase_reply->an_numrrsets+chase_reply->ns_numrrsets,
|
||||
qchase, kkey, wc, &vq->nsec3_cache_table,
|
||||
nsec3_calculations);
|
||||
chase_reply->an_numrrsets+chase_reply->ns_numrrsets,
|
||||
qchase, kkey, wc);
|
||||
if(sec == sec_status_insecure) {
|
||||
verbose(VERB_ALGO, "Positive ANY wildcard response is "
|
||||
"insecure");
|
||||
chase_reply->security = sec_status_insecure;
|
||||
return;
|
||||
} else if(sec == sec_status_secure) {
|
||||
} else if(sec == sec_status_secure)
|
||||
wc_NSEC_ok = 1;
|
||||
} else if(sec == sec_status_unchecked) {
|
||||
*suspend = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If after all this, we still haven't proven the positive wildcard
|
||||
@@ -1474,17 +1269,11 @@ validate_any_response(struct module_env* env, struct val_env* ve,
|
||||
* @param chase_reply: answer to that query to validate.
|
||||
* @param kkey: the key entry, which is trusted, and which matches
|
||||
* the signer of the answer. The key entry isgood().
|
||||
* @param qstate: query state for the region.
|
||||
* @param vq: validator state for the nsec3 cache table.
|
||||
* @param nsec3_calculations: current nsec3 hash calculations.
|
||||
* @param suspend: returned true if the task takes too long and needs to
|
||||
* suspend to continue the effort later.
|
||||
*/
|
||||
static void
|
||||
validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qchase, struct reply_info* chase_reply,
|
||||
struct key_entry_key* kkey, struct module_qstate* qstate,
|
||||
struct val_qstate* vq, int* nsec3_calculations, int* suspend)
|
||||
struct key_entry_key* kkey)
|
||||
{
|
||||
uint8_t* wc = NULL;
|
||||
size_t wl;
|
||||
@@ -1492,7 +1281,6 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
int nsec3s_seen = 0;
|
||||
size_t i;
|
||||
struct ub_packed_rrset_key* s;
|
||||
*suspend = 0;
|
||||
|
||||
/* validate the ANSWER section - this will be the CNAME (+DNAME) */
|
||||
for(i=0; i<chase_reply->an_numrrsets; i++) {
|
||||
@@ -1557,23 +1345,17 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
/* If this was a positive wildcard response that we haven't already
|
||||
* proven, and we have NSEC3 records, try to prove it using the NSEC3
|
||||
* records. */
|
||||
if(wc != NULL && !wc_NSEC_ok && nsec3s_seen &&
|
||||
nsec3_cache_table_init(&vq->nsec3_cache_table, qstate->region)) {
|
||||
enum sec_status sec = nsec3_prove_wildcard(env, ve,
|
||||
if(wc != NULL && !wc_NSEC_ok && nsec3s_seen) {
|
||||
enum sec_status sec = nsec3_prove_wildcard(env, ve,
|
||||
chase_reply->rrsets+chase_reply->an_numrrsets,
|
||||
chase_reply->ns_numrrsets, qchase, kkey, wc,
|
||||
&vq->nsec3_cache_table, nsec3_calculations);
|
||||
chase_reply->ns_numrrsets, qchase, kkey, wc);
|
||||
if(sec == sec_status_insecure) {
|
||||
verbose(VERB_ALGO, "wildcard CNAME response is "
|
||||
"insecure");
|
||||
chase_reply->security = sec_status_insecure;
|
||||
return;
|
||||
} else if(sec == sec_status_secure) {
|
||||
} else if(sec == sec_status_secure)
|
||||
wc_NSEC_ok = 1;
|
||||
} else if(sec == sec_status_unchecked) {
|
||||
*suspend = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If after all this, we still haven't proven the positive wildcard
|
||||
@@ -1604,17 +1386,11 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
* @param chase_reply: answer to that query to validate.
|
||||
* @param kkey: the key entry, which is trusted, and which matches
|
||||
* the signer of the answer. The key entry isgood().
|
||||
* @param qstate: query state for the region.
|
||||
* @param vq: validator state for the nsec3 cache table.
|
||||
* @param nsec3_calculations: current nsec3 hash calculations.
|
||||
* @param suspend: returned true if the task takes too long and needs to
|
||||
* suspend to continue the effort later.
|
||||
*/
|
||||
static void
|
||||
validate_cname_noanswer_response(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qchase, struct reply_info* chase_reply,
|
||||
struct key_entry_key* kkey, struct module_qstate* qstate,
|
||||
struct val_qstate* vq, int* nsec3_calculations, int* suspend)
|
||||
struct key_entry_key* kkey)
|
||||
{
|
||||
int nodata_valid_nsec = 0; /* If true, then NODATA has been proven.*/
|
||||
uint8_t* ce = NULL; /* for wildcard nodata responses. This is the
|
||||
@@ -1628,7 +1404,6 @@ validate_cname_noanswer_response(struct module_env* env, struct val_env* ve,
|
||||
uint8_t* nsec_ce; /* Used to find the NSEC with the longest ce */
|
||||
int ce_labs = 0;
|
||||
int prev_ce_labs = 0;
|
||||
*suspend = 0;
|
||||
|
||||
/* the AUTHORITY section */
|
||||
for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+
|
||||
@@ -1694,13 +1469,11 @@ validate_cname_noanswer_response(struct module_env* env, struct val_env* ve,
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
if(!nodata_valid_nsec && !nxdomain_valid_nsec && nsec3s_seen &&
|
||||
nsec3_cache_table_init(&vq->nsec3_cache_table, qstate->region)) {
|
||||
if(!nodata_valid_nsec && !nxdomain_valid_nsec && nsec3s_seen) {
|
||||
int nodata;
|
||||
enum sec_status sec = nsec3_prove_nxornodata(env, ve,
|
||||
chase_reply->rrsets+chase_reply->an_numrrsets,
|
||||
chase_reply->ns_numrrsets, qchase, kkey, &nodata,
|
||||
&vq->nsec3_cache_table, nsec3_calculations);
|
||||
chase_reply->ns_numrrsets, qchase, kkey, &nodata);
|
||||
if(sec == sec_status_insecure) {
|
||||
verbose(VERB_ALGO, "CNAMEchain to noanswer response "
|
||||
"is insecure");
|
||||
@@ -1710,9 +1483,6 @@ validate_cname_noanswer_response(struct module_env* env, struct val_env* ve,
|
||||
if(nodata)
|
||||
nodata_valid_nsec = 1;
|
||||
else nxdomain_valid_nsec = 1;
|
||||
} else if(sec == sec_status_unchecked) {
|
||||
*suspend = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2056,37 +1826,13 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
|
||||
* Uses negative cache for NSEC3 lookup of DS responses. */
|
||||
/* only if cache not blacklisted, of course */
|
||||
struct dns_msg* msg;
|
||||
int suspend;
|
||||
if(vq->sub_ds_msg) {
|
||||
/* We have a suspended DS reply from a sub-query;
|
||||
* process it. */
|
||||
verbose(VERB_ALGO, "Process suspended sub DS response");
|
||||
msg = vq->sub_ds_msg;
|
||||
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
|
||||
msg, &msg->qinfo, NULL, &suspend);
|
||||
if(suspend) {
|
||||
/* we'll come back here later to continue */
|
||||
if(!validate_suspend_setup_timer(qstate, vq,
|
||||
id, VAL_FINDKEY_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
vq->sub_ds_msg = NULL;
|
||||
return 1; /* continue processing ds-response results */
|
||||
} else if(!qstate->blacklist && !vq->chain_blacklist &&
|
||||
if(!qstate->blacklist && !vq->chain_blacklist &&
|
||||
(msg=val_find_DS(qstate->env, target_key_name,
|
||||
target_key_len, vq->qchase.qclass, qstate->region,
|
||||
vq->key_entry->name)) ) {
|
||||
verbose(VERB_ALGO, "Process cached DS response");
|
||||
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
|
||||
msg, &msg->qinfo, NULL, &suspend);
|
||||
if(suspend) {
|
||||
/* we'll come back here later to continue */
|
||||
if(!validate_suspend_setup_timer(qstate, vq,
|
||||
id, VAL_FINDKEY_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
msg, &msg->qinfo, NULL);
|
||||
return 1; /* continue processing ds-response results */
|
||||
}
|
||||
if(!generate_request(qstate, id, target_key_name,
|
||||
@@ -2129,7 +1875,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct val_env* ve, int id)
|
||||
{
|
||||
enum val_classification subtype;
|
||||
int rcode, suspend, nsec3_calculations = 0;
|
||||
int rcode;
|
||||
|
||||
if(!vq->key_entry) {
|
||||
verbose(VERB_ALGO, "validate: no key entry, failed");
|
||||
@@ -2186,14 +1932,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
|
||||
/* check signatures in the message;
|
||||
* answer and authority must be valid, additional is only checked. */
|
||||
if(!validate_msg_signatures(qstate, vq, qstate->env, ve, &vq->qchase,
|
||||
vq->chase_reply, vq->key_entry, &suspend)) {
|
||||
if(suspend) {
|
||||
if(!validate_suspend_setup_timer(qstate, vq,
|
||||
id, VAL_VALIDATE_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
if(!validate_msg_signatures(qstate, qstate->env, ve, &vq->qchase,
|
||||
vq->chase_reply, vq->key_entry)) {
|
||||
/* workaround bad recursor out there that truncates (even
|
||||
* with EDNS4k) to 512 by removing RRSIG from auth section
|
||||
* for positive replies*/
|
||||
@@ -2222,14 +1962,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
case VAL_CLASS_POSITIVE:
|
||||
verbose(VERB_ALGO, "Validating a positive response");
|
||||
validate_positive_response(qstate->env, ve,
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry,
|
||||
qstate, vq, &nsec3_calculations, &suspend);
|
||||
if(suspend) {
|
||||
if(!validate_suspend_setup_timer(qstate,
|
||||
vq, id, VAL_VALIDATE_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry);
|
||||
verbose(VERB_DETAIL, "validate(positive): %s",
|
||||
sec_status_to_string(
|
||||
vq->chase_reply->security));
|
||||
@@ -2238,14 +1971,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
case VAL_CLASS_NODATA:
|
||||
verbose(VERB_ALGO, "Validating a nodata response");
|
||||
validate_nodata_response(qstate->env, ve,
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry,
|
||||
qstate, vq, &nsec3_calculations, &suspend);
|
||||
if(suspend) {
|
||||
if(!validate_suspend_setup_timer(qstate,
|
||||
vq, id, VAL_VALIDATE_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry);
|
||||
verbose(VERB_DETAIL, "validate(nodata): %s",
|
||||
sec_status_to_string(
|
||||
vq->chase_reply->security));
|
||||
@@ -2255,14 +1981,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
rcode = (int)FLAGS_GET_RCODE(vq->orig_msg->rep->flags);
|
||||
verbose(VERB_ALGO, "Validating a nxdomain response");
|
||||
validate_nameerror_response(qstate->env, ve,
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry, &rcode,
|
||||
qstate, vq, &nsec3_calculations, &suspend);
|
||||
if(suspend) {
|
||||
if(!validate_suspend_setup_timer(qstate,
|
||||
vq, id, VAL_VALIDATE_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry, &rcode);
|
||||
verbose(VERB_DETAIL, "validate(nxdomain): %s",
|
||||
sec_status_to_string(
|
||||
vq->chase_reply->security));
|
||||
@@ -2273,14 +1992,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
case VAL_CLASS_CNAME:
|
||||
verbose(VERB_ALGO, "Validating a cname response");
|
||||
validate_cname_response(qstate->env, ve,
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry,
|
||||
qstate, vq, &nsec3_calculations, &suspend);
|
||||
if(suspend) {
|
||||
if(!validate_suspend_setup_timer(qstate,
|
||||
vq, id, VAL_VALIDATE_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry);
|
||||
verbose(VERB_DETAIL, "validate(cname): %s",
|
||||
sec_status_to_string(
|
||||
vq->chase_reply->security));
|
||||
@@ -2290,14 +2002,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
verbose(VERB_ALGO, "Validating a cname noanswer "
|
||||
"response");
|
||||
validate_cname_noanswer_response(qstate->env, ve,
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry,
|
||||
qstate, vq, &nsec3_calculations, &suspend);
|
||||
if(suspend) {
|
||||
if(!validate_suspend_setup_timer(qstate,
|
||||
vq, id, VAL_VALIDATE_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
&vq->qchase, vq->chase_reply, vq->key_entry);
|
||||
verbose(VERB_DETAIL, "validate(cname_noanswer): %s",
|
||||
sec_status_to_string(
|
||||
vq->chase_reply->security));
|
||||
@@ -2314,15 +2019,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
case VAL_CLASS_ANY:
|
||||
verbose(VERB_ALGO, "Validating a positive ANY "
|
||||
"response");
|
||||
validate_any_response(qstate->env, ve, &vq->qchase,
|
||||
vq->chase_reply, vq->key_entry, qstate, vq,
|
||||
&nsec3_calculations, &suspend);
|
||||
if(suspend) {
|
||||
if(!validate_suspend_setup_timer(qstate,
|
||||
vq, id, VAL_VALIDATE_STATE))
|
||||
return val_error(qstate, id);
|
||||
return 0;
|
||||
}
|
||||
validate_any_response(qstate->env, ve, &vq->qchase,
|
||||
vq->chase_reply, vq->key_entry);
|
||||
verbose(VERB_DETAIL, "validate(positive_any): %s",
|
||||
sec_status_to_string(
|
||||
vq->chase_reply->security));
|
||||
@@ -2431,13 +2129,16 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
if(vq->orig_msg->rep->security == sec_status_bogus) {
|
||||
/* see if we can try again to fetch data */
|
||||
if(vq->restart_count < ve->max_restart) {
|
||||
int restart_count = vq->restart_count+1;
|
||||
verbose(VERB_ALGO, "validation failed, "
|
||||
"blacklist and retry to fetch data");
|
||||
val_blacklist(&qstate->blacklist, qstate->region,
|
||||
qstate->reply_origin, 0);
|
||||
qstate->reply_origin = NULL;
|
||||
qstate->errinf = NULL;
|
||||
val_restart(vq);
|
||||
memset(vq, 0, sizeof(*vq));
|
||||
vq->restart_count = restart_count;
|
||||
vq->state = VAL_INIT_STATE;
|
||||
verbose(VERB_ALGO, "pass back to next module");
|
||||
qstate->ext_state[id] = module_restart_next;
|
||||
return 0;
|
||||
@@ -2764,10 +2465,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
* DS response indicated an end to secure space, is_good if the DS
|
||||
* validated. It returns ke=NULL if the DS response indicated that the
|
||||
* request wasn't a delegation point.
|
||||
* @return
|
||||
* 0 on success,
|
||||
* 1 on servfail error (malloc failure),
|
||||
* 2 on NSEC3 suspend.
|
||||
* @return 0 on servfail error (malloc failure).
|
||||
*/
|
||||
static int
|
||||
ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
@@ -2778,7 +2476,6 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
enum val_classification subtype;
|
||||
int verified;
|
||||
if(rcode != LDNS_RCODE_NOERROR) {
|
||||
char rc[16];
|
||||
rc[0]=0;
|
||||
@@ -2809,7 +2506,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* 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, &reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified);
|
||||
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");
|
||||
@@ -2827,7 +2524,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
ub_packed_rrset_ttl(ds),
|
||||
LDNS_EDE_UNSUPPORTED_DS_DIGEST, NULL,
|
||||
*qstate->env->now);
|
||||
return (*ke) == NULL;
|
||||
return (*ke) != NULL;
|
||||
}
|
||||
|
||||
/* Otherwise, we return the positive response. */
|
||||
@@ -2835,7 +2532,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
*ke = key_entry_create_rrset(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len, qinfo->qclass, ds,
|
||||
NULL, LDNS_EDE_NONE, NULL, *qstate->env->now);
|
||||
return (*ke) == NULL;
|
||||
return (*ke) != NULL;
|
||||
} else if(subtype == VAL_CLASS_NODATA ||
|
||||
subtype == VAL_CLASS_NAMEERROR) {
|
||||
/* NODATA means that the qname exists, but that there was
|
||||
@@ -2869,12 +2566,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
qinfo->qclass, proof_ttl,
|
||||
LDNS_EDE_NONE, NULL,
|
||||
*qstate->env->now);
|
||||
return (*ke) == NULL;
|
||||
return (*ke) != NULL;
|
||||
case sec_status_insecure:
|
||||
verbose(VERB_DETAIL, "NSEC RRset for the "
|
||||
"referral proved not a delegation point");
|
||||
*ke = NULL;
|
||||
return 0;
|
||||
return 1;
|
||||
case sec_status_bogus:
|
||||
verbose(VERB_DETAIL, "NSEC RRset for the "
|
||||
"referral did not prove no DS.");
|
||||
@@ -2886,17 +2583,10 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
break;
|
||||
}
|
||||
|
||||
if(!nsec3_cache_table_init(&vq->nsec3_cache_table, qstate->region)) {
|
||||
log_err("malloc failure in ds_response_to_ke for "
|
||||
"NSEC3 cache");
|
||||
reason = "malloc failure";
|
||||
errinf_ede(qstate, reason, 0);
|
||||
goto return_bogus;
|
||||
}
|
||||
sec = nsec3_prove_nods(qstate->env, ve,
|
||||
msg->rep->rrsets + msg->rep->an_numrrsets,
|
||||
msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason,
|
||||
&reason_bogus, qstate, &vq->nsec3_cache_table);
|
||||
&reason_bogus, qstate);
|
||||
switch(sec) {
|
||||
case sec_status_insecure:
|
||||
/* case insecure also continues to unsigned
|
||||
@@ -2910,19 +2600,18 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
qinfo->qclass, proof_ttl,
|
||||
LDNS_EDE_NONE, NULL,
|
||||
*qstate->env->now);
|
||||
return (*ke) == NULL;
|
||||
return (*ke) != NULL;
|
||||
case sec_status_indeterminate:
|
||||
verbose(VERB_DETAIL, "NSEC3s for the "
|
||||
"referral proved no delegation");
|
||||
*ke = NULL;
|
||||
return 0;
|
||||
return 1;
|
||||
case sec_status_bogus:
|
||||
verbose(VERB_DETAIL, "NSEC3s for the "
|
||||
"referral did not prove no DS.");
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
case sec_status_unchecked:
|
||||
return 2;
|
||||
default:
|
||||
/* NSEC3 proof did not work */
|
||||
break;
|
||||
@@ -2963,13 +2652,13 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
}
|
||||
sec = val_verify_rrset_entry(qstate->env, ve, cname,
|
||||
vq->key_entry, &reason, &reason_bogus,
|
||||
LDNS_SECTION_ANSWER, qstate, &verified);
|
||||
LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
verbose(VERB_ALGO, "CNAME validated, "
|
||||
"proof that DS does not exist");
|
||||
/* and that it is not a referral point */
|
||||
*ke = NULL;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
errinf(qstate, "CNAME in DS response was not secure.");
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
@@ -2993,7 +2682,7 @@ return_bogus:
|
||||
*ke = key_entry_create_bad(qstate->region, qinfo->qname,
|
||||
qinfo->qname_len, qinfo->qclass, BOGUS_KEY_TTL,
|
||||
reason_bogus, reason, *qstate->env->now);
|
||||
return (*ke) == NULL;
|
||||
return (*ke) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3014,31 +2703,17 @@ return_bogus:
|
||||
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, int* suspend)
|
||||
struct sock_list* origin)
|
||||
{
|
||||
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
||||
struct key_entry_key* dske = NULL;
|
||||
uint8_t* olds = vq->empty_DS_name;
|
||||
int ret;
|
||||
*suspend = 0;
|
||||
vq->empty_DS_name = NULL;
|
||||
ret = ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske);
|
||||
if(ret != 0) {
|
||||
switch(ret) {
|
||||
case 1:
|
||||
if(!ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske)) {
|
||||
log_err("malloc failure in process_ds_response");
|
||||
vq->key_entry = NULL; /* make it error */
|
||||
vq->state = VAL_VALIDATE_STATE;
|
||||
return;
|
||||
case 2:
|
||||
*suspend = 1;
|
||||
return;
|
||||
default:
|
||||
log_err("unhandled error value for ds_response_to_ke");
|
||||
vq->key_entry = NULL; /* make it error */
|
||||
vq->state = VAL_VALIDATE_STATE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(dske == NULL) {
|
||||
vq->empty_DS_name = regional_alloc_init(qstate->region,
|
||||
@@ -3290,26 +2965,9 @@ val_inform_super(struct module_qstate* qstate, int id,
|
||||
return;
|
||||
}
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_DS) {
|
||||
int suspend;
|
||||
process_ds_response(super, vq, id, qstate->return_rcode,
|
||||
qstate->return_msg, &qstate->qinfo,
|
||||
qstate->reply_origin, &suspend);
|
||||
/* If NSEC3 was needed during validation, NULL the NSEC3 cache;
|
||||
* it will be re-initiated if needed later on.
|
||||
* Validation (and the cache table) are happening/allocated in
|
||||
* the super qstate whilst the RRs are allocated (and pointed
|
||||
* to) in this sub qstate. */
|
||||
if(vq->nsec3_cache_table.ct) {
|
||||
vq->nsec3_cache_table.ct = NULL;
|
||||
}
|
||||
if(suspend) {
|
||||
/* deep copy the return_msg to vq->sub_ds_msg; it will
|
||||
* be resumed later in the super state with the caveat
|
||||
* that the initial calculations will be re-caclulated
|
||||
* and re-suspended there before continuing. */
|
||||
vq->sub_ds_msg = dns_msg_deepcopy_region(
|
||||
qstate->return_msg, super->region);
|
||||
}
|
||||
qstate->return_msg, &qstate->qinfo,
|
||||
qstate->reply_origin);
|
||||
return;
|
||||
} else if(qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY) {
|
||||
process_dnskey_response(super, vq, id, qstate->return_rcode,
|
||||
@@ -3323,15 +2981,8 @@ val_inform_super(struct module_qstate* qstate, int id,
|
||||
void
|
||||
val_clear(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct val_qstate* vq;
|
||||
if(!qstate)
|
||||
return;
|
||||
vq = (struct val_qstate*)qstate->minfo[id];
|
||||
if(vq) {
|
||||
if(vq->suspend_timer) {
|
||||
comm_timer_delete(vq->suspend_timer);
|
||||
}
|
||||
}
|
||||
/* everything is allocated in the region, so assign NULL */
|
||||
qstate->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
@@ -45,13 +45,11 @@
|
||||
#include "util/module.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "validator/val_utils.h"
|
||||
#include "validator/val_nsec3.h"
|
||||
struct val_anchors;
|
||||
struct key_cache;
|
||||
struct key_entry_key;
|
||||
struct val_neg_cache;
|
||||
struct config_strlist;
|
||||
struct comm_timer;
|
||||
|
||||
/**
|
||||
* This is the TTL to use when a trust anchor fails to prime. A trust anchor
|
||||
@@ -217,19 +215,6 @@ struct val_qstate {
|
||||
|
||||
/** true if this state is waiting to prime a trust anchor */
|
||||
int wait_prime_ta;
|
||||
|
||||
/** State to continue with RRSIG validation in a message later */
|
||||
int msg_signatures_state;
|
||||
/** The rrset index for the msg signatures to continue from */
|
||||
size_t msg_signatures_index;
|
||||
/** Cache table for NSEC3 hashes */
|
||||
struct nsec3_cache_table nsec3_cache_table;
|
||||
/** DS message from sub if it got suspended from NSEC3 calculations */
|
||||
struct dns_msg* sub_ds_msg;
|
||||
/** The timer to resume processing msg signatures */
|
||||
struct comm_timer* suspend_timer;
|
||||
/** Number of suspends */
|
||||
int suspend_count;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -277,7 +262,4 @@ void val_clear(struct module_qstate* qstate, int id);
|
||||
*/
|
||||
size_t val_get_mem(struct module_env* env, int id);
|
||||
|
||||
/** Timer callback for msg signatures continue timer */
|
||||
void validate_suspend_timer_cb(void* arg);
|
||||
|
||||
#endif /* VALIDATOR_VALIDATOR_H */
|
||||
|
||||
Reference in New Issue
Block a user