Compare commits

...
Author SHA1 Message Date
Matthijs Mekking f089e25217 Add unit test case for issue #4702
Add the found erroneous case to the unit tests.
2024-04-30 17:39:39 +02:00
Matthijs Mekking 1fa199fba2 Add a unit test case for converting \000\009
Sanity checking that this domain converts to the key I am expecting.

Also fix some of the other names that had trailing 0x02 bits.
2024-04-30 17:38:26 +02:00
Michał Kępień 29cef34a34 Merge branch 'michal/update-urls-and-paths-for-the-bind-9-qa-repository' into 'main'
Update URLs and paths for the BIND 9 QA repository

See merge request isc-projects/bind9!8990
2024-04-29 09:48:06 +00:00
Michał Kępień 25ec1d79e4 Update URLs and paths for the BIND 9 QA repository
Since the BIND 9 QA repository has been made public, adjust the relevant
URLs and paths used in .gitlab-ci.yml so that they work with the public
version of that repository.
2024-04-26 18:43:07 +02:00
Aydın Mercan 79573f1390 Merge branch '4523-dnstap-support-for-new-transport-protocols' into 'main'
Emit and read correct DoT and DoH dnstap entries

Closes #4523

See merge request isc-projects/bind9!8697
2024-04-26 15:47:46 +00:00
Aydın Mercan 042bb98846 Add CHANGES and release note for [GL #4523] 2024-04-26 16:12:29 +03:00
Aydın Mercan f30008a71c Provide an early escape hatch for ns_client_transport_type
Because some tests don't have a legtimate handle, provide a temporary
return early that should be fixed and removed before squashing. This
short circuiting is still correct until DoQ/DoH3 support is introduced.
2024-04-26 16:12:29 +03:00
Aydın Mercan b5478654a2 Add fallback to ns_client_get_type despite unreachable
GCC might fail to compile because it expects a return after UNREACHABLE.
It should ideally just work anyway since UNREACHABLE is either a
noreturn or UB (__builtin_unreachable / C23 unreachable).

Either way, it should be optimized almost always so the fallback is
free or basically free anyway when it isn't optimized out.
2024-04-26 16:12:29 +03:00
Aydın Mercan 4a3f7fe1ef Emit and read correct DoT and DoH dnstap entries
Other protocols still pretend to be TCP/UDP.
This only causes a difference when using dnstap-read on a file with DoQ
or DNSCrypt entries
2024-04-26 16:12:29 +03:00
Aydın Mercan 9d1a8a98c6 Update the dnstap protobuf definition
The new definition includes the missing protocol definitions and
specifies the protobuf version.
2024-04-26 16:08:46 +03:00
Evan Hunt 657ee2b997 Merge branch 'each-qpzone-oneheap' into 'main'
simplify qpzone database by using only one heap for resigning

See merge request isc-projects/bind9!8889
2024-04-26 01:19:42 +00:00
Ondřej SurýandEvan Hunt 6c54337f52 avoid a race in the qpzone getsigningtime() implementation
the previous commit introduced a possible race in getsigningtime()
where the rdataset header could change between being found on the
heap and being bound.

getsigningtime() now looks at the first element of the heap, gathers the
locknum, locks the respective lock, and retrieves the header from the
heap again.  If the locknum has changed, it will rinse and repeat.
Theoretically, this could spin forever, but practically, it almost never
will as the heap changes on the zone are very rare.

we simplify matters further by changing the dns_db_getsigningtime()
API call. instead of passing back a bound rdataset, we pass back the
information the caller actually needed: the resigning time, owner name
and type of the rdataset that was first on the heap.
2024-04-25 15:48:43 -07:00
Evan Hunt 7e6be9f1b5 simplify qpzone database by using only one heap for resigning
in RBTDB, the heap was used by zone databases for resigning, and
by the cache for TTL-based cache cleaning. the cache use case required
very frequent updates, so there was a separate heap for each of the
node lock buckets.

qpzone is for zones only, so it doesn't need to support the cache
use case; the heap will only be touched when the zone is updated or
incrementally signed. we can simplify the code by using only a single
heap.
2024-04-25 15:41:39 -07:00
Evan Hunt 7d289e5333 Merge branch '4659-rootkeysentinel-test-fails-for-certain-values-of-oldid' into 'main'
fix_iterator() bug causes DNSSEC NXDOMAIN responses to be broken

Closes #4659

See merge request isc-projects/bind9!8942
2024-04-25 18:10:29 +00:00
Evan Hunt 6f4ef40ccd CHANGES for [GL #4659] 2024-04-25 10:30:47 -07:00
Evan Hunt 237123e500 simplify code by removing return values where possible
fix_iterator() and related functions are quite difficult to read.
perhaps it would be a little clearer if we didn't assign values
to variables that won't subsequently be used, or unnecessarily
pop the stack and then push the same value back onto it.

also, in dns_qp_lookup() we previously called fix_iterator(),
removed the leaf from the top of the iterator stack, and then
added it back on. this would be clearer if we just push the leaf
onto the stack when we need to, but leave the stack alone when
it's already complete.
2024-04-25 10:29:07 -07:00
Evan Hunt b1b1ca8ca4 add another broken testcase 2024-04-25 10:29:07 -07:00
Evan Hunt 66dbff596b clean up fix_iterator() arguments
the value passed as 'start' was redundant; it's always the same
as the current top of the iterator stack.
2024-04-25 10:29:07 -07:00
Evan Hunt 2dff926624 yet another fix_iterator() bug
under some circumstances it was possible for the iterator to
be set to the first leaf in a set of twigs, when it should have
been set to the last.

a unit test has been added to test this scenario. if there is a
a tree containing the following values: {".", "abb.", "abc."}, and
we query for "acb.", previously the iterator would be positioned at
"abb." instead of "abc.".

the tree structure is:
    branch (offset 1, ".")
      branch (offset 3, ".ab")
        leaf (".abb")
        leaf (".abc")

we find the branch with offset 3 (indicating that its twigs differ
from each other in the third position of the label, "abB" vs "abC").
but the search key differs from the found keys at position 2
("aC" vs "aB").  we look up the bit value in position 3 of the
search key ("B"), and incorrectly follow it onto the wrong twig
("abB").

to correct for this, we need to check for the case where the search
key is greater than the found key in a position earlier than the
branch offset. if it is, then we need to pop from the current leaf
to its parent, and get the greatest leaf from there.

a further change is needed to ensure that we don't do this twice;
when we've moved to a new leaf and the point of difference between
it and the search key even earlier than before, then we're definitely
at a predecessor node and there's no need to continue the loop.
2024-04-25 10:29:07 -07:00
Michal Nowak b1184d916d Merge branch 'mnowak/fix-changes-entry-6378' into 'main'
Reformat overflowing CHANGES entry 6378

See merge request isc-projects/bind9!8981
2024-04-25 07:31:29 +00:00
Michal Nowak 84180c8ee1 Reformat overflowing CHANGES entry 6378
$ sh util/check-line-length.sh CHANGES
    CHANGES: Line Too Long
                            previously removed. An attempt to use the option now prints
2024-04-25 09:22:27 +02:00
Ondřej Surý 1359694267 Merge branch '1879-fix-documentation-on-named--U' into 'main'
Properly document that named -U <n> is no-op now

Closes #1879

See merge request isc-projects/bind9!8976
2024-04-24 20:50:09 +00:00
Ondřej Surý 9305ebdabe Add CHANGES and release note for [GL #1879] 2024-04-24 22:49:26 +02:00
Ondřej Surý d69cd51f91 Properly document that named -U <n> is no-op now
We don't create <n> UDP dispatches anymore and -U <n> option to named is
a no-op for a while.  Properly document that in the named man page.
2024-04-24 22:49:14 +02:00
Petr Špaček 0f86976672 Merge branch 'spdx-custom-test-driver' into 'main'
Use standard SPDX license for custom-test-driver

See merge request isc-projects/bind9!8971
2024-04-24 09:49:44 +00:00
Petr MenšíkandPetr Špaček 2b348a5daa Change exception SPDX to Autoconf-exception-generic
License text is in fact Autoconf generic exception, with already defined
SPDX identificator. Use that instead.

https://spdx.org/licenses/Autoconf-exception-generic.html
2024-04-24 09:46:58 +00:00
Mark Andrews ed77b61599 Merge branch '4684-unit-test-error-handling-in-dns_name_-api' into 'main'
test dns_name_fromregion

Closes #4684

See merge request isc-projects/bind9!8967
2024-04-24 02:14:05 +00:00
Mark Andrews e6984e5c07 Extract empty name in 'source' into 'name' 2024-04-24 01:38:14 +00:00
Mark Andrews 7a13fcd601 Extract non absolute name from source
The entire source region needs to be consumed for this usage.
2024-04-24 01:38:14 +00:00
Mark Andrews 7d7fc8cb2d Extract fully qualified named from source without buffer
'name.ndata' should point to the source.
2024-04-24 01:38:14 +00:00
Mark Andrews 254ba1b051 Test dns_name_fromregion
with a large source region and a large target buffer, both
larger than DNS_NAME_MAXWIRE.
2024-04-24 01:38:14 +00:00
Mark Andrews 63b93ccda2 Merge branch '4689-test-invalid-notify-source-address' into 'main'
Check behaviour using invalid notify source address

Closes #4689

See merge request isc-projects/bind9!8966
2024-04-24 01:09:35 +00:00
Mark Andrews 580c41de0d check behaviour with invalid notify-source-v6 address
This was reported as causing the server to fail to shutdown on
NetBSD.  Look for the expected informational and error messages.
2024-04-24 10:12:42 +10:00
Michal Nowak 4f7947c583 Merge branch 'mnowak/llvm-18' into 'main'
Bump the LLVM version to 18 and reformat sources

See merge request isc-projects/bind9!8827
2024-04-23 12:48:22 +00:00
Michal Nowak f454fa6dea Update sources to Clang 18 formatting 2024-04-23 13:11:52 +02:00
Michal Nowak 7107c44c7c Update Clang to version 18 2024-04-23 13:11:52 +02:00
Ondřej Surý abbc59a270 Merge branch 'ondrej/fix-adb-entries-cleaning' into 'main'
Always set ADB entry expiration to now + ADB_ENTRY_WINDOW

See merge request isc-projects/bind9!8934
2024-04-22 08:37:45 +00:00
Ondřej Surý 141e4c9805 Change the ADB_ENTRY_WINDOW to 60 seconds
The previous value of 30 minutes used to cache the ADB names and entries
was quite long.  Change the value to 60 seconds for faster recovery
after cached intermittent failure of the remote nameservers.
2024-04-22 10:36:36 +02:00
Ondřej Surý 6708da3112 Unify the expiration time handling for all ADB expiration
The algorithm from the previous commit[1] is now used to calculate all
the expiration values through the code (ncache results, cname/dname
targets).

1. ISC_MIN(cur, ISC_MAX(now + ADB_ENTRY_WINDOW, now + rdataset->ttl))
2024-04-22 10:36:36 +02:00
Ondřej Surý 53cc00ee3f Fix the expire_v4 and expire_v6 logic
Correct the logic to set the expiration period of expire_{v4,v6} as
follows:

1. If the trust is ultimate (local entry), immediately set the entry as
   expired, so the changes to the local zones have immediate effect.

3. If the expiration is already set and smaller than the new value, then
   leave the expiration value as it is.

2. Otherwise pick larger of `now + ADB_ENTRY_WINDOW` and `now + TTL` as
   the new expiration value.
2024-04-22 10:36:36 +02:00
Ondřej Surý 932665410d Always set ADB entry expiration to now + ADB_ENTRY_WINDOW
When ADB entry was created it was set to never expire.  If we never
called any of the functions that adjust the expiration, it could linger
in the ADB forever.

Set the expiration (.expires) to now + ADB_ENTRY_WINDOW when creating
the new ADB entry to ensure the ADB entry will always expire.
2024-04-22 10:36:36 +02:00
Mark Andrews 6cb6b99ae7 Merge branch '4687-validator-c-1280-insist-val-nfails-0-failed' into 'main'
Resolve "validator.c:1280: INSIST((*val->nfails) > 0) failed"

Closes #4687

See merge request isc-projects/bind9!8963
2024-04-22 04:57:45 +00:00
Mark Andrews 26375bdcf2 Break out of the switch if we have already reached the quota
This prevents consume_validation_fail being called and causing an
INSIST.
2024-04-22 12:32:36 +10:00
Michal Nowak 970ac03196 Merge branch 'mnowak/drop-respdiff-short-ci-jobs' into 'main'
Drop respdiff-short CI jobs

See merge request isc-projects/bind9!8958
2024-04-19 15:56:00 +00:00
Michal Nowak 6a045cd8ec Drop respdiff-short CI jobs
In the past, our CI infrastructure was more sensitive to the number of
CI jobs running on it. We tried to limit long-running jobs in merge
request-triggered pipelines, as there are many of them, and spawned them
only in daily scheduled ones. Moving most of the CI infrastructure to
AWS has made it way better to run jobs in parallel, and the existence of
short respdiff jobs has lost its original merit. It can also be harmful
as some problems are detected only by the longer respdiff variant when a
faulty merge request has already been merged. We should run all long
respdiff tests in merge request-triggered pipelines.

Also, move the former respdiff-long job (now just "respdiff") to AWS as
old instance memory constraints (see
f09cf69594) are no longer an issue.
2024-04-19 16:42:49 +02:00
Petr Špaček c35f00e48a Merge branch 'pspacek/auto-backports' into 'main'
Attempt automatic MR backports after every merge

See merge request isc-projects/bind9!8959
2024-04-19 13:40:51 +00:00
Petr Špaček 49f9487577 Attempt automatic MR backports after every merge 2024-04-19 13:35:19 +00:00
Matthijs Mekking b53c03d98e Merge branch '1128-offline-ksk' into 'main'
Introduce new DNSSEC tool dnssec-ksr

See merge request isc-projects/bind9!8188
2024-04-19 11:56:50 +00:00
Matthijs Mekking afda87cb08 dnssec-keygen: Change flag options into booleans
We now have ctx.kskflag, ctx.zskflag, and ctx.revflag, but zskflag is
not quite like the other two, as it doesn't have a special bit in the
DNS packet, and is used as a boolean.

This patch changes so that we use booleans for all three, and
construct the flags based on which ones are set.

patch by @aram
2024-04-19 13:52:21 +02:00
Matthijs Mekking 7007025302 Don't leak
Make tsan happy, fix memory leaks by keeping track of the buffers
to be cleaned up.
2024-04-19 13:52:21 +02:00
Matthijs Mekking d9c947c57d Add test cases for CDS/CDNSKEY
Add two more test cases to ensure that a Signed Key Response file
creates signed CDNSKEY and/or CDS RRsets according to the policy.
2024-04-19 13:52:21 +02:00
Matthijs Mekking cdf0fd2e5e Adjust system test to expect CDS and CDNSKEY
Requires storing the KSK keyfile identifier to calculate the expected
CDS and CDNSKEY.
2024-04-19 13:52:21 +02:00
Matthijs Mekking 83da52d6e4 Add option to dnssec-dsfromkey to chop up rdata
The new option 'w' allows us to print DS rdata with the base64 portions
split up in chunks. This is mainly done for testing purposes.
2024-04-19 13:52:21 +02:00
Matthijs Mekking efe4fa6fc7 Add CDS and CDNSKEY to SKR
Add signed CDS and CDNSKEY RRsets to the Signed Key Response (SKR) for the
used KSKs.

We only print one bundle header for all three RRsets.
2024-04-19 13:52:21 +02:00
Matthijs Mekking 46785dc71e sh the fmt up
Apply shfmt patch. Ideally I fixup every commit that changes testing,
but that is just too much at this point.
2024-04-19 13:52:21 +02:00
Matthijs Mekking e7525cab4f Add CHANGES and release note
Introduce the new 'dnssec-ksr' tool.
2024-04-19 13:52:21 +02:00
Matthijs Mekking 695be761b0 Test dnssec-ksr sign
Add test cases for the 'sign' command. Reuse the earlier generated KSR
files.

Also update dnssec-ksr.c to have better cleanup.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 887fa0ddc9 Implement dnssec-ksr sign
Add code that can create a Signed Key Response (SKR) given a Key
Signing Request (KSR), a DNSSEC policy, a set of keys and an interval.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 31521fade2 Change ksr format
Make the ksr format compatible with knot.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 2bf03ab7df Refactor dnssec-ksr
Refactor some more, making the cleanup a generic function.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 852ba174dd Test dnssec-ksr request
Add test cases for the 'request' command. Reuse the earlier
pregenerated ZSKs. We also need to set up some KSK files, that can
be done with 'dnssec-keygen -k <policy> -fK' now.

The 'check_keys()' function is adjusted such that the expected active
time of the successor key is set to the inactive time of the
predecessor. Some additional information is saved to make 'request'
testing easier.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 1b39172ee7 Implement dnssec-ksr request
Add code that can create a Key Signing Request (KSR) given a DNSSEC
policy, a set of keys and an interval.

Multiple keys that match the bundle and kasp parameters are sorted by
keytag, mainly for testing purposes.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 22a4bd5bbe Also free the dst_key after keygen
During cleanup, we also need to free the dst_key structure that is part
of the dns_dnsseckey.
2024-04-19 10:41:04 +02:00
Matthijs Mekking ed9704fcda Refactor dnssec-ksr keygen
Create some helper functions for code that is going to be reused by the
other commands (request, sign), such as setting and checking the context
parameters, and retrieving the dnssec-policy/kasp.
2024-04-19 10:41:04 +02:00
Matthijs Mekking e033e58a85 dnssec-keygen: allow -f and -k together
The 'dnssec-keygen' tool now allows the options '-k <dnssec-policy>'
and '-f <flags>' together to create keys from a DNSSEC policy that only
match the given role. Allow setting '-fZ' to only create ZSKs, while
'-fK' will only create KSKs.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 7508534789 Implement dnssec-ksr keygen
Add code that can pregenerate ZSKs given a DNSSEC policy and an
interval.

Fix configuration shell scripts, fixing the ksr system test.
2024-04-19 10:41:04 +02:00
Matthijs Mekking a3915e535a Move kasp key match function to kasp header
The dnssec-ksr tool needs to check if existing key files match lines
in the keys section of a dnssec-policy, so make this function publicly
available.
2024-04-19 10:41:04 +02:00
Matthijs Mekking bc31575899 Move common create key functions to dnssectool.c
The dnssec-ksr tool needs to read a dnssec-policy from configuration
too, as well as deal with FIPS mode checks.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 1cb345fa95 Add ksr system test
Add a system test for testing dnssec-ksr, initally for the keygen
command. This should be able to create or select key files given a
DNSSEC policy and a time window.
2024-04-19 10:41:04 +02:00
Matthijs Mekking 77d4afba1b Introduce new DNSSEC tool dnssec-ksr
Introduce a new DNSSEC tool, dnssec-ksr, for creating signed key
response (SKR) files, given one or more key signing requests (KSRs).

For now it is just a dummy tool, but the future purpose of this utility
is to pregenerate ZSKs and signed RRsets for DNSKEY, CDNSKEY, and CDS
for a given period that a KSK is to be offline.
2024-04-19 10:41:04 +02:00
Michal Nowak 2ca6bcc99a Merge branch 'mnowak/revert-874329b3b1a56e58e8caf61d89127441d2cc79a1' into 'main'
Revert "Temporarily allow failure of respdiff-long:tsan job"

See merge request isc-projects/bind9!8957
2024-04-19 08:37:47 +00:00
Michal Nowak 620cce8f7e Revert "Temporarily allow failure of respdiff-long:tsan job"
This reverts commit 874329b3b1.

Addressed in isc-projects/bind9#4475.
2024-04-19 10:28:51 +02:00
Ondřej Surý e4793242eb Merge branch '4416-fix-reading-multiple-rndc-messages-in-single-TCP-message' into 'main'
Rework isccc_ccmsg to support multiple messages per tcp read

Closes #4416

See merge request isc-projects/bind9!8956
2024-04-18 18:10:56 +00:00
Ondřej Surý cbbc0051a3 Add CHANGES note for [GL #4416] 2024-04-18 20:09:47 +02:00
Dominik ThalhammerandOndřej Surý 24ae1157e8 Rework isccc_ccmsg to support multiple messages per tcp read
Previously, only a single controlconf message would be processed from a
single TCP read even if the TCP read buffer contained multiple messages.
Refactor the isccc_ccmsg unit to store the extra buffer in the internal
buffer and use the already read data first before reading from the
network again.

Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Dominik Thalhammer <dominik@thalhammer.it>
2024-04-18 20:08:44 +02:00
Ondřej Surý e13728413a Merge branch '4586-don-t-count-expired-future-rrsigs-in-verification-failure-quota' into 'main'
Don't count expired / future RRSIGs in verification failure quota

Closes #4586

See merge request isc-projects/bind9!8746
2024-04-18 15:07:43 +00:00
Ondřej Surý 5d4233c2c2 Add CHANGES and release notes for [GL #4586] 2024-04-18 16:05:32 +02:00
Ondřej Surý 3b9ea189b2 Don't count expired / future RRSIG against quota
These don't trigger a public key verification unless
dnssec-accept-expired is set.
2024-04-18 16:05:31 +02:00
Petr Špaček 903af2e1de Merge branch 'pspacek/update-sphinx' into 'main'
Update Sphinx version used for documentation build

See merge request isc-projects/bind9!8952
2024-04-18 14:00:33 +00:00
Petr Špaček da607d6a06 Update Sphinx version used for documentation build 2024-04-18 12:46:13 +02:00
Ondřej Surý bbb2741de8 Merge branch 'ondrej-offload-statschannel' into 'main'
Offload the isc_http response processing to worker thread

Closes #4680

See merge request isc-projects/bind9!7647
2024-04-18 08:56:06 +00:00
Ondřej Surý fbea3bb255 Add CHANGES and release note for [GL #4680] 2024-04-18 10:53:31 +02:00
Ondřej Surý c7ed858c6e Supress the leak detection in xmlGetGlobalState
The xmlGetGlobalState allocates per-thread memory that is not properly
cleaned up when the libxml2 is used from offloaded threads.  Add the
function the the LeakSanitizer suppression list.
2024-04-18 10:53:31 +02:00
Ondřej Surý 23835c4afe Use xmlMemSetup() instead of xmlGcMemSetup()
Since we don't have a specialized function for "atomic" allocations,
it's better to just use xmlMemSetup() instead of xmlGcMemSetup()
according to this:

https://mail.gnome.org/archives/xml/2007-August/msg00032.html
2024-04-18 10:53:31 +02:00
Ondřej Surý 950f828cd2 Offload the isc_http response processing to worker thread
Prepare the statistics channel data in the offloaded worker thread, so
the networking thread is not blocked by the process gathering data from
various data structures.  Only the netmgr send is then run on the
networkin thread when all the data is already there.
2024-04-18 10:53:00 +02:00
Matthijs Mekking f8a09fd91a Merge branch '4554-dnssec-policy-jitter' into 'main'
Add signatures-jitter option

Closes #4554

See merge request isc-projects/bind9!8686
2024-04-18 08:11:18 +00:00
Matthijs Mekking c3d8932f79 Add checkconf check for signatures-jitter
Having a value higher than signatures-validity does not make sense
and should be treated as a configuration error.
2024-04-18 09:50:33 +02:00
Matthijs Mekking 8b7785bc23 Add release notes and CHANGES for #4554
Mention the new signature jitter option.
2024-04-18 09:50:31 +02:00
Matthijs Mekking 67f403a423 Implement signature jitter
When calculating the RRSIG validity, jitter is now derived from the
config option rather than from the refresh value.
2024-04-18 09:50:10 +02:00
Matthijs Mekking 0438d3655b Refactor code that calculates signature validity
There are three code blocks that are (almost) similar, refactor it
to one function.
2024-04-18 09:50:10 +02:00
Matthijs Mekking 50bd729019 Update autosign test to use signatures-jitter
Now that we have an option to configure jitter, use it in system tests
that test jitter.
2024-04-18 09:50:10 +02:00
Matthijs Mekking 2a4daaedca Add signatures-jitter option
Add an option to speficy signatures jitter.
2024-04-18 09:50:10 +02:00
Petr Špaček c9ff77c067 Merge tag 'v9.19.23' 2024-04-18 09:21:47 +02:00
Mark Andrews 9360d90bf2 Merge branch '4671-calling-dns_qpkey_toname-twice-fails' into 'main'
Resolve "Calling dns_qpkey_toname twice fails."

Closes #4671

See merge request isc-projects/bind9!8948
2024-04-18 01:05:42 +00:00
Mark Andrews 36c11d9180 Check that name is properly reset by dns_qpkey_toname 2024-04-18 00:17:48 +00:00
Mark Andrews bf70d4840c dns_qpkey_toname failed to reset name correctly
This could lead to a mismatch between name->length and the rest
of the name structure.
2024-04-18 00:17:48 +00:00
Ondřej Surý fcf2919c93 Merge branch '4475-use-atomics-to-access-trust-access-in-dns_ncache' into 'main'
Use atomic operations to access the trust byte in ncache data

Closes #4475

See merge request isc-projects/bind9!8946
2024-04-17 19:18:35 +00:00
Mark AndrewsandOndřej Surý d2fd97f4da Add CHANGES note for [GL #4475] 2024-04-17 17:14:50 +02:00
Ondřej Surý eb1829b970 Use atomic operations to access the trust byte in ncache data
Protect the access to the trust byte in the ncache data with relaxed
atomic operation to mimick the current behaviour.  This will teach
TSAN that the concurrent access is fine.
2024-04-17 17:14:34 +02:00
Mark AndrewsandOndřej Surý 4ef755ffb0 Only copy the name data after we know its actual length
This prevents TSAN errors with the ncache code where the trust byte
access needs to be protected by a lock.  The old code copied the
entire region before determining where the name ended.  We now
determine where the name ends then copy just that data and in doing
so avoid reading the trust byte.
2024-04-17 17:14:34 +02:00
Artem Boldariev 90b0038ea0 Merge branch '4434-use-nm-tests-timeouts-for-the-dispatch-test' into 'main'
dispatch_test: use the NM tests timeouts

Closes #4434

See merge request isc-projects/bind9!8923
2024-04-15 14:25:13 +00:00
Artem Boldariev 7f805659c3 dispatch_test: use the NM tests timeouts
This commit makes the dispatch_test use the same timeouts that network
manager tests. We do that because the old values appear to be too
small for our heavy loaded CI machines, leading to spurious failures
on them. The network manager tests are much more stable in this
situation and they use somewhat larger timeout values.

We use a smaller connection timeouts for the tests which are expected
to timeout to not wait for too long.
2024-04-15 16:33:24 +03:00
Mark Andrews 381273f89f Merge branch '4669-error-sending-notify-to-ipv6-secondary' into 'main'
Wrong source address used for IPv6 notify messages

Closes #4669

See merge request isc-projects/bind9!8935
2024-04-12 00:16:01 +00:00
Mark Andrews 9cc6b4a68a Add CHANGES note for [GL #4669] 2024-04-11 18:05:25 +00:00
Mark Andrews 7c369ea3d9 Check that notify message was sent over IPv6 2024-04-11 18:05:25 +00:00
Mark Andrews 40fd4cd407 Wrong source address used for IPv6 notify messages
The source address field of 'newnotify' was not updated from the
default (0.0.0.0) when the destination address was an IPv6 address.
This resulted in the messages failing to be sent.  Set the source
address to :: when the destination address is an IPv6 address.
2024-04-11 18:05:25 +00:00
Petr Špaček 9c712eff0a Merge branch 'pspacek/releng-changes' into 'main'
Move Release issue template to BIND QA repo

See merge request isc-projects/bind9!8944
2024-04-11 15:15:49 +00:00
Petr Špaček d2fa9a642b Move Release issue template to BIND QA repo
It's easier to maintain the template in a single place together with
the script used to in the template.

In future use script bind9/releng/create_checklist.py
from isc-private/bind-qa to generate release issue.
2024-04-11 15:15:32 +00:00
Evan Hunt c13e8e1859 Merge branch 'each-dupwithoffsets-cannot-fail' into 'main'
dns_name_dupwithoffsets() cannot fail

See merge request isc-projects/bind9!8945
2024-04-11 03:25:07 +00:00
Evan Hunt 2c88946590 dns_name_dupwithoffsets() cannot fail
this function now always returns success; change it to void and
clean up its callers.
2024-04-10 22:51:07 -04:00
Petr Špaček 480126919a Merge branch 'pspacek/set-up-version-and-release-notes-for-bind-9.19.24' into 'main'
Set up version and release notes for BIND 9.19.24

See merge request isc-projects/bind9!8939
2024-04-04 19:15:28 +00:00
Petr Špaček 1341a1a734 Set up release notes for BIND 9.19.24 2024-04-04 19:35:03 +02:00
Petr Špaček b0b4ea3975 Update BIND version to 9.19.24-dev 2024-04-04 19:35:03 +02:00
Petr Špaček 3c0eaff4c6 Update BIND version for release 2024-04-02 18:08:00 +02:00
Petr Špaček dc9d9a8fdf Add a CHANGES marker 2024-04-02 18:06:04 +02:00
Petr Špaček 03c9e0b753 Merge branch 'pspacek/prepare-documentation-for-bind-9.19.23' into 'v9.19.23-release'
Prepare documentation for BIND 9.19.23

See merge request isc-private/bind9!677
2024-04-02 16:04:47 +00:00
Suzanne GoldlustandPetr Špaček 4c0db2ee3c Tweak and reword release notes 2024-04-02 17:45:25 +02:00
Petr Špaček e4344b7d1a Add release note for GL #4622 and #4652 2024-04-02 17:31:42 +02:00
Petr Špaček 3989b99a0b Add release note for GL #4614 2024-04-02 17:31:42 +02:00
Petr Špaček 1076bd3c78 Add release note for GL #4552 2024-04-02 17:31:42 +02:00
Petr Špaček bf92e16c0e Prepare release notes for BIND 9.19.23 2024-04-02 17:31:42 +02:00
Ondřej Surý ae2b59bfe7 Merge branch '4446-deprecate-fixed-rrset-order' into 'main'
Deprecate fixed value for the rrset-order option

Closes #4446

See merge request isc-projects/bind9!8808
2024-04-02 15:21:10 +00:00
Ondřej Surý 792ac13d60 Add CHANGES and release note for [GL #4446] 2024-04-02 15:21:00 +00:00
Ondřej Surý 304b5ec1ad Deprecate fixed value for the rrset-order option
Mark the "fixed" value for the "rrset-order" option deprecated, so we
can remove it in the future.
2024-04-02 15:21:00 +00:00
Ondřej Surý bf538b63a8 Merge branch '4593-deprecate-sortlist' into 'main'
Deprecate sortlist option

Closes #4593

See merge request isc-projects/bind9!8807
2024-04-02 15:13:26 +00:00
Ondřej Surý dfefc89b7e Add CHANGES and release note for [GL #4593] 2024-04-02 16:27:03 +02:00
Ondřej Surý 7c96bf3e71 Deprecate sortlist option
Mark the sortlist option deprecated, so we can remove it in the
future.
2024-04-02 16:26:39 +02:00
Ondřej Surý b7b69d9cf0 Merge branch '4654-validator-invalid-name' into 'main'
Rename and fix dns_validator_destroy()

Closes #4654

See merge request isc-projects/bind9!8933
2024-04-02 14:22:55 +00:00
Aram SargsyanandOndřej Surý 88d826ac5d Add a CHANGES note for [GL #4654] 2024-04-02 16:21:54 +02:00
Aram SargsyanandOndřej Surý a5ea7bcd25 Rename and fix dns_validator_destroy() to dns_validator_shutdown()
Since the dns_validator_destroy() function doesn't guarantee that
it destroys the validator, rename it to dns_validator_shutdown()
and require explicit dns_validator_detach() to follow.

Enforce the documented function requirement that the validator must
be completed when the function is called.

Make sure to set val->name to NULL when the function is called,
so that the owner of the validator may destroy the name, even if
the validator is not destroyed immediately. This should be safe,
because the name can be used further only for logging by the
offloaded work callbacks when they detect that the validator is
already canceled/complete, and the logging function has a condition
to use the name only when it is non-NULL.
2024-04-02 16:21:54 +02:00
Aram Sargsyan a6c6ad048d Remove a redundant log message and a comment
If val->result is not ISC_R_SUCCESS, a similar message is logged
further down in the function. Remove the redundant log message.

Also remove an unnecessary code comment line.
2024-04-02 10:34:31 +00:00
Ondřej Surý 424cb59a43 Merge branch 'each-isc-loop' into 'main'
use a thread-local variable to get the current running loop

See merge request isc-projects/bind9!8911
2024-04-02 09:49:06 +00:00
Ondřej Surý cad6292fc4 Merge branch '4652-dname-assertion' into 'main'
fix crash from NS target below DNAME

Closes #4652

See merge request isc-projects/bind9!8931
2024-04-02 08:36:08 +00:00
Evan HuntandOndřej Surý 63659e2e3a complete removal of isc_loop_current()
isc_loop() can now take its place.

This also requires changes to the test harness - instead of running the
setup and teardown outside of th main loop, we now schedule the setup
and teardown to run on the loop (via isc_loop_setup() and
isc_loop_teardown()) - this is needed because the new the isc_loop()
call has to be run on the active event loop, but previously the
isc_loop_current() (and the variants like isc_loop_main()) would work
even outside of the loop because it needed just isc_tid() to work, but
not the full loop (which was mainly true for the main thread).
2024-04-02 10:35:56 +02:00
Evan HuntandOndřej Surý c47fa689d4 use a thread-local variable to get the current running loop
if we had a method to get the running loop, similar to how
isc_tid() gets the current thread ID, we can simplify loop
and loopmgr initialization.

remove most uses of isc_loop_current() in favor of isc_loop().
in some places where that was the only reason to pass loopmgr,
remove loopmgr from the function parameters.
2024-04-02 10:35:56 +02:00
Evan HuntandOndřej Surý f95b890759 Add CHANGES note for [GL #4652] 2024-04-02 10:00:17 +02:00
Evan HuntandOndřej Surý ea6659a5e9 update foundname when detecting a zonecut above qname
an assertion could be triggered in the QPDB cache if a DNAME
was found above a queried NS, because the 'foundname' value was
not correctly updated to point to the zone cut.

the same mistake existed in qpzone and has been fixed there as well.
2024-04-02 10:00:03 +02:00
Evan HuntandOndřej Surý b4cc46de07 add a test for handling illegal NS below DNAME
an assertion could be triggered in the QPDB cache if an NS
was encountered that pointed to a name below a DNAME.
2024-04-02 10:00:03 +02:00
Ondřej Surý 183b3cb6aa Merge branch 'ondrej/placeholder' into 'main'
Add placeholder

See merge request isc-projects/bind9!8932
2024-04-02 07:18:53 +00:00
Ondřej Surý 40a6efae01 Add placeholder 2024-04-02 09:16:39 +02:00
Michał Kępień 86d5981dcd Merge branch 'michal/extract-changes-checks-to-a-separate-gitlab-ci-job' into 'main'
Extract CHANGES checks to a separate GitLab CI job

See merge request isc-projects/bind9!8918
2024-03-29 07:29:59 +00:00
Michał Kępień a7ece8e0bd Restore consistency in YAML anchor names
Commit a4e9ce500a added "pipelines" to CI
job trigger lists without updating the names of the YAML anchors
containing those lists accordingly.  Update YAML anchor names so that
they are consistent with their own contents.
2024-03-29 08:27:49 +01:00
Michał Kępień 8c2503947f Do not check CHANGES in pre-release pipelines
Since pre-release testing is usually carried out for branches in which
CHANGES entries are intentionally malformed to prevent entry numbering
conflicts down the road, do not run the "changes" GitLab CI job in
pipelines that are triggered by a parent pipeline (which can currently
only be a pre-release testing pipeline) to prevent triggering job
failures that would be meaningless anyway.
2024-03-29 08:27:49 +01:00
Michał Kępień 1335e139f2 Extract CHANGES checks to a separate GitLab CI job
Checking the contents of the CHANGES file currently requires invoking
multiple shell scripts.  These invocations are conflated with those for
other test scripts in the "misc" GitLab CI job.  Extract the commands
checking the contents of the CHANGES file to a separate GitLab CI job,
"changes", to improve readability.  Remove similar checks for the
CHANGES.SE file altogether as they are only relevant for BIND -S and
therefore should not be present in an open source branch.
2024-03-29 08:27:49 +01:00
Michał Kępień 7b5b3a842b Merge branch '4281-CVE-2023-5517-test' into 'main'
[CVE-2023-5517] Check nxdomain-redirect against built-in RFC-1918 zone

Closes #4281

See merge request isc-projects/bind9!8919
2024-03-28 13:42:02 +00:00
Mark AndrewsandMichał Kępień 2789906ce4 Checking nxdomain-redirect against built-in RFC-1918 zone
Check that RFC 1918 leak detection does not trigger an assertion
when nxdomain redirection is enabled in the server but not for the
RFC 1918 reverse namespace.
2024-03-28 13:15:45 +01:00
Michal Nowak 0371223343 Merge branch 'mnowak/freebsd-use-mit-kerberos5' into 'main'
Build FreeBSD with MIT Kerberos5 instead of Heimdal

See merge request isc-projects/bind9!8906
2024-03-27 08:15:26 +00:00
Michal Nowak d6df757fdc Build FreeBSD with MIT Kerberos5 instead of Heimdal
tsiggss system tests crash or are unstable with the base FreeBSD
(Heimdal-based) GSS-API.
2024-03-26 18:13:40 +01:00
Michal Nowak f0800501c7 Merge branch 'mnowak/revert-05b09f2b5bb68a916288f56bf627babad4055b90' into 'main'
Revert "Work around a TSAN issue with newer kernels"

Closes #4649

See merge request isc-projects/bind9!8905
2024-03-25 13:45:39 +00:00
Michal Nowak aba16af556 Revert "Work around a TSAN issue with newer kernels"
This reverts commit 05b09f2b5b.

The workaround has been moved to the AMI image (isc-private/packer!10).
2024-03-25 14:38:12 +01:00
Matthijs Mekking af220a5b72 Merge branch '4622-qp-hang-in-fix-iterator' into 'main'
Fix fix_iterator hang

Closes #4622 and #4632

See merge request isc-projects/bind9!8881
2024-03-25 10:53:36 +00:00
Matthijs Mekking 77d4bb9751 Fix fix_iterator hang
If there are no more previous leaves, it means the queried name
precedes the entire range of names in the database, so we should just
move the iterator one step back and return, instead of continuing our
search for the predecessor.

This is similar to an earlier bug fixed in an earlier commit:

    ea9a8cb392
2024-03-25 10:40:23 +01:00
Matthijs Mekking 2a724a808d Add a test case for fix_iterator hang
When fixing the iterator, when every leaf on this branch is greater
than the one we wanted we go back to the parent branch and iterate back
to the predecessor from that point.

But if there are no more previous leafs, it means the queried name
precedes the entire range of names in the database, so we would just
move the iterator one step back and continue from there.

This could end in a loop because the queried name precedes the entire
range of names and so none of those names are the predecessor of the
queried name.
2024-03-25 10:40:23 +01:00
Petr Špaček 948a89d591 Merge branch 'pspacek/hazard-improvements' into 'main'
CI hazard improvements

See merge request isc-projects/bind9!8843
2024-03-21 16:57:12 +00:00
Michał KępieńandPetr Špaček 5e02a007ca Warn if security fixes are not marked for testing 2024-03-21 17:38:57 +01:00
Petr Špaček 0ba29730f7 Warn about release notes without CHANGES entry 2024-03-21 17:38:57 +01:00
Petr Špaček 82cfb48295 Detect change in supported RR types and issue Hazard warning 2024-03-21 17:38:57 +01:00
Tom Krizek 087e7b590f Merge branch '4605-re-enable-enginepkcs11-test' into 'main'
Re-enable enginepkcs11 system test

Closes #4605

See merge request isc-projects/bind9!8888
2024-03-21 16:36:13 +00:00
Tom Krizek d1f1b6a934 Mark the enginepkcs11 test as flaky
There are frequent intermittent failures due to "crypto failure".
2024-03-21 16:25:02 +01:00
Tom Krizek 3712a219cb Re-enable enginepkcs11 system test
The condition in prereq.sh which attempts to match two string uses
integer equality operation. This results in an error, causing the
enginepkcs11 test to always be skipped. Use = operator for the string
comparison instead.
2024-03-21 16:25:00 +01:00
Tom Krizek da39dffd08 Merge branch 'tkrizek/autosign-flaky' into 'main'
Mark the autosign system test as flaky

Closes #4247 and #1565

See merge request isc-projects/bind9!8867
2024-03-21 15:23:27 +00:00
Tom Krizek a061fd67f6 Mark the autosign system test as flaky
The autosign test uses sleep in many cases to wait for something to
happen. This inevitably leads to an instability that manifests in our
CI. Allow an automatic rerun of the test to improve its stability.
2024-03-21 15:26:28 +01:00
Tom Krizek 32e7e0a8ee Merge branch 'tkrizek/resolver-test-export-home' into 'main'
Export variable in resolver system test

See merge request isc-projects/bind9!8799
2024-03-21 13:14:52 +00:00
Tom Krizek 86a192cece Export variable in resolver system test
Variable assignment when calling subroutines might not be portable.
Notably, it doesn't work with FreeBSD shell, where the value of HOME
would be ignored in this case.

Since the commands are already executed in a subshell, export the HOME
variable to ensure it is properly handled in all shells.
2024-03-21 13:25:00 +01:00
Michał Kępień b1ebd49f3a Merge branch 'michal/add-pipelines-to-ci-job-trigger-lists' into 'main'
Add "pipelines" to CI job trigger lists

See merge request isc-projects/bind9!8884
2024-03-21 11:29:53 +00:00
Michał Kępień a4e9ce500a Add "pipelines" to CI job trigger lists
To enable GitLab CI jobs in other projects to trigger pipelines in the
BIND 9 project using their CI_JOB_TOKEN, add "pipelines" to the relevant
GitLab CI job trigger lists.
2024-03-21 12:29:21 +01:00
Petr Špaček 225d986cdf Merge branch '4649-work-around-a-tsan-issue-with-newer-kernels' into 'main'
Work around a TSAN issue with newer kernels

Closes #4649

See merge request isc-projects/bind9!8893
2024-03-21 07:59:46 +00:00
Michał Kępień 05b09f2b5b Work around a TSAN issue with newer kernels
The ThreadSanitizer version currently available from Fedora 39
repositories is unable to cope with very high ASLR entropy, which is the
default in some recent Linux distributions [1].  This causes all
TSAN-enabled builds to fail on the affected systems with an error like:

    FATAL: ThreadSanitizer: unexpected memory mapping 0x7d00e0772000-0x7d00e0c00000

Work around the problem by reducing ASLR entropy for all TSAN-enabled
builds until the problem is resolved upstream.

[1] https://github.com/google/sanitizers/issues/1716
2024-03-21 06:47:29 +01:00
Mark Andrews ab441581b5 Merge branch '4640-checkzone-in-system-test-leaks-queries' into 'main'
Resolve "Checkzone in system test leaks queries"

Closes #4640

See merge request isc-projects/bind9!8870
2024-03-21 02:37:07 +00:00
Mark Andrews ad083897cc Stop named-checkzone leaking test queries 2024-03-21 01:10:36 +00:00
Mark Andrews c8efe7fe1d Merge branch '4580-add-resolver-arpa-to-the-built-in-empty-zones' into 'main'
Resolve "Add resolver.arpa to the built in empty zones"

Closes #4580

See merge request isc-projects/bind9!8732
2024-03-20 21:51:24 +00:00
Mark Andrews ecb043fc7b Add release note for [GL #4580] 2024-03-21 07:45:55 +11:00
Mark Andrews d12c238750 Add CHANGES entry for [GL #4580] 2024-03-21 07:45:55 +11:00
Mark Andrews 49561277de Add RESOLVER.ARPA to the built in empty zones
RFC 9462 adds RESOLVER.ARPA to the list of built in empty zones.
2024-03-21 07:45:55 +11:00
Michał Kępień 22591ae0a7 Merge tag 'v9.19.22' 2024-03-20 14:04:49 +01:00
Michał Kępień 13c6f25abb Merge branch 'michal/add-an-async-dns-server-for-use-in-system-tests' into 'main'
Add an async DNS server for use in system tests

See merge request isc-projects/bind9!8519
2024-03-20 09:28:43 +00:00
Tom KrizekandMichał Kępień 673387c4d5 Move conftest log initialization to conftest.py
Initializing the conftest logging upon importing the isctest package
isn't practical when there are standalone pieces which can be used
outside of the testing framework, such as the asyncdnsserver module.
2024-03-20 09:22:36 +01:00
Michał KępieńandTom Krizek 6c010a5644 Add an async DNS server for use in system tests
Implement a new Python class, AsyncDnsServer, which can be used by
ans.py scripts placed in ansX/ system test subdirectories.  This enables
conveniently starting a feature-limited, non-standards-compliant, custom
DNS server instance.  It can read and serve zone files, but it is also
able to evaluate any user-provided query-processing logic, allowing
query responses to be changed, delayed, or dropped altogether.  These
are all actions commonly taken by custom DNS servers written in Python
that are used in BIND 9 system tests.  Having a single "base"
implementation of such a custom DNS server reduces code duplication,
improving test maintainability.

Co-authored-by: Tom Krizek <tkrizek@isc.org>
2024-03-20 09:22:36 +01:00
Mark Andrews d3172cb47c Merge branch '4645-cid-488064-passing-null-pointer-version-to-maybe_update_recordsandsize-which-dereferences-it' into 'main'
Resolve "CID 488064: Passing null pointer "version" to "maybe_update_recordsandsize", which dereferences it"

Closes #4645 and #4646

See merge request isc-projects/bind9!8880
2024-03-19 22:41:35 +00:00
Mark Andrews 4d2d80f534 Remove remenants of cache support from qpzone.c
These where leading to Coverity errors being reported.
2024-03-19 22:04:10 +00:00
Michal Nowak e790b0cba1 Merge branch 'mnowak/pytest_rewrite_glue' into 'main'
Rewrite glue system test to pytest

See merge request isc-projects/bind9!8846
2024-03-19 19:16:53 +00:00
Michal Nowak 69d3efed89 Use bitwise operation to remove RD from default flags 2024-03-19 19:28:55 +01:00
Michal Nowak 9950f6d651 Rewrite glue system test to pytest
Limit dnspython to version 2.0.0+
(https://github.com/rthalley/dnspython/pull/503), otherwise the test
fails with:

    E   AttributeError: module 'dns.edns' has no attribute 'OptionType'
2024-03-19 19:28:55 +01:00
Michal Nowak c252ca2ce5 Merge branch 'mnowak/pytest_rewrite_masterfile' into 'main'
Rewrite masterfile system test to pytest

See merge request isc-projects/bind9!8791
2024-03-19 10:38:07 +00:00
Michal Nowak 7a161f615a Rewrite masterfile system test to pytest 2024-03-19 10:51:02 +01:00
Michal Nowak 686033e48d Add zones_equal() with optional TTL comparison 2024-03-19 10:51:02 +01:00
Michal Nowak 5af3b713af Modify rrsets_equal() to optionally compare TTL 2024-03-19 10:51:01 +01:00
Michal Nowak db272a4968 Merge branch 'mnowak/pytest_rewrite_limits' into 'main'
Rewrite limits system test to pytest

See merge request isc-projects/bind9!8798
2024-03-18 15:32:47 +00:00
Michal Nowak f90a772298 Rewrite limits system test to pytest
Also, tweak the IP ranges of A RRsets so they are more easily processed
by for loops.
2024-03-18 15:59:46 +01:00
Michal Nowak 67087b6c43 Merge branch 'mnowak/freebsd-13.3' into 'main'
Add FreeBSD 13.3

See merge request isc-projects/bind9!8826
2024-03-18 14:59:33 +00:00
Michal Nowak 9019985d2d Add FreeBSD 13.3 2024-03-18 15:36:54 +01:00
Mark Andrews 0906848ae9 Merge branch '4641-dig-ednsflags-does-not-re-enable-edns' into 'main'
Resolve "dig +ednsflags does not re-enable EDNS"

Closes #4641

See merge request isc-projects/bind9!8874
2024-03-17 03:06:22 +00:00
Mark Andrews b41d1820d2 Add CHANGES for [GL #4641 2024-03-16 16:26:47 +11:00
Mark Andrews 8babbd09a1 Test +noedns +ednsflags=non-zero-value 2024-03-16 16:26:17 +11:00
Mark Andrews d74bba4fae Re-enable EDNS if an EDNS flag gets set to 1 by +ednsflags
This is consistent with +dnssec and +nsid which only re-enable
EDNS if do is set to 1 or nsid is requested.
2024-03-16 16:07:55 +11:00
Michal Nowak cbc121ce9a Merge branch 'mnowak/move-stress-tests-to-freebsd-13' into 'main'
FreeBSD "stress" tests now run on FreeBSD 13.2

See merge request isc-projects/bind9!8689
2024-03-15 11:12:11 +00:00
Michal Nowak 176bf877e1 FreeBSD "stress" tests now run on FreeBSD 13.2 2024-03-15 12:11:08 +01:00
Michal Nowak f7f7b09d98 Merge branch 'mnowak/pytest_rewrite_rrchecker' into 'main'
Rewrite rrchecker system test to pytest

See merge request isc-projects/bind9!8832
2024-03-15 09:05:20 +00:00
Michal Nowak 6a301c1d35 Rewrite rrchecker system test to pytest 2024-03-15 09:40:01 +01:00
Mark Andrews 4be1db6e82 Merge branch '4639-add-openssl-flags-to-proxystream_test' into 'main'
Resolve "Add OpenSSL Flags to proxystream_test"

Closes #4639

See merge request isc-projects/bind9!8869
2024-03-14 23:42:25 +00:00
Mark Andrews 52b053537d Add OpenSSL libraries and flags to proxystream_test 2024-03-15 10:08:57 +11:00
Evan Hunt 120b4a9ef9 Merge branch '4614-qpdb-excess-memory' into 'main'
reduce memory consumption of QP zone and cache databases

Closes #4614

See merge request isc-projects/bind9!8849
2024-03-14 18:06:54 +00:00
Evan Hunt 1f67a3f474 CHANGES for [GL #4614] 2024-03-14 10:25:12 -07:00
Evan Hunt 17186e06bb reduce memory consumption of the remaining QP databases
use dynamically allocated names instead of fixednames in
forward.c, keytable.c, nametree.c, and nta.c
2024-03-14 10:25:07 -07:00
Evan Hunt c0fcc2899e reduce memory consumption of rpz summary database
use dynamically allocated names instead of fixednames in rpz.c
2024-03-14 10:20:52 -07:00
Evan Hunt 8b67476249 reduce memory consumption of qpcache database
as with qpzone, use a dynamically-allocated dns_name instead
of a dns_fixedname object to store node names in the QP database.
2024-03-14 10:20:52 -07:00
Evan Hunt f908d358c4 reduce memory consumption of qpzone database
every node of a QP database contains a copy of the nodename,
which is used as the key for the QP-trie. previously, the name
was stored as a dns_fixedname object, which has room for up to
255 characters. we can reduce the space consumed by dynamically
allocating a dns_name object that's just long enough for the name
to be stored.
2024-03-14 10:20:52 -07:00
Matthijs Mekking 78aa2fb64c Merge branch '4629-cid-487882-error-handling-issues' into 'main'
Resolve "CID 487882: Error handling issues in lib/dns/qpzone.c"

Closes #4629

See merge request isc-projects/bind9!8852
2024-03-14 14:12:57 +00:00
Matthijs Mekking ad33a73f83 Fix Coverity CID 487882: Error handling issues
The dns_qpiter_next() was called without checking the return value. If
we cannot move the iterator forward, there is no use in calling the
step() function.

/lib/dns/qpzone.c: 2804 in activeempty()
2798     	 * of the name we were searching for. Step the iterator
2799     	 * forward, then step() will continue forward until it
2800     	 * finds a node with active data. If that node is a
2801     	 * subdomain of the one we were looking for, then we're
2802     	 * at an active empty nonterminal node.
2803     	 */
>>>     CID 487882:  Error handling issues  (CHECKED_RETURN)
>>>     Calling "dns_qpiter_next" without checking return value (as is done elsewhere 26 out of 27 times).
2804     	dns_qpiter_next(it, NULL, NULL, NULL);
2805     	return (step(search, it, FORWARD, next) &&
2806     		dns_name_issubdomain(next, current));
2807     }
2024-03-14 14:01:23 +01:00
Matthijs Mekking 8d3f601a6b Merge branch 'matthijs-add-rfc-9460-to-arm' into 'main'
Add RFC 9460 to list of supported RFCs

See merge request isc-projects/bind9!8847
2024-03-14 12:53:23 +00:00
Matthijs Mekking 5b5f43babc Add RFC 9460 to list of supported RFCs
The specification was implemented (#1132) when it was a draft. Now that
it is RFC, add the RFC to the list of supported RFCs.
2024-03-14 12:52:42 +00:00
Matthijs Mekking 4d560d5ffd Merge branch '4631-cid-487884-dead-code-in-qpcache' into 'main'
Resolve "CID 487884: Dead code in qpcache.c"

Closes #4631

See merge request isc-projects/bind9!8853
2024-03-14 11:50:17 +00:00
Matthijs Mekking 659fa0cbc3 Fix Coverity CID 487884: Dead code in qpcache.c
Adding a changed record is zonedb related and does not belong in
the cache code. This is a leftover dead code and can be safely
removed.

/lib/dns/qpcache.c: 3459 in add()
3453     			}
3454     			newheader->next = topheader->next;
3455     			newheader->down = topheader;
3456     			topheader->next = newheader;
3457     			qpnode->dirty = 1;
3458     			if (changed != NULL) {
>>>     CID 487884:    (DEADCODE)
>>>     Execution cannot reach this statement: "changed->dirty = true;".
3459     				changed->dirty = true;
3460     			}
3461     		} else {
3462     			/*
3463     			 * No rdatasets of the given type exist at the node.
3464     			 */
/lib/dns/qpcache.c: 3409 in add()
3403     			}
3404     			newheader->next = topheader->next;
3405     			newheader->down = topheader;
3406     			topheader->next = newheader;
3407     			qpnode->dirty = 1;
3408     			if (changed != NULL) {
>>>     CID 487884:    (DEADCODE)
>>>     Execution cannot reach this statement: "changed->dirty = true;".
3409     				changed->dirty = true;
3410     			}
3411     			mark_ancient(header);
3412     			if (sigheader != NULL) {
3413     				mark_ancient(sigheader);
3414
2024-03-14 10:42:30 +00:00
Matthijs Mekking 1102c5d552 Merge branch '4624-duration-error-checking' into 'main'
Detect invalid durations

Closes #4624

See merge request isc-projects/bind9!8844
2024-03-14 10:08:43 +00:00
Matthijs Mekking bc600ae2a1 Add CHANGES and release note for #4624 2024-03-14 09:07:44 +01:00
Matthijs Mekking e39de45adc Detect invalid durations
Be stricter in durations that are accepted. Basically we accept ISO 8601
formats, but fail to detect garbage after the integers in such strings.

For example, 'P7.5D' will be treated as 7 days. Pass 'endptr' to
'strtoll' and check if the endptr is at the correct suffix.
2024-03-14 08:51:46 +01:00
Mark Andrews fd49abf254 Merge branch '4608-ensure-static-stub-ns-records-are-not-returned' into 'main'
Resolve "Ensure static stub NS records are not returned"

Closes #4608

See merge request isc-projects/bind9!8790
2024-03-14 04:16:39 +00:00
Mark Andrews 6a91862ac5 Add CHANGES note for [GL #4608] 2024-03-14 11:40:10 +11:00
Mark Andrews 229bf863e2 Check static-stub synthesised NS is not returned 2024-03-14 11:39:27 +11:00
Mark Andrews 40816e4e35 Don't use static stub when returning best NS
If we find a static stub zone in query_addbestns look for a parent
zone which isn't a static stub.
2024-03-14 11:39:27 +11:00
Evan Hunt 5a17764a77 Merge branch '4630-deadcode-fix' into 'main'
Resolve "CID 487883: Null pointer dereference in lib/dns/qpzone.c"

Closes #4630

See merge request isc-projects/bind9!8854
2024-03-14 00:15:38 +00:00
Evan Hunt b3c8b5cfb2 remove dead code in rbtdb.c
dns_db_addrdataset() enforces a requirement that version can only
be NULL for a cache database. code that checks for zone semantics
and version == NULL can never be reached.
2024-03-13 17:15:18 -07:00
Evan Hunt 29f1c93734 support nodefullname in rbt-zonedb.c
this enables the 'dyndb' system test to pass when we
build using --with-zonedb=rbt.
2024-03-13 17:15:18 -07:00
Evan Hunt f0b164430a remove dead code in qpzone.c
qpzone does not support cache semantics, so dns_db_addrdataset(),
_deleterdataset() and _subtractrdataset() can't be run with
version == NULL; there's no need to check for it.

we can also clean up free_qpdb() a bit since current_version
is always non-NULL.
2024-03-13 17:15:18 -07:00
Mark Andrews 41eed193b2 Merge branch '4633-undefined-behaviour-in-rdataslab-c' into 'main'
Resolve "Undefined behaviour in rdataslab.c"

Closes #4633

See merge request isc-projects/bind9!8855
2024-03-13 23:40:17 +00:00
Mark Andrews 228cc557fe Only call memmove if the rdata length is non zero
This avoids undefined behaviour on zero length rdata where the
data pointer is NULL.
2024-03-13 23:04:56 +00:00
Matthijs Mekking 377bd35574 Merge branch '4552-keymgr-depends-function-bug' into 'main'
Fix bug in keymgr Depends function

Closes #4552

See merge request isc-projects/bind9!8682
2024-03-13 10:46:25 +00:00
Matthijs Mekking 32e43764dd Add CHANGES for #4552 2024-03-13 10:58:45 +01:00
Matthijs Mekking 0aac81cf80 Fix bug in keymgr Depends function
The Depends relation refers to types of rollovers in which a certain
record type is going to be swapped. Specifically, the Depends relation
says there should be no dependency on the predecessor key (the set
Dep(x, T) must be empty).

But if the key is phased out (all its states are in HIDDEN), there is
no longer a dependency. Since the relationship is still maintained
(Predecessor and Successor metadata), the keymgr_dep function still
returned true. In other words, the set Dep(x, T) is not considered
empty.

This slows down key rollovers, only retiring keys when the successor
key has been fully propagated.
2024-03-13 10:58:24 +01:00
Michał Kępień 03c040da53 Merge branch 'michal/set-up-version-and-release-notes-for-bind-9.19.23' into 'main'
Set up version and release notes for BIND 9.19.23

See merge request isc-projects/bind9!8856
2024-03-13 08:59:24 +00:00
Michał Kępień 33bdbfe2f5 Set up release notes for BIND 9.19.23 2024-03-13 09:51:24 +01:00
Michał Kępień df0229e7ee Update BIND version to 9.19.23-dev 2024-03-13 09:51:24 +01:00
Michał Kępień d01a4e5fc6 Update BIND version for release 2024-03-12 09:33:06 +01:00
Michał Kępień 0ba0025566 Add a CHANGES marker 2024-03-12 09:33:06 +01:00
Michał Kępień 2896a2a15e Merge branch 'pspacek/prepare-documentation-for-bind-9.19.22' into 'v9.19.22-release'
Prepare documentation for BIND 9.19.22

See merge request isc-private/bind9!671
2024-03-12 08:31:48 +00:00
Petr ŠpačekandMichał Kępień 59dd8c7de5 Tweak and reword release notes 2024-03-12 09:19:53 +01:00
Petr ŠpačekandMichał Kępień 2fac89f039 Add release note for GL #4591 2024-03-12 09:19:53 +01:00
Petr ŠpačekandMichał Kępień 1b039fdfc5 Reorder release notes 2024-03-12 09:19:53 +01:00
Petr ŠpačekandMichał Kępień cd117a932f Add release note for GL #4413 2024-03-12 09:19:53 +01:00
Petr ŠpačekandMichał Kępień 353ebedb94 Prepare release notes for BIND 9.19.22 2024-03-12 09:19:53 +01:00
193 changed files with 6081 additions and 16465 deletions
+1
View File
@@ -75,6 +75,7 @@ doc/man/dnssec-importkey.8in
doc/man/dnssec-keyfromlabel.8in
doc/man/dnssec-keygen.8in
doc/man/dnssec-keymgr.8in
doc/man/dnssec-ksr.8in
doc/man/dnssec-revoke.8in
doc/man/dnssec-settime.8in
doc/man/dnssec-signzone.8in
+74 -96
View File
@@ -15,7 +15,7 @@ variables:
TEST_PARALLEL_JOBS: 4
CONFIGURE: ./configure
CLANG_VERSION: 17
CLANG_VERSION: 18
CLANG: "clang-${CLANG_VERSION}"
SCAN_BUILD: "scan-build-${CLANG_VERSION}"
LLVM_SYMBOLIZER: "/usr/lib/llvm-${CLANG_VERSION}/bin/llvm-symbolizer"
@@ -71,6 +71,7 @@ stages:
- performance
- docs
- postcheck
- postmerge
- release
### Runner Tag Templates
@@ -80,14 +81,6 @@ stages:
- libvirt
- amd64
# Jobs with these tags do not run on AWS but on permanent OVH systems.
.linux-respdiff-amd64: &linux_respdiff_amd64
tags:
- linux
- ovh
- amd64
# Autoscaling GitLab Runner on AWS EC2 (amd64)
.linux-amd64: &linux_amd64
@@ -147,10 +140,6 @@ stages:
image: "$CI_REGISTRY_IMAGE:debian-bullseye-amd64"
<<: *linux_amd64
.respdiff-debian-bookworm-amd64: &respdiff_debian_bookworm_amd64_image
image: "$CI_REGISTRY_IMAGE:debian-bookworm-amd64"
<<: *linux_respdiff_amd64
.debian-bookworm-amd64: &debian_bookworm_amd64_image
image: "$CI_REGISTRY_IMAGE:debian-bookworm-amd64"
<<: *linux_amd64
@@ -206,7 +195,7 @@ stages:
### QCOW2 Image Templates
.freebsd-13-amd64: &freebsd_13_amd64_image
image: "freebsd-13.2-x86_64"
image: "freebsd-13.3-x86_64"
<<: *libvirt_amd64
.freebsd-14-amd64: &freebsd_14_amd64_image
@@ -219,17 +208,19 @@ stages:
### Job Templates
.api-schedules-tags-triggers-web-triggering-rules: &api_schedules_tags_triggers_web_triggering_rules
.api-pipelines-schedules-tags-triggers-web-triggering-rules: &api_pipelines_schedules_tags_triggers_web_triggering_rules
only:
- api
- pipelines
- schedules
- tags
- triggers
- web
.api-schedules-triggers-web-triggering-rules: &api_schedules_triggers_web_triggering_rules
.api-pipelines-schedules-triggers-web-triggering-rules: &api_pipelines_schedules_triggers_web_triggering_rules
only:
- api
- pipelines
- schedules
- triggers
- web
@@ -238,6 +229,7 @@ stages:
only:
- api
- merge_requests
- pipelines
- schedules
- tags
- triggers
@@ -344,7 +336,7 @@ stages:
.shotgun: &shotgun_job
<<: *base_image
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
stage: performance
script:
- if [ -z "$CI_COMMIT_TAG" ]; then export SHOTGUN_ROUNDS=1; else export SHOTGUN_ROUNDS=3; fi
@@ -479,14 +471,14 @@ stages:
- *configure
- make -j${BUILD_PARALLEL_JOBS:-1} V=1
- *setup_interfaces
- git clone --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.isc.org/isc-private/bind-qa.git
- cd bind-qa/bind9/respdiff
- git clone --depth 1 https://gitlab.isc.org/isc-projects/bind9-qa.git
- cd bind9-qa/respdiff
needs: []
artifacts:
paths:
- bind-qa/bind9/respdiff
- bind9-qa/respdiff
exclude:
- bind-qa/bind9/respdiff/rspworkdir/data.mdb # Exclude a 10 GB file.
- bind9-qa/respdiff/rspworkdir/data.mdb # Exclude a 10 GB file.
untracked: true
when: always
@@ -501,15 +493,6 @@ misc:
<<: *precheck_job
script:
- sh util/checklibs.sh > checklibs.out
- sh util/tabify-changes < CHANGES > CHANGES.tmp
- diff -urNap CHANGES CHANGES.tmp
- perl util/check-changes CHANGES
- sh util/check-line-length.sh CHANGES
- test ! -f CHANGES.SE || sh util/tabify-changes < CHANGES.SE > CHANGES.tmp
- test ! -f CHANGES.SE || diff -urNap CHANGES.SE CHANGES.tmp
- test ! -f CHANGES.SE || perl util/check-changes master=0 CHANGES.SE
- test ! -f CHANGES.SE || sh util/check-line-length.sh CHANGES.SE
- rm CHANGES.tmp
- sh util/check-categories.sh
- sh util/check-gitignore.sh
- sh util/check-trailing-whitespace.sh
@@ -522,6 +505,18 @@ misc:
- checklibs.out
when: on_failure
changes:
<<: *precheck_job
except:
- pipelines
script:
- sh util/tabify-changes < CHANGES > CHANGES.tmp
- diff -urNap CHANGES CHANGES.tmp
- perl util/check-changes CHANGES
- sh util/check-line-length.sh CHANGES
- rm CHANGES.tmp
needs: []
black:
<<: *precheck_job
needs: []
@@ -800,12 +795,12 @@ gcc:8fips:amd64:
EXTRA_CONFIGURE: "--with-libidn2 --enable-fips-mode --disable-tracing"
<<: *oraclelinux_8fips_amd64_image
<<: *build_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
system:gcc:8fips:amd64:
<<: *oraclelinux_8fips_amd64_image
<<: *system_test_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: gcc:8fips:amd64
artifacts: true
@@ -813,7 +808,7 @@ system:gcc:8fips:amd64:
unit:gcc:8fips:amd64:
<<: *oraclelinux_8fips_amd64_image
<<: *unit_test_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: gcc:8fips:amd64
artifacts: true
@@ -825,12 +820,12 @@ gcc:9fips:amd64:
EXTRA_CONFIGURE: "--with-libidn2 --enable-fips-mode --disable-leak-detection --disable-tracing"
<<: *oraclelinux_9fips_amd64_image
<<: *build_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
system:gcc:9fips:amd64:
<<: *oraclelinux_9fips_amd64_image
<<: *system_test_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: gcc:9fips:amd64
artifacts: true
@@ -838,7 +833,7 @@ system:gcc:9fips:amd64:
unit:gcc:9fips:amd64:
<<: *oraclelinux_9fips_amd64_image
<<: *unit_test_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: gcc:9fips:amd64
artifacts: true
@@ -1008,7 +1003,7 @@ system:gcc:out-of-tree:
artifacts: true
<<: *base_image
<<: *system_test_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
unit:gcc:out-of-tree:
variables:
@@ -1018,7 +1013,7 @@ unit:gcc:out-of-tree:
artifacts: true
<<: *base_image
<<: *unit_test_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
# Jobs for tarball GCC builds on Debian 12 "bookworm" (amd64)
@@ -1038,7 +1033,7 @@ gcc:tarball:
system:gcc:tarball:
<<: *base_image
<<: *system_test_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
before_script:
- cd bind-*
- *setup_interfaces
@@ -1052,7 +1047,7 @@ system:gcc:tarball:
unit:gcc:tarball:
<<: *base_image
<<: *unit_test_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
before_script:
- cd bind-*
needs:
@@ -1331,7 +1326,9 @@ unit:clang:bookworm:amd64:
clang:freebsd13:amd64:
variables:
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "${WITH_READLINE_LIBEDIT}"
# Use MIT Kerberos5 for BIND 9 GSS-API support because of FreeBSD Heimdal
# incompatibility; see https://bugs.freebsd.org/275241.
EXTRA_CONFIGURE: "${WITH_READLINE_LIBEDIT} --with-gssapi=/usr/local/bin/krb5-config"
USER: gitlab-runner
<<: *freebsd_13_amd64_image
<<: *build_job
@@ -1357,7 +1354,9 @@ unit:clang:freebsd13:amd64:
clang:freebsd14:amd64:
variables:
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "${WITH_READLINE_EDITLINE}"
# Use MIT Kerberos5 for BIND 9 GSS-API support because of FreeBSD Heimdal
# incompatibility; see https://bugs.freebsd.org/275241.
EXTRA_CONFIGURE: "${WITH_READLINE_EDITLINE} --with-gssapi=/usr/local/bin/krb5-config"
USER: gitlab-runner
<<: *freebsd_14_amd64_image
<<: *build_job
@@ -1524,51 +1523,10 @@ coverity:
# Respdiff tests
respdiff-short:
respdiff:
<<: *respdiff_job
<<: *default_triggering_rules
<<: *debian_bookworm_amd64_image
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og -DISC_TRACK_PTHREADS_OBJECTS"
MAX_DISAGREEMENTS_PERCENTAGE: "0.5"
script:
- bash respdiff.sh -m /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 -s named -q "${PWD}/10k_a.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "/usr/local/respdiff-reference-bind/sbin/named"
respdiff-short:asan:
<<: *respdiff_job
<<: *default_triggering_rules
<<: *debian_bookworm_amd64_image
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og -fsanitize=address,undefined"
LDFLAGS: "-fsanitize=address,undefined"
EXTRA_CONFIGURE: "--disable-dnsrps --without-jemalloc"
MAX_DISAGREEMENTS_PERCENTAGE: "0.5"
script:
- bash respdiff.sh -s named -q "${PWD}/10k_a.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "/usr/local/respdiff-reference-bind/sbin/named"
respdiff-short:tsan:
<<: *respdiff_job
<<: *default_triggering_rules
<<: *tsan_debian_bookworm_amd64_image
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og -fsanitize=thread"
LDFLAGS: "-fsanitize=thread"
EXTRA_CONFIGURE: "--disable-dnsrps --enable-pthread-rwlock --without-jemalloc"
MAX_DISAGREEMENTS_PERCENTAGE: "0.5"
TSAN_OPTIONS: "${TSAN_OPTIONS_DEBIAN}"
script:
- bash respdiff.sh -s named -q "${PWD}/10k_a.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "/usr/local/respdiff-reference-bind/sbin/named"
after_script:
- *find_python
- *parse_tsan
respdiff-long:
<<: *respdiff_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *respdiff_debian_bookworm_amd64_image
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og -DISC_TRACK_PTHREADS_OBJECTS"
@@ -1576,9 +1534,9 @@ respdiff-long:
script:
- bash respdiff.sh -m /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 -s named -q "${PWD}/100k_mixed.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "/usr/local/respdiff-reference-bind/sbin/named"
respdiff-long:asan:
respdiff:asan:
<<: *respdiff_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *default_triggering_rules
<<: *debian_bookworm_amd64_image
variables:
CC: gcc
@@ -1589,9 +1547,9 @@ respdiff-long:asan:
script:
- bash respdiff.sh -s named -q "${PWD}/100k_mixed.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "/usr/local/respdiff-reference-bind/sbin/named"
respdiff-long:tsan:
respdiff:tsan:
<<: *respdiff_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *default_triggering_rules
<<: *tsan_debian_bookworm_amd64_image
variables:
CC: gcc
@@ -1605,11 +1563,10 @@ respdiff-long:tsan:
after_script:
- *find_python
- *parse_tsan
allow_failure: true # affected by GL #4475
respdiff-long-third-party:
respdiff-third-party:
<<: *respdiff_job
<<: *api_schedules_tags_triggers_web_triggering_rules
<<: *default_triggering_rules
<<: *debian_bookworm_amd64_image
variables:
CC: gcc
@@ -1656,8 +1613,8 @@ shotgun:dot:
- *setup_interfaces
- make -k all V=1
- make DESTDIR="${INSTALL_PATH}" install
- git clone --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.isc.org/isc-private/bind-qa.git
- cd bind-qa/bind9/stress
- git clone --depth 1 https://gitlab.isc.org/isc-projects/bind9-qa.git
- cd bind9-qa/stress
- LD_LIBRARY_PATH="${INSTALL_PATH}/usr/local/lib" BIND_INSTALL_PATH="${INSTALL_PATH}/usr/local" WORKSPACE="${CI_PROJECT_DIR}" bash stress.sh
needs:
- job: autoreconf
@@ -1758,7 +1715,7 @@ stress:rpz:fedora:39:arm64:
variables:
- $CI_COMMIT_TAG || ($BIND_STRESS_TEST_OS =~ /linux/i && $BIND_STRESS_TEST_MODE =~ /rpz/i && $BIND_STRESS_TEST_ARCH =~ /arm64/i)
stress:authoritative:freebsd12:amd64:
stress:authoritative:freebsd13:amd64:
<<: *freebsd_stress_amd64
<<: *stress_job
variables:
@@ -1772,7 +1729,7 @@ stress:authoritative:freebsd12:amd64:
variables:
- $CI_COMMIT_TAG || ($BIND_STRESS_TEST_OS =~ /freebsd/i && $BIND_STRESS_TEST_MODE =~ /authoritative/i && $BIND_STRESS_TEST_ARCH =~ /amd64/i)
stress:recursive:freebsd12:amd64:
stress:recursive:freebsd13:amd64:
<<: *freebsd_stress_amd64
<<: *stress_job
variables:
@@ -1786,7 +1743,7 @@ stress:recursive:freebsd12:amd64:
variables:
- $CI_COMMIT_TAG || ($BIND_STRESS_TEST_OS =~ /freebsd/i && $BIND_STRESS_TEST_MODE =~ /recursive/i && $BIND_STRESS_TEST_ARCH =~ /amd64/i)
stress:rpz:freebsd12:amd64:
stress:rpz:freebsd13:amd64:
<<: *freebsd_stress_amd64
<<: *stress_job
variables:
@@ -1868,3 +1825,24 @@ pairwise:
only:
variables:
- $PAIRWISE_TESTING
backports:
<<: *base_image
stage: postmerge
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_REF_NAME =~ /^bind-9.[0-9]+$/ || $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH)'
variables:
# automated commits will inherit identification from the user who pressed Merge button
GIT_COMMITTER_NAME: $GITLAB_USER_NAME
GIT_COMMITTER_EMAIL: $GITLAB_USER_EMAIL
# avoid leftover branches from previous jobs
GIT_STRATEGY: clone
# assumed max depth of a MR for backport
GIT_DEPTH: 200
script:
# CI job token is not sufficient for push operations
- git remote get-url origin | sed -e "s/gitlab-ci-token:$CI_JOB_TOKEN/oauth2:$BACKPORT_GITLAB_API_TOKEN/" | xargs git remote set-url --push origin
# force-pushing is disabled so we have to have merge request on top
- MERGE_REQUEST_ID="$(git log -1 --format='%b' | sed --silent -e 's/^See merge request [^!]\+!//p')"
- git clone --depth 1 https://gitlab.isc.org/isc-projects/bind9-qa.git
- bind9-qa/releng/backport_mr.py $CI_PROJECT_ID "$MERGE_REQUEST_ID"
-101
View File
@@ -1,101 +0,0 @@
## Release Schedule
**Code Freeze:**
**Tagging Deadline:**
**Public Release:**
## Documentation Review Links
**Closed issues assigned to the milestone without a release note:**
- []()
- []()
- []()
**Merge requests merged into the milestone without a release note:**
- []()
- []()
- []()
**Merge requests merged into the milestone without a `CHANGES` entry:**
- []()
- []()
- []()
## Release Checklist
### Before the Code Freeze
- [ ] ***(QA)*** Rebase -S editions on top of current open-source versions: `git checkout bind-9.18-sub && git rebase origin/bind-9.18`
- [ ] ***(QA)*** [Inform](https://gitlab.isc.org/isc-private/bind-qa/-/blob/master/bind9/releng/inform_supp_marketing.py) Support and Marketing of impending release (and give estimated release dates).
- [ ] ***(QA)*** Ensure there are no permanent test failures on any platform. Check [public](https://gitlab.isc.org/isc-projects/bind9/-/pipelines?scope=all&source=schedule) and [private](https://gitlab.isc.org/isc-private/bind9/-/pipelines?scope=all&source=schedule) scheduled pipelines.
- [ ] ***(QA)*** Check charts from `shotgun:*` jobs in the scheduled pipelines to verify there is no unexplained performance drop for any protocol.
- [ ] ***(QA)*** Check [Perflab](https://perflab.isc.org/) to ensure there has been no unexplained drop in performance for the versions being released.
- [ ] ***(QA)*** Check whether all issues assigned to the release milestone are resolved[^1].
- [ ] ***(QA)*** Ensure that there are no outstanding [merge requests in the private repository](https://gitlab.isc.org/isc-private/bind9/-/merge_requests/)[^1] (Subscription Edition only).
- [ ] ***(QA)*** [Ensure](https://gitlab.isc.org/isc-private/bind-qa/-/blob/master/bind9/releng/check_backports.py) all merge requests marked for backporting have been indeed backported.
- [ ] ***(QA)*** [Announce](https://gitlab.isc.org/isc-private/bind-qa/-/blob/master/bind9/releng/inform_code_freeze.py) (on Mattermost) that the code freeze is in effect.
### Before the Tagging Deadline
- [ ] ***(QA)*** Inspect the current output of the `cross-version-config-tests` job to verify that no unexpected backward-incompatible change was introduced in the current release cycle.
- [ ] ***(QA)*** Ensure release notes are correct, ask Support and Marketing to check them as well. [Example](https://gitlab.isc.org/isc-private/bind9/-/merge_requests/510)
- [ ] ***(QA)*** Add a release marker to `CHANGES`. Examples: [9.18](https://gitlab.isc.org/isc-projects/bind9/-/commit/f14d8ad78c0506fd4247187f2177f8eceeb6b3b9), [9.16](https://gitlab.isc.org/isc-projects/bind9/-/commit/1bcdf21874f99a00da389d723e0ad07dfd70f9f1)
- [ ] ***(QA)*** Add a release marker to `CHANGES.SE` (Subscription Edition only). [Example](https://gitlab.isc.org/isc-private/bind9/-/commit/0f03d5737bcbdaa1bf713c6db1887b14938c3421)
- [ ] ***(QA)*** Update BIND 9 version in `configure.ac` ([9.18+](https://gitlab.isc.org/isc-projects/bind9/-/commit/3c85ab7f4c35e6d8acef1393606002a0a8730100)) or `version` ([9.16](https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/7692/diffs?commit_id=1bcdf21874f99a00da389d723e0ad07dfd70f9f1)).
- [ ] ***(QA)*** Rebuild `configure` using Autoconf on `docs.isc.org` (9.16).
- [ ] ***(QA)*** Update GitLab settings for all maintained branches to disallow merging to them: [public](https://gitlab.isc.org/isc-projects/bind9/-/settings/repository), [private](https://gitlab.isc.org/isc-private/bind9/-/settings/repository)
- [ ] ***(QA)*** Tag the releases in the private repository (`git tag -s -m "BIND 9.x.y" v9.x.y`).
### Before the ASN Deadline (for ASN Releases) or the Public Release Date (for Regular Releases)
- [ ] ***(QA)*** Check that the formatting is correct for the HTML version of release notes.
- [ ] ***(QA)*** Check that the formatting of the generated man pages is correct.
- [ ] ***(QA)*** Verify GitLab CI results [for the tags](https://gitlab.isc.org/isc-private/bind9/-/pipelines?scope=tags) created and sign off on the releases to be published.
- [ ] ***(QA)*** Update GitLab settings for all maintained branches to allow merging to them again: [public](https://gitlab.isc.org/isc-projects/bind9/-/settings/repository), [private](https://gitlab.isc.org/isc-private/bind9/-/settings/repository)
- [ ] ***(QA)*** Prepare (using [`version_bump.py`](https://gitlab.isc.org/isc-private/bind-qa/-/blob/master/bind9/releng/version_bump.py)) and merge MRs resetting the release notes and updating the version string for each maintained branch.
- [ ] ***(QA)*** Rebase the Subscription Edition branches (including recent release prep commits) on top of the open source branches with updated version strings.
- [ ] ***(QA)*** Announce (on Mattermost) that the code freeze is over.
- [ ] ***(QA)*** Request signatures for the tarballs, providing their location and checksums. Ask [signers on Mattermost](https://mattermost.isc.org/isc/channels/bind-9-qa).
- [ ] ***(Signers)*** Ensure that the contents of tarballs and tags are identical.
- [ ] ***(Signers)*** Validate tarball checksums, sign tarballs, and upload signatures.
- [ ] ***(QA)*** Verify tarball signatures and check tarball checksums again: Run `publish_bind.sh` on repo.isc.org to pre-publish.
- [ ] ***(QA)*** Prepare the `patches/` subdirectory for each security release (if applicable).
- [ ] ***(QA)*** Pre-publish ASN and/or Subscription Edition tarballs so that packages can be built.
- [ ] ***(QA)*** Build and test ASN and/or Subscription Edition packages (in [cloudsmith branch in private repo](https://gitlab.isc.org/isc-private/rpms/bind/-/tree/cloudsmith)). [Example](https://gitlab.isc.org/isc-private/rpms/bind/-/commit/e2512f4cfaf991827a635e374e7e93b27a5f38ba)
- [ ] ***(Marketing)*** Prepare and send out ASN emails (as outlined in the CVE checklist; if applicable).
### On the Day of Public Release
- [ ] ***(QA)*** Wait for clearance from Security Officer to proceed with the public release (if applicable).
- [ ] ***(QA)*** Place tarballs in public location on FTP site.
- [ ] ***(QA)*** Inform Marketing of the release, providing FTP links for the published tarballs.
- [ ] ***(QA)*** Use the [Printing Press project](https://gitlab.isc.org/isc-private/printing-press/-/wikis/home#adding-new-documents) to prepare a release announcement email.
- [ ] ***(Marketing)*** Publish links to downloads on ISC website. [Example](https://gitlab.isc.org/website/theme-staging-site/-/commit/1ac7b30b73cb03228df4cd5651fa4e774ac35625)
- [ ] ***(Marketing)*** Update the BIND -S information document in SF with download links to the new versions. (If this is a security release, this will have already been done as part of the ASN process.)
- [ ] ***(Marketing)*** Update the Current Software Versions document in the SF portal if any stable versions were released.
- [ ] ***(Marketing)*** Send the release announcement email to the *bind-announce* mailing list (and to *bind-users* if a major release - [example](https://lists.isc.org/pipermail/bind-users/2022-January/105624.html)).
- [ ] ***(Marketing)*** Announce release on social media sites.
- [ ] ***(Marketing)*** Update [Wikipedia entry for BIND](https://en.wikipedia.org/wiki/BIND).
- [ ] ***(Support)*** Add the new releases to the [vulnerability matrix in the Knowledge Base](https://kb.isc.org/docs/aa-00913).
- [ ] ***(Support)*** Update tickets in case of waiting support customers.
- [ ] ***(QA)*** Build and test any outstanding private packages in [private repo](https://gitlab.isc.org/isc-private/rpms/bind/-/tree/cloudsmith). [Example](https://gitlab.isc.org/isc-private/rpms/bind/-/commit/2007d566db81dd9dfd79e571e2f600a3bc284da4)
- [ ] ***(QA)*** Build [public RPMs](https://gitlab.isc.org/isc-packages/rpms/bind). [Example commit](https://gitlab.isc.org/isc-packages/rpms/bind/-/commit/3b5e851ea7c4e3570371a4878b5461f02a44f8cc) which triggers [Copr builds](https://copr.fedorainfracloud.org/coprs/isc/) automatically
- [ ] ***(SwEng)*** Build Debian/Ubuntu packages.
- [ ] ***(SwEng)*** Update Docker files [here](https://gitlab.isc.org/isc-projects/bind9-docker/-/branches) and make sure push is synchronized to [GitHub](https://github.com/isc-projects/bind9-docker). [Docker Hub](https://hub.docker.com/r/internetsystemsconsortium/bind9) should pick it up automatically. [Example](https://gitlab.isc.org/isc-projects/bind9-docker/-/commit/cada7e10e9af951595c98bfffc4bd42512faac05)
- [ ] ***(QA)*** Ensure all new tags are annotated and signed. `git show --show-signature v9.19.12`
- [ ] ***(QA)*** Push tags for the published releases to the public repository.
- [ ] ***(QA)*** Using [`merge_tag.py`](https://gitlab.isc.org/isc-private/bind-qa/-/blob/master/bind9/releng/merge_tag.py), merge published release tags back into the their relevant development/maintenance branches.
- [ ] ***(QA)*** Ensure `allow_failure: true` is removed from the `cross-version-config-tests` job if it was set during the current release cycle.
- [ ] ***(QA)*** Sanitize confidential issues which are assigned to the current release milestone and do not describe a security vulnerability, then make them public.
- [ ] ***(QA)*** Sanitize [confidential issues](https://gitlab.isc.org/isc-projects/bind9/-/issues/?sort=milestone_due_desc&state=opened&confidential=yes) which are assigned to older release milestones and describe security vulnerabilities, then make them public if appropriate[^2].
- [ ] ***(QA)*** Update QA tools used in GitLab CI (e.g. Black, PyLint, Sphinx) by modifying the relevant [`Dockerfile`](https://gitlab.isc.org/isc-projects/images/-/merge_requests/228/diffs).
- [ ] ***(QA)*** Run a pipeline to rebuild all [images](https://gitlab.isc.org/isc-projects/images) used in GitLab CI.
- [ ] ***(QA)*** Update [`metadata.json`](https://gitlab.isc.org/isc-private/bind-qa/-/blob/master/bind9/releng/metadata.json) with the upcoming release information.
[^1]: If not, use the time remaining until the tagging deadline to ensure all outstanding issues are either resolved or moved to a different milestone.
[^2]: As a rule of thumb, security vulnerabilities which have reproducers merged to the public repository are considered okay for full disclosure.
+74
View File
@@ -1,3 +1,77 @@
6380. [func] Queries and responses now emit distinct dnstap entries
for DoT and DoH. [GL #4523]
6379. [bug] A QP iterator bug could result in DNSSEC validation
failing because the wrong NSEC was returned. [GL #4659]
6378. [func] The option to specify the number of UDP dispatches was
previously removed. An attempt to use the option now
prints a warning. [GL #1879]
6377. [func] Introduce 'dnssec-ksr', a DNSSEC tool to create
Key Signing Requests (KSRs) and Signed Key Responses
(SKRs). [GL #1128]
6376. [func] Allow 'dnssec-keygen' options '-f' and '-k' to be used
together to create a subset of keys from the DNSSEC
policy. [GL !8188]
6375. [func] Allow multiple RNDC message to be processed from
a single TCP read. [GL #4416]
6374. [func] Don't count expired / future RRSIGs in verification
failure quota. [GL #4586]
6373. [func] Offload the isc_http response processing to worker
thread. [GL #4680]
6372. [func] Implement signature jitter for dnssec-policy. [GL #4554]
6371. [bug] Access to the trust bytes in the ncache data needed to
be made thread safe. [GL #4475]
6370. [bug] Wrong source address used for IPv6 notify messages.
[GL #4669]
--- 9.19.23 released ---
6369. [func] The 'fixed' value for the 'rrset-order' option has
been marked and documented as deprecated. [GL #4446]
6368. [func] The 'sortlist' option has been marked and documented
as deprecated. [GL #4593]
6367. [bug] Since the dns_validator_destroy() function doesn't
guarantee that it destroys the validator, rename it to
dns_validator_shutdown() and require explicit
dns_validator_detach() to follow. Implement an expected
behavior of the function to release a name associated
with the validator. [GL #4654]
6366. [bug] An assertion could be triggered in the QPDB cache when
encountering a delegation below a DNAME. [GL #4652]
6365. [placeholder]
6364. [protocol] Add RESOLVER.ARPA to the built in empty zones.
[GL #4580]
6363. [bug] dig/mdig +ednsflags=<non-zero-value> did not re-enable
EDNS if it had been disabled. [GL #4641]
6362. [bug] Reduce memory consumption of QP-trie based databases
by dynamically allocating the nodenames. [GL #4614]
6361. [bug] Some invalid ISO 8601 durations were accepted
erroneously. [GL #4624]
6360. [bug] Don't return static-stub synthesised NS RRset.
[GL #4608]
6359. [bug] Fix bug in Depends (keymgr_dep) function. [GL #4552]
--- 9.19.22 released ---
6358. [bug] Fix validate_dnskey_dsset when KSK is not signing,
do not skip remainder of DS RRset. [GL #4625]
+5 -6
View File
@@ -2103,9 +2103,8 @@ sendquery(void *arg) {
dns_view_attach(view, &(dns_view_t *){ NULL });
CHECK(dns_request_create(requestmgr, message, NULL, &peer, NULL, NULL,
DNS_REQUESTOPT_TCP, NULL, 1, 0, 0,
isc_loop_current(loopmgr), recvresponse,
message, &request));
DNS_REQUESTOPT_TCP, NULL, 1, 0, 0, isc_loop(),
recvresponse, message, &request));
return;
cleanup:
@@ -2167,8 +2166,8 @@ run_server(void *arg) {
dns_view_initsecroots(view);
CHECK(setup_dnsseckeys(NULL, view));
CHECK(dns_view_createresolver(view, loopmgr, netmgr, 0,
tlsctx_client_cache, dispatch, NULL));
CHECK(dns_view_createresolver(view, netmgr, 0, tlsctx_client_cache,
dispatch, NULL));
isc_stats_create(mctx, &resstats, dns_resstatscounter_max);
dns_resolver_setstats(view->resolver, resstats);
@@ -2187,7 +2186,7 @@ run_server(void *arg) {
NULL, NULL, ISC_NM_PROXY_NONE,
&ifp->tcplistensocket));
ifp->flags |= NS_INTERFACEFLAG_LISTENING;
isc_async_current(loopmgr, sendquery, ifp->tcplistensocket);
isc_async_current(sendquery, ifp->tcplistensocket);
return;
+4
View File
@@ -1797,6 +1797,10 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
"ednsflags");
goto exit_or_usage;
}
if (lookup->edns == -1) {
lookup->edns =
DEFAULT_EDNS_VERSION;
}
lookup->ednsflags = num;
break;
case 'n':
+1
View File
@@ -2,6 +2,7 @@ dnssec-cds
dnssec-dsfromkey
dnssec-keyfromlabel
dnssec-keygen
dnssec-ksr
dnssec-makekeyset
dnssec-revoke
dnssec-settime
+3 -4
View File
@@ -2,6 +2,7 @@ include $(top_srcdir)/Makefile.top
AM_CPPFLAGS += \
$(LIBISC_CFLAGS) \
$(LIBISCCFG_CFLAGS) \
$(LIBDNS_CFLAGS)
AM_CPPFLAGS += \
@@ -12,6 +13,7 @@ noinst_LTLIBRARIES = libdnssectool.la
LDADD += \
libdnssectool.la \
$(LIBISC_LIBS) \
$(LIBISCCFG_LIBS) \
$(LIBDNS_LIBS) \
$(OPENSSL_LIBS)
@@ -21,6 +23,7 @@ bin_PROGRAMS = \
dnssec-importkey \
dnssec-keyfromlabel \
dnssec-keygen \
dnssec-ksr \
dnssec-revoke \
dnssec-settime \
dnssec-signzone \
@@ -32,20 +35,16 @@ libdnssectool_la_SOURCES = \
dnssec_keygen_CPPFLAGS = \
$(AM_CPPFLAGS) \
$(LIBISCCFG_CFLAGS) \
$(OPENSSL_CFLAGS)
dnssec_keygen_LDADD = \
$(LDADD) \
$(LIBISCCFG_LIBS) \
$(OPENSSL_LIBS)
dnssec_signzone_CPPFLAGS = \
$(AM_CPPFLAGS) \
$(LIBISCCFG_CFLAGS) \
$(OPENSSL_CFLAGS)
dnssec_signzone_LDADD = \
$(LDADD) \
$(LIBISCCFG_LIBS) \
$(OPENSSL_LIBS)
+8 -3
View File
@@ -54,6 +54,7 @@ static dns_name_t *name = NULL;
static isc_mem_t *mctx = NULL;
static uint32_t ttl;
static bool emitttl = false;
static unsigned int split_width = 0;
static isc_result_t
initname(char *setname) {
@@ -279,8 +280,8 @@ emit(dns_dsdigest_t dt, bool showall, bool cds, dns_rdata_t *rdata) {
fatal("can't print name");
}
result = dns_rdata_tofmttext(&ds, (dns_name_t *)NULL, 0, 0, 0, "",
&textb);
result = dns_rdata_tofmttext(&ds, (dns_name_t *)NULL, 0, 0, split_width,
"", &textb);
if (result != ISC_R_SUCCESS) {
fatal("can't print rdata");
@@ -347,6 +348,7 @@ usage(void) {
" -f zonefile: read keys from a zone file\n"
" -h: print help information\n"
" -K directory: where to find key or keyset files\n"
" -w split base64 rdata text into chunks\n"
" -s: read keys from keyset-<dnsname> file\n"
" -T: TTL of output records (omitted by default)\n"
" -v level: verbosity\n"
@@ -380,7 +382,7 @@ main(int argc, char **argv) {
isc_commandline_errprint = false;
#define OPTIONS "12Aa:Cc:d:Ff:K:l:sT:v:hV"
#define OPTIONS "12Aa:Cc:d:Ff:K:l:sT:v:whV"
while ((ch = isc_commandline_parse(argc, argv, OPTIONS)) != -1) {
switch (ch) {
case '1':
@@ -432,6 +434,9 @@ main(int argc, char **argv) {
fatal("-v must be followed by a number");
}
break;
case 'w':
split_width = UINT_MAX;
break;
case 'F':
/* Reserved for FIPS mode */
FALLTHROUGH;
+28 -112
View File
@@ -56,10 +56,6 @@
#include <dst/dst.h>
#include <isccfg/cfg.h>
#include <isccfg/grammar.h>
#include <isccfg/kaspconf.h>
#include <isccfg/namedconf.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000
#include <openssl/err.h>
#include <openssl/provider.h>
@@ -67,9 +63,6 @@
#include "dnssectool.h"
#define MAX_RSA 4096 /* should be long enough... */
#define MAX_DH 4096 /* should be long enough... */
const char *program = "dnssec-keygen";
/*
@@ -103,8 +96,9 @@ struct keygen_ctx {
int options;
int dbits;
dns_ttl_t ttl;
uint16_t kskflag;
uint16_t revflag;
bool wantzsk;
bool wantksk;
bool wantrev;
dns_secalg_t alg;
/* timing data */
int prepub;
@@ -184,7 +178,7 @@ usage(void) {
fprintf(stderr, " -d <digest bits> (0 => max, default)\n");
fprintf(stderr, " -E <engine>:\n");
fprintf(stderr, " name of an OpenSSL engine to use\n");
fprintf(stderr, " -f <keyflag>: KSK | REVOKE\n");
fprintf(stderr, " -f <keyflag>: ZSK | KSK | REVOKE\n");
fprintf(stderr, " -F: FIPS mode\n");
fprintf(stderr, " -L <ttl>: default key TTL\n");
fprintf(stderr, " -p <protocol>: (default: 3 [dnssec])\n");
@@ -254,90 +248,6 @@ progress(int p) {
(void)fflush(stderr);
}
static void
kasp_from_conf(cfg_obj_t *config, isc_mem_t *mctx, const char *name,
const char *keydir, const char *engine, dns_kasp_t **kaspp) {
isc_result_t result = ISC_R_NOTFOUND;
const cfg_listelt_t *element;
const cfg_obj_t *kasps = NULL;
dns_kasp_t *kasp = NULL, *kasp_next;
dns_kasplist_t kasplist;
const cfg_obj_t *keystores = NULL;
dns_keystore_t *ks = NULL, *ks_next;
dns_keystorelist_t kslist;
ISC_LIST_INIT(kasplist);
ISC_LIST_INIT(kslist);
(void)cfg_map_get(config, "key-store", &keystores);
for (element = cfg_list_first(keystores); element != NULL;
element = cfg_list_next(element))
{
cfg_obj_t *kconfig = cfg_listelt_value(element);
ks = NULL;
result = cfg_keystore_fromconfig(kconfig, mctx, lctx, engine,
&kslist, NULL);
if (result != ISC_R_SUCCESS) {
fatal("failed to configure key-store '%s': %s",
cfg_obj_asstring(cfg_tuple_get(kconfig, "name")),
isc_result_totext(result));
}
}
/* Default key-directory key store. */
ks = NULL;
(void)cfg_keystore_fromconfig(NULL, mctx, lctx, engine, &kslist, &ks);
INSIST(ks != NULL);
if (keydir != NULL) {
/* '-K keydir' takes priority */
dns_keystore_setdirectory(ks, keydir);
}
dns_keystore_detach(&ks);
(void)cfg_map_get(config, "dnssec-policy", &kasps);
for (element = cfg_list_first(kasps); element != NULL;
element = cfg_list_next(element))
{
cfg_obj_t *kconfig = cfg_listelt_value(element);
kasp = NULL;
if (strcmp(cfg_obj_asstring(cfg_tuple_get(kconfig, "name")),
name) != 0)
{
continue;
}
result = cfg_kasp_fromconfig(kconfig, NULL, true, mctx, lctx,
&kslist, &kasplist, &kasp);
if (result != ISC_R_SUCCESS) {
fatal("failed to configure dnssec-policy '%s': %s",
cfg_obj_asstring(cfg_tuple_get(kconfig, "name")),
isc_result_totext(result));
}
INSIST(kasp != NULL);
dns_kasp_freeze(kasp);
break;
}
*kaspp = kasp;
/*
* Cleanup kasp list.
*/
for (kasp = ISC_LIST_HEAD(kasplist); kasp != NULL; kasp = kasp_next) {
kasp_next = ISC_LIST_NEXT(kasp, link);
ISC_LIST_UNLINK(kasplist, kasp, link);
dns_kasp_detach(&kasp);
}
/*
* Cleanup keystore list.
*/
for (ks = ISC_LIST_HEAD(kslist); ks != NULL; ks = ks_next) {
ks_next = ISC_LIST_NEXT(ks, link);
ISC_LIST_UNLINK(kslist, ks, link);
dns_keystore_detach(&ks);
}
}
static void
keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
char filename[255];
@@ -645,8 +555,12 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
if ((ctx->options & DST_TYPE_KEY) != 0) { /* KEY */
flags |= ctx->signatory;
} else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
flags |= ctx->kskflag;
flags |= ctx->revflag;
if (ctx->ksk || ctx->wantksk) {
flags |= DNS_KEYFLAG_KSK;
}
if (ctx->wantrev) {
flags |= DNS_KEYFLAG_REVOKE;
}
}
if (ctx->protocol == -1) {
@@ -769,7 +683,7 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
}
if (ctx->setrev) {
if (ctx->kskflag == 0) {
if (!ctx->wantksk) {
fprintf(stderr,
"%s: warning: Key is "
"not flagged as a KSK, but -R "
@@ -1013,9 +927,11 @@ main(int argc, char **argv) {
case 'f':
c = (unsigned char)(isc_commandline_argument[0]);
if (toupper(c) == 'K') {
ctx.kskflag = DNS_KEYFLAG_KSK;
ctx.wantksk = true;
} else if (toupper(c) == 'Z') {
ctx.wantzsk = true;
} else if (toupper(c) == 'R') {
ctx.revflag = DNS_KEYFLAG_REVOKE;
ctx.wantrev = true;
} else {
fatal("unknown flag '%s'",
isc_commandline_argument);
@@ -1289,8 +1205,8 @@ main(int argc, char **argv) {
if (ctx.size != -1) {
fatal("-k and -b cannot be used together");
}
if (ctx.kskflag || ctx.revflag) {
fatal("-k and -f cannot be used together");
if (ctx.wantrev) {
fatal("-k and -fR cannot be used together");
}
if (ctx.options & DST_TYPE_KEY) {
fatal("-k and -T KEY cannot be used together");
@@ -1305,7 +1221,6 @@ main(int argc, char **argv) {
ctx.use_nsec3 = false;
ctx.alg = DST_ALG_ECDSA256;
ctx.size = 0;
ctx.kskflag = DNS_KEYFLAG_KSK;
ctx.ttl = 3600;
ctx.setttl = true;
ctx.ksk = true;
@@ -1330,8 +1245,8 @@ main(int argc, char **argv) {
ctx.policy, ctx.configfile);
}
kasp_from_conf(config, mctx, ctx.policy, ctx.directory,
engine, &kasp);
kasp_from_conf(config, mctx, lctx, ctx.policy,
ctx.directory, engine, &kasp);
if (kasp == NULL) {
fatal("failed to load dnssec-policy '%s'",
ctx.policy);
@@ -1345,15 +1260,13 @@ main(int argc, char **argv) {
ctx.ttl = dns_kasp_dnskeyttl(kasp);
ctx.setttl = true;
kaspkey = ISC_LIST_HEAD(dns_kasp_keys(kasp));
while (kaspkey != NULL) {
for (kaspkey = ISC_LIST_HEAD(dns_kasp_keys(kasp));
kaspkey != NULL;
kaspkey = ISC_LIST_NEXT(kaspkey, link))
{
ctx.use_nsec3 = false;
ctx.alg = dns_kasp_key_algorithm(kaspkey);
ctx.size = dns_kasp_key_size(kaspkey);
ctx.kskflag = dns_kasp_key_ksk(kaspkey)
? DNS_KEYFLAG_KSK
: 0;
ctx.ksk = dns_kasp_key_ksk(kaspkey);
ctx.zsk = dns_kasp_key_zsk(kaspkey);
ctx.lifetime = dns_kasp_key_lifetime(kaspkey);
@@ -1361,9 +1274,12 @@ main(int argc, char **argv) {
if (ctx.keystore != NULL) {
check_keystore_options(&ctx);
}
if ((ctx.ksk && !ctx.wantksk && ctx.wantzsk) ||
(ctx.zsk && !ctx.wantzsk && ctx.wantksk))
{
continue;
}
keygen(&ctx, mctx, argc, argv);
kaspkey = ISC_LIST_NEXT(kaspkey, link);
}
dns_kasp_detach(&kasp);
+7 -1
View File
@@ -105,7 +105,13 @@ Options
.. option:: -f flag
This option sets the specified flag in the flag field of the KEY/DNSKEY record.
The only recognized flags are KSK (Key-Signing Key) and REVOKE.
The only recognized flags are ZSK (Zone-Signing Key), KSK (Key-Signing Key)
and REVOKE.
Note that ZSK is not a physical flag in the DNSKEY record, it is merely used
to explicitly tell that you want to create a ZSK. Setting :option:`-f` in
conjunction with :option:`-k` will result in generating keys that only
match the given role set with this option.
.. option:: -F
File diff suppressed because it is too large Load Diff
+159
View File
@@ -0,0 +1,159 @@
.. Copyright (C) Internet Systems Consortium, Inc. ("ISC")
..
.. SPDX-License-Identifier: MPL-2.0
..
.. This Source Code Form is subject to the terms of the Mozilla Public
.. License, v. 2.0. If a copy of the MPL was not distributed with this
.. file, you can obtain one at https://mozilla.org/MPL/2.0/.
..
.. See the COPYRIGHT file distributed with this work for additional
.. information regarding copyright ownership.
.. highlight: console
.. iscman:: dnssec-ksr
.. program:: dnssec-ksr
.. _man_dnssec-ksr:
dnssec-ksr - Create signed key response (SKR) files for offline KSK setups
--------------------------------------------------------------------------
Synopsis
~~~~~~~~
:program:`dnssec-ksr` [**-E** engine] [**-e** date/offset] [**-F**] [**-h**] [**-i** date/offset] [**-K** directory] [**-k** policy] [**-l** file] [**-V**] [**-v** level] {command} {zone}
Description
~~~~~~~~~~~
The :program:`dnssec-ksr` can be used to issue several commands that are needed
to generate presigned RRsets for a zone where the private key file of the Key
Signing Key (KSK) is typically offline. This requires Zone Signing Keys
(ZSKs) to be pregenerated, and the DNSKEY, CDNSKEY, and CDS RRsets to be
already signed in advance.
The latter is done by creating Key Signing Requests (KSRs) that can be imported
to the environment where the KSK is available. Once there, this program can
create Signed Key Responses (SKRs) that can be loaded by an authoritative DNS
server.
Options
~~~~~~~
.. option:: -E engine
This option specifies the cryptographic hardware to use, when applicable.
When BIND 9 is built with OpenSSL, this needs to be set to the OpenSSL
engine identifier that drives the cryptographic accelerator or
hardware service module (usually ``pkcs11``).
.. option:: -e date/offset
This option sets the end date for which keys or SKRs need to be generated
(depending on the command).
.. option:: -F
This options turns on FIPS (US Federal Information Processing Standards)
mode if the underlying crytographic library supports running in FIPS
mode.
.. option:: -h
This option prints a short summary of the options and arguments to
:program:`dnssec-ksr`.
.. option:: -i date/offset
This option sets the start date for which keys or SKRs need to be generated
(depending on the command).
.. option:: -K directory
This option sets the directory in which the key files are to be read or
written (depending on the command).
.. option:: -k policy
This option sets the specific ``dnssec-policy`` for which keys need to
be generated, or signed.
.. option:: -l file
This option provides a configuration file that contains a ``dnssec-policy``
statement (matching the policy set with :option:`-k`).
.. option:: -V
This option prints version information.
.. option:: -v level
This option sets the debugging level. Level 1 is intended to be usefully
verbose for general users; higher levels are intended for developers.
``command``
The KSR command to be executed. See below for the available commands.
``zone``
The name of the zone for which the KSR command is being executed.
Commands
~~~~~~~~
.. option:: keygen
Pregenerate a number of zone signing keys (ZSKs), given a DNSSEC policy and
an interval. The number of generated keys depends on the interval and the
ZSK lifetime.
.. option:: request
Create a Key Signing Request (KSR), given a DNSSEC policy and an interval.
.. option:: sign
Sign a Key Signing Request (KSR), given a DNSSEC policy and an interval,
creating a Signed Key Response (SKR).
Exit Status
~~~~~~~~~~~
The :program:`dnssec-ksr` command exits 0 on success, or non-zero if an error
occurred.
Examples
~~~~~~~~
When you need to generate keys for the zone "example.com" for the next year,
given a ``dnssec-policy`` named "mypolicy":
::
dnssec-ksr -i now -e +1y -k mypolicy -l named.conf keygen example.com
Creating a KSR for the same zone and period can be done with:
::
dnssec-ksr -i now -e +1y -k mypolicy -l named.conf request example.com > ksr.txt
Typically you would now transfer the KSR to the system that has access to the KSK.
Signing the KSR created above can be done with:
::
dnssec-ksr -i now -e +1y -k kskpolicy -l named.conf -f ksr.txt sign example.com
Make sure that the DNSSEC parameters in ``kskpolicy`` match those in ``mypolicy``.
See Also
~~~~~~~~
:iscman:`dnssec-keygen(8) <dnssec-keygen>`,
:iscman:`dnssec-signzone(8) <dnssec-signzone>`,
BIND 9 Administrator Reference Manual.
+1 -1
View File
@@ -1674,7 +1674,7 @@ assignwork(void *arg) {
lock_and_dumpnode(dns_fixedname_name(&fname), node);
dns_db_detachnode(gdb, &node);
isc_async_current(loopmgr, assignwork, NULL);
isc_async_current(assignwork, NULL);
}
/*%
+85
View File
@@ -602,3 +602,88 @@ loadjournal(isc_mem_t *mctx, dns_db_t *db, const char *file) {
cleanup:
dns_journal_destroy(&jnl);
}
void
kasp_from_conf(cfg_obj_t *config, isc_mem_t *mctx, isc_log_t *lctx,
const char *name, const char *keydir, const char *engine,
dns_kasp_t **kaspp) {
isc_result_t result = ISC_R_NOTFOUND;
const cfg_listelt_t *element;
const cfg_obj_t *kasps = NULL;
dns_kasp_t *kasp = NULL, *kasp_next;
dns_kasplist_t kasplist;
const cfg_obj_t *keystores = NULL;
dns_keystore_t *ks = NULL, *ks_next;
dns_keystorelist_t kslist;
ISC_LIST_INIT(kasplist);
ISC_LIST_INIT(kslist);
(void)cfg_map_get(config, "key-store", &keystores);
for (element = cfg_list_first(keystores); element != NULL;
element = cfg_list_next(element))
{
cfg_obj_t *kconfig = cfg_listelt_value(element);
ks = NULL;
result = cfg_keystore_fromconfig(kconfig, mctx, lctx, engine,
&kslist, NULL);
if (result != ISC_R_SUCCESS) {
fatal("failed to configure key-store '%s': %s",
cfg_obj_asstring(cfg_tuple_get(kconfig, "name")),
isc_result_totext(result));
}
}
/* Default key-directory key store. */
ks = NULL;
(void)cfg_keystore_fromconfig(NULL, mctx, lctx, engine, &kslist, &ks);
INSIST(ks != NULL);
if (keydir != NULL) {
/* '-K keydir' takes priority */
dns_keystore_setdirectory(ks, keydir);
}
dns_keystore_detach(&ks);
(void)cfg_map_get(config, "dnssec-policy", &kasps);
for (element = cfg_list_first(kasps); element != NULL;
element = cfg_list_next(element))
{
cfg_obj_t *kconfig = cfg_listelt_value(element);
kasp = NULL;
if (strcmp(cfg_obj_asstring(cfg_tuple_get(kconfig, "name")),
name) != 0)
{
continue;
}
result = cfg_kasp_fromconfig(kconfig, NULL, true, mctx, lctx,
&kslist, &kasplist, &kasp);
if (result != ISC_R_SUCCESS) {
fatal("failed to configure dnssec-policy '%s': %s",
cfg_obj_asstring(cfg_tuple_get(kconfig, "name")),
isc_result_totext(result));
}
INSIST(kasp != NULL);
dns_kasp_freeze(kasp);
break;
}
*kaspp = kasp;
/*
* Cleanup kasp list.
*/
for (kasp = ISC_LIST_HEAD(kasplist); kasp != NULL; kasp = kasp_next) {
kasp_next = ISC_LIST_NEXT(kasp, link);
ISC_LIST_UNLINK(kasplist, kasp, link);
dns_kasp_detach(&kasp);
}
/*
* Cleanup keystore list.
*/
for (ks = ISC_LIST_HEAD(kslist); ks != NULL; ks = ks_next) {
ks_next = ISC_LIST_NEXT(ks, link);
ISC_LIST_UNLINK(kslist, ks, link);
dns_keystore_detach(&ks);
}
}
+13
View File
@@ -20,10 +20,18 @@
#include <isc/log.h>
#include <isc/stdtime.h>
#include <dns/kasp.h>
#include <dns/rdatastruct.h>
#include <dst/dst.h>
#include <isccfg/cfg.h>
#include <isccfg/kaspconf.h>
#include <isccfg/namedconf.h>
#define MAX_RSA 4096 /* should be long enough... */
#define MAX_DH 4096 /* should be long enough... */
/*! verbosity: set by -v and -q option in each program, defined in dnssectool.c
*/
extern int verbose;
@@ -108,3 +116,8 @@ isoptarg(const char *arg, char **argv, void (*usage)(void));
void
loadjournal(isc_mem_t *mctx, dns_db_t *db, const char *journal);
void
kasp_from_conf(cfg_obj_t *config, isc_mem_t *mctx, isc_log_t *lctx,
const char *name, const char *keydir, const char *engine,
dns_kasp_t **kaspp);
+1
View File
@@ -298,6 +298,7 @@ dnssec-policy \"default\" {\n\
publish-safety " DNS_KASP_PUBLISH_SAFETY "; \n\
retire-safety " DNS_KASP_RETIRE_SAFETY "; \n\
purge-keys " DNS_KASP_PURGE_KEYS "; \n\
signatures-jitter " DNS_KASP_SIG_JITTER "; \n\
signatures-refresh " DNS_KASP_SIG_REFRESH "; \n\
signatures-validity " DNS_KASP_SIG_VALIDITY "; \n\
signatures-validity-dnskey " DNS_KASP_SIG_VALIDITY_DNSKEY "; \n\
+1
View File
@@ -949,6 +949,7 @@ parse_command_line(int argc, char *argv[]) {
break;
case 'U':
/* Obsolete. No longer in use. Ignore. */
named_main_earlywarning("option '-U' has been removed");
break;
case 'u':
named_g_username = isc_commandline_argument;
+2 -9
View File
@@ -21,7 +21,7 @@ named - Internet domain name server
Synopsis
~~~~~~~~
:program:`named` [ [**-4**] | [**-6**] ] [**-c** config-file] [**-C**] [**-d** debug-level] [**-D** string] [**-E** engine-name] [**-f**] [**-g**] [**-L** logfile] [**-M** option] [**-m** flag] [**-n** #cpus] [**-p** port] [**-s**] [**-t** directory] [**-U** #listeners] [**-u** user] [**-v**] [**-V**] ]
:program:`named` [ [**-4**] | [**-6**] ] [**-c** config-file] [**-C**] [**-d** debug-level] [**-D** string] [**-E** engine-name] [**-f**] [**-g**] [**-L** logfile] [**-M** option] [**-m** flag] [**-n** #cpus] [**-p** port] [**-s**] [**-t** directory] [**-u** user] [**-v**] [**-V**] ]
Description
~~~~~~~~~~~
@@ -163,14 +163,7 @@ Options
.. option:: -U #listeners
This option tells :program:`named` the number of ``#listeners`` worker threads to listen on, for incoming UDP packets on
each address. If not specified, :program:`named` calculates a default
value based on the number of detected CPUs: 1 for 1 CPU, and the
number of detected CPUs minus one for machines with more than 1 CPU.
This cannot be increased to a value higher than the number of CPUs.
If :option:`-n` has been set to a higher value than the number of detected
CPUs, then :option:`-U` may be increased as high as that value, but no
higher.
This option has been removed. Attempts to use it now result in a warning.
.. option:: -u user
+18 -19
View File
@@ -152,11 +152,11 @@
#endif /* HAVE_LMDB */
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#define SIZE_MAX ((size_t) - 1)
#endif /* ifndef SIZE_MAX */
#ifndef SIZE_AS_PERCENT
#define SIZE_AS_PERCENT ((size_t)-2)
#define SIZE_AS_PERCENT ((size_t) - 2)
#endif /* ifndef SIZE_AS_PERCENT */
/* RFC7828 defines timeout as 16-bit value specified in units of 100
@@ -400,6 +400,9 @@ const char *empty_zones[] = {
/* RFC 8375 */
"HOME.ARPA",
/* RFC 9462 */
"RESOLVER.ARPA",
NULL
};
@@ -4698,9 +4701,9 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
goto cleanup;
}
CHECK(dns_view_createresolver(
view, named_g_loopmgr, named_g_netmgr, resopts,
named_g_server->tlsctx_client_cache, dispatch4, dispatch6));
CHECK(dns_view_createresolver(view, named_g_netmgr, resopts,
named_g_server->tlsctx_client_cache,
dispatch4, dispatch6));
if (resstats == NULL) {
isc_stats_create(mctx, &resstats, dns_resstatscounter_max);
@@ -8184,7 +8187,7 @@ load_configuration(const char *filename, named_server_t *server,
/*
* Require the reconfiguration to happen always on the main loop
*/
REQUIRE(isc_loop_current(named_g_loopmgr) == named_g_mainloop);
REQUIRE(isc_loop() == named_g_mainloop);
ISC_LIST_INIT(kasplist);
ISC_LIST_INIT(keystorelist);
@@ -9835,8 +9838,7 @@ run_server(void *arg) {
named_server_t *server = (named_server_t *)arg;
dns_geoip_databases_t *geoip = NULL;
dns_zonemgr_create(named_g_mctx, named_g_loopmgr, named_g_netmgr,
&server->zonemgr);
dns_zonemgr_create(named_g_mctx, named_g_netmgr, &server->zonemgr);
CHECKFATAL(dns_dispatchmgr_create(named_g_mctx, named_g_loopmgr,
named_g_netmgr, &named_g_dispatchmgr),
@@ -15079,29 +15081,26 @@ named_server_zonestatus(named_server_t *server, isc_lex_t *lex,
{
dns_name_t *name;
dns_fixedname_t fixed;
dns_rdataset_t next;
isc_stdtime_t resign;
dns_typepair_t typepair;
dns_rdataset_init(&next);
name = dns_fixedname_initname(&fixed);
result = dns_db_getsigningtime(db, &next, name);
result = dns_db_getsigningtime(db, &resign, name, &typepair);
if (result == ISC_R_SUCCESS) {
char namebuf[DNS_NAME_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
resign -= dns_zone_getsigresigninginterval(zone);
dns_name_format(name, namebuf, sizeof(namebuf));
dns_rdatatype_format(next.covers, typebuf,
sizeof(typebuf));
dns_rdatatype_format(DNS_TYPEPAIR_COVERS(typepair),
typebuf, sizeof(typebuf));
snprintf(resignbuf, sizeof(resignbuf), "%s/%s", namebuf,
typebuf);
isc_time_set(
&resigntime,
next.resign -
dns_zone_getsigresigninginterval(zone),
0);
isc_time_set(&resigntime, resign, 0);
isc_time_formathttptimestamp(&resigntime, rtbuf,
sizeof(rtbuf));
dns_rdataset_disassociate(&next);
}
}
+1 -1
View File
@@ -2484,7 +2484,7 @@ static void
done_update(void) {
ddebug("done_update()");
isc_async_current(loopmgr, getinput, NULL);
isc_async_current(getinput, NULL);
}
static void
+2 -4
View File
@@ -305,8 +305,7 @@ rndc_recvdone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
fatal("recv failed: %s", isc_result_totext(result));
}
source.rstart = isc_buffer_base(ccmsg->buffer);
source.rend = isc_buffer_used(ccmsg->buffer);
isccc_ccmsg_toregion(ccmsg, &source);
DO("parse message",
isccc_cc_fromwire(&source, &response, algorithm, &secret));
@@ -381,8 +380,7 @@ rndc_recvnonce(isc_nmhandle_t *handle ISC_ATTR_UNUSED, isc_result_t result,
fatal("recv failed: %s", isc_result_totext(result));
}
source.rstart = isc_buffer_base(ccmsg->buffer);
source.rend = isc_buffer_used(ccmsg->buffer);
isccc_ccmsg_toregion(ccmsg, &source);
DO("parse message",
isccc_cc_fromwire(&source, &response, algorithm, &secret));
+1
View File
@@ -128,6 +128,7 @@ TESTS = \
kasp \
keepalive \
keyfromlabel \
ksr \
legacy \
limits \
logfileconfig \
@@ -87,6 +87,7 @@ dnssec-policy "jitter" {
signatures-validity P10D;
signatures-validity-dnskey P10D;
signatures-refresh P2D;
signatures-jitter P8D;
};
# Jitter, NSEC3
+4 -4
View File
@@ -91,10 +91,10 @@ checkjitter() {
_count=0
# Check if we have at least 4 days
# This number has been tuned for `signatures-validity 10d; signatures-refresh 2d`, as
# 1 signature expiration dates should be spread out across at most 8 (10-2) days
# 2. we remove first and last day to remove frequency outlier, we are left with 6 (8-2) days
# 3. we subtract two more days to allow test pass on day boundaries, etc. leaving us with 4 (6-2)
# This number has been tuned for `signatures-validity 10d; signatures-jitter 8d`, as
# 1. signature expiration dates should be spread out across at most 8 days
# 2. we remove first and last day to remove frequency outlier, we are left with 6 days
# 3. we subtract two more days to allow test pass on day boundaries, etc. leaving us with 4 days
for _num in $_expiretimes; do
_count=$((_count + 1))
done
@@ -10,5 +10,9 @@
# information regarding copyright ownership.
import isctest.mark
@isctest.mark.flaky(max_runs=2)
def test_autosign(run_tests_sh):
run_tests_sh()
+3 -2
View File
@@ -120,7 +120,8 @@ A.E.F.IP6.ARPA
B.E.F.IP6.ARPA
8.B.D.0.1.0.0.2.IP6.ARPA
EMPTY.AS112.ARPA
HOME.ARPA"
HOME.ARPA
RESOLVER.ARPA"
n=$((n + 1))
ret=0
@@ -134,7 +135,7 @@ for zone in ${emptyzones}; do
count=$((count + 1))
done
lines=$(grep "automatic empty zone: " ns1/named.run | wc -l)
test $count -eq $lines -a $count -eq 99 || {
test $count -eq $lines -a $count -eq 100 || {
ret=1
echo_i "failed (count mismatch)"
}
+31 -7
View File
@@ -51,22 +51,22 @@ sub reply_handler {
STDOUT->flush();
if ($qname eq "example.broken") {
if ($qtype eq "SOA") {
if ($qtype eq "SOA") {
my $rr = new Net::DNS::RR("$qname $ttl $qclass SOA . . 0 0 0 0 0");
push @ans, $rr;
} elsif ($qtype eq "NS") {
} elsif ($qtype eq "NS") {
my $rr = new Net::DNS::RR("$qname $ttl $qclass NS $nsname");
push @ans, $rr;
$rr = new Net::DNS::RR("$nsname $ttl $qclass A $localaddr");
push @add, $rr;
}
$rcode = "NOERROR";
}
$rcode = "NOERROR";
} elsif ($qname eq "cname-to-$synth2") {
my $rr = new Net::DNS::RR("$qname $ttl $qclass CNAME name.$synth2");
my $rr = new Net::DNS::RR("$qname $ttl $qclass CNAME name.$synth2");
push @ans, $rr;
$rr = new Net::DNS::RR("name.$synth2 $ttl $qclass CNAME name");
$rr = new Net::DNS::RR("name.$synth2 $ttl $qclass CNAME name");
push @ans, $rr;
$rr = new Net::DNS::RR("$synth2 $ttl $qclass DNAME .");
$rr = new Net::DNS::RR("$synth2 $ttl $qclass DNAME .");
push @ans, $rr;
$rcode = "NOERROR";
} elsif ($qname eq "$synth" || $qname eq "$synth2") {
@@ -115,6 +115,30 @@ sub reply_handler {
push @ans, $rr;
}
$rcode = "NOERROR";
# The next few branches produce a zone with an illegal NS below a DNAME.
} elsif ($qname eq "jeff.dname") {
if ($qtype eq "SOA") {
my $rr = new Net::DNS::RR("$qname $ttl $qclass SOA . . 0 0 0 0 0");
push @ans, $rr;
} elsif ($qtype eq "NS") {
my $rr = new Net::DNS::RR("$qname $ttl $qclass NS ns.jeff.dname.");
push @ans, $rr;
$rr = new Net::DNS::RR("$nsname $ttl $qclass A $localaddr");
push @add, $rr;
} elsif ($qtype eq "DNAME") {
my $rr = new Net::DNS::RR("$qname $ttl $qclass DNAME mutt.example.");
push @ans, $rr;
}
$rcode = "NOERROR";
} elsif ($qname eq "ns.jeff.dname") {
if ($qtype eq "A") {
my $rr = new Net::DNS::RR("$qname $ttl $qclass A 10.53.0.3");
push @ans, $rr;
} elsif ($qtype eq "AAAA") {
my $rr = new Net::DNS::RR("jeff.dname. $ttl $qclass SOA . . 0 0 0 0 $ttl");
push @auth, $rr;
}
$rcode = "NOERROR";
} else {
$rcode = "REFUSED";
}
+4
View File
@@ -30,6 +30,10 @@ ns3.example.broken. A 10.53.0.3
example.dname. NS ns3.example.dname.
ns3.example.dname. A 10.53.0.3
; regression test for illegal NS below DNAME
jeff.dname. NS ns.jeff.dname.
ns.jeff.dname. A 10.53.0.3
domain0.nil. NS ns2.domain0.nil
domain1.nil. NS ns2.domain0.nil
domain2.nil. NS ns2.domain0.nil
+3
View File
@@ -48,6 +48,9 @@ signed-sub2 NS ns2.sub2
signed-sub2 DS 44137 8 2 1CB4F54E0B4F4F85109143113A3C679716A2377D86EB0907846A03FB 0C0A3927
d CNAME d.signed-sub2
mutt NS ns5.mutt
ns5.mutt A 10.53.0.5
; long CNAME loop
loop CNAME goop
goop CNAME boop
+5
View File
@@ -40,3 +40,8 @@ zone "signed-sub5.example" {
type primary;
file "sub.db";
};
zone "mutt.example" {
type primary;
file "mutt.db";
};
+11
View File
@@ -626,5 +626,16 @@ grep 'status: NOERROR' dig.out.7.$n >/dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
# Regression test for GL #4652
n=$((n + 1))
echo_i "checking handling of illegal NS below DNAME ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.7 DNAME jeff.dname. >dig.out.ns7.1.$n 2>&1
grep 'status: NOERROR' dig.out.ns7.1.$n >/dev/null 2>&1 || ret=1
$DIG $DIGOPTS @10.53.0.7 NS jeff.dname. >dig.out.ns7.2.$n 2>&1
grep 'status: SERVFAIL' dig.out.ns7.2.$n >/dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
@@ -0,0 +1,25 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
dnssec-policy "invalid-sigrefresh" {
keys {
csk lifetime unlimited algorithm 13;
};
signatures-refresh P7.5D;
};
zone "example.net" {
type primary;
file "example.db";
dnssec-policy "invalid-sigrefresh";
};
@@ -0,0 +1,27 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*
* The dnssec-policy jitter is more than signatures-validity,
* which is not allowed.
*/
dnssec-policy high-jitter {
signatures-jitter P8DT1S;
signatures-validity P8D;
};
zone "example.net" {
type primary;
file "example.db";
dnssec-policy high-jitter;
};
@@ -28,6 +28,12 @@ options {
avoid-v6-udp-ports { range 1 1023; };
dnssec-must-be-secure mustbesecure.example yes;
sortlist { };
rrset-order {
name "fixed.example" order fixed;
};
};
trusted-keys {
@@ -34,6 +34,7 @@ dnssec-policy "test" {
parent-propagation-delay PT1H;
publish-safety PT3600S;
retire-safety PT3600S;
signatures-jitter PT12H;
signatures-refresh P3D;
signatures-validity P2W;
signatures-validity-dnskey P14D;
+1
View File
@@ -34,6 +34,7 @@ dnssec-policy "test" {
publish-safety PT3600S;
purge-keys P90D;
retire-safety PT3600S;
signatures-jitter PT12H;
signatures-refresh P3D;
signatures-validity P2W;
signatures-validity-dnskey P14D;
+14 -2
View File
@@ -165,6 +165,12 @@ warnings=$(grep "'notify' is disabled" <checkconf.out$n | wc -l)
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
if grep "^#define DNS_RDATASET_FIXED" "$TOP_BUILDDIR/config.h" >/dev/null 2>&1; then
test_fixed=true
else
test_fixed=false
fi
n=$((n + 1))
echo_i "checking named-checkconf deprecate warnings ($n)"
ret=0
@@ -179,12 +185,18 @@ grep "option 'avoid-v6-udp-ports' is deprecated" <checkconf.out$n.1 >/dev/null |
grep "option 'dialup' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
grep "option 'heartbeat-interval' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
grep "option 'dnssec-must-be-secure' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
grep "option 'sortlist' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
grep "token 'port' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
if $test_fixed; then
grep "rrset-order: order 'fixed' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
else
grep "rrset-order: order 'fixed' was disabled at compilation time" <checkconf.out$n.1 >/dev/null || ret=1
fi
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
# set -i to ignore deprecate warnings
$CHECKCONF -i deprecated.conf >checkconf.out$n.2 2>&1
grep '.*' <checkconf.out$n.2 >/dev/null && ret=1
$CHECKCONF -i deprecated.conf 2>&1 | grep_v "rrset-order: order 'fixed' was disabled at compilation time" >checkconf.out$n.2
grep '^.+$' <checkconf.out$n.2 >/dev/null && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
+2 -2
View File
@@ -86,8 +86,8 @@ status=$((status + ret))
echo_i "checking with max ttl (text) ($n)"
ret=0
$CHECKZONE -l 300 example zones/good1.db >test.out1.$n 2>&1 && ret=1
$CHECKZONE -l 600 example zones/good1.db >test.out2.$n 2>&1 || ret=1
$CHECKZONE -i local -l 300 example zones/good1.db >test.out1.$n 2>&1 && ret=1
$CHECKZONE -i local -l 600 example zones/good1.db >test.out2.$n 2>&1 || ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
+2
View File
@@ -650,3 +650,5 @@ parse_openssl_config() {
esac
done < "$OPENSSL_CONF"
}
grep_v() { grep -v "$@" || test $? = 1; }
+3
View File
@@ -42,6 +42,7 @@ export IMPORTKEY=$TOP_BUILDDIR/bin/dnssec/dnssec-importkey
export JOURNALPRINT=$TOP_BUILDDIR/bin/tools/named-journalprint
export KEYFRLAB=$TOP_BUILDDIR/bin/dnssec/dnssec-keyfromlabel
export KEYGEN=$TOP_BUILDDIR/bin/dnssec/dnssec-keygen
export KSR=$TOP_BUILDDIR/bin/dnssec/dnssec-ksr
export MDIG=$TOP_BUILDDIR/bin/tools/mdig
export NAMED=$TOP_BUILDDIR/bin/named/named
export NSEC3HASH=$TOP_BUILDDIR/bin/tools/nsec3hash
@@ -68,6 +69,8 @@ export KRB5_CONFIG=/dev/null
# use local keytab instead of default /etc/krb5.keytab
export KRB5_KTNAME=dns.keytab
export ANS_LOG_LEVEL=debug
#
# Programs detected by configure
# Variables will be empty if no program was found by configure
+3
View File
@@ -30,6 +30,9 @@ import isctest
# pylint: disable=redefined-outer-name
isctest.log.init_conftest_logger()
isctest.log.avoid_duplicated_logs()
# ----------------- Older pytest / xdist compatibility -------------------
# As of 2023-01-11, the minimal supported pytest / xdist versions are
# determined by what is available in EL8/EPEL8:
+1 -1
View File
@@ -6,7 +6,7 @@ scriptversion=2021-09-20.08 # UTC
# Copyright (C) 2011-2020 Free Software Foundation, Inc.
#
# SPDX-License-Identifier: GPL-2.0-or-later WITH LicenseRef-Automake-exception-2.0
# SPDX-License-Identifier: GPL-2.0-or-later WITH Autoconf-exception-generic
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@ import dns.message
def test_dialup_zone_transfer(named_port, servers, ns):
msg = dns.message.make_query("example.", "SOA")
# Drop the RD flag from the query
msg.flags -= dns.flags.RD
msg.flags &= ~dns.flags.RD
ns1response = isctest.query.tcp(msg, "10.53.0.1")
with servers[f"ns{ns}"].watch_log_from_start() as watcher:
watcher.wait_for_line(
+8
View File
@@ -1117,6 +1117,14 @@ if [ -x "$DIG" ]; then
grep -F "IN A 10.0.0.1" dig.out.test$n >/dev/null || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "check that dig +noedns +ednsflags=<nonzero> re-enables EDNS ($n)"
dig_with_opts @10.53.0.3 +qr +noedns +ednsflags=0x70 a.example >dig.out.test$n 2>&1 || ret=1
grep "; EDNS: version: 0, flags:; MBZ: 0x0070, udp: 1232" dig.out.test$n >/dev/null || ret=1
grep "; EDNS: version: 0, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
else
echo_i "$DIG is needed, so skipping these dig tests"
fi
+4 -5
View File
@@ -363,14 +363,13 @@ setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
}
static isc_result_t
getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
dns_name_t *name DNS__DB_FLARG) {
getsigningtime(dns_db_t *db, isc_stdtime_t *resign, dns_name_t *name,
dns_typepair_t *type) {
sampledb_t *sampledb = (sampledb_t *)db;
REQUIRE(VALID_SAMPLEDB(sampledb));
return (dns__db_getsigningtime(sampledb->rbtdb, rdataset,
name DNS__DB_FLARG_PASS));
return (dns_db_getsigningtime(sampledb->rbtdb, resign, name, type));
}
static dns_stats_t *
@@ -614,7 +613,7 @@ create_db(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
isc_mem_attach(mctx, &sampledb->common.mctx);
dns_name_init(&sampledb->common.origin, NULL);
CHECK(dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin));
dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin);
isc_refcount_init(&sampledb->common.references, 1);
+1 -1
View File
@@ -13,7 +13,7 @@
. ../conf.sh
[ "prereq/var/tmp/etc/openssl-provider.cnf" -eq "prereq${OPENSSL_CONF}" ] || {
[ "prereq/var/tmp/etc/openssl-provider.cnf" = "prereq${OPENSSL_CONF}" ] || {
echo_i "skip: pkcs11-provider not enabled"
exit 255
}
@@ -9,6 +9,9 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import isctest.mark
@isctest.mark.flaky(max_runs=3) # GL#4605
def test_enginepkcs11(run_tests_sh):
run_tests_sh()
-1
View File
@@ -18,7 +18,6 @@
rm -f */named.conf
rm -f */named.memstats
rm -f */named.run
rm -f dig.out
rm -f ns*/K*
rm -f ns*/dsset-*
rm -f ns*/managed-keys.bind*
-27
View File
@@ -1,27 +0,0 @@
; <<>> DiG 9.0 <<>> +norec @10.53.0.1 -p 5300 foo.bar.fi. A
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58772
;; flags: qr ad; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 7
;; QUESTION SECTION:
;foo.bar.fi. IN A
;; AUTHORITY SECTION:
fi. 172800 IN NS NS.EU.NET.
fi. 172800 IN NS NS.TELE.fi.
fi. 172800 IN NS PRIFI.EUNET.fi.
fi. 172800 IN NS NS.UU.NET.
fi. 172800 IN NS T.NS.VERIO.NET.
fi. 172800 IN NS HYDRA.HELSINKI.fi.
;; ADDITIONAL SECTION:
NS.TELE.fi. 172800 IN A 193.210.19.19
NS.TELE.fi. 172800 IN A 193.210.18.18
PRIFI.EUNET.fi. 172800 IN A 193.66.1.146
NS.UU.NET. 172800 IN A 137.39.1.3
T.NS.VERIO.NET. 172800 IN A 192.67.14.16
HYDRA.HELSINKI.fi. 172800 IN A 128.214.4.29
NS.EU.NET. 172800 IN A 192.16.202.11
-14
View File
@@ -1,14 +0,0 @@
; <<>> DiG 9.0 <<>> @10.53.0.1 -p 5300 example.net a
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29409
;; flags: qr rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 0
;; QUESTION SECTION:
;example.net. IN A
;; AUTHORITY SECTION:
example.net. 300 IN NS ns2.example.
example.net. 300 IN NS ns1.example.
-90
View File
@@ -1,90 +0,0 @@
#!/bin/sh
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
set -e
. ../conf.sh
dig_with_opts() {
"$DIG" +norec -p "${PORT}" "$@"
}
status=0
n=0
n=$((n + 1))
echo_i "testing that a ccTLD referral gets a full glue set from the root zone ($n)"
ret=0
dig_with_opts @10.53.0.1 foo.bar.fi. A >dig.out.$n || ret=1
digcomp --lc fi.good dig.out.$n || ret=1
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "testing that we don't find out-of-zone glue ($n)"
ret=0
dig_with_opts @10.53.0.1 example.net. A >dig.out.$n || ret=1
digcomp noglue.good dig.out.$n || ret=1
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "testing truncation for unsigned referrals close to UDP packet size limit (A glue) ($n)"
ret=0
dig_with_opts @10.53.0.1 +ignore +noedns foo.subdomain-a.tc-test-unsigned. >dig.out.$n || ret=1
grep -q "flags:[^;]* tc" dig.out.$n || ret=1
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "testing truncation for unsigned referrals close to UDP packet size limit (AAAA glue) ($n)"
ret=0
dig_with_opts @10.53.0.1 +ignore +noedns foo.subdomain-aaaa.tc-test-unsigned. >dig.out.$n || ret=1
grep -q "flags:[^;]* tc" dig.out.$n || ret=1
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "testing truncation for unsigned referrals close to UDP packet size limit (A+AAAA glue) ($n)"
ret=0
dig_with_opts @10.53.0.1 +ignore +noedns foo.subdomain-both.tc-test-unsigned. >dig.out.$n || ret=1
grep -q "flags:[^;]* tc" dig.out.$n || ret=1
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "testing truncation for signed referrals close to UDP packet size limit (A glue) ($n)"
ret=0
dig_with_opts @10.53.0.1 +ignore +dnssec +bufsize=512 foo.subdomain-a.tc-test-signed. >dig.out.$n || ret=1
grep -q "flags:[^;]* tc" dig.out.$n || ret=1
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "testing truncation for signed referrals close to UDP packet size limit (AAAA glue) ($n)"
ret=0
dig_with_opts @10.53.0.1 +ignore +dnssec +bufsize=512 foo.subdomain-aaaa.tc-test-signed. >dig.out.$n || ret=1
grep -q "flags:[^;]* tc" dig.out.$n || ret=1
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "testing truncation for signed referrals close to UDP packet size limit (A+AAAA glue) ($n)"
ret=0
dig_with_opts @10.53.0.1 +ignore +dnssec +bufsize=512 foo.subdomain-both.tc-test-signed. >dig.out.$n || ret=1
grep -q "flags:[^;]* tc" dig.out.$n || ret=1
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
+104
View File
@@ -0,0 +1,104 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import dns.message
import isctest
import pytest
pytest.importorskip("dns", minversion="2.0.0")
def test_glue_full_glue_set():
"""test that a ccTLD referral gets a full glue set from the root zone"""
msg = dns.message.make_query("foo.bar.fi", "A")
msg.flags &= ~dns.flags.RD
res = isctest.query.udp(msg, "10.53.0.1")
answer = """;ANSWER
;AUTHORITY
fi. 172800 IN NS HYDRA.HELSINKI.fi.
fi. 172800 IN NS NS.EU.NET.
fi. 172800 IN NS NS.UU.NET.
fi. 172800 IN NS NS.TELE.fi.
fi. 172800 IN NS T.NS.VERIO.NET.
fi. 172800 IN NS PRIFI.EUNET.fi.
;ADDITIONAL
NS.TELE.fi. 172800 IN A 193.210.18.18
NS.TELE.fi. 172800 IN A 193.210.19.19
PRIFI.EUNET.fi. 172800 IN A 193.66.1.146
HYDRA.HELSINKI.fi. 172800 IN A 128.214.4.29
NS.EU.NET. 172800 IN A 192.16.202.11
T.NS.VERIO.NET. 172800 IN A 192.67.14.16
NS.UU.NET. 172800 IN A 137.39.1.3
"""
expected_answer = dns.message.from_text(answer)
isctest.check.noerror(res)
isctest.check.rrsets_equal(res.answer, expected_answer.answer)
isctest.check.rrsets_equal(res.authority, expected_answer.authority)
isctest.check.rrsets_equal(res.additional, expected_answer.additional)
def test_glue_no_glue_set():
"""test that out-of-zone glue is not found"""
msg = dns.message.make_query("example.net.", "A")
msg.flags &= ~dns.flags.RD
res = isctest.query.udp(msg, "10.53.0.1")
answer = """;ANSWER
;AUTHORITY
example.net. 300 IN NS ns2.example.
example.net. 300 IN NS ns1.example.
;ADDITIONAL
"""
expected_answer = dns.message.from_text(answer)
isctest.check.noerror(res)
isctest.check.rrsets_equal(res.answer, expected_answer.answer)
isctest.check.rrsets_equal(res.authority, expected_answer.authority)
isctest.check.rrsets_equal(res.additional, expected_answer.additional)
@pytest.mark.parametrize(
"qname,dnssec",
[
# test truncation for unsigned referrals close to UDP packet size limit (A glue)
("foo.subdomain-a.tc-test-unsigned.", False),
# test truncation for unsigned referrals close to UDP packet size limit (AAAA glue)
("foo.subdomain-aaaa.tc-test-unsigned.", False),
# test truncation for unsigned referrals close to UDP packet size limit (A+AAAA glue)
("foo.subdomain-both.tc-test-unsigned.", False),
# test truncation for signed referrals close to UDP packet size limit (A glue)
("foo.subdomain-a.tc-test-signed.", True),
# test truncation for signed referrals close to UDP packet size limit (AAAA glue)
("foo.subdomain-aaaa.tc-test-signed.", True),
# test truncation for signed referrals close to UDP packet size limit (A+AAAA glue)
("foo.subdomain-both.tc-test-signed.", True),
],
)
def test_glue_truncation(qname, dnssec):
msg = dns.message.make_query(qname, "A")
msg.flags &= ~dns.flags.RD
if dnssec:
msg.use_edns(
payload=512,
# Zones used in this test were created with dig in mind that, unlike dnspython,
# by default, sets a cookie. Given that the message size must be close to the
# truncation limit, we also need to set a cookie here.
options=[dns.edns.GenericOption(dns.edns.OptionType.COOKIE, b"0xda13cc")],
)
msg.want_dnssec(wanted=True)
res = isctest.query.udp(msg, "10.53.0.1")
isctest.check.noerror(res)
assert res.flags & dns.flags.TC
+799
View File
@@ -0,0 +1,799 @@
"""
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
SPDX-License-Identifier: MPL-2.0
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, you can obtain one at https://mozilla.org/MPL/2.0/.
See the COPYRIGHT file distributed with this work for additional
information regarding copyright ownership.
"""
from dataclasses import dataclass, field
from typing import (
Any,
AsyncGenerator,
Callable,
Coroutine,
List,
Optional,
Tuple,
Union,
cast,
)
import abc
import asyncio
import enum
import functools
import logging
import os
import pathlib
import re
import signal
import struct
import sys
import dns.flags
import dns.message
import dns.name
import dns.node
import dns.rcode
import dns.rdataclass
import dns.rdatatype
import dns.rrset
import dns.zone
try:
RdataType = dns.rdatatype.RdataType
RdataClass = dns.rdataclass.RdataClass
except AttributeError: # dnspython < 2.0.0 compat
RdataType = int # type: ignore
RdataClass = int # type: ignore
_UdpHandler = Callable[
[bytes, Tuple[str, int], asyncio.DatagramTransport], Coroutine[Any, Any, None]
]
_TcpHandler = Callable[
[asyncio.StreamReader, asyncio.StreamWriter], Coroutine[Any, Any, None]
]
class _AsyncUdpHandler(asyncio.DatagramProtocol):
"""
Protocol implementation for handling UDP traffic using asyncio.
"""
def __init__(
self,
handler: _UdpHandler,
) -> None:
self._transport: Optional[asyncio.DatagramTransport] = None
self._handler: _UdpHandler = handler
def connection_made(self, transport: asyncio.BaseTransport) -> None:
"""
Called by asyncio when a connection is made.
"""
self._transport = cast(asyncio.DatagramTransport, transport)
def datagram_received(self, data: bytes, addr: Tuple[str, int]) -> None:
"""
Called by asyncio when a datagram is received.
"""
assert self._transport
handler_coroutine = self._handler(data, addr, self._transport)
try:
# Python >= 3.7
asyncio.create_task(handler_coroutine)
except AttributeError:
# Python < 3.7
loop = asyncio.get_event_loop()
loop.create_task(handler_coroutine)
# pylint: disable=too-few-public-methods
class AsyncServer:
"""
A generic asynchronous server which may handle UDP and/or TCP traffic.
Once the server is executed as asyncio coroutine, it will keep running
until a SIGINT/SIGTERM signal is received.
"""
def __init__(
self,
udp_handler: Optional[_UdpHandler],
tcp_handler: Optional[_TcpHandler],
pidfile: Optional[str] = None,
) -> None:
logging.basicConfig(
format="%(asctime)s %(levelname)8s %(message)s",
level=os.environ.get("ANS_LOG_LEVEL", "INFO").upper(),
)
try:
ipv4_address = sys.argv[1]
except IndexError:
ipv4_address = self._get_ipv4_address_from_directory_name()
last_ipv4_address_octet = ipv4_address.split(".")[-1]
ipv6_address = f"fd92:7065:b8e:ffff::{last_ipv4_address_octet}"
try:
port = int(sys.argv[2])
except IndexError:
port = int(os.environ.get("PORT", 5300))
logging.info("Setting up IPv4 listener at %s:%d", ipv4_address, port)
logging.info("Setting up IPv6 listener at [%s]:%d", ipv6_address, port)
self._ip_addresses: Tuple[str, str] = (ipv4_address, ipv6_address)
self._port: int = port
self._udp_handler: Optional[_UdpHandler] = udp_handler
self._tcp_handler: Optional[_TcpHandler] = tcp_handler
self._pidfile: Optional[str] = pidfile
self._work_done: Optional[asyncio.Future] = None
def _get_ipv4_address_from_directory_name(self) -> str:
containing_directory = pathlib.Path().absolute().stem
match_result = re.match(r"ans(?P<index>\d+)", containing_directory)
if not match_result:
raise RuntimeError("Unable to auto-determine the IPv4 address to use")
return f"10.53.0.{match_result.group('index')}"
def run(self) -> None:
"""
Start the server in an asynchronous coroutine.
"""
coroutine = self._run
try:
# Python >= 3.7
asyncio.run(coroutine())
except AttributeError:
# Python < 3.7
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
async def _run(self) -> None:
self._setup_signals()
assert self._work_done
await self._listen_udp()
await self._listen_tcp()
self._write_pidfile()
await self._work_done
self._cleanup_pidfile()
def _get_asyncio_loop(self) -> asyncio.AbstractEventLoop:
try:
# Python >= 3.7
loop = asyncio.get_running_loop()
except AttributeError:
# Python < 3.7
loop = asyncio.get_event_loop()
return loop
def _setup_signals(self) -> None:
loop = self._get_asyncio_loop()
self._work_done = loop.create_future()
loop.add_signal_handler(signal.SIGINT, functools.partial(self._signal_done))
loop.add_signal_handler(signal.SIGTERM, functools.partial(self._signal_done))
def _signal_done(self) -> None:
assert self._work_done
self._work_done.set_result(True)
async def _listen_udp(self) -> None:
if not self._udp_handler:
return
loop = self._get_asyncio_loop()
for ip_address in self._ip_addresses:
await loop.create_datagram_endpoint(
lambda: _AsyncUdpHandler(cast(_UdpHandler, self._udp_handler)),
(ip_address, self._port),
)
async def _listen_tcp(self) -> None:
if not self._tcp_handler:
return
for ip_address in self._ip_addresses:
await asyncio.start_server(
self._tcp_handler, host=ip_address, port=self._port
)
def _write_pidfile(self) -> None:
if not self._pidfile:
return
logging.info("Writing PID to %s", self._pidfile)
with open(self._pidfile, "w", encoding="ascii") as pidfile:
print(f"{os.getpid()}", file=pidfile)
def _cleanup_pidfile(self) -> None:
if not self._pidfile:
return
logging.info("Removing %s", self._pidfile)
os.unlink(self._pidfile)
class DnsProtocol(enum.Enum):
UDP = enum.auto()
TCP = enum.auto()
# pylint: disable=too-many-instance-attributes
@dataclass
class QueryContext:
"""
Context for the incoming query which may be used for preparing the response.
"""
query: dns.message.Message
response: dns.message.Message
peer: Tuple[str, int]
protocol: DnsProtocol
zone: Optional[dns.zone.Zone] = None
soa: Optional[dns.rrset.RRset] = None
node: Optional[dns.node.Node] = None
answer: Optional[dns.rdataset.Rdataset] = None
@property
def qname(self) -> dns.name.Name:
return self.query.question[0].name
@property
def qclass(self) -> RdataClass:
return self.query.question[0].rdclass
@property
def qtype(self) -> RdataType:
return self.query.question[0].rdtype
@dataclass
class ResponseAction(abc.ABC):
"""
Base class for actions that can be taken in response to a query.
"""
@abc.abstractmethod
async def perform(self) -> Optional[Union[dns.message.Message, bytes]]:
"""
This method is expected to carry out arbitrary actions (e.g. wait for a
specific amount of time, modify the answer, etc.) and then return the
DNS response to send (a dns.message.Message, a raw bytes object, or
None, which prevents any response from being sent).
"""
raise NotImplementedError
@dataclass
class DnsResponseSend(ResponseAction):
"""
Action which yields a dns.message.Message response.
The response may be sent with a delay if requested.
Depending on the value of the `authoritative` property, this class may set
the AA bit in the response (True), clear it (False), or not touch it at all
(None).
"""
response: dns.message.Message
authoritative: Optional[bool] = None
delay: float = 0.0
async def perform(self) -> Optional[Union[dns.message.Message, bytes]]:
"""
Yield a potentially delayed response that is a dns.message.Message.
"""
assert isinstance(self.response, dns.message.Message)
if self.authoritative is not None:
if self.authoritative:
self.response.flags |= dns.flags.AA
else:
self.response.flags &= ~dns.flags.AA
if self.delay > 0:
logging.info(
"Delaying response (ID=%d) by %d ms",
self.response.id,
self.delay * 1000,
)
await asyncio.sleep(self.delay)
return self.response
@dataclass
class BytesResponseSend(ResponseAction):
"""
Action which yields a raw response that is a sequence of bytes.
The response may be sent with a delay if requested.
"""
response: bytes
delay: float = 0.0
async def perform(self) -> Optional[Union[dns.message.Message, bytes]]:
"""
Yield a potentially delayed response that is a sequence of bytes.
"""
assert isinstance(self.response, bytes)
if self.delay > 0:
logging.info("Delaying raw response by %d ms", self.delay * 1000)
await asyncio.sleep(self.delay)
return self.response
@dataclass
class ResponseDrop(ResponseAction):
"""
Action which does nothing - as if a packet was dropped.
"""
async def perform(self) -> Optional[Union[dns.message.Message, bytes]]:
return None
class ResponseHandler(abc.ABC):
"""
Base class for generic response handlers.
If a query passes the `match()` function logic, then it is handled by this
response handler and response(s) may be generated by the `get_responses()`
method.
"""
@abc.abstractmethod
def match(self, qctx: QueryContext) -> bool:
"""
Matching logic - query is handled when it returns True.
"""
return True
@abc.abstractmethod
async def get_responses(
self, qctx: QueryContext
) -> AsyncGenerator[ResponseAction, None]:
"""
Custom handler which may produce response(s) to matching queries.
The response prepared from zone data is passed to this method in
qctx.response.
"""
yield DnsResponseSend(qctx.response)
class DomainHandler(ResponseHandler):
"""
Base class used for deriving custom domain handlers.
The derived class must specify a list of `domains` that it wants to handle.
Queries for any of these domains (and their subdomains) will then be passed
to the `get_response()` method in the derived class.
"""
@property
@abc.abstractmethod
def domains(self) -> List[str]:
"""
A list of domain names handled by this class.
"""
raise NotImplementedError
def __init__(self) -> None:
self._domains: List[dns.name.Name] = [
dns.name.from_text(d) for d in self.domains
]
def __str__(self) -> str:
return f"{self.__class__.__name__}(domains: {', '.join(self.domains)})"
def match(self, qctx: QueryContext) -> bool:
"""
Handle queries whose QNAME matches any of the domains handled by this
class.
"""
for domain in self._domains:
if qctx.qname.is_subdomain(domain):
return True
return False
@dataclass
class _ZoneTreeNode:
"""
A node representing a zone with one origin.
"""
zone: Optional[dns.zone.Zone]
children: List["_ZoneTreeNode"] = field(default_factory=list)
class _ZoneTree:
"""
Tree with independent zones.
This zone tree is used as a backing structure for the DNS server. The
individual zones are independent to allow the (single) server to serve both
the parent zone and a child zone if needed.
"""
def __init__(self) -> None:
self._root: _ZoneTreeNode = _ZoneTreeNode(None)
def add(self, zone: dns.zone.Zone) -> None:
"""
Add a zone to the tree and rearrange sub-zones if necessary.
"""
assert zone.origin
best_match = self._find_best_match(zone.origin, self._root)
added_node = _ZoneTreeNode(zone)
self._move_children(best_match, added_node)
best_match.children.append(added_node)
def _find_best_match(
self, name: dns.name.Name, start_node: _ZoneTreeNode
) -> _ZoneTreeNode:
for child in start_node.children:
assert child.zone
assert child.zone.origin
if name.is_subdomain(child.zone.origin):
return self._find_best_match(name, child)
return start_node
def _move_children(self, node_from: _ZoneTreeNode, node_to: _ZoneTreeNode) -> None:
assert node_to.zone
assert node_to.zone.origin
children_to_move = []
for child in node_from.children:
assert child.zone
assert child.zone.origin
if child.zone.origin.is_subdomain(node_to.zone.origin):
children_to_move.append(child)
for child in children_to_move:
node_from.children.remove(child)
node_to.children.append(child)
def find_best_zone(self, name: dns.name.Name) -> Optional[dns.zone.Zone]:
"""
Return the closest matching zone (if any) for the domain name.
"""
node = self._find_best_match(name, self._root)
return node.zone if node != self._root else None
class AsyncDnsServer(AsyncServer):
"""
DNS server which responds to queries based on zone data and/or custom
handlers.
The server may use custom handlers which allow arbitrary query processing.
These don't need to be standards-compliant and can be used for testing all
sorts of scenarios, including delaying responses, synthesizing them based
on query contents etc.
The server also loads any zone files (*.db) found in its directory and
serves them. Responses prepared using zone data can then be modified,
replaced, or suppressed by query handlers. Query handlers can also generate
response from scratch, without using zone data at all.
"""
def __init__(self, load_zones: bool = True):
super().__init__(self._handle_udp, self._handle_tcp, "ans.pid")
self._zone_tree: _ZoneTree = _ZoneTree()
self._response_handlers: List[ResponseHandler] = []
if load_zones:
self._load_zones()
def install_response_handler(self, handler: ResponseHandler) -> None:
"""
Add a response handler which will be used to handle matching queries.
Response handlers can modify, replace, or suppress the answers prepared
from zone file contents.
"""
logging.info("Installing response handler: %s", handler)
self._response_handlers.append(handler)
def _load_zones(self) -> None:
for entry in os.scandir():
entry_path = pathlib.Path(entry.path)
if entry_path.suffix != ".db":
continue
origin = dns.name.from_text(entry_path.stem)
logging.info("Loading zone file %s", entry_path)
zone = dns.zone.from_file(entry.path, origin, relativize=False)
self._zone_tree.add(zone)
async def _handle_udp(
self, wire: bytes, peer: Tuple[str, int], transport: asyncio.DatagramTransport
) -> None:
logging.debug("Received UDP message: %s", wire.hex())
responses = self._handle_query(wire, peer, DnsProtocol.UDP)
async for response in responses:
transport.sendto(response, peer)
async def _handle_tcp(
self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter
) -> None:
wire_length_bytes = await reader.read(2)
(wire_length,) = struct.unpack("!H", wire_length_bytes)
logging.debug("Receiving TCP message (%d octets)...", wire_length)
wire = await reader.read(wire_length)
full_message = wire_length_bytes + wire
logging.debug("Received complete TCP message: %s", full_message.hex())
peer = writer.get_extra_info("peername")
responses = self._handle_query(wire, peer, DnsProtocol.TCP)
async for response in responses:
writer.write(response)
try:
await writer.drain()
except ConnectionResetError:
logging.error(
"TCP connection from %s reset by peer", self._format_peer(peer)
)
return
writer.close()
await writer.wait_closed()
def _format_peer(self, peer: Tuple[str, int]) -> str:
host = peer[0]
port = peer[1]
if "::" in host:
host = f"[{host}]"
return f"{host}:{port}"
def _log_query(
self, qctx: QueryContext, peer: Tuple[str, int], protocol: DnsProtocol
) -> None:
logging.info(
"Received %s/%s/%s (ID=%d) query from %s (%s)",
qctx.qname.to_text(omit_final_dot=True),
dns.rdataclass.to_text(qctx.qclass),
dns.rdatatype.to_text(qctx.qtype),
qctx.query.id,
self._format_peer(peer),
protocol.name,
)
logging.debug(
"\n".join([f"[IN] {l}" for l in [""] + str(qctx.query).splitlines()])
)
def _log_response(
self,
qctx: QueryContext,
response: Optional[Union[dns.message.Message, bytes]],
peer: Tuple[str, int],
protocol: DnsProtocol,
) -> None:
if not response:
logging.info(
"Not sending a response to query (ID=%d) from %s (%s)",
qctx.query.id,
self._format_peer(peer),
protocol.name,
)
return
if isinstance(response, dns.message.Message):
try:
qname = response.question[0].name.to_text(omit_final_dot=True)
qclass = dns.rdataclass.to_text(response.question[0].rdclass)
qtype = dns.rdatatype.to_text(response.question[0].rdtype)
except IndexError:
qname = "<empty>"
qclass = "-"
qtype = "-"
logging.info(
"Sending %s/%s/%s (ID=%d) response (%d/%d/%d/%d) to a query (ID=%d) from %s (%s)",
qname,
qclass,
qtype,
response.id,
len(response.question),
len(response.answer),
len(response.authority),
len(response.additional),
qctx.query.id,
self._format_peer(peer),
protocol.name,
)
logging.debug(
"\n".join([f"[OUT] {l}" for l in [""] + str(response).splitlines()])
)
return
logging.info(
"Sending response (%d bytes) to a query (ID=%d) from %s (%s)",
len(response),
qctx.query.id,
self._format_peer(peer),
protocol.name,
)
logging.debug("[OUT] %s", response.hex())
async def _handle_query(
self, wire: bytes, peer: Tuple[str, int], protocol: DnsProtocol
) -> AsyncGenerator[bytes, None]:
"""
Yield wire data to send as a response over the established transport.
"""
query = dns.message.from_wire(wire)
response_stub = dns.message.make_response(query)
qctx = QueryContext(query, response_stub, peer, protocol)
self._log_query(qctx, peer, protocol)
responses = self._prepare_responses(qctx)
async for response in responses:
self._log_response(qctx, response, peer, protocol)
if response:
if isinstance(response, dns.message.Message):
response = response.to_wire(max_size=65535)
if protocol == DnsProtocol.UDP:
yield response
else:
response_length = struct.pack("!H", len(response))
yield response_length + response
async def _prepare_responses(
self, qctx: QueryContext
) -> AsyncGenerator[Optional[Union[dns.message.Message, bytes]], None]:
"""
Yield response(s) either from response handlers or zone data.
"""
self._prepare_response_from_zone_data(qctx)
response_handled = False
async for action in self._run_response_handlers(qctx):
yield await action.perform()
response_handled = True
if not response_handled:
yield qctx.response
def _prepare_response_from_zone_data(self, qctx: QueryContext) -> None:
"""
Prepare a response to the query based on the available zone data.
The functionality is split across smaller functions that modify the
query context until a proper response is formed.
"""
if self._refused_response(qctx):
return
if self._delegation_response(qctx):
return
qctx.response.flags |= dns.flags.AA
if self._ent_response(qctx):
return
if self._nxdomain_response(qctx):
return
if self._nodata_response(qctx):
return
self._noerror_response(qctx)
def _refused_response(self, qctx: QueryContext) -> bool:
qctx.zone = self._zone_tree.find_best_zone(qctx.qname)
if qctx.zone:
return False
qctx.response.set_rcode(dns.rcode.REFUSED)
return True
def _delegation_response(self, qctx: QueryContext) -> bool:
assert qctx.zone
name = qctx.qname
delegation = None
while name != qctx.zone.origin:
node = qctx.zone.get_node(name)
if node:
delegation = node.get_rdataset(qctx.qclass, dns.rdatatype.NS)
if delegation:
break
name = name.parent()
if not delegation:
return False
delegation_rrset = dns.rrset.RRset(name, qctx.qclass, dns.rdatatype.NS)
delegation_rrset.update(delegation)
qctx.response.set_rcode(dns.rcode.NOERROR)
qctx.response.authority.append(delegation_rrset)
self._delegation_response_additional(qctx)
return True
def _delegation_response_additional(self, qctx: QueryContext) -> None:
assert qctx.zone
assert qctx.response.authority[0]
for nameserver in qctx.response.authority[0]:
if not nameserver.target.is_subdomain(qctx.response.authority[0].name):
continue
glue_a = qctx.zone.get_rrset(nameserver.target, dns.rdatatype.A)
if glue_a:
qctx.response.additional.append(glue_a)
glue_aaaa = qctx.zone.get_rrset(nameserver.target, dns.rdatatype.AAAA)
if glue_aaaa:
qctx.response.additional.append(glue_aaaa)
def _ent_response(self, qctx: QueryContext) -> bool:
assert qctx.zone
assert qctx.zone.origin
qctx.soa = qctx.zone.find_rrset(qctx.zone.origin, dns.rdatatype.SOA)
assert qctx.soa
qctx.node = qctx.zone.get_node(qctx.qname)
if qctx.node or not any(
n for n in qctx.zone.nodes if n.is_subdomain(qctx.qname)
):
return False
qctx.response.set_rcode(dns.rcode.NOERROR)
qctx.response.authority.append(qctx.soa)
return True
def _nxdomain_response(self, qctx: QueryContext) -> bool:
assert qctx.soa
if qctx.node:
return False
qctx.response.set_rcode(dns.rcode.NXDOMAIN)
qctx.response.authority.append(qctx.soa)
return True
def _nodata_response(self, qctx: QueryContext) -> bool:
assert qctx.node
assert qctx.soa
qctx.answer = qctx.node.get_rdataset(qctx.qclass, qctx.qtype)
if qctx.answer:
return False
qctx.response.set_rcode(dns.rcode.NOERROR)
qctx.response.authority.append(qctx.soa)
return True
def _noerror_response(self, qctx: QueryContext) -> None:
assert qctx.answer
answer_rrset = dns.rrset.RRset(qctx.qname, qctx.qclass, qctx.qtype)
answer_rrset.update(qctx.answer)
qctx.response.set_rcode(dns.rcode.NOERROR)
qctx.response.answer.append(answer_rrset)
async def _run_response_handlers(
self, qctx: QueryContext
) -> AsyncGenerator[ResponseAction, None]:
"""
Yield response(s) to the query from a matching query handler.
"""
for handler in self._response_handlers:
if handler.match(qctx):
async for response in handler.get_responses(qctx):
yield response
return
+56 -4
View File
@@ -9,11 +9,13 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
from typing import Any
from typing import Any, Optional
import dns.rcode
import dns.message
import dns.zone
import isctest.log
# compatiblity with dnspython<2.0.0
try:
@@ -38,8 +40,58 @@ def servfail(message: dns.message.Message) -> None:
rcode(message, dns_rcode.SERVFAIL)
def rrsets_equal(first_rrset: dns.rrset.RRset, second_rrset: dns.rrset.RRset) -> None:
def rrsets_equal(
first_rrset: dns.rrset.RRset,
second_rrset: dns.rrset.RRset,
compare_ttl: Optional[bool] = False,
) -> None:
"""Compare two RRset (optionally including TTL)"""
def compare_rrs(rr1, rrset):
rr2 = next((other_rr for other_rr in rrset if rr1 == other_rr), None)
assert rr2 is not None, f"No corresponding RR found for: {rr1}"
if compare_ttl:
assert rr1.ttl == rr2.ttl
isctest.log.debug(
"%s() first RRset:\n%s",
rrsets_equal.__name__,
"\n".join([str(rr) for rr in first_rrset]),
)
isctest.log.debug(
"%s() second RRset:\n%s",
rrsets_equal.__name__,
"\n".join([str(rr) for rr in second_rrset]),
)
for rr in first_rrset:
assert rr in second_rrset
compare_rrs(rr, second_rrset)
for rr in second_rrset:
assert rr in first_rrset
compare_rrs(rr, first_rrset)
def zones_equal(
first_zone: dns.zone.Zone,
second_zone: dns.zone.Zone,
compare_ttl: Optional[bool] = False,
) -> None:
"""Compare two zones (optionally including TTL)"""
isctest.log.debug(
"%s() first zone:\n%s",
zones_equal.__name__,
first_zone.to_text(relativize=False),
)
isctest.log.debug(
"%s() second zone:\n%s",
zones_equal.__name__,
second_zone.to_text(relativize=False),
)
assert first_zone == second_zone
if compare_ttl:
for name, node in first_zone.nodes.items():
for rdataset in node:
found_rdataset = second_zone.find_rdataset(
name=name, rdtype=rdataset.rdtype
)
assert found_rdataset
assert found_rdataset.ttl == rdataset.ttl
+2
View File
@@ -10,8 +10,10 @@
# information regarding copyright ownership.
from .basic import (
avoid_duplicated_logs,
deinit_module_logger,
deinit_test_logger,
init_conftest_logger,
init_module_logger,
init_test_logger,
debug,
-4
View File
@@ -53,10 +53,6 @@ def avoid_duplicated_logs():
logging.root.handlers.remove(handler)
init_conftest_logger()
avoid_duplicated_logs()
def init_module_logger(system_test_name: str, testdir: Path):
logger = logging.getLogger(system_test_name)
logger.handlers.clear()
@@ -11,4 +11,21 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
rm -f classlist.out privatelist.out typelist.out tempzone checkzone.out* checker.out
set -e
rm -f ./*.ksk*
rm -f ./*.zsk*
rm -f ./created.out
rm -f ./footer.*
rm -f ./keygen.out.*
rm -f ./named.conf
rm -f ./now.out
rm -rf ./offline
rm -f ./python.out
rm -f ./settime.out.*
rm -f ./K*
rm -rf ./keydir
rm -f ./ksr.*.err.*
rm -f ./ksr.*.expect
rm -f ./ksr.*.expect.*
rm -f ./ksr.*.out.*
+58
View File
@@ -0,0 +1,58 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
dnssec-policy "common" {
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk lifetime P6M algorithm @DEFAULT_ALGORITHM@;
};
};
dnssec-policy "csk" {
keys {
csk lifetime P6M algorithm @DEFAULT_ALGORITHM@;
};
};
dnssec-policy "unlimited" {
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
};
};
dnssec-policy "no-cdnskey" {
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
};
cdnskey no;
cds-digest-types { SHA-1; SHA-256; SHA-384; };
};
dnssec-policy "no-cds" {
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
};
cds-digest-types { };
};
dnssec-policy "two-tone" {
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
ksk lifetime unlimited algorithm @ALTERNATIVE_ALGORITHM@;
zsk lifetime P3M algorithm @DEFAULT_ALGORITHM@;
zsk lifetime P5M algorithm @ALTERNATIVE_ALGORITHM@;
};
};
+40
View File
@@ -0,0 +1,40 @@
#!/bin/sh -e
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# shellcheck source=conf.sh
. ../conf.sh
set -e
$SHELL clean.sh
mkdir keydir
mkdir offline
copy_setports named.conf.in named.conf
# Create KSK for the various policies.
create_ksk() {
KSK=$($KEYGEN -l named.conf -fK -k $2 $1 2>keygen.out.$1)
num=0
for ksk in $KSK; do
num=$(($num + 1))
echo $ksk >"${1}.ksk${num}.id"
cat "${ksk}.key" | grep -v ";.*" >"$1.ksk$num"
cp "${ksk}.key" offline/
cp "${ksk}.private" offline/
done
}
create_ksk common.test common
create_ksk unlimited.test unlimited
create_ksk two-tone.test two-tone
+806
View File
@@ -0,0 +1,806 @@
#!/bin/sh
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# shellcheck source=conf.sh
. ../conf.sh
# shellcheck source=kasp.sh
. ../kasp.sh
set -e
CDS_SHA1="no"
CDS_SHA256="yes"
CDS_SHA384="no"
CDNSKEY="yes"
status=0
n=0
# Get timing metadata from a value plus additional time.
# $1: Value
# $2: Additional time
addtime() {
if [ -x "$PYTHON" ]; then
# Convert "%Y%m%d%H%M%S" format to epoch seconds.
# Then, add the additional time (can be negative).
_value=$1
_plus=$2
$PYTHON >python.out <<EOF
from datetime import datetime
from datetime import timedelta
_now = datetime.strptime("$_value", "%Y%m%d%H%M%S")
_delta = timedelta(seconds=$_plus)
_then = _now + _delta
print(_then.strftime("%Y%m%d%H%M%S"));
EOF
cat python.out
fi
}
# Check keys that were created. The keys created are listed in the latest ksr
# output file, ksr.keygen.out.$n.
# $1: zone name
# $2: key directory
check_keys() (
zone=$1
dir=$2
lifetime=$LIFETIME
alg=$ALG
size=$SIZE
inception=0
pad=$(printf "%03d" "$alg")
num=0
for key in $(grep "K${zone}.+$pad+" ksr.keygen.out.$n); do
grep "; Created:" "${dir}/${key}.key" >created.out || return 1
created=$(awk '{print $3}' <created.out)
test "$num" -eq 0 && retired=$created
# active: retired previous key
active=$retired
# published: 2h5m (dnskey-ttl + publish-safety + propagation)
published=$(addtime $active -7500)
# retired: zsk-lifetime
retired=$(addtime $active $lifetime)
# removed: 10d1h5m (ttlsig + retire-safety + sign-delay + propagation)
removed=$(addtime $retired 867900)
echo_i "check metadata on $key"
statefile="${dir}/${key}.state"
grep "Algorithm: $alg" $statefile >/dev/null || return 1
grep "Length: $size" $statefile >/dev/null || return 1
grep "Lifetime: $lifetime" $statefile >/dev/null || return 1
grep "KSK: no" $statefile >/dev/null || return 1
grep "ZSK: yes" $statefile >/dev/null || return 1
grep "Published: $published" $statefile >/dev/null || return 1
grep "Active: $active" $statefile >/dev/null || return 1
grep "Retired: $retired" $statefile >/dev/null || return 1
grep "Removed: $removed" $statefile >/dev/null || return 1
inception=$((inception + lifetime))
num=$((num + 1))
# Save some information for testing
cp ${dir}/${key}.key ${key}.key.expect
cp ${dir}/${key}.private ${key}.private.expect
cp ${dir}/${key}.state ${key}.state.expect
cat ${dir}/${key}.key | grep -v ";.*" >"${zone}.${alg}.zsk${num}"
echo $key >"${zone}.${alg}.zsk${num}.id"
done
return 0
)
# Print the DNSKEY records for zone $1, which have keys listed in file $5
# that match the keys with numbers $2 and $3, and match algorithm number $4,
# sorted by keytag.
print_dnskeys() {
for key in $(cat $5 | sort); do
for num in $2 $3; do
zsk=$(cat $1.$4.zsk$num.id)
if [ "$key" = "$zsk" ]; then
cat $1.$4.zsk$num >>ksr.request.expect.$n
fi
done
done
}
# Call the dnssec-ksr command:
# ksr <policy> [options] <command> <zone>
ksr() {
$KSR -l named.conf -k "$@"
}
# Unknown action.
n=$((n + 1))
echo_i "check that 'dnssec-ksr' errors on unknown action ($n)"
ret=0
ksr common foobar common.test >ksr.foobar.out.$n 2>&1 && ret=1
grep "dnssec-ksr: fatal: unknown command 'foobar'" ksr.foobar.out.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Key generation: common
set_zsk() {
ALG=$1
SIZE=$2
LIFETIME=$3
}
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' errors on missing end date ($n)"
ret=0
ksr common keygen common.test >ksr.keygen.out.$n 2>&1 && ret=1
grep "dnssec-ksr: fatal: keygen requires an end date" ksr.keygen.out.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' pregenerates right amount of keys in the common case ($n)"
ret=0
ksr common -i now -e +1y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 2 ] || ret=1
set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
check_keys common.test "." || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# save now time
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
grep "; Created:" "${key}.key" >now.out || ret=1
now=$(awk '{print $3}' <now.out)
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' selects pregenerated keys for the same time bundle ($n)"
ret=0
ksr common -e +1y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
diff -w ksr.keygen.out.expect ksr.keygen.out.$n >/dev/null || ret=1
for key in $(cat ksr.keygen.out.$n); do
# Ensure the files are not modified.
diff ${key}.key ${key}.key.expect >/dev/null || ret=1
diff ${key}.private ${key}.private.expect >/dev/null || ret=1
diff ${key}.state ${key}.state.expect >/dev/null || ret=1
done
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Create request: common
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' errors on missing end date ($n)"
ret=0
ksr common request common.test >ksr.request.out.$n 2>&1 && ret=1
grep "dnssec-ksr: fatal: request requires an end date" ksr.request.out.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR in the common case ($n)"
ret=0
ksr common -i $now -e +1y request common.test >ksr.request.out.$n 2>&1 || ret=1
# Bundle 1: KSK + ZSK1
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Generated" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >ksr.request.expect.$n
cat common.test.ksk1 >>ksr.request.expect.$n
cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Bundle 2: KSK + ZSK1 + ZSK2
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk2.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.ksk1 >>ksr.request.expect.$n
print_dnskeys common.test 1 2 $DEFAULT_ALGORITHM_NUMBER ksr.keygen.out.expect
# Bundle 3: KSK + ZSK2
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.ksk1 >>ksr.request.expect.$n
cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
# Footer
cp ksr.request.expect.$n ksr.request.expect.base
grep ";; KeySigningRequest generated at" ksr.request.out.$n >footer.$n || ret=1
cat footer.$n >>ksr.request.expect.$n
# Check if request output is the same as expected.
diff -w ksr.request.out.$n ksr.request.expect.$n >/dev/null || ret=1
# Save request for ksr sign operation.
cp ksr.request.expect.$n ksr.request.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Sign request: common
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' errors on missing KSR file ($n)"
ret=0
ksr common -i $now -e +1y sign common.test >ksr.sign.out.$n 2>&1 && ret=1
grep "dnssec-ksr: fatal: 'sign' requires a KSR file" ksr.sign.out.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR in the common case ($n)"
ret=0
ksr common -i $now -e +1y -K offline -f ksr.request.expect sign common.test >ksr.sign.out.$n 2>&1 || ret=1
_update_expected_zsks() {
zsk=$((zsk + 1))
next=$((next + 1))
inception=$rollover_done
if [ "$next" -le "$numzsks" ]; then
key1="${zone}.${DEFAULT_ALGORITHM_NUMBER}.zsk${zsk}"
key2="${zone}.${DEFAULT_ALGORITHM_NUMBER}.zsk${next}"
zsk1=$(cat $key1.id)
zsk2=$(cat $key2.id)
rollover_start=$(cat $zsk2.state | grep "Published" | awk '{print $2}')
rollover_done=$(cat $zsk1.state | grep "Removed" | awk '{print $2}')
else
# No more expected rollovers.
key1="${zone}.${DEFAULT_ALGORITHM_NUMBER}.zsk${zsk}"
zsk1=$(cat $key1.id)
rollover_start=$((end + 1))
rollover_done=$((end + 1))
fi
}
check_ksr() {
_ret=0
zone=$1
file=$2
start=$3
end=$4
numzsks=$5
cds1=$($DSFROMKEY -T 3600 -a SHA-1 -C -w $(cat "${zone}.ksk1.id"))
cds2=$($DSFROMKEY -T 3600 -a SHA-256 -C -w $(cat "${zone}.ksk1.id"))
cds4=$($DSFROMKEY -T 3600 -a SHA-384 -C -w $(cat "${zone}.ksk1.id"))
cdnskey=$(awk '{sub(/DNSKEY/,"CDNSKEY")}1' <${zone}.ksk1)
echo_i "check ksr: zone $1 file $2 from $3 to $4 num-zsk $5"
# Initial state: not in a rollover, expect a SignedKeyResponse header
# on the first line, start with the first ZSK (set zsk=0 so when we
# call _update_expected_zsks, zsk is set to 1.
rollover=0
expect="header"
zsk=0
next=1
rollover_done=$start
_update_expected_zsks
echo_i "check ksr: inception $inception rollover-start $rollover_start rollover-done $rollover_done"
lineno=0
complete=0
while IFS= read -r line; do
# A single signed key response may consist of:
# ;; SignedKeyResponse (header)
# ;; DNSKEY 257 (ksk)
# ;; one or two (during rollover) DNSKEY 256 (zsk1, zsk2)
# ;; RRSIG(DNSKEY) (rrsig-dnskey)
# ;; CDNSKEY (cdnskey)
# ;; RRSIG(CDNSKEY) (rrsig-cdnskey)
# ;; CDS (cds)
# ;; RRSIG(CDS) (rrsig-cds)
err=0
lineno=$((lineno + 1))
# skip empty lines
if [ -z "$line" ]; then
continue
fi
if [ "$expect" = "header" ]; then
expected=";; SignedKeyResponse 1.0 $inception"
echo $line | grep "$expected" >/dev/null || err=1
next_inception=$(addtime $inception 777600)
expect="ksk"
elif [ "$expect" = "ksk" ]; then
expected="$(cat ${zone}.ksk1)"
echo $line | grep "$expected" >/dev/null || err=1
expect="zsk1"
elif [ "$expect" = "cdnskey" ]; then
expected="$cdnskey"
echo $line | grep "$expected" >/dev/null || err=1
expect="rrsig-cdnskey"
elif [ "$expect" = "cds1" ]; then
expected="$cds1"
echo $line | grep "$expected" >/dev/null || err=1
if [ "$CDS_SHA256" = "yes" ]; then
expect="cds2"
elif [ "$CDS_SHA384" = "yes" ]; then
expect="cds4"
else
expect="rrsig-cds"
fi
elif [ "$expect" = "cds2" ]; then
expected="$cds2"
echo $line | grep "$expected" >/dev/null || err=1
if [ "$CDS_SHA384" = "yes" ]; then
expect="cds4"
else
expect="rrsig-cds"
fi
elif [ "$expect" = "cds4" ]; then
expected="$cds4"
echo $line | grep "$expected" >/dev/null || err=1
expect="rrsig-cds"
elif [ "$expect" = "zsk1" ]; then
expected="$(cat $key1)"
echo $line | grep "$expected" >/dev/null || err=1
expect="rrsig-dnskey"
[ "$rollover" -eq 1 ] && expect="zsk2"
elif [ "$expect" = "zsk2" ]; then
expected="$(cat $key2)"
echo $line | grep "$expected" >/dev/null || err=1
expect="rrsig-dnskey"
elif [ "$expect" = "rrsig-dnskey" ]; then
exp=$(addtime $inception 1209600) # signature-validity 14 days
inc=$(addtime $inception -3600) # adjust for one hour clock skew
expected="${zone}. 3600 IN RRSIG DNSKEY 13 2 3600 $exp $inc"
echo $line | grep "$expected" >/dev/null || err=1
if [ "$CDNSKEY" = "yes" ]; then
expect="cdnskey"
elif [ "$CDS_SHA1" = "yes" ]; then
expect="cds1"
elif [ "$CDS_SHA256" = "yes" ]; then
expect="cds2"
elif [ "$CDS_SHA384" = "yes" ]; then
expect="cds4"
else
complete=1
fi
elif [ "$expect" = "rrsig-cdnskey" ]; then
exp=$(addtime $inception 1209600) # signature-validity 14 days
inc=$(addtime $inception -3600) # adjust for one hour clock skew
expected="${zone}. 3600 IN RRSIG CDNSKEY 13 2 3600 $exp $inc"
echo $line | grep "$expected" >/dev/null || err=1
if [ "$CDS_SHA1" = "yes" ]; then
expect="cds1"
elif [ "$CDS_SHA256" = "yes" ]; then
expect="cds2"
elif [ "$CDS_SHA384" = "yes" ]; then
expect="cds4"
else
complete=1
fi
elif [ "$expect" = "rrsig-cds" ]; then
exp=$(addtime $inception 1209600) # signature-validity 14 days
inc=$(addtime $inception -3600) # adjust for one hour clock skew
expected="${zone}. 3600 IN RRSIG CDS 13 2 3600 $exp $inc"
echo $line | grep "$expected" >/dev/null || err=1
complete=1
elif [ "$expect" = "footer" ]; then
expected=";; SignedKeyResponse 1.0 generated at"
echo "$(echo $line | tr -s ' ')" | grep "$expected" >/dev/null || err=1
expect="eof"
elif [ "$expect" = "eof" ]; then
expected="EOF"
echo_i "failed: expected EOF"
err=1
else
echo_i "failed: bad expect value $expect"
err=1
fi
echo "$(echo $line | tr -s ' ')" | grep "$expected" >/dev/null || err=1
if [ "$err" -ne 0 ]; then
echo_i "unexpected data on line $lineno:"
echo_i "line: $(echo $line | tr -s ' ')"
echo_i "expected: $expected"
fi
if [ "$complete" -eq 1 ]; then
inception=$next_inception
expect="header"
# Update rollover status if required.
if [ "$inception" -ge "$end" ]; then
expect="footer"
elif [ "$inception" -ge "$rollover_done" ]; then
[ "$rollover" -eq 1 ] && inception=$rollover_done
rollover=0
_update_expected_zsks
elif [ "$inception" -ge "$rollover_start" ]; then
[ "$rollover" -eq 0 ] && inception=$rollover_start
rollover=1
# Keys will be sorted, so during a rollover a key with a
# lower keytag will be printed first. Update key1/key2 and
# zsk1/zsk2 accordingly.
id1=$(keyfile_to_key_id "$zsk1")
id2=$(keyfile_to_key_id "$zsk2")
if [ $id1 -gt $id2 ]; then
key1="${zone}.${DEFAULT_ALGORITHM_NUMBER}.zsk${next}"
key2="${zone}.${DEFAULT_ALGORITHM_NUMBER}.zsk${zsk}"
zsk1=$(cat $key1.id)
zsk2=$(cat $key2.id)
fi
fi
complete=0
fi
_ret=$((_ret + err))
test "$_ret" -eq 0 || exit $_ret
done <$file
return $_ret
}
zsk1=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
start=$(cat $zsk1.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 31536000) # one year
check_ksr "common.test" "ksr.sign.out.$n" $start $end 2 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Key generation: common (2)
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' pregenerates keys in the given key-directory ($n)"
ret=0
ksr common -e +1y -K keydir keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 2 ] || ret=1
set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
check_keys common.test keydir || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' selects generates only necessary keys for overlapping time bundle ($n)"
ret=0
ksr common -e +2y -v 1 keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 4 ] || ret=1
# 2 selected, 2 generated
num=$(grep "Selecting" ksr.keygen.out.$n | wc -l)
[ $num -eq 2 ] || ret=1
num=$(grep "Generating" ksr.keygen.out.$n | wc -l)
[ $num -eq 2 ] || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "run 'dnssec-ksr keygen' again with verbosity 0 ($n)"
ret=0
ksr common -i $now -e +2y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 4 ] || ret=1
set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
check_keys common.test "." || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Create request: common (2)
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR if the interval is shorter ($n)"
ret=0
ksr common -i $now -e +1y request common.test >ksr.request.out.$n 2>&1 || ret=1
# Same as earlier.
cp ksr.request.expect.base ksr.request.expect.$n
grep ";; KeySigningRequest generated at" ksr.request.out.$n >footer.$n || ret=1
cat footer.$n >>ksr.request.expect.$n
diff -w ksr.request.out.$n ksr.request.expect.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR with new interval ($n)"
ret=0
ksr common -i $now -e +2y request common.test >ksr.request.out.$n 2>&1 || ret=1
cp ksr.request.expect.base ksr.request.expect.$n
# Bundle 4: KSK + ZSK2 + ZSK3
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk3.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.ksk1 >>ksr.request.expect.$n
print_dnskeys common.test 2 3 $DEFAULT_ALGORITHM_NUMBER ksr.keygen.out.expect
# Bundle 5: KSK + ZSK3
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk2.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.ksk1 >>ksr.request.expect.$n
cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk3 >>ksr.request.expect.$n
# Bundle 6: KSK + ZSK3 + ZSK4
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk4.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.ksk1 >>ksr.request.expect.$n
print_dnskeys common.test 3 4 $DEFAULT_ALGORITHM_NUMBER ksr.keygen.out.expect
# Bundle 7: KSK + ZSK4
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk3.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.ksk1 >>ksr.request.expect.$n
cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk4 >>ksr.request.expect.$n
# Footer
cp ksr.request.expect.$n ksr.request.expect.base
grep ";; KeySigningRequest generated at" ksr.request.out.$n >footer.$n || ret=1
cat footer.$n >>ksr.request.expect.$n
diff -w ksr.request.out.$n ksr.request.expect.$n >/dev/null || ret=1
# Save request for ksr sign operation.
cp ksr.request.expect.$n ksr.request.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' errors if there are not enough keys ($n)"
ret=0
ksr common -i $now -e +3y request common.test >ksr.request.out.$n 2>ksr.request.err.$n && ret=1
grep "dnssec-ksr: fatal: no common.test/ECDSAP256SHA256 zsk key pair found for bundle" ksr.request.err.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Sign request: common (2)
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with the new interval ($n)"
ret=0
ksr common -i $now -e +2y -K offline -f ksr.request.expect sign common.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat $zsk1.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 63072000) # two years
check_ksr "common.test" "ksr.sign.out.$n" $start $end 4 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Key generation: csk
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' creates no keys for policy with csk ($n)"
ret=0
ksr csk -e +2y keygen csk.test >ksr.keygen.out.$n 2>&1 && ret=1
grep "dnssec-ksr: fatal: policy 'csk' has no zsks" ksr.keygen.out.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Key generation: unlimited
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' creates only one key for zsk with unlimited lifetime ($n)"
ret=0
ksr unlimited -e +2y keygen unlimited.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 1 ] || ret=1
key=$(cat ksr.keygen.out.$n)
grep "; Created:" "${key}.key" >created.out || ret=1
created=$(awk '{print $3}' <created.out)
active=$created
published=$(addtime $active -7500)
echo_i "check metadata on $key"
grep "Algorithm: $DEFAULT_ALGORITHM_NUMBER" ${key}.state >/dev/null || ret=1
grep "Length: $DEFAULT_BITS" ${key}.state >/dev/null || ret=1
grep "Lifetime: 0" ${key}.state >/dev/null || ret=1
grep "KSK: no" ${key}.state >/dev/null || ret=1
grep "ZSK: yes" ${key}.state >/dev/null || ret=1
grep "Published: $published" ${key}.state >/dev/null || ret=1
grep "Active: $active" ${key}.state >/dev/null || ret=1
grep "Retired:" ${key}.state >/dev/null && ret=1
grep "Removed:" ${key}.state >/dev/null && ret=1
cat ${key}.key | grep -v ";.*" >unlimited.test.$DEFAULT_ALGORITHM_NUMBER.zsk1
echo $key >"unlimited.test.${DEFAULT_ALGORITHM_NUMBER}.zsk1.id"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Create request: unlimited
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR with unlimited zsk ($n)"
ret=0
ksr unlimited -i $created -e +4y request unlimited.test >ksr.request.out.$n 2>&1 || ret=1
# Only one bundle: KSK + ZSK
inception=$(cat $key.state | grep "Generated" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >ksr.request.expect.$n
cat unlimited.test.ksk1 >>ksr.request.expect.$n
cat unlimited.test.$DEFAULT_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Footer
grep ";; KeySigningRequest generated at" ksr.request.out.$n >footer.$n || ret=1
cat footer.$n >>ksr.request.expect.$n
diff -w ksr.request.out.$n ksr.request.expect.$n >/dev/null || ret=1
# Save request for ksr sign operation.
cp ksr.request.expect.$n ksr.request.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Sign request: unlimited
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with unlimited zsk ($n)"
ret=0
ksr unlimited -i $created -e +4y -K offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat $key.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 126144000) # four years
check_ksr "unlimited.test" "ksr.sign.out.$n" $start $end 1 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Sign request: unlimited (no-cdnskey)
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with unlimited zsk, no cdnskey ($n)"
ret=0
ksr no-cdnskey -i $created -e +4y -K offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat $key.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 126144000) # four years
CDNSKEY="no"
CDS_SHA1="yes"
CDS_SHA256="yes"
CDS_SHA384="yes"
check_ksr "unlimited.test" "ksr.sign.out.$n" $start $end 1 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Sign request: unlimited (no-cds)
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with unlimited zsk, no cds ($n)"
ret=0
ksr no-cds -i $created -e +4y -K offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat $key.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 126144000) # four years
CDNSKEY="yes"
CDS_SHA1="no"
CDS_SHA256="no"
CDS_SHA384="no"
check_ksr "unlimited.test" "ksr.sign.out.$n" $start $end 1 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Reset CDS and CDNSKEY to default values
CDNSKEY="yes"
CDS_SHA1="no"
CDS_SHA256="yes"
CDS_SHA384="no"
# Key generation: two-tone
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' creates keys for different algorithms ($n)"
ret=0
ksr two-tone -e +1y keygen two-tone.test >ksr.keygen.out.$n 2>&1 || ret=1
# First algorithm keys have a lifetime of 3 months, so there should be 4 created keys.
alg=$(printf "%03d" "$DEFAULT_ALGORITHM_NUMBER")
num=$(grep "Ktwo-tone.test.+$alg+" ksr.keygen.out.$n | wc -l)
[ $num -eq 4 ] || ret=1
set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 8035200
check_keys two-tone.test "." || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect.$DEFAULT_ALGORITHM_NUMBER
# Second algorithm keys have a lifetime of 5 months, so there should be 3 created keys.
# While only two time bundles of 5 months fit into one year, we need to create an
# extra key for the remainder of the bundle.
alg=$(printf "%03d" "$ALTERNATIVE_ALGORITHM_NUMBER")
num=$(grep "Ktwo-tone.test.+$alg+" ksr.keygen.out.$n | wc -l)
[ $num -eq 3 ] || ret=1
set_zsk $ALTERNATIVE_ALGORITHM_NUMBER $ALTERNATIVE_BITS 13392000
check_keys two-tone.test "." $ALTERNATIVE_ALGORITHM_NUMBER 13392000 || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect.$ALTERNATIVE_ALGORITHM_NUMBER
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Create request: two-tone
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR with multiple algorithms ($n)"
ret=0
key=$(cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
grep "; Created:" "${key}.key" >created.out || ret=1
created=$(awk '{print $3}' <created.out)
ksr two-tone -i $created -e +6mo request two-tone.test >ksr.request.out.$n 2>&1 || ret=1
# The two-tone policy uses two sets of KSK/ZSK with different algorithms. One
# set uses the default algorithm (denoted as A below), the other is using the
# alternative algorithm (denoted as B). The A-ZSKs roll every three months,
# so in the second bundle there should be a new DNSKEY prepublished, and the
# predecessor is removed in the third bundle. Then, after five months the
# ZSK for the B set is rolled, adding the successor in bundle 4 and removing
# its predecessor in bundle 5.
#
# Bundle 1: KSK-A1, KSK-B1, ZSK-A1, ZSK-B1
key=$(cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Generated" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >ksr.request.expect.$n
cat two-tone.test.ksk1 >>ksr.request.expect.$n
cat two-tone.test.ksk2 >>ksr.request.expect.$n
cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Bundle 2: KSK-A1, KSK-B1, ZSK-A1 + ZSK-A2, ZSK-B1
key=$(cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk2.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat two-tone.test.ksk1 >>ksr.request.expect.$n
cat two-tone.test.ksk2 >>ksr.request.expect.$n
print_dnskeys two-tone.test 1 2 $DEFAULT_ALGORITHM_NUMBER ksr.keygen.out.expect.$DEFAULT_ALGORITHM_NUMBER >>ksr.request.expect.$n
cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Bundle 3: KSK-A1, KSK-B1, ZSK-A2, ZSK-B1
key=$(cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat two-tone.test.ksk1 >>ksr.request.expect.$n
cat two-tone.test.ksk2 >>ksr.request.expect.$n
cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Bundle 4: KSK-A1, KSK-B1, ZSK-A2, ZSK-B1 + ZSK-B2
key=$(cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk2.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat two-tone.test.ksk1 >>ksr.request.expect.$n
cat two-tone.test.ksk2 >>ksr.request.expect.$n
cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
print_dnskeys two-tone.test 1 2 $ALTERNATIVE_ALGORITHM_NUMBER ksr.keygen.out.expect.$ALTERNATIVE_ALGORITHM_NUMBER >>ksr.request.expect.$n
# Bundle 5: KSK-A1, KSK-B1, ZSK-A2, ZSK-B2
key=$(cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat two-tone.test.ksk1 >>ksr.request.expect.$n
cat two-tone.test.ksk2 >>ksr.request.expect.$n
cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
# Footer
grep ";; KeySigningRequest generated at" ksr.request.out.$n >footer.$n || ret=1
cat footer.$n >>ksr.request.expect.$n
# Check the KSR request against the expected request.
diff -w ksr.request.out.$n ksr.request.expect.$n >/dev/null || ret=1
# Save request for ksr sign operation.
cp ksr.request.expect.$n ksr.request.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
num_occurrences() {
count="$1"
file="$2"
line="$3"
exclude="$4"
if [ -z "$exclude" ]; then
lines=$(cat "$file" | while read line; do echo $line; done | grep "$line" | wc -l)
echo_i "$lines occurrences: $1 $2 $3"
else
lines=$(cat "$file" | while read line; do echo $line; done | grep -v "$exclude" | grep "$line" | wc -l)
echo_i "$lines occurrences: $1 $2 $3 (exclude $4)"
fi
test "$lines" -eq "$count" || return 1
}
# Sign request: two-tone
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with multiple algorithms ($n)"
ret=0
ksr two-tone -i $created -e +6mo -K offline -f ksr.request.expect sign two-tone.test >ksr.sign.out.$n 2>&1 || ret=1
test "$ret" -eq 0 || echo_i "failed"
# Weak testing:
zone="two-tone.test"
# expect 24 headers (including the footer)
num_occurrences 24 ksr.sign.out.$n ";; SignedKeyResponse 1.0" || ret=1
# expect 23 KSKs and its signatures (for each header one)
num_occurrences 23 ksr.sign.out.$n "DNSKEY 257 3 8" "CDNSKEY" || ret=1 # exclude CDNSKEY lines
test "$ret" -eq 0 || echo_i "2 failed"
num_occurrences 23 ksr.sign.out.$n "DNSKEY 257 3 13" "CDNSKEY" || ret=1 # exclude CDNSKEY lines
test "$ret" -eq 0 || echo_i "3 failed"
num_occurrences 23 ksr.sign.out.$n "RRSIG DNSKEY 8" "CDNSKEY" || ret=1 # exclude CDNSKEY lines
test "$ret" -eq 0 || echo_i "4 failed"
num_occurrences 23 ksr.sign.out.$n "RRSIG DNSKEY 13" "CDNSKEY" || ret=1 # exclude CDNSKEY lines
test "$ret" -eq 0 || echo_i "5 failed"
# ... 23 CDNSKEY records and its signatures
num_occurrences 23 ksr.sign.out.$n "CDNSKEY 257 3 8" || ret=1
test "$ret" -eq 0 || echo_i "6 failed"
num_occurrences 23 ksr.sign.out.$n "CDNSKEY 257 3 13" || ret=1
test "$ret" -eq 0 || echo_i "7 failed"
num_occurrences 23 ksr.sign.out.$n "RRSIG CDNSKEY 8" || ret=1
test "$ret" -eq 0 || echo_i "8 failed"
num_occurrences 23 ksr.sign.out.$n "RRSIG CDNSKEY 13" || ret=1
test "$ret" -eq 0 || echo_i "9 failed"
# ... 23 CDS records and its signatures
num_occurrences 23 ksr.sign.out.$n "CDS 8 2" || ret=1
test "$ret" -eq 0 || echo_i "10 failed"
num_occurrences 23 ksr.sign.out.$n "CDS 13 2" || ret=1
test "$ret" -eq 0 || echo_i "11 failed"
num_occurrences 23 ksr.sign.out.$n "RRSIG CDS 8" || ret=1
test "$ret" -eq 0 || echo_i "12 failed"
num_occurrences 23 ksr.sign.out.$n "RRSIG CDS 13" || ret=1
test "$ret" -eq 0 || echo_i "13 failed"
# expect 25 ZSK (two more for double keys during the rollover)
num_occurrences 25 ksr.sign.out.$n "DNSKEY 256 3 8" || ret=1
test "$ret" -eq 0 || echo_i "14 failed"
num_occurrences 25 ksr.sign.out.$n "DNSKEY 256 3 13" || ret=1
test "$ret" -eq 0 || echo_i "15 failed"
status=$((status + ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
@@ -10,5 +10,5 @@
# information regarding copyright ownership.
def test_glue(run_tests_sh):
def test_ksr(run_tests_sh):
run_tests_sh()
-1
View File
@@ -14,7 +14,6 @@
#
# Clean up after limits tests.
#
rm -f dig.out.*
rm -f */named.memstats
rm -f */named.conf
rm -f */named.run
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+91 -91
View File
@@ -19019,94 +19019,94 @@ a-maximum-rrset A 10.0.0.0
A 10.0.15.157
A 10.0.15.158
A 10.0.15.159
A 10.1.0.0
A 10.1.0.1
A 10.1.0.2
A 10.1.0.3
A 10.1.0.4
A 10.1.0.5
A 10.1.0.6
A 10.1.0.7
A 10.1.0.8
A 10.1.0.9
A 10.1.0.10
A 10.1.0.11
A 10.1.0.12
A 10.1.0.13
A 10.1.0.14
A 10.1.0.15
A 10.1.0.16
A 10.1.0.17
A 10.1.0.18
A 10.1.0.19
A 10.1.0.20
A 10.1.0.21
A 10.1.0.22
A 10.1.0.23
A 10.1.0.24
A 10.1.0.25
A 10.1.0.26
A 10.1.0.27
A 10.1.0.28
A 10.1.0.29
A 10.1.0.30
A 10.1.0.31
A 10.1.0.32
A 10.1.0.33
A 10.1.0.34
A 10.1.0.35
A 10.1.0.36
A 10.1.0.37
A 10.1.0.38
A 10.1.0.39
A 10.1.0.40
A 10.1.0.41
A 10.1.0.42
A 10.1.0.43
A 10.1.0.44
A 10.1.0.45
A 10.1.0.46
A 10.1.0.47
A 10.1.0.48
A 10.1.0.49
A 10.1.0.50
A 10.1.0.51
A 10.1.0.52
A 10.1.0.53
A 10.1.0.54
A 10.1.0.55
A 10.1.0.56
A 10.1.0.57
A 10.1.0.58
A 10.1.0.59
A 10.1.0.60
A 10.1.0.61
A 10.1.0.62
A 10.1.0.63
A 10.1.0.64
A 10.1.0.65
A 10.1.0.66
A 10.1.0.67
A 10.1.0.68
A 10.1.0.69
A 10.1.0.70
A 10.1.0.71
A 10.1.0.72
A 10.1.0.73
A 10.1.0.74
A 10.1.0.75
A 10.1.0.76
A 10.1.0.77
A 10.1.0.78
A 10.1.0.79
A 10.1.0.80
A 10.1.0.81
A 10.1.0.82
A 10.1.0.83
A 10.1.0.84
A 10.1.0.85
A 10.1.0.86
A 10.1.0.87
A 10.1.0.88
A 10.1.0.89
A 10.1.0.90
A 10.0.15.160
A 10.0.15.161
A 10.0.15.162
A 10.0.15.163
A 10.0.15.164
A 10.0.15.165
A 10.0.15.166
A 10.0.15.167
A 10.0.15.168
A 10.0.15.169
A 10.0.15.170
A 10.0.15.171
A 10.0.15.172
A 10.0.15.173
A 10.0.15.174
A 10.0.15.175
A 10.0.15.176
A 10.0.15.177
A 10.0.15.178
A 10.0.15.179
A 10.0.15.180
A 10.0.15.181
A 10.0.15.182
A 10.0.15.183
A 10.0.15.184
A 10.0.15.185
A 10.0.15.186
A 10.0.15.187
A 10.0.15.188
A 10.0.15.189
A 10.0.15.190
A 10.0.15.191
A 10.0.15.192
A 10.0.15.193
A 10.0.15.194
A 10.0.15.195
A 10.0.15.196
A 10.0.15.197
A 10.0.15.198
A 10.0.15.199
A 10.0.15.200
A 10.0.15.201
A 10.0.15.202
A 10.0.15.203
A 10.0.15.204
A 10.0.15.205
A 10.0.15.206
A 10.0.15.207
A 10.0.15.208
A 10.0.15.209
A 10.0.15.210
A 10.0.15.211
A 10.0.15.212
A 10.0.15.213
A 10.0.15.214
A 10.0.15.215
A 10.0.15.216
A 10.0.15.217
A 10.0.15.218
A 10.0.15.219
A 10.0.15.220
A 10.0.15.221
A 10.0.15.222
A 10.0.15.223
A 10.0.15.224
A 10.0.15.225
A 10.0.15.226
A 10.0.15.227
A 10.0.15.228
A 10.0.15.229
A 10.0.15.230
A 10.0.15.231
A 10.0.15.232
A 10.0.15.233
A 10.0.15.234
A 10.0.15.235
A 10.0.15.236
A 10.0.15.237
A 10.0.15.238
A 10.0.15.239
A 10.0.15.240
A 10.0.15.241
A 10.0.15.242
A 10.0.15.243
A 10.0.15.244
A 10.0.15.245
A 10.0.15.246
A 10.0.15.247
A 10.0.15.248
A 10.0.15.249
A 10.0.15.250
-57
View File
@@ -1,57 +0,0 @@
#!/bin/sh
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
set -e
. ../conf.sh
DIGOPTS="-p ${PORT}"
status=0
echo_i "1000 A records"
$DIG $DIGOPTS +tcp +norec 1000.example. @10.53.0.1 a >dig.out.1000 || status=1
# $DIG $DIGOPTS 1000.example. @10.53.0.1 a > knowngood.dig.out.1000
digcomp knowngood.dig.out.1000 dig.out.1000 || status=1
echo_i "2000 A records"
$DIG $DIGOPTS +tcp +norec 2000.example. @10.53.0.1 a >dig.out.2000 || status=1
# $DIG $DIGOPTS 2000.example. @10.53.0.1 a > knowngood.dig.out.2000
digcomp knowngood.dig.out.2000 dig.out.2000 || status=1
echo_i "3000 A records"
$DIG $DIGOPTS +tcp +norec 3000.example. @10.53.0.1 a >dig.out.3000 || status=1
# $DIG $DIGOPTS 3000.example. @10.53.0.1 a > knowngood.dig.out.3000
digcomp knowngood.dig.out.3000 dig.out.3000 || status=1
echo_i "4000 A records"
$DIG $DIGOPTS +tcp +norec 4000.example. @10.53.0.1 a >dig.out.4000 || status=1
# $DIG $DIGOPTS 4000.example. @10.53.0.1 a > knowngood.dig.out.4000
digcomp knowngood.dig.out.4000 dig.out.4000 || status=1
echo_i "exactly maximum rrset"
$DIG $DIGOPTS +tcp +norec +noedns a-maximum-rrset.example. @10.53.0.1 a >dig.out.a-maximum-rrset \
|| status=1
# $DIG $DIGOPTS a-maximum-rrset.example. @10.53.0.1 a > knowngood.dig.out.a-maximum-rrset
digcomp knowngood.dig.out.a-maximum-rrset dig.out.a-maximum-rrset || status=1
echo_i "exceed maximum rrset (5000 A records)"
$DIG $DIGOPTS +tcp +norec +noadd 5000.example. @10.53.0.1 a >dig.out.exceed || status=1
# Look for truncation bit (tc).
grep 'flags: .*tc.*;' dig.out.exceed >/dev/null || {
echo_i "TC bit was not set"
status=1
}
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
+52
View File
@@ -0,0 +1,52 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import itertools
import isctest
import pytest
import dns.message
# Everything from getting a big answer to creating an RR set with thousands
# of records takes minutes of CPU and real time with dnspython < 2.0.0.
pytest.importorskip("dns", minversion="2.0.0")
@pytest.mark.parametrize(
"name,limit",
[
("1000", 1000),
("2000", 2000),
("3000", 3000),
("4000", 4000),
("a-maximum-rrset", 4091),
],
)
def test_limits(name, limit):
msg_query = dns.message.make_query(f"{name}.example.", "A")
res = isctest.query.tcp(msg_query, "10.53.0.1")
iplist = [
f"10.0.{x}.{y}"
for x, y in itertools.islice(itertools.product(range(256), repeat=2), limit)
]
msg_rrset = [dns.rrset.from_text_list(f"{name}.example.", "5M", "IN", "A", iplist)]
assert res.answer == msg_rrset
def test_limit_exceeded():
msg_query = dns.message.make_query("5000.example.", "A")
res = isctest.query.tcp(msg_query, "10.53.0.1")
assert res.flags & dns.flags.TC, "TC flag was not set"
@@ -1,14 +0,0 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
def test_limits(run_tests_sh):
run_tests_sh()
-2
View File
@@ -11,9 +11,7 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
rm -f dig.out.*
rm -f */named.memstats
rm -f */named.conf
rm -f */named.run
rm -f checkzone.out*
rm -f ns*/managed-keys.bind*
@@ -1,12 +0,0 @@
include. 300 IN SOA ns.include. hostmaster.include. 1 3600 1800 1814400 3600
include. 300 IN NS ns.include.
a.include. 300 IN A 10.0.0.1
a.include. 300 IN A 10.0.0.99
a.a.include. 300 IN A 10.0.1.1
b.foo.a.include. 300 IN A 10.0.2.2
b.include. 300 IN A 10.0.0.2
a.b.include. 300 IN A 10.0.1.1
c.b.include. 300 IN A 10.0.0.3
b.foo.b.include. 300 IN A 10.0.2.2
ns.include. 300 IN A 127.0.0.1
include. 300 IN SOA ns.include. hostmaster.include. 1 3600 1800 1814400 3600
@@ -1,10 +0,0 @@
ttl1. 3 IN SOA ns.ttl1. hostmaster.ttl1. 1 3600 1800 1814400 3
ttl1. 3 IN NS ns.ttl1.
a.ttl1. 3 IN TXT "soa minttl 3"
b.ttl1. 2 IN TXT "explicit ttl 2"
c.ttl1. 3 IN TXT "soa minttl 3"
d.ttl1. 1 IN TXT "default ttl 1"
e.ttl1. 4 IN TXT "explicit ttl 4"
f.ttl1. 1 IN TXT "default ttl 1"
ns.ttl1. 3 IN A 10.53.0.1
ttl1. 3 IN SOA ns.ttl1. hostmaster.ttl1. 1 3600 1800 1814400 3
@@ -1,10 +0,0 @@
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
ttl2. 1 IN NS ns.ttl2.
a.ttl2. 1 IN TXT "inherited ttl 1"
b.ttl2. 2 IN TXT "explicit ttl 2"
c.ttl2. 2 IN TXT "inherited ttl 2"
d.ttl2. 3 IN TXT "default ttl 3"
e.ttl2. 2 IN TXT "explicit ttl 2"
f.ttl2. 3 IN TXT "default ttl 3"
ns.ttl2. 1 IN A 10.53.0.1
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
-75
View File
@@ -1,75 +0,0 @@
#!/bin/sh
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
set -e
. ../conf.sh
DIGOPTS="-p ${PORT}"
status=0
n=0
ret=0
n=$((n + 1))
echo_i "test master file \$INCLUDE semantics ($n)"
$DIG $DIGOPTS +nostats +nocmd include. axfr @10.53.0.1 >dig.out.$n || ret=1
diff dig.out.$n knowngood.include || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
ret=0
n=$((n + 1))
echo_i "test master file BIND 8 compatibility TTL and \$TTL semantics ($n)"
$DIG $DIGOPTS +nostats +nocmd ttl1. axfr @10.53.0.1 >dig.out.$n || ret=1
diff dig.out.$n knowngood.ttl1 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
ret=0
n=$((n + 1))
echo_i "test of master file RFC1035 TTL and \$TTL semantics ($n)"
$DIG $DIGOPTS +nostats +nocmd ttl2. axfr @10.53.0.1 >dig.out.$n || ret=1
diff dig.out.$n knowngood.ttl2 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
ret=0
n=$((n + 1))
echo_i "test that the nameserver is running with a missing master file ($n)"
$DIG $DIGOPTS +tcp +noall +answer example soa @10.53.0.2 >dig.out.$n || ret=1
grep SOA dig.out.$n >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
ret=0
n=$((n + 1))
echo_i "test that the nameserver returns SERVFAIL for a missing master file ($n)"
$DIG $DIGOPTS +tcp +all missing soa @10.53.0.2 >dig.out.$n || ret=1
grep "status: SERVFAIL" dig.out.$n >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
ret=0
n=$((n + 1))
echo_i "test owner inheritance after "'$INCLUDE'" ($n)"
$CHECKZONE -Dq example zone/inheritownerafterinclude.db >checkzone.out$n
diff checkzone.out$n zone/inheritownerafterinclude.good || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
@@ -0,0 +1,119 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import os
import subprocess
import dns.message
import dns.zone
import isctest
def test_masterfile_include_semantics():
"""Test master file $INCLUDE semantics"""
msg_axfr = dns.message.make_query("include.", "AXFR")
res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1")
axfr_include_semantics = """;ANSWER
include. 300 IN SOA ns.include. hostmaster.include. 1 3600 1800 1814400 3600
include. 300 IN NS ns.include.
a.include. 300 IN A 10.0.0.1
a.include. 300 IN A 10.0.0.99
a.a.include. 300 IN A 10.0.1.1
b.foo.a.include. 300 IN A 10.0.2.2
b.include. 300 IN A 10.0.0.2
a.b.include. 300 IN A 10.0.1.1
c.b.include. 300 IN A 10.0.0.3
b.foo.b.include. 300 IN A 10.0.2.2
ns.include. 300 IN A 127.0.0.1
"""
expected = dns.message.from_text(axfr_include_semantics)
isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True)
def test_masterfile_bind_8_compat_semantics():
"""Test master file BIND 8 TTL and $TTL semantics compatibility"""
msg_axfr = dns.message.make_query("ttl1.", "AXFR")
res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1")
axfr_ttl_semantics = """;ANSWER
ttl1. 3 IN SOA ns.ttl1. hostmaster.ttl1. 1 3600 1800 1814400 3
ttl1. 3 IN NS ns.ttl1.
a.ttl1. 3 IN TXT "soa minttl 3"
b.ttl1. 2 IN TXT "explicit ttl 2"
c.ttl1. 3 IN TXT "soa minttl 3"
d.ttl1. 1 IN TXT "default ttl 1"
e.ttl1. 4 IN TXT "explicit ttl 4"
f.ttl1. 1 IN TXT "default ttl 1"
ns.ttl1. 3 IN A 10.53.0.1
"""
expected = dns.message.from_text(axfr_ttl_semantics)
isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True)
def test_masterfile_rfc_1035_semantics():
"""Test master file RFC1035 TTL and $TTL semantics"""
msg_axfr = dns.message.make_query("ttl2.", "AXFR")
res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1")
axfr_ttl_semantics = """;ANSWER
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
ttl2. 1 IN NS ns.ttl2.
a.ttl2. 1 IN TXT "inherited ttl 1"
b.ttl2. 2 IN TXT "explicit ttl 2"
c.ttl2. 2 IN TXT "inherited ttl 2"
d.ttl2. 3 IN TXT "default ttl 3"
e.ttl2. 2 IN TXT "explicit ttl 2"
f.ttl2. 3 IN TXT "default ttl 3"
ns.ttl2. 1 IN A 10.53.0.1
"""
expected = dns.message.from_text(axfr_ttl_semantics)
isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True)
def test_masterfile_missing_master_file():
"""Test nameserver running with a missing master file"""
msg_soa = dns.message.make_query("example.", "SOA")
res_soa = isctest.query.tcp(msg_soa, "10.53.0.2")
expected_soa_rr = """;ANSWER
example. 300 IN SOA mname1. . 2010042407 20 20 1814400 3600
"""
expected = dns.message.from_text(expected_soa_rr)
isctest.check.rrsets_equal(res_soa.answer, expected.answer, compare_ttl=True)
def test_masterfile_missing_master_file_servfail():
"""Test nameserver returning SERVFAIL for a missing master file"""
msg_soa = dns.message.make_query("missing.", "SOA")
res_soa = isctest.query.tcp(msg_soa, "10.53.0.2")
isctest.check.servfail(res_soa)
def test_masterfile_owner_inheritance():
"""Test owner inheritance after $INCLUDE"""
checker_output = subprocess.run(
[
os.environ["CHECKZONE"],
"-D",
"-q",
"example",
"zone/inheritownerafterinclude.db",
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
).stdout.decode("utf-8")
owner_inheritance_zone = """
example. 0 IN SOA . . 0 0 0 0 0
example. 0 IN TXT "this should be at the zone apex"
example. 0 IN NS .
"""
checker_zone = dns.zone.from_text(checker_output, origin="example.")
expected = dns.zone.from_text(owner_inheritance_zone, origin="example.")
isctest.check.zones_equal(checker_zone, expected, compare_ttl=True)
@@ -1,14 +0,0 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
def test_masterfile(run_tests_sh):
run_tests_sh()
@@ -1,3 +0,0 @@
example. 0 IN SOA . . 0 0 0 0 0
example. 0 IN NS .
example. 0 IN TXT "this should be at the zone apex"
@@ -14,6 +14,8 @@
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
# invalid notify-source-v6 address
notify-source-v6 fd92:7065:b8e:fffe::a35:5;
transfer-source 10.53.0.1;
port @PORT@;
pid-file "named.pid";
+3
View File
@@ -19,6 +19,9 @@ $TTL 300
)
. NS a.root-servers.nil.
a.root-servers.nil. A 10.53.0.1
; sends NOTIFY using invalid notify-source-v6 address
. NS other.root-servers.nil.
other.root-servers.nil. AAAA fd92:7065:b8e:fffe::a35:4
example. NS ns2.example.
ns2.example. A 10.53.0.2
+1
View File
@@ -22,6 +22,7 @@ example. NS ns2.example.
ns2.example. A 10.53.0.2
example. NS ns3.example.
ns3.example. A 10.53.0.3
ns3.example. AAAA fd92:7065:b8e:ffff::3
$ORIGIN example.
a A 10.0.0.2
@@ -14,6 +14,7 @@
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
notify-source-v6 fd92:7065:b8e:ffff::2;
transfer-source 10.53.0.2;
port @PORT@;
pid-file "named.pid";
+1 -1
View File
@@ -18,7 +18,7 @@ options {
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
listen-on-v6 { fd92:7065:b8e:ffff::3; };
recursion yes;
notify yes;
dnssec-validation no;
+7
View File
@@ -98,6 +98,12 @@ END {
}' ns2/named.run >awk.out.ns2.test$n || ret=1
test_end
# See [GL#4689]
test_start "checking server behaviour with invalid notify-source-v6 address"
grep "zone ./IN: sending notify to fd92:7065:b8e:fffe::a35:4#" ns1/named.run >/dev/null || ret=1
grep "dns_request_create: failed address not available" ns1/named.run >/dev/null || ret=1
test_end
nextpart ns3/named.run >/dev/null
sleep 1 # make sure filesystem time stamp is newer for reload.
@@ -109,6 +115,7 @@ wait_for_log_re 45 "transfer of 'example/IN' from 10.53.0.2#.*success" ns3/named
test_start "checking notify message was logged"
grep 'notify from 10.53.0.2#[0-9][0-9]*: serial 2$' ns3/named.run >/dev/null || ret=1
grep 'refused notify from non-primary: fd92:7065:b8e:ffff::2#[0-9][0-9]*$' ns3/named.run >/dev/null || ret=1
test_end
test_start "checking example2 loaded"
@@ -12,5 +12,6 @@
$TTL 300
@ IN SOA a.root-servers.nil. hostmaster.example.net. 0 0 0 0 0
@ IN NS a.root-servers.nil.
10.in-addr.arpa TXT turn off redirect
* IN A 100.100.100.1
* IN AAAA 2001:ffff:ffff::100.100.100.1
+8
View File
@@ -518,6 +518,14 @@ n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "checking nxdomain-redirect against built-in RFC-1918 zone ($n)"
ret=0
$DIG $DIGOPTS -x 10.0.0.1 @10.53.0.4 -b 10.53.0.2 >dig.out.ns4.test$n || ret=1
grep "status: NXDOMAIN" dig.out.ns4.test$n >/dev/null || ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "checking tld nxdomain-redirect against signed root zone ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.5 asdfasdfasdf >dig.out.ns5.test$n || ret=1
+15 -3
View File
@@ -505,9 +505,21 @@ n=$((n + 1))
echo_i "check that '-t aaaa' in .digrc does not have unexpected side effects ($n)"
ret=0
echo "-t aaaa" >.digrc
(HOME="$(pwd)" dig_with_opts @10.53.0.4 . >dig.out.1.${n}) || ret=1
(HOME="$(pwd)" dig_with_opts @10.53.0.4 . A >dig.out.2.${n}) || ret=1
(HOME="$(pwd)" dig_with_opts @10.53.0.4 -x 127.0.0.1 >dig.out.3.${n}) || ret=1
(
HOME="$(pwd)"
export HOME
dig_with_opts @10.53.0.4 . >dig.out.1.${n}
) || ret=1
(
HOME="$(pwd)"
export HOME
dig_with_opts @10.53.0.4 . A >dig.out.2.${n}
) || ret=1
(
HOME="$(pwd)"
export HOME
dig_with_opts @10.53.0.4 -x 127.0.0.1 >dig.out.3.${n}
) || ret=1
grep ';\..*IN.*AAAA$' dig.out.1.${n} >/dev/null || ret=1
grep ';\..*IN.*A$' dig.out.2.${n} >/dev/null || ret=1
grep 'extra type option' dig.out.2.${n} >/dev/null && ret=1
+1 -1
View File
@@ -436,7 +436,7 @@ n=$((n + 1))
echo_i "testing automatic zones are reported ($n)"
ret=0
$RNDC -s 10.53.0.4 -p ${EXTRAPORT6} -c ns4/key6.conf status >rndc.out.1.test$n || ret=1
grep "number of zones: 199 (198 automatic)" rndc.out.1.test$n >/dev/null || ret=1
grep "number of zones: 201 (200 automatic)" rndc.out.1.test$n >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
@@ -1,3 +0,0 @@
IN
CH
HS
-98
View File
@@ -1,98 +0,0 @@
#!/bin/sh
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
set -e
. ../conf.sh
status=0
n=0
n=$((n + 1))
echo_i "class list ($n)"
$RRCHECKER -C >classlist.out
diff classlist.out classlist.good || {
echo_i "failed"
status=$((status + 1))
}
n=$((n + 1))
echo_i "type list ($n)"
$RRCHECKER -T >typelist.out
diff typelist.out typelist.good || {
echo_i "failed"
status=$((status + 1))
}
n=$((n + 1))
echo_i "private type list ($n)"
$RRCHECKER -P >privatelist.out
diff privatelist.out privatelist.good || {
echo_i "failed"
status=$((status + 1))
}
myecho() {
cat <<EOF
$*
EOF
}
n=$((n + 1))
echo_i "check conversions to canonical format ($n)"
ret=0
$SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 0 >tempzone
$CHECKZONE -Dq . tempzone | sed '/^;/d' >checkzone.out$n
while read -r name tt cl ty rest; do
myecho "$cl $ty $rest" | $RRCHECKER -p >checker.out || {
ret=1
echo_i "'$cl $ty $rest' not handled."
}
read -r cl0 ty0 rest0 <checker.out
test "$cl $ty $rest" = "$cl0 $ty0 $rest0" || {
ret=1
echo_i "'$cl $ty $rest' != '$cl0 $ty0 $rest0'"
}
done <checkzone.out$n
test $ret -eq 0 || {
echo_i "failed"
status=$((status + 1))
}
n=$((n + 1))
echo_i "check conversions to and from unknown record format ($n)"
ret=0
$CHECKZONE -Dq . tempzone | sed '/^;/d' >checkzone.out$n
while read -r name tt cl ty rest; do
myecho "$cl $ty $rest" | $RRCHECKER -u >checker.out || {
ret=1
echo_i "'$cl $ty $rest' not converted to unknown record format"
}
read -r clu tyu restu <checker.out
myecho "$clu $tyu $restu" | $RRCHECKER -p >checker.out || {
ret=1
echo_i "'$cl $ty $rest' not converted back to canonical format"
}
read -r cl0 ty0 rest0 <checker.out
test "$cl $ty $rest" = "$cl0 $ty0 $rest0" || {
ret=1
echo_i "'$cl $ty $rest' != '$cl0 $ty0 $rest0'"
}
done <checkzone.out$n
test $ret -eq 0 || {
echo_i "failed"
status=$((status + 1))
}
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
@@ -0,0 +1,188 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import os
import subprocess
import pytest
@pytest.mark.parametrize(
"option,expected_result",
[
("-C", ["HS", "CH", "IN"]),
(
"-T",
[
"A",
"A6",
"AAAA",
"AFSDB",
"AMTRELAY",
"APL",
"ATMA",
"AVC",
"CAA",
"CDNSKEY",
"CDS",
"CERT",
"CNAME",
"CSYNC",
"DHCID",
"DLV",
"DNAME",
"DNSKEY",
"DOA",
"DS",
"EID",
"EUI48",
"EUI64",
"GID",
"GPOS",
"HINFO",
"HIP",
"HTTPS",
"IPSECKEY",
"ISDN",
"KEY",
"KX",
"L32",
"L64",
"LOC",
"LP",
"MB",
"MD",
"MF",
"MG",
"MINFO",
"MR",
"MX",
"NAPTR",
"NID",
"NIMLOC",
"NINFO",
"NS",
"NSAP",
"NSAP-PTR",
"NSEC",
"NSEC3",
"NSEC3PARAM",
"NULL",
"NXT",
"OPENPGPKEY",
"PTR",
"PX",
"RESINFO",
"RKEY",
"RP",
"RRSIG",
"RT",
"SIG",
"SINK",
"SMIMEA",
"SOA",
"SPF",
"SRV",
"SSHFP",
"SVCB",
"TA",
"TALINK",
"TLSA",
"TXT",
"UID",
"UINFO",
"UNSPEC",
"URI",
"WKS",
"X25",
"ZONEMD",
],
),
("-P", []),
],
)
def test_rrchecker_list_standard_names(option, expected_result):
stdout = subprocess.run(
[
os.environ["RRCHECKER"],
option,
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
).stdout.decode("utf-8")
values = [line for line in stdout.split("\n") if line.strip()]
assert sorted(values) == sorted(expected_result)
def run_rrchecker(option, rr_class, rr_type, rr_rest):
with subprocess.Popen(
[os.environ["RRCHECKER"], option],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
) as process:
rrchecker_output, _ = process.communicate(
f"{rr_class} {rr_type} {rr_rest}".encode("utf-8")
)
return rrchecker_output.decode("utf-8").split()
@pytest.mark.parametrize("option", ["-p", "-u"])
def test_rrchecker_conversions(option):
tempzone_file = "tempzone"
with open(tempzone_file, "w", encoding="utf-8") as file:
subprocess.run(
[
os.environ["SHELL"],
os.environ["TOP_SRCDIR"] + "/bin/tests/system/genzone.sh",
"0",
],
stdout=file,
stderr=subprocess.PIPE,
check=True,
)
checkzone_output = subprocess.run(
[
os.environ["CHECKZONE"],
"-D",
"-q",
".",
tempzone_file,
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
).stdout.decode("utf-8")
checkzone_output = [
line for line in checkzone_output.splitlines() if not line.startswith(";")
]
for rr in checkzone_output:
rr_parts_orig = rr.split()
assert len(rr_parts_orig) >= 4, f"invalid rr: {rr}"
rr_class_orig, rr_type_orig, rr_rest_orig = (
rr_parts_orig[2],
rr_parts_orig[3],
" ".join(rr_parts_orig[4:]),
)
rr_class, rr_type, rr_rest = rr_class_orig, rr_type_orig, rr_rest_orig
if option == "-u":
rr_class, rr_type, *rr_rest = run_rrchecker(
"-u", rr_class_orig, rr_type_orig, rr_rest_orig
)
rr_rest = " ".join(rr_rest)
rr_class, rr_type, *rr_rest = run_rrchecker("-p", rr_class, rr_type, rr_rest)
assert rr_class_orig == rr_class
assert rr_type_orig == rr_type
assert rr_rest_orig == " ".join(rr_rest)
@@ -1,14 +0,0 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
def test_rrchecker(run_tests_sh):
run_tests_sh()
-82
View File
@@ -1,82 +0,0 @@
A
NS
MD
MF
CNAME
SOA
MB
MG
MR
NULL
WKS
PTR
HINFO
MINFO
MX
TXT
RP
AFSDB
X25
ISDN
RT
NSAP
NSAP-PTR
SIG
KEY
PX
GPOS
AAAA
LOC
NXT
EID
NIMLOC
SRV
ATMA
NAPTR
KX
CERT
A6
DNAME
SINK
APL
DS
SSHFP
IPSECKEY
RRSIG
NSEC
DNSKEY
DHCID
NSEC3
NSEC3PARAM
TLSA
SMIMEA
HIP
NINFO
RKEY
TALINK
CDS
CDNSKEY
OPENPGPKEY
CSYNC
ZONEMD
SVCB
HTTPS
SPF
UINFO
UID
GID
UNSPEC
NID
L32
L64
LP
EUI48
EUI64
URI
CAA
AVC
DOA
AMTRELAY
RESINFO
TA
DLV
+1
View File
@@ -323,6 +323,7 @@ sub construct_ans_command {
}
if (-e "$testdir/$server/ans.py") {
$ENV{'PYTHONPATH'} = $testdir . ":" . $ENV{'srcdir'};
$command = "$PYTHON -u ans.py 10.53.0.$n $queryport";
} elsif (-e "$testdir/$server/ans.pl") {
$command = "$PERL ans.pl";
+3
View File
@@ -17,3 +17,6 @@ a.root-servers.nil. A 10.53.0.1
example.com. NS example.
ns.example.net. A 10.53.0.3
unsigned. NS ns.unsigned.
ns.unsigned. A 10.53.0.3
@@ -33,6 +33,7 @@ options {
recursion yes;
dnssec-validation yes;
notify no;
minimal-responses no;
};
zone "." {
@@ -60,3 +61,8 @@ zone "undelegated" {
type static-stub;
server-addresses { 10.53.0.3; };
};
zone "unsigned" {
type static-stub;
server-addresses { 10.53.0.3; };
};

Some files were not shown because too many files have changed in this diff Show More