Ondřej Surý [Thu, 11 Feb 2021 13:40:59 +0000 (14:40 +0100)]
Stop including gssapi.h from dst/gssapi.h header
The only reason for including the gssapi.h from the dst/gssapi.h header
was to get the typedefs of gss_cred_id_t and gss_ctx_id_t. Instead of
using those types directly this commit introduces dns_gss_cred_id_t and
dns_gss_ctx_id_t types that are being used in the public API and
privately retyped to their counterparts when we actually call the gss
api.
This also conceals the gssapi headers, so users of the libdns library
doesn't have to add GSSAPI_CFLAGS to the Makefile when including libdns
dst API.
Ondřej Surý [Thu, 11 Feb 2021 13:15:38 +0000 (14:15 +0100)]
Stop including lmdb.h from <dns/view.h>
The lmdb.h doesn't have to be included from the dns/view.h header as it
is separately included where used. This stops exposing the inclusion of
lmdb.h from the libdns headers.
Ondřej Surý [Thu, 11 Feb 2021 13:13:27 +0000 (14:13 +0100)]
Move the <isc/readline.h> header to bin/dig/readline.h
The <isc/readline.h> header provided a compatibility shim to use when
other non-GNU readline libraries are in use. The two places where
readline library is being used is nslookup and nsupdate, so the header
file has been moved to bin/dig directory and it's directly included from
bin/nsupdate.
This also conceals any readline headers exposed from the libisc headers.
Ondřej Surý [Thu, 11 Feb 2021 13:07:26 +0000 (14:07 +0100)]
Remove the extra CFLAGS from libisc_CFLAGS and libdns_CFLAGS
The extra library CFLAGS were causing the headers to be included in
wrong order possibly pulling header files from previously installed
BIND 9 version.
This commit cleans up the extra <foo>_CFLAGS from the includes in favor
of not exposing 3rd party headers in our own header files.
Diego Fronza [Thu, 11 Feb 2021 14:32:20 +0000 (11:32 -0300)]
Fix dangling references to outdated views after reconfig
This commit fix a leak which was happening every time an inline-signed
zone was added to the configuration, followed by a rndc reconfig.
During the reconfig process, the secure version of every inline-signed
zone was "moved" to a new view upon a reconfig and it "took the raw
version along", but only once the secure version was freed (at shutdown)
was prev_view for the raw version detached from, causing the old view to
be released as well.
This caused dangling references to be kept for the previous view, thus
keeping all resources used by that view in memory.
Michal Nowak [Wed, 30 Dec 2020 12:22:46 +0000 (13:22 +0100)]
Merge UNTESTED and SKIPPED system test results
Descriptions of UNTESTED and SKIPPED system test results are very
similar to one another and it may be confusing when to pick one and
when the other. Merging these two system test results removes the
confusion and also makes system test more aligned with Automake,
which does not know about UNTESTED test result.
Michal Nowak [Wed, 30 Dec 2020 12:23:18 +0000 (13:23 +0100)]
Record skipped test as skipped in testsuite summary
When system test execution was ported to Automake, SKIPPED and UNTESTED
system test result were not made to match Automake expectations,
therefore a skipped test is recorded by Automake as "PASS":
$ make check TESTS=cpu V=1
I:cpu:cpu test only runs on Linux, skipping test
I:cpu:Prerequisites missing, skipping test.
R:cpu:SKIPPED
E:cpu:2020-12-16T11:36:58+0000
PASS: cpu
====================================================================
Testsuite summary for BIND 9.17.7
====================================================================
# TOTAL: 1
# PASS: 1
For a test to be recorded by Automake as skipped, the test, or it's test
driver, needs to exit with code 77:
$ make check TESTS=cpu V=1
I:cpu:cpu test only runs on Linux, skipping test
I:cpu:Prerequisites missing, skipping test.
R:cpu:SKIPPED
E:cpu:2020-12-16T11:39:10+0000
SKIP: cpu
====================================================================
Testsuite summary for BIND 9.17.7
====================================================================
# TOTAL: 1
# PASS: 0
# SKIP: 1
Mark Andrews [Thu, 28 Jan 2021 23:12:14 +0000 (10:12 +1100)]
Address theoretical buffer overrun in recent change
The strlcat() call was wrong.
*** CID 316608: Memory - corruptions (OVERRUN)
/lib/dns/resolver.c: 5017 in fctx_create()
5011 * Make fctx->info point to a copy of a formatted string
5012 * "name/type".
5013 */
5014 dns_name_format(name, buf, sizeof(buf));
5015 dns_rdatatype_format(type, typebuf, sizeof(typebuf));
5016 p = strlcat(buf, "/", sizeof(buf));
>>> CID 316608: Memory - corruptions (OVERRUN)
>>> Calling "strlcat" with "buf + p" and "1036UL" is suspicious because "buf" points into a buffer of 1036 bytes and the function call may access "(char *)(buf + p) + 1035UL". [Note: The source code implementation of the function has been overridden by a builtin model.]
5017 strlcat(buf + p, typebuf, sizeof(buf));
5018 fctx->info = isc_mem_strdup(mctx, buf);
5019
5020 FCTXTRACE("create");
5021 dns_name_init(&fctx->name, NULL);
5022 dns_name_dup(name, mctx, &fctx->name);
Michal Nowak [Thu, 14 Jan 2021 11:09:04 +0000 (12:09 +0100)]
Add --enable-option-checking=fatal to ./configure in CI
The --enable-option-checking=fatal option prevents ./configure from
proceeding when an unknown option is used in the ./configure step in CI.
This change will avoid adding unsupported ./configure options or options
with typo or typo in pairwise testing "# [pairwise: ...]" marker.
Michal Nowak [Mon, 7 Dec 2020 17:08:53 +0000 (18:08 +0100)]
Lint manual pages
As we generate manual pages from reStructuredText sources, we don't have
absolute control on manual page output and therefore 'mandoc -Tlint' may
always report warnings we can't eliminate. In light of this some mandoc
warnings need to be ignored.
Michal Nowak [Wed, 3 Feb 2021 12:44:55 +0000 (13:44 +0100)]
Build man pages when "make doc" is run
Man pages are currently only generated from reStructuredText sources
when "make man" is run in the doc/man/ directory. Tweak
doc/man/Makefile.am so that running "make doc" in the top-level
directory also causes man pages to be generated, so that all potential
documentation building problems can be detected by a single make
invocation.
Mark Andrews [Wed, 27 Jan 2021 06:17:36 +0000 (17:17 +1100)]
Silence Insecure data handling (TAINTED_SCALAR)
Coverity assumes that the memory holding any value read using byte
swapping is tainted. As we store the NSEC3PARAM records in wire
form and iterations is byte swapped the memory holding the record
is marked as tainted. nsec3->salt_length is marked as tainted
transitively. To remove the taint the value need to be range checked.
For a correctly formatted record region.length should match
nsec3->salt_length and provides a convenient value to check the field
against.
*** CID 316507: Insecure data handling (TAINTED_SCALAR)
/lib/dns/rdata/generic/nsec3param_51.c: 241 in tostruct_nsec3param()
235 region.length = rdata->length;
236 nsec3param->hash = uint8_consume_fromregion(®ion);
237 nsec3param->flags = uint8_consume_fromregion(®ion);
238 nsec3param->iterations = uint16_consume_fromregion(®ion);
239
240 nsec3param->salt_length = uint8_consume_fromregion(®ion);
>>> CID 316507: Insecure data handling (TAINTED_SCALAR)
>>> Passing tainted expression "nsec3param->salt_length" to "mem_maybedup", which uses it as an offset.
241 nsec3param->salt = mem_maybedup(mctx, region.base,
242 nsec3param->salt_length);
243 if (nsec3param->salt == NULL) {
244 return (ISC_R_NOMEMORY);
245 }
246 isc_region_consume(®ion, nsec3param->salt_length);
Mark Andrews [Wed, 27 Jan 2021 06:11:52 +0000 (17:11 +1100)]
Silence Untrusted value as argument (TAINTED_SCALAR)
Coverity assumes that the memory holding any value read using byte
swapping is tainted. As we store the NSEC3 records in wire form
and iterations is byte swapped the memory holding the record is
marked as tainted. nsec3->salt_length and nsec3->next_length are
marked as tainted transitively. To remove the taint the values need
to be range checked. Valid values for these should never exceed
region.length so that is becomes a reasonable value to check against.
*** CID 316509: (TAINTED_SCALAR)
/lib/dns/rdata/generic/nsec3_50.c: 312 in tostruct_nsec3()
306 if (nsec3->salt == NULL) {
307 return (ISC_R_NOMEMORY);
308 }
309 isc_region_consume(®ion, nsec3->salt_length);
310
311 nsec3->next_length = uint8_consume_fromregion(®ion);
>>> CID 316509: (TAINTED_SCALAR)
>>> Passing tainted expression "nsec3->next_length" to "mem_maybedup", which uses it as an offset.
312 nsec3->next = mem_maybedup(mctx, region.base, nsec3->next_length);
313 if (nsec3->next == NULL) {
314 goto cleanup;
315 }
316 isc_region_consume(®ion, nsec3->next_length);
317
/lib/dns/rdata/generic/nsec3_50.c: 305 in tostruct_nsec3()
299 region.length = rdata->length;
300 nsec3->hash = uint8_consume_fromregion(®ion);
301 nsec3->flags = uint8_consume_fromregion(®ion);
302 nsec3->iterations = uint16_consume_fromregion(®ion);
303
304 nsec3->salt_length = uint8_consume_fromregion(®ion);
>>> CID 316509: (TAINTED_SCALAR)
>>> Passing tainted expression "nsec3->salt_length" to "mem_maybedup", which uses it as an offset.
305 nsec3->salt = mem_maybedup(mctx, region.base, nsec3->salt_length);
306 if (nsec3->salt == NULL) {
307 return (ISC_R_NOMEMORY);
308 }
309 isc_region_consume(®ion, nsec3->salt_length);
310
Mark Andrews [Mon, 1 Feb 2021 00:43:45 +0000 (11:43 +1100)]
Fix wrong length passed to isc_mem_put
If an invalid key name (e.g. "a..b") in a primaries list in named.conf
is specified the wrong size is passed to isc_mem_put resulting in the
returned memory being put on the wrong freed list.
*** CID 316784: Incorrect expression (SIZEOF_MISMATCH)
/bin/named/config.c: 636 in named_config_getname()
630 isc_buffer_constinit(&b, objstr, strlen(objstr));
631 isc_buffer_add(&b, strlen(objstr));
632 dns_fixedname_init(&fname);
633 result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname,
634 0, NULL);
635 if (result != ISC_R_SUCCESS) {
CID 316784: Incorrect expression (SIZEOF_MISMATCH)
Passing argument "*namep" of type "dns_name_t *" and argument "8UL /* sizeof (*namep) */" to function "isc__mem_put" is suspicious.
636 isc_mem_put(mctx, *namep, sizeof(*namep));
637 *namep = NULL;
638 return (result);
639 }
640 dns_name_dup(dns_fixedname_name(&fname), mctx, *namep);
641
Test for Ed25519 and Ed448. If both algorithms are not supported, skip
test. If only one algorithm is supported, run test, skip the
unsupported algorithm. If both are supported, run test normally.
Create new ns3. This will test Ed448 specifically, while now ns2 only
tests Ed25519. This moves some files from ns2/ to ns3/.
The number of queries to use in the burst can be reduced, as we have
a very low fetch limit of 1.
The dig command in 'wait_for_fetchlimits()' should time out sooner as
we expect a SERVFAIL to be returned promptly.
Enabling serve-stale can be done before hitting fetch-limits. This
reduces the chance that the resolver queries time out and fetch count
is reset. The chance of that happening is already slim because
'resolver-query-timeout' is 10 seconds, but better to first let the
data become stale rather than doing that while attempting to resolve.
The 'query_usestale()' function was only called when in
'query_gotanswer()' and an unexpected error occurred. This may have
been "quota reached", and thus we were in some cases returning
stale data on fetch-limits (and if serve-stale enabled of course).
But we can also hit fetch-limits when recursing because we are
following a referral (in 'query_notfound()' and
'query_delegation_recurse()'). Here we should also check for using
stale data in case an error occurred.
Specifically don't check for using stale data when refetching a
zero TTL RRset from cache.
Move the setting of DNS_DBFIND_STALESTART into the 'query_usestale()'
function to avoid code duplication.
Mark Andrews [Wed, 3 Feb 2021 06:20:09 +0000 (17:20 +1100)]
Attempt to silence untrusted loop bound
Assign hit_len + key_len to len and test the result
rather than recomputing and letting the compiler simplify.
213 isc_region_consume(®ion, 2); /* hit length + algorithm */
9. tainted_return_value: Function uint16_fromregion returns tainted data. [show details]
10. tainted_data_transitive: Call to function uint16_fromregion with tainted argument *region.base returns tainted data.
11. tainted_return_value: Function uint16_fromregion returns tainted data.
12. tainted_data_transitive: Call to function uint16_fromregion with tainted argument *region.base returns tainted data.
13. var_assign: Assigning: key_len = uint16_fromregion(®ion), which taints key_len.
214 key_len = uint16_fromregion(®ion);
14. lower_bounds: Casting narrower unsigned key_len to wider signed type int effectively tests its lower bound.
15. Condition key_len == 0, taking false branch.
215 if (key_len == 0) {
216 RETERR(DNS_R_FORMERR);
217 }
16. Condition !!(_r->length >= _l), taking true branch.
17. Condition !!(_r->length >= _l), taking true branch.
218 isc_region_consume(®ion, 2);
18. lower_bounds: Casting narrower unsigned key_len to wider signed type int effectively tests its lower bound.
19. Condition region.length < (unsigned int)(hit_len + key_len), taking false branch.
219 if (region.length < (unsigned)(hit_len + key_len)) {
220 RETERR(DNS_R_FORMERR);
221 }
222
20. lower_bounds: Casting narrower unsigned key_len to wider signed type int effectively tests its lower bound.
21. Condition _r != 0, taking false branch.
223 RETERR(mem_tobuffer(target, rr.base, 4 + hit_len + key_len));
22. lower_bounds: Casting narrower unsigned key_len to wider signed type int effectively tests its lower bound.
23. var_assign_var: Compound assignment involving tainted variable 4 + hit_len + key_len to variable source->current taints source->current.
224 isc_buffer_forward(source, 4 + hit_len + key_len);
225
226 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
CID 281461 (#1 of 1): Untrusted loop bound (TAINTED_SCALAR)
24. tainted_data: Using tainted variable source->active - source->current as a loop boundary.
Ensure that tainted values are properly sanitized, by checking that their values are within a permissible range.
227 while (isc_buffer_activelength(source) > 0) {
228 dns_name_init(&name, NULL);
229 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
230 }
1. Remove an unused keystr/dst_key_format.
2. Initialize a dst_key_state_t state with NA.
3. Update false comment about local policy (local policy only adds
barrier on transitions to the RUMOURED state, not the UNRETENTIVE
state).
There was a bug in function 'keymgr_ds_hidden_or_chained()'.
The funcion 'keymgr_ds_hidden_or_chained()' implements (3e) of rule2
as defined in the "Flexible and Robust Key Rollover" paper. The rules
says: All DS records need to be in the HIDDEN state, or if it is not
there must be a key with its DNSKEY and KRRSIG in OMNIPRESENT, and
its DS in the same state as the key in question. In human langauge,
if all keys have their DS in HIDDEN state you can do what you want,
but if a DS record is available to some validators, there must be
a chain of trust for it.
Note that the barriers on transitions first check if the current
state is valid, and then if the next state is valid too. But
here we falsely updated the 'dnskey_omnipresent' (now 'dnskey_chained')
with the next state. The next state applies to 'key' not to the state
to be checked. Updating the state here leads to (true) always, because
the key that will move its state will match the falsely updated
expected state. This could lead to the assumption that Key 2 would be
a valid chain of trust for Key 1, while clearly the presence of any
DS is uncertain.
The fix here is to check if the DNSKEY and KRRSIG are in OMNIPRESENT
state for the key that does not have its DS in the HIDDEN state, and
only if that is not the case, ensure that there is a key with the same
algorithm, that provides a valid chain of trust, that is, has its
DNSKEY, KRRSIG, and DS in OMNIPRESENT state.
The changes in 'keymgr_dnskey_hidden_or_chained()' are only cosmetical,
renaming 'rrsig_omnipresent' to 'rrsig_chained' and removing the
redundant initialization of the DST_KEY_DNSKEY expected state to NA.
The previous commit changed the function definition of
'keymgr_key_is_successor()', this commit updates the code where
this function is called.
In 'keymgr_key_exists_with_state()' the logic is also updated slightly
to become more readable. First handle the easy cases:
- If the key does not match the state, continue with the next key.
- If we found a key with matching state, and there is no need to
check the successor relationship, return (true).
- Otherwise check the successor relationship.
In 'keymgr_key_has_successor()' it is enough to check if a key has
a direct successor, so instead of calling 'keymgr_key_is_successor()',
we can just check 'keymgr_direct_dep()'.
In 'dns_keymgr_run()', we want to make sure that there is no
dependency on the keys before retiring excess keys, so replace
'keymgr_key_is_successor()' with 'keymgr_dep()'.
So far the key manager could only deal with two keys in a rollover,
because it used a simplified version of the successor relationship
equation from "Flexible and Robust Key Rollover" paper. The simplified
version assumes only two keys take part in the key rollover and it
for that it is enough to check the direct relationship between two
keys (is key x the direct predecessor of key z and is key z the direct
successor of key x?).
But when a third key (or more keys) comes into the equation, the key
manager would assume that one key (or more) is redundant and removed
it from the zone prematurely.
Fix by implementing Equation(2) correctly, where we check for
dependencies on keys:
z ->T x: Dep(x, T) = ∅ ∧
(x ∈ Dep(z, T) ∨
∃ y ∈ Dep(z, T)(y != z ∧ y ->T x ∧ DyKyRySy = DzKzRzSz))
This says: key z is a successor of key x if:
- key x depends on key z if z is a direct successor of x,
- or if there is another key y that depends on key z that has identical
key states as key z and key y is a successor of key x.
- Also, key x may not have any other keys depending on it.
This is still a simplified version of Equation(2) (but at least much
better), because the paper allows for a set of keys to depend on a
key. This is defined as the set Dep(x, T). Keys in the set Dep(x, T)
have a dependency on key x for record type T. The BIND implementation
can only have one key in the set Dep(x, T). The function
'keymgr_dep()' stores this key in 'uint32_t *dep' if there is a
dependency.
There are two scenarios where multiple keys can depend on a single key:
1. Rolling keys is faster than the time required to finish the
rollover procedure. This scenario is covered by the recursive
implementation, and checking for a chain of direct dependencies
will suffice.
2. Changing the policy, when a zone is requested to be signed with
a different key length for example. BIND 9 will not mark successor
relationships in this case, but tries to move towards the new
policy. Since there is no successor relationship, the rules are
even more strict, and the DNSSEC reconfiguration is actually slower
than required.
Note: this commit breaks the build, because the function definition
of 'keymgr_key_is_successor' changed. This will be fixed in the
following commit.
Mark Andrews [Wed, 3 Feb 2021 05:38:29 +0000 (16:38 +1100)]
Remove redundant 'version == NULL' check
*** CID 318094: Null pointer dereferences (REVERSE_INULL)
/lib/dns/rbtdb.c: 1389 in newversion()
1383 version->xfrsize = rbtdb->current_version->xfrsize;
1384 RWUNLOCK(&rbtdb->current_version->rwlock, isc_rwlocktype_read);
1385 rbtdb->next_serial++;
1386 rbtdb->future_version = version;
1387 RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
1388
CID 318094: Null pointer dereferences (REVERSE_INULL)
Null-checking "version" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
1389 if (version == NULL) {
1390 return (result);
1391 }
1392
1393 *versionp = version;
1394
Ondřej Surý [Wed, 3 Feb 2021 09:27:45 +0000 (10:27 +0100)]
Drop gcc:sid:i386 from GitLab CI
Building sid-i386 in Docker no longer works and we don't have a viable
alternative now, so dropping gcc:sid:i386 is our only option in this
very moment.
Evan Hunt [Wed, 3 Feb 2021 06:05:00 +0000 (22:05 -0800)]
tls and http configuration code was unnecessarily complex
removed the isc_cfg_http_t and isc_cfg_tls_t structures
and the functions that loaded and accessed them; this can
be done using normal config parser functions.
Ondřej Surý [Tue, 2 Feb 2021 08:28:23 +0000 (09:28 +0100)]
Unit-test fixes and manual page updates for DoH configuration
This commit contains fixes to unit tests to make them work well on
various platforms (in particular ones shipping old versions of
OpenSSL) and for different configurations.
It also updates the generated manpage to include DoH configuration
options.
Artem Boldariev [Mon, 7 Dec 2020 12:19:10 +0000 (14:19 +0200)]
Initial support for DNS-over-HTTP(S)
This commit completes the support for DNS-over-HTTP(S) built on top of
nghttp2 and plugs it into the BIND. Support for both GET and POST
requests is present, as required by RFC8484.
Both encrypted (via TLS) and unencrypted HTTP/2 connections are
supported. The latter are mostly there for debugging/troubleshooting
purposes and for the means of encryption offloading to third-party
software (as might be desirable in some environments to simplify TLS
certificates management).
This commit adds stub parser support and tests for:
- an "http" global option for HTTP/2 endpoint configuration.
- command line options to set http or https port numbers by
specifying -p http=PORT or -p https=PORT. (NOTE: this change
only affects syntax; specifying HTTP and HTTPS ports on the
command line currently has no effect.)
- named.conf options "http-port" and "https-port"
- HTTPSPORT environment variable for use when running tests.
Michał Kępień [Wed, 3 Feb 2021 10:44:02 +0000 (11:44 +0100)]
Make sphinx-build warnings fatal
In order to prevent documentation building issues from being glossed
over, pass the -W command line switch to all sphinx-build invocations.
This causes the latter to return with a non-zero exit code whenever any
Sphinx warnings are triggered.
Michał Kępień [Wed, 3 Feb 2021 10:44:02 +0000 (11:44 +0100)]
Address a Sphinx duplicate label warning
Both doc/man/ddns-confgen.rst and doc/man/tsig-keygen.rst include
bin/confgen/tsig-keygen.rst, which defines a "man_tsig-keygen" label.
This triggers the following warning when running sphinx-build with the
-W command line switch in the doc/man/ directory:
../../bin/confgen/tsig-keygen.rst:27: WARNING: duplicate label man_tsig-keygen, other instance in /tmp/bind9/doc/man/ddns-confgen.rst
Move the offending label from bin/confgen/tsig-keygen.rst to the proper
spot in doc/arm/manpages.rst to avoid effectively defining it twice in
different source documents while still allowing the relevant man page to
be referenced in the ARM. Also rename that label so that it more
closely matches the content it points to. As the label no longer
immediately precedes a section title in its new location, use
:ref:`Title <label>` syntax for the only reference to the
tsig-keygen/ddns-confgen man page in the ARM.
Michał Kępień [Wed, 3 Feb 2021 10:44:02 +0000 (11:44 +0100)]
Use separate sphinx-build cache directories
Simultaneously starting multiple sphinx-build instances with the -d
command line switch set to a common value (which is what happens when
e.g. "make -j6 doc" is run) causes intermittent problems which we failed
to notice before because they only trigger Sphinx warnings, not errors,
e.g.:
WARNING: toctree contains ref to nonexisting file 'reference'
The message above is not triggered because doc/arm/reference.rst is
actually missing from disk at any point, but rather because a temporary
file created by one sphinx-build instance gets truncated by another one
working in parallel (the confusing message quoted above is logged
because of an overly broad "except" statement in Sphinx code).
Prevent this problem from being triggered by making each sphinx-build
process use its own dedicated cache directory.
Matthijs Mekking [Tue, 26 Jan 2021 10:32:24 +0000 (11:32 +0100)]
Correctly initialize old key with state file
The 'key_init()' function is used to initialize a state file for keys
that don't have one yet. This can happen if you are migrating from a
'auto-dnssec' or 'inline-signing' to a 'dnssec-policy' configuration.
It did not look at the "Inactive" and "Delete" timing metadata and so
old keys left behind in the key directory would also be considered as
a possible active key. This commit fixes this and now explicitly sets
the key goal to OMNIPRESENT for keys that have their "Active/Publish"
timing metadata in the past, but their "Inactive/Delete" timing
metadata in the future. If the "Inactive/Delete" timing metadata is
also in the past, the key goal is set to HIDDEN.
If the "Inactive/Delete" timing metadata is in the past, also the
key states are adjusted to either UNRETENTIVE or HIDDEN, depending on
how far in the past the metadata is set.
Matthijs Mekking [Tue, 26 Jan 2021 10:24:40 +0000 (11:24 +0100)]
Update legacy-keys kasp test
The 'legacy-keys.kasp' test checks that a zone with key files but not
yet state files is signed correctly. This test is expanded to cover
the case where old key files still exist in the key directory. This
covers bug #2406 where keys with the "Delete" timing metadata are
picked up by the keymgr as active keys.
Fix the 'legacy-keys.kasp' test, by creating the right key files
(for zone 'legacy-keys.kasp', not 'legacy,kasp').
Use a unique policy for this zone, using shorter lifetimes.
Create two more keys for the zone, and use 'dnssec-settime' to set
the timing metadata in the past, long enough ago so that the keys
should not be considered by the keymgr.
Update the 'key_unused()' test function, and consider keys with
their "Delete" timing metadata in the past as unused.
Extend the test to ensure that the keys to be used are not the old
predecessor keys (with their "Delete" timing metadata in the past).
Update the test so that the checks performed are consistent with the
newly configured policy.
Ondřej Surý [Thu, 14 Jan 2021 11:51:25 +0000 (12:51 +0100)]
implement xfrin via XoT
Add support for a "tls" key/value pair for zone primaries, referencing
either a "tls" configuration statement or "ephemeral". If set to use
TLS, zones will send SOA and AXFR/IXFR queries over a TLS channel.
Diego Fronza [Wed, 27 Jan 2021 22:09:46 +0000 (19:09 -0300)]
Fix race condition on check_stale_header
This commit fix a race that could happen when two or more threads have
failed to refresh the same RRset, the threads could simultaneously
attempt to update the header->last_refresh_fail_ts field in
check_stale_header, a field used to implement stale-refresh-time.
Matthijs Mekking [Thu, 28 Jan 2021 11:30:08 +0000 (12:30 +0100)]
Add test for serve-stale /w fetch-limits
Add a test case when fetch-limits are reached and we have stale data
in cache.
This test starts with a positive answer for 'data.example/TXT' in
cache.
1. Reload named.conf to set fetch limits.
2. Disable responses from the authoritative server.
3. Now send a batch of queries to the resolver, until hitting the
fetch limits. We can detect this by looking at the response RCODE,
at some point we will see SERVFAIL responses.
4. At that point we will turn on serve-stale.
5. Clients should see stale answers now.
6. An incoming query should not set the stale-refresh-time window,
so a following query should still get a stale answer because of a
resolver failure (and not because it was in the stale-refresh-time
window).
Matthijs Mekking [Wed, 27 Jan 2021 15:59:27 +0000 (16:59 +0100)]
Only start stale refresh window when resuming
If we did not attempt a fetch due to fetch-limits, we should not start
the stale-refresh-time window.
Introduce a new flag DNS_DBFIND_STALESTART to differentiate between
a resolver failure and unexpected error. If we are resuming, this
indicates a resolver failure, then start the stale-refresh-time window,
otherwise don't start the stale-refresh-time window, but still fall
back to using stale data.
(This commit also wraps some docstrings to 80 characters width)
Matthijs Mekking [Tue, 19 Jan 2021 08:04:29 +0000 (09:04 +0100)]
Use stale data also if we are not resuming
Before this change, BIND will only fallback to using stale data if
there was an actual attempt to resolve the query. Then on a timeout,
the stale data from cache becomes eligible.
This commit changes this so that on any unexpected error stale data
becomes eligble (you would still have to have 'stale-answer-enable'
enabled of course).
If there is no stale data, this may return in an error again, so don't
loop on stale data lookup attempts. If the DNS_DBFIND_STALEOK flag is
set, this means we already tried to lookup stale data, so if that is
the case, don't use stale again.