mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-10 07:49:59 -04:00
[9.18] fix: usr: Adding NSEC3 opt-out records could leave invalid records in chain
When creating an NSEC3 opt-out chain, a node in the chain could be removed too soon, causing the previous NSEC3 being unable to be found, resulting in invalid NSEC3 records to be left in the zone. This has been fixed. Closes #5671 Backport of MR !11328 Merge branch 'backport-5671-fix-dbiterator-prev-9.18' into 'bind-9.18' See merge request isc-projects/bind9!11341
This commit is contained in:
commit
335be0e079
5 changed files with 190 additions and 2 deletions
41
bin/tests/system/optout/ns2/named.conf.j2
Normal file
41
bin/tests/system/optout/ns2/named.conf.j2
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
options {
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.2; };
|
||||
listen-on-v6 { none; };
|
||||
allow-transfer { any; };
|
||||
recursion no;
|
||||
dnssec-validation no;
|
||||
ixfr-from-differences yes;
|
||||
sig-signing-nodes 900;
|
||||
sig-signing-signatures 900;
|
||||
};
|
||||
|
||||
include "controls.conf";
|
||||
|
||||
dnssec-policy "optout" {
|
||||
keys {
|
||||
csk lifetime unlimited algorithm ecdsa256;
|
||||
};
|
||||
nsec3param iterations 0 optout yes salt-length 0;
|
||||
};
|
||||
|
||||
zone "test" {
|
||||
type primary;
|
||||
file "test.db";
|
||||
dnssec-policy "optout";
|
||||
inline-signing yes;
|
||||
};
|
||||
22
bin/tests/system/optout/ns2/test.db
Normal file
22
bin/tests/system/optout/ns2/test.db
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
; 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.
|
||||
|
||||
$TTL 3600
|
||||
@ IN SOA ns2.test. hostmaster.test. 1 7200 3600 24796800 3600
|
||||
IN NS ns2
|
||||
|
||||
ns2 IN A 10.53.0.2
|
||||
|
||||
a IN A 127.0.0.1
|
||||
|
||||
$GENERATE 1-50000 child$ IN NS ns.example.
|
||||
|
||||
child303 IN DS 7250 13 2 A30B3F78B6DDE9A4A9A2AD0C805518B4F49EC62E7D3F4531D33DE697 CDA01CB2
|
||||
16
bin/tests/system/optout/setup.sh
Normal file
16
bin/tests/system/optout/setup.sh
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#!/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.
|
||||
|
||||
. ../conf.sh
|
||||
|
||||
copy_setports ../_common/controls.conf.in ns2/controls.conf
|
||||
108
bin/tests/system/optout/tests_optout.py
Executable file
108
bin/tests/system/optout/tests_optout.py
Executable file
|
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
# 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 re
|
||||
import sys
|
||||
|
||||
import isctest
|
||||
import pytest
|
||||
|
||||
pytest.importorskip("dns", minversion="2.0.0")
|
||||
import dns.exception
|
||||
import dns.message
|
||||
import dns.name
|
||||
import dns.query
|
||||
import dns.rcode
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skipif(
|
||||
sys.version_info < (3, 7), reason="Python >= 3.7 required [GL #3001]"
|
||||
),
|
||||
pytest.mark.extra_artifacts(
|
||||
[
|
||||
"*.out",
|
||||
"ns2/*.infile",
|
||||
"ns2/*.signed",
|
||||
"ns2/*.jnl",
|
||||
"ns2/*.jbk",
|
||||
"ns2/controls.conf",
|
||||
"ns2/dsset-*",
|
||||
"ns2/K*",
|
||||
]
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def has_nsec3param(zone, response):
|
||||
match = rf"{re.escape(zone)}\.\s+\d+\s+IN\s+NSEC3PARAM\s+1\s+0\s+0\s+-"
|
||||
|
||||
for rr in response.answer:
|
||||
if re.search(match, rr.to_text()):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def do_query(server, qname, qtype, tcp=False):
|
||||
msg = isctest.query.create(qname, qtype)
|
||||
query_func = isctest.query.tcp if tcp else isctest.query.udp
|
||||
response = query_func(msg, server.ip, expected_rcode=dns.rcode.NOERROR)
|
||||
return response
|
||||
|
||||
|
||||
def do_xfr(server, qname):
|
||||
xfr = dns.zone.Zone(origin=f"{qname}.", relativize=False)
|
||||
dns.query.inbound_xfr(
|
||||
where=server.ip, txn_manager=xfr, port=int(os.environ["PORT"])
|
||||
)
|
||||
return xfr
|
||||
|
||||
|
||||
def verify_zone(zone, transfer):
|
||||
verify = os.getenv("VERIFY")
|
||||
assert verify is not None
|
||||
|
||||
filename = f"{zone}.out"
|
||||
with open(filename, "w", encoding="utf-8") as file:
|
||||
file.write(transfer.to_text())
|
||||
|
||||
# dnssec-verify command with default arguments.
|
||||
verify_cmd = [verify, "-z", "-o", zone, filename]
|
||||
|
||||
verifier = isctest.run.cmd(verify_cmd)
|
||||
|
||||
if verifier.returncode != 0:
|
||||
isctest.log.error(f"dnssec-verify {zone}. failed")
|
||||
|
||||
return verifier.returncode == 0
|
||||
|
||||
|
||||
def test_optout(ns2):
|
||||
zone = "test"
|
||||
|
||||
# Wait until the provided zone is signed and then verify its DNSSEC data.
|
||||
def check_nsec3param():
|
||||
response = do_query(ns2, zone, "NSEC3PARAM")
|
||||
return has_nsec3param(zone, response)
|
||||
|
||||
# check zone is fully signed.
|
||||
isctest.run.retry_with_timeout(check_nsec3param, timeout=300)
|
||||
|
||||
# check if zone if DNSSEC valid.
|
||||
transfer = do_xfr(ns2, zone)
|
||||
assert verify_zone(zone, transfer)
|
||||
|
|
@ -9582,11 +9582,12 @@ dbiterator_prev(dns_dbiterator_t *iterator) {
|
|||
resume_iteration(rbtdbiter);
|
||||
}
|
||||
|
||||
dereference_iter_node(rbtdbiter);
|
||||
|
||||
name = dns_fixedname_name(&rbtdbiter->name);
|
||||
origin = dns_fixedname_name(&rbtdbiter->origin);
|
||||
result = dns_rbtnodechain_prev(rbtdbiter->current, name, origin);
|
||||
|
||||
dereference_iter_node(rbtdbiter);
|
||||
|
||||
if (rbtdbiter->current == &rbtdbiter->nsec3chain &&
|
||||
(result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN))
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue