Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88e33102e5 | ||
|
|
bc8b58d8fd | ||
|
|
31165bfe11 | ||
|
|
b793f39cf3 | ||
|
|
76fb29d800 | ||
|
|
18dd7e36db | ||
|
|
7e68928ee1 | ||
|
|
ee2970c861 | ||
|
|
a092cb3d48 | ||
|
|
769baa1188 | ||
|
|
212c72b1f3 |
@@ -1,3 +1,6 @@
|
||||
6012. [bug] Fix inline-signing bugs related to the multisigner
|
||||
model (RFC 8901). [GL #2710]
|
||||
|
||||
6011. [func] Refactor the privilege setting part of named_os unit
|
||||
to make libcap on Linux mandatory and use setreuid
|
||||
and setregid if available. [GL #3583]
|
||||
|
||||
@@ -1595,8 +1595,14 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
if (use_kasp) {
|
||||
seconds = (uint32_t)dns_kasp_sigvalidity(kasp);
|
||||
dns_zone_setsigvalidityinterval(zone, seconds);
|
||||
if (raw != NULL) {
|
||||
dns_zone_setsigvalidityinterval(raw, seconds);
|
||||
}
|
||||
seconds = (uint32_t)dns_kasp_sigrefresh(kasp);
|
||||
dns_zone_setsigresigninginterval(zone, seconds);
|
||||
if (raw != NULL) {
|
||||
dns_zone_setsigresigninginterval(raw, seconds);
|
||||
}
|
||||
} else {
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "sig-validity-interval",
|
||||
@@ -1611,6 +1617,9 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
seconds *= 86400;
|
||||
}
|
||||
dns_zone_setsigvalidityinterval(zone, seconds);
|
||||
if (raw != NULL) {
|
||||
dns_zone_setsigvalidityinterval(raw, seconds);
|
||||
}
|
||||
|
||||
resign = cfg_tuple_get(obj, "re-sign");
|
||||
if (cfg_obj_isvoid(resign)) {
|
||||
@@ -1626,6 +1635,9 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
seconds = cfg_obj_asuint32(resign);
|
||||
}
|
||||
dns_zone_setsigresigninginterval(zone, seconds);
|
||||
if (raw != NULL) {
|
||||
dns_zone_setsigresigninginterval(raw, seconds);
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
@@ -1634,21 +1646,33 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
filename = cfg_obj_asstring(obj);
|
||||
RETERR(dns_zone_setkeydirectory(zone, filename));
|
||||
}
|
||||
if (raw != NULL) {
|
||||
RETERR(dns_zone_setkeydirectory(raw, filename));
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "sig-signing-signatures", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
dns_zone_setsignatures(zone, cfg_obj_asuint32(obj));
|
||||
if (raw != NULL) {
|
||||
dns_zone_setsignatures(raw, cfg_obj_asuint32(obj));
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "sig-signing-nodes", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
dns_zone_setnodes(zone, cfg_obj_asuint32(obj));
|
||||
if (raw != NULL) {
|
||||
dns_zone_setnodes(raw, cfg_obj_asuint32(obj));
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "sig-signing-type", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj));
|
||||
if (raw != NULL) {
|
||||
dns_zone_setprivatetype(raw, cfg_obj_asuint32(obj));
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "update-check-ksk", &obj);
|
||||
@@ -1676,6 +1700,10 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
RETERR(dns_zone_setrefreshkeyinterval(zone,
|
||||
cfg_obj_asuint32(obj)));
|
||||
if (raw != NULL) {
|
||||
RETERR(dns_zone_setrefreshkeyinterval(
|
||||
raw, cfg_obj_asuint32(obj)));
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = cfg_map_get(zoptions, "auto-dnssec", &obj);
|
||||
|
||||
@@ -198,7 +198,7 @@ endif HAVE_PERLMOD_NET_DNS_NAMESERVER
|
||||
endif HAVE_PERLMOD_NET_DNS
|
||||
|
||||
if HAVE_PYTHON
|
||||
TESTS += kasp keymgr2kasp tcp pipelined
|
||||
TESTS += kasp keymgr2kasp multisigner tcp pipelined
|
||||
|
||||
if HAVE_PYTEST
|
||||
TESTS += checkds dispatch rpzextra shutdown timeouts
|
||||
|
||||
@@ -86,6 +86,7 @@ keyfromlabel
|
||||
keymgr2kasp
|
||||
legacy
|
||||
logfileconfig
|
||||
multisigner
|
||||
nzd2nzf
|
||||
pipelined
|
||||
qmin
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/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
|
||||
|
||||
rm -f *.created
|
||||
rm -f cdnskey.ns*
|
||||
rm -f cds.ns*
|
||||
rm -f created.key-*
|
||||
rm -f dig.out.*
|
||||
rm -f python.out.*
|
||||
rm -f rndc.dnssec.status.out.*
|
||||
rm -f unused.key-*
|
||||
|
||||
rm -f ns*/*.jbk
|
||||
rm -f ns*/*.jnl
|
||||
rm -f ns*/*.signed
|
||||
rm -f ns*/*.signed.jnl
|
||||
rm -f ns*/*.zsk
|
||||
rm -f ns*/K*
|
||||
rm -f ns*/keygen.out.*
|
||||
rm -f ns*/managed-keys*
|
||||
rm -f ns*/named.conf
|
||||
rm -f ns*/named.memstats
|
||||
rm -f ns*/named.run
|
||||
rm -f ns*/settime.out.*
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 "model2" {
|
||||
keys {
|
||||
ksk lifetime unlimited algorithm ecdsap256sha256;
|
||||
zsk lifetime unlimited algorithm ecdsap256sha256;
|
||||
};
|
||||
};
|
||||
@@ -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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns3
|
||||
ns3 A 10.53.0.3
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// NS3
|
||||
|
||||
include "../kasp.conf";
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.3;
|
||||
notify-source 10.53.0.3;
|
||||
transfer-source 10.53.0.3;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.3; };
|
||||
listen-on-v6 { none; };
|
||||
allow-transfer { any; };
|
||||
recursion no;
|
||||
key-directory ".";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "model2.multisigner." {
|
||||
type primary;
|
||||
allow-update { any; };
|
||||
file "model2.multisigner.db";
|
||||
dnssec-policy model2;
|
||||
inline-signing no;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/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
|
||||
|
||||
echo_i "ns3/setup.sh"
|
||||
|
||||
zone="model2.multisigner"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
|
||||
O="OMNIPRESENT"
|
||||
ksktimes="-P now -A now -P sync now"
|
||||
zsktimes="-P now -A now"
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 $ksktimes $zone 2> keygen.out.$zone.1)
|
||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2> keygen.out.$zone.2)
|
||||
$SETTIME -s -g $O -k $O now -r $O now -d $O now "$KSK" > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -g $O -k $O now -z $O now "$ZSK" > settime.out.$zone.2 2>&1
|
||||
# ZSK will be added to the other provider with nsupdate.
|
||||
cat "${ZSK}.key" | grep -v ";.*" > "${zone}.zsk"
|
||||
@@ -0,0 +1,26 @@
|
||||
; 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 300
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns4
|
||||
ns4 A 10.53.0.4
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
@@ -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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns3
|
||||
ns3 A 10.53.0.3
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// NS4
|
||||
|
||||
include "../kasp.conf";
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.4;
|
||||
notify-source 10.53.0.4;
|
||||
transfer-source 10.53.0.4;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.4; };
|
||||
listen-on-v6 { none; };
|
||||
allow-transfer { any; };
|
||||
recursion no;
|
||||
key-directory ".";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "model2.multisigner." {
|
||||
type primary;
|
||||
allow-update { any; };
|
||||
file "model2.multisigner.db";
|
||||
dnssec-policy model2;
|
||||
inline-signing yes;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/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
|
||||
|
||||
echo_i "ns4/setup.sh"
|
||||
|
||||
zone="model2.multisigner"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
|
||||
O="OMNIPRESENT"
|
||||
ksktimes="-P now -A now -P sync now"
|
||||
zsktimes="-P now -A now"
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 $ksktimes $zone 2> keygen.out.$zone.1)
|
||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2> keygen.out.$zone.2)
|
||||
$SETTIME -s -g $O -k $O now -r $O now -d $O now "$KSK" > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -g $O -k $O now -z $O now "$ZSK" > settime.out.$zone.2 2>&1
|
||||
# ZSK will be added to the other provider with nsupdate.
|
||||
cat "${ZSK}.key" | grep -v ";.*" > "${zone}.zsk"
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/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
|
||||
|
||||
copy_setports ns3/named.conf.in ns3/named.conf
|
||||
copy_setports ns4/named.conf.in ns4/named.conf
|
||||
|
||||
(
|
||||
cd ns3
|
||||
$SHELL setup.sh
|
||||
)
|
||||
(
|
||||
cd ns4
|
||||
$SHELL setup.sh
|
||||
)
|
||||
@@ -0,0 +1,270 @@
|
||||
#!/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
|
||||
|
||||
dig_with_opts() {
|
||||
$DIG +tcp +noadd +nosea +nostat +nocmd +dnssec -p $PORT "$@"
|
||||
}
|
||||
|
||||
|
||||
start_time="$(TZ=UTC date +%s)"
|
||||
status=0
|
||||
n=0
|
||||
|
||||
set_zone "model2.multisigner"
|
||||
set_policy "model2" "2" "3600"
|
||||
|
||||
# Key properties and states.
|
||||
key_clear "KEY1"
|
||||
set_keyrole "KEY1" "ksk"
|
||||
set_keylifetime "KEY1" "0"
|
||||
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
|
||||
set_keysigning "KEY1" "yes"
|
||||
set_zonesigning "KEY1" "no"
|
||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_DS" "omnipresent"
|
||||
|
||||
key_clear "KEY2"
|
||||
set_keyrole "KEY2" "zsk"
|
||||
set_keylifetime "KEY2" "0"
|
||||
set_keyalgorithm "KEY2" "13" "ECDSAP256SHA256" "256"
|
||||
set_keysigning "KEY2" "no"
|
||||
set_zonesigning "KEY2" "yes"
|
||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
||||
set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
|
||||
set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
|
||||
|
||||
key_clear "KEY3"
|
||||
key_clear "KEY4"
|
||||
|
||||
set_keytimes_model2() {
|
||||
# The first KSK is immediately published and activated.
|
||||
created=$(key_get KEY1 CREATED)
|
||||
set_keytime "KEY1" "PUBLISHED" "${created}"
|
||||
set_keytime "KEY1" "ACTIVE" "${created}"
|
||||
set_keytime "KEY1" "SYNCPUBLISH" "${created}"
|
||||
|
||||
# The first ZSKs are immediately published and activated.
|
||||
created=$(key_get KEY2 CREATED)
|
||||
set_keytime "KEY2" "PUBLISHED" "${created}"
|
||||
set_keytime "KEY2" "ACTIVE" "${created}"
|
||||
}
|
||||
|
||||
set_server "ns3" "10.53.0.3"
|
||||
check_keys
|
||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
set_keytimes_model2
|
||||
check_keytimes
|
||||
check_apex
|
||||
dnssec_verify
|
||||
|
||||
set_server "ns4" "10.53.0.4"
|
||||
check_keys
|
||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
set_keytimes_model2
|
||||
check_keytimes
|
||||
check_apex
|
||||
dnssec_verify
|
||||
|
||||
|
||||
#
|
||||
# Update DNSKEY RRset.
|
||||
#
|
||||
|
||||
# Check that the ZSKs from the other provider are published.
|
||||
zsks_are_published() {
|
||||
dig_with_opts "$ZONE" "@${SERVER}" DNSKEY > "dig.out.$DIR.test$n" || return 1
|
||||
# We should have two ZSKs.
|
||||
lines=$(grep "256 3 13" dig.out.$DIR.test$n | wc -l)
|
||||
test "$lines" -eq 2 || return 1
|
||||
# And one KSK.
|
||||
lines=$(grep "257 3 13" dig.out.$DIR.test$n | wc -l)
|
||||
test "$lines" -eq 1 || return 1
|
||||
}
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "update zone ${ZONE} at ns3 with ZSK from provider ns4"
|
||||
ret=0
|
||||
set_server "ns3" "10.53.0.3"
|
||||
(
|
||||
echo zone "${ZONE}"
|
||||
echo server "${SERVER}" "${PORT}"
|
||||
echo update add $(cat "ns4/${ZONE}.zsk")
|
||||
echo send
|
||||
) | $NSUPDATE
|
||||
echo_i "check zone ${ZONE} DNSKEY RRset after update ($n)"
|
||||
retry_quiet 10 zsks_are_published || ret=1
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
# Verify again.
|
||||
dnssec_verify
|
||||
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "update zone ${ZONE} at ns4 with ZSK from provider ns3"
|
||||
ret=0
|
||||
set_server "ns4" "10.53.0.4"
|
||||
(
|
||||
echo zone "${ZONE}"
|
||||
echo server "${SERVER}" "${PORT}"
|
||||
echo update add $(cat "ns3/${ZONE}.zsk")
|
||||
echo send
|
||||
) | $NSUPDATE
|
||||
echo_i "check zone ${ZONE} DNSKEY RRset after update ($n)"
|
||||
retry_quiet 10 zsks_are_published || ret=1
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
# Verify again.
|
||||
dnssec_verify
|
||||
|
||||
|
||||
#
|
||||
# Update CDNSKEY RRset.
|
||||
#
|
||||
|
||||
# Check that the CDNSKEY from both providers are published.
|
||||
records_published() {
|
||||
_rrtype=$1
|
||||
_expect=$2
|
||||
|
||||
dig_with_opts "$ZONE" "@${SERVER}" "${_rrtype}" > "dig.out.$DIR.test$n" || return 1
|
||||
lines=$(awk -v rt="${_rrtype}" '$4 == rt {print}' dig.out.$DIR.test$n | wc -l)
|
||||
test "$lines" -eq "$_expect" || return 1
|
||||
}
|
||||
|
||||
# Retrieve CDNSKEY records from the other provider.
|
||||
dig_with_opts ${ZONE} @10.53.0.3 CDNSKEY > dig.out.ns3.cdnskey
|
||||
awk '$4 == "CDNSKEY" {print}' dig.out.ns3.cdnskey > cdnskey.ns3
|
||||
dig_with_opts ${ZONE} @10.53.0.4 CDNSKEY > dig.out.ns4.cdnskey
|
||||
awk '$4 == "CDNSKEY" {print}' dig.out.ns4.cdnskey > cdnskey.ns4
|
||||
|
||||
set_server "ns3" "10.53.0.3"
|
||||
|
||||
# Initially there should be one CDNSKEY.
|
||||
n=$((n+1))
|
||||
echo_i "check zone ${ZONE} ${DIR} initially CDNSKEY ($n)"
|
||||
ret=0
|
||||
retry_quiet 10 records_published CDNSKEY 1 || ret=1
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "update zone ${ZONE} at ns3 with CDNSKEY from provider ns4"
|
||||
ret=0
|
||||
(
|
||||
echo zone "${ZONE}"
|
||||
echo server "${SERVER}" "${PORT}"
|
||||
echo update add $(cat "cdnskey.ns4")
|
||||
echo send
|
||||
) | $NSUPDATE
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
# Now there should be two CDNSKEY records (we test that BIND does not
|
||||
# skip it during DNSSEC maintenance).
|
||||
n=$((n+1))
|
||||
echo_i "check zone ${ZONE} CDNSKEY RRset after update ($n)"
|
||||
ret=0
|
||||
retry_quiet 10 records_published CDNSKEY 2 || ret=1
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
set_server "ns4" "10.53.0.4"
|
||||
|
||||
# Initially there should be one CDNSKEY.
|
||||
n=$((n+1))
|
||||
echo_i "check zone ${ZONE} ${DIR} initially CDNSKEY ($n)"
|
||||
ret=0
|
||||
retry_quiet 10 records_published CDNSKEY 1 || ret=1
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "update zone ${ZONE} at ns4 with CDNSKEY from provider ns3"
|
||||
ret=0
|
||||
(
|
||||
echo zone "${ZONE}"
|
||||
echo server "${SERVER}" "${PORT}"
|
||||
echo update add $(cat "cdnskey.ns3")
|
||||
echo send
|
||||
) | $NSUPDATE
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
# Now there should be two CDNSKEY records (we test that BIND does not
|
||||
# skip it during DNSSEC maintenance).
|
||||
n=$((n+1))
|
||||
echo_i "check zone ${ZONE} CDNSKEY RRset after update ($n)"
|
||||
ret=0
|
||||
retry_quiet 10 records_published CDNSKEY 2 || ret=1
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
|
||||
#
|
||||
# Update CDS RRset.
|
||||
#
|
||||
|
||||
# Retrieve CDS records from the other provider.
|
||||
dig_with_opts ${ZONE} @10.53.0.3 CDS > dig.out.ns3.cds
|
||||
awk '$4 == "CDS" {print}' dig.out.ns3.cds > cds.ns3
|
||||
dig_with_opts ${ZONE} @10.53.0.4 CDS > dig.out.ns4.cds
|
||||
awk '$4 == "CDS" {print}' dig.out.ns4.cds > cds.ns4
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "update zone ${ZONE} at ns3 with CDS from provider ns4"
|
||||
ret=0
|
||||
set_server "ns3" "10.53.0.3"
|
||||
# Initially there should be one CDS.
|
||||
retry_quiet 10 records_published CDS 1 || ret=1
|
||||
(
|
||||
echo zone "${ZONE}"
|
||||
echo server "${SERVER}" "${PORT}"
|
||||
echo update add $(cat "cds.ns4")
|
||||
echo send
|
||||
) | $NSUPDATE
|
||||
# Now there should be two CDS records (we test that BIND does not
|
||||
# skip it during DNSSEC maintenance).
|
||||
echo_i "check zone ${ZONE} CDS RRset after update ($n)"
|
||||
retry_quiet 10 records_published CDS 2 || ret=1
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "update zone ${ZONE} at ns4 with CDS from provider ns3"
|
||||
ret=0
|
||||
set_server "ns4" "10.53.0.4"
|
||||
# Initially there should be one CDS.
|
||||
retry_quiet 10 records_published CDS 1 || ret=1
|
||||
(
|
||||
echo zone "${ZONE}"
|
||||
echo server "${SERVER}" "${PORT}"
|
||||
echo update add $(cat "cds.ns3")
|
||||
echo send
|
||||
) | $NSUPDATE
|
||||
# Now there should be two CDS records (we test that BIND does not
|
||||
# skip it during DNSSEC maintenance).
|
||||
echo_i "check zone ${ZONE} CDS RRset after update ($n)"
|
||||
retry_quiet 10 records_published CDS 2 || ret=1
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
@@ -63,3 +63,8 @@ Bug Fixes
|
||||
enter into a state where it would not recover without stopping ``named``,
|
||||
manually deleting ``managed-keys.bind`` and ``managed-keys.bind.jnl`` files,
|
||||
and starting ``named`` again. :gl:`#2895`
|
||||
|
||||
- Fix bugs related to ``inline-signing`` zones that are subject to a
|
||||
multisigner model (RFC 8901). In some cases it was not possible to update
|
||||
the zone with a DNSKEY, CDS or CDNSKEY from the other provider, or the
|
||||
record would be removed again after a re-sign of the zone. :gl:`#2710`
|
||||
|
||||
+11
-4
@@ -828,7 +828,7 @@ dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
|
||||
}
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (true) {
|
||||
char filename[DNS_NAME_FORMATSIZE +
|
||||
DNS_SECALG_FORMATSIZE +
|
||||
sizeof("key file for //65535")];
|
||||
@@ -857,9 +857,16 @@ dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
|
||||
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING,
|
||||
"dns_dnssec_findzonekeys2: error "
|
||||
"reading %s: %s",
|
||||
filename, isc_result_totext(result));
|
||||
"dns_dnssec_findzonekeys: reading %s",
|
||||
filename);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING,
|
||||
"dns_dnssec_findzonekeys: error "
|
||||
"reading %s: %s",
|
||||
filename, isc_result_totext(result));
|
||||
}
|
||||
}
|
||||
|
||||
if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) {
|
||||
|
||||
@@ -2520,9 +2520,15 @@ dns_zone_getserialupdatemethod(dns_zone_t *zone);
|
||||
isc_result_t
|
||||
dns_zone_link(dns_zone_t *zone, dns_zone_t *raw);
|
||||
|
||||
void
|
||||
dns_zone_getsecure(dns_zone_t *zone, dns_zone_t **secure);
|
||||
|
||||
void
|
||||
dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw);
|
||||
|
||||
bool
|
||||
dns_zone_israw(dns_zone_t *zone);
|
||||
|
||||
isc_result_t
|
||||
dns_zone_keydone(dns_zone_t *zone, const char *data);
|
||||
|
||||
|
||||
+46
-16
@@ -1057,27 +1057,58 @@ failure:
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
|
||||
isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys,
|
||||
unsigned int *nkeys) {
|
||||
find_zone_keys(dns_zone_t *zone, isc_mem_t *mctx, unsigned int maxkeys,
|
||||
dst_key_t **keys, unsigned int *nkeys) {
|
||||
dns_dnsseckeylist_t keylist;
|
||||
dns_dnsseckey_t *key = NULL;
|
||||
dns_dnsseckey_t *key_next = NULL;
|
||||
isc_result_t result;
|
||||
unsigned int count = 0;
|
||||
isc_stdtime_t now;
|
||||
dns_dbnode_t *node = NULL;
|
||||
const char *directory = dns_zone_getkeydirectory(zone);
|
||||
|
||||
CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node));
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
ISC_LIST_INIT(keylist);
|
||||
|
||||
dns_zone_lock_keyfiles(zone);
|
||||
result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
|
||||
directory, now, mctx, maxkeys, keys,
|
||||
nkeys);
|
||||
result = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone),
|
||||
dns_zone_getkeydirectory(zone),
|
||||
now, mctx, &keylist);
|
||||
dns_zone_unlock_keyfiles(zone);
|
||||
|
||||
failure:
|
||||
if (node != NULL) {
|
||||
dns_db_detachnode(db, &node);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Add new 'dnskeys' to 'keys' */
|
||||
count = 0;
|
||||
for (dns_dnsseckey_t *k = ISC_LIST_HEAD(keylist); k != NULL;
|
||||
k = key_next) {
|
||||
key_next = ISC_LIST_NEXT(k, link);
|
||||
|
||||
if (count >= maxkeys) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Detect inactive keys */
|
||||
if (!dns_dnssec_keyactive(k->key, now)) {
|
||||
dst_key_setinactive(k->key, true);
|
||||
}
|
||||
|
||||
keys[count] = k->key;
|
||||
k->key = NULL;
|
||||
ISC_LIST_UNLINK(keylist, k, link);
|
||||
dns_dnsseckey_destroy(mctx, &k);
|
||||
count++;
|
||||
}
|
||||
|
||||
failure:
|
||||
while (!ISC_LIST_EMPTY(keylist)) {
|
||||
key = ISC_LIST_HEAD(keylist);
|
||||
ISC_LIST_UNLINK(keylist, key, link);
|
||||
dns_dnsseckey_destroy(mctx, &key);
|
||||
}
|
||||
|
||||
*nkeys = count;
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -1550,9 +1581,8 @@ dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
|
||||
state->nkeys = 0;
|
||||
state->build_nsec3 = false;
|
||||
|
||||
result = find_zone_keys(zone, db, newver, diff->mctx,
|
||||
DNS_MAXZONEKEYS, state->zone_keys,
|
||||
&state->nkeys);
|
||||
result = find_zone_keys(zone, diff->mctx, DNS_MAXZONEKEYS,
|
||||
state->zone_keys, &state->nkeys);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(log, zone, ISC_LOG_ERROR,
|
||||
"could not get zone keys for secure "
|
||||
|
||||
@@ -5921,6 +5921,10 @@ dns_kasp_t *
|
||||
dns_zone_getkasp(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
if (inline_raw(zone) && zone->secure != NULL) {
|
||||
return (zone->secure->kasp);
|
||||
}
|
||||
|
||||
return (zone->kasp);
|
||||
}
|
||||
|
||||
@@ -22559,6 +22563,29 @@ dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
|
||||
UNLOCK(&zone->lock);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_getsecure(dns_zone_t *zone, dns_zone_t **secure) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
REQUIRE(secure != NULL && *secure == NULL);
|
||||
|
||||
LOCK(&zone->lock);
|
||||
INSIST(zone != zone->secure);
|
||||
if (zone->secure != NULL) {
|
||||
dns_zone_attach(zone->secure, secure);
|
||||
}
|
||||
UNLOCK(&zone->lock);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_zone_israw(dns_zone_t *zone) {
|
||||
bool result;
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
LOCK(&zone->lock);
|
||||
result = zone->secure != NULL;
|
||||
UNLOCK(&zone->lock);
|
||||
return (result);
|
||||
}
|
||||
|
||||
struct keydone {
|
||||
isc_event_t event;
|
||||
bool all;
|
||||
|
||||
+436
-147
@@ -2606,13 +2606,21 @@ static void
|
||||
update_action(isc_task_t *task, isc_event_t *event) {
|
||||
update_event_t *uev = (update_event_t *)event;
|
||||
dns_zone_t *zone = uev->zone;
|
||||
dns_zone_t *securezone = NULL;
|
||||
dns_zone_t *updatezone = NULL;
|
||||
ns_client_t *client = (ns_client_t *)event->ev_arg;
|
||||
isc_result_t result;
|
||||
dns_db_t *db = NULL;
|
||||
dns_db_t *securedb = NULL;
|
||||
dns_db_t *updatedb = NULL;
|
||||
dns_dbversion_t *oldver = NULL;
|
||||
dns_dbversion_t *ver = NULL;
|
||||
dns_diff_t diff; /* Pending updates. */
|
||||
dns_diff_t temp; /* Pending RR existence assertions. */
|
||||
dns_dbversion_t *secureoldver = NULL;
|
||||
dns_dbversion_t *securever = NULL;
|
||||
dns_dbversion_t *updatever = NULL;
|
||||
dns_diff_t diff; /* Pending updates. */
|
||||
dns_diff_t securediff; /* Pending updates (secure zone). */
|
||||
dns_diff_t temp; /* Pending RR existence assertions. */
|
||||
bool soa_serial_changed = false;
|
||||
isc_mem_t *mctx = client->manager->mctx;
|
||||
dns_rdatatype_t covers;
|
||||
@@ -2634,16 +2642,22 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
size_t ruleslen = 0;
|
||||
size_t rule;
|
||||
const dns_ssurule_t **rules = NULL;
|
||||
bool rawzone_done = false;
|
||||
|
||||
INSIST(event->ev_type == DNS_EVENT_UPDATE);
|
||||
|
||||
dns_diff_init(mctx, &diff);
|
||||
dns_diff_init(mctx, &securediff);
|
||||
dns_diff_init(mctx, &temp);
|
||||
|
||||
CHECK(dns_zone_getdb(zone, &db));
|
||||
zonename = dns_db_origin(db);
|
||||
zoneclass = dns_db_class(db);
|
||||
dns_zone_getssutable(zone, &ssutable);
|
||||
if (dns_zone_israw(zone)) {
|
||||
dns_zone_getsecure(zone, &securezone);
|
||||
CHECK(dns_zone_getdb(securezone, &securedb));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update message processing can leak record existence information
|
||||
@@ -2658,11 +2672,14 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
dns_db_currentversion(db, &oldver);
|
||||
CHECK(dns_db_newversion(db, &ver));
|
||||
if (securedb != NULL) {
|
||||
dns_db_currentversion(securedb, &secureoldver);
|
||||
CHECK(dns_db_newversion(securedb, &securever));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check prerequisites.
|
||||
*/
|
||||
|
||||
for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE))
|
||||
@@ -2702,8 +2719,16 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
"satisfied");
|
||||
}
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, name, rdata.type,
|
||||
covers, &flag));
|
||||
if (rdata.type == dns_rdatatype_dnskey &&
|
||||
securedb != NULL) {
|
||||
CHECK(rrset_exists(securedb, securever,
|
||||
name, rdata.type,
|
||||
covers, &flag));
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, name,
|
||||
rdata.type, covers,
|
||||
&flag));
|
||||
}
|
||||
if (!flag) {
|
||||
/* RRset does not exist. */
|
||||
PREREQFAILNT(DNS_R_NXRRSET, name,
|
||||
@@ -2730,8 +2755,16 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
"satisfied");
|
||||
}
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, name, rdata.type,
|
||||
covers, &flag));
|
||||
if (rdata.type == dns_rdatatype_dnskey &&
|
||||
securedb != NULL) {
|
||||
CHECK(rrset_exists(securedb, securever,
|
||||
name, rdata.type,
|
||||
covers, &flag));
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, name,
|
||||
rdata.type, covers,
|
||||
&flag));
|
||||
}
|
||||
if (flag) {
|
||||
/* RRset exists. */
|
||||
PREREQFAILNT(DNS_R_YXRRSET, name,
|
||||
@@ -3009,6 +3042,35 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, &name,
|
||||
&rdata, &covers, &ttl, &update_class);
|
||||
if (rdata.type == dns_rdatatype_dnskey && securedb != NULL) {
|
||||
isc_buffer_t b;
|
||||
dst_key_t *keyp = NULL;
|
||||
|
||||
updatedb = securedb;
|
||||
updatever = securever;
|
||||
/* Create key files for this new DNSKEY */
|
||||
isc_buffer_init(&b, rdata.data, rdata.length);
|
||||
isc_buffer_add(&b, rdata.length);
|
||||
result = dst_key_fromdns(dns_db_origin(db), zoneclass,
|
||||
&b, dns_zone_getmctx(zone),
|
||||
&keyp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone, LOGLEVEL_PROTOCOL,
|
||||
"attempt to add key file failed");
|
||||
} else {
|
||||
result = dst_key_tofile(
|
||||
keyp,
|
||||
(DST_TYPE_PUBLIC | DST_TYPE_PRIVATE),
|
||||
dns_zone_getkeydirectory(zone));
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone, LOGLEVEL_PROTOCOL,
|
||||
"attempt to add key file failed");
|
||||
}
|
||||
} else {
|
||||
updatedb = db;
|
||||
updatever = ver;
|
||||
}
|
||||
|
||||
if (update_class == zoneclass) {
|
||||
unsigned int max = 0;
|
||||
@@ -3043,7 +3105,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
if (rdata.type == dns_rdatatype_cname) {
|
||||
CHECK(cname_incompatible_rrset_exists(
|
||||
db, ver, name, &flag));
|
||||
updatedb, updatever, name, &flag));
|
||||
if (flag) {
|
||||
update_log(client, zone,
|
||||
LOGLEVEL_PROTOCOL,
|
||||
@@ -3053,7 +3115,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, name,
|
||||
CHECK(rrset_exists(updatedb, updatever, name,
|
||||
dns_rdatatype_cname, 0,
|
||||
&flag));
|
||||
if (flag && !dns_rdatatype_atcname(rdata.type))
|
||||
@@ -3067,7 +3129,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
if (rdata.type == dns_rdatatype_soa) {
|
||||
bool ok;
|
||||
CHECK(rrset_exists(db, ver, name,
|
||||
CHECK(rrset_exists(updatedb, updatever, name,
|
||||
dns_rdatatype_soa, 0,
|
||||
&flag));
|
||||
if (!flag) {
|
||||
@@ -3077,8 +3139,8 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
"SOA ignored");
|
||||
continue;
|
||||
}
|
||||
CHECK(check_soa_increment(db, ver, &rdata,
|
||||
&ok));
|
||||
CHECK(check_soa_increment(updatedb, updatever,
|
||||
&rdata, &ok));
|
||||
if (!ok) {
|
||||
update_log(client, zone,
|
||||
LOGLEVEL_PROTOCOL,
|
||||
@@ -3087,7 +3149,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
"ignoring it");
|
||||
continue;
|
||||
}
|
||||
soa_serial_changed = true;
|
||||
if (updatedb != securedb) {
|
||||
soa_serial_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dns_rdatatype_atparent(rdata.type) &&
|
||||
@@ -3156,8 +3220,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
if (max != 0) {
|
||||
unsigned int count = 0;
|
||||
CHECK(foreach_rr(db, ver, name, rdata.type,
|
||||
covers, count_action, &count));
|
||||
CHECK(foreach_rr(updatedb, updatever, name,
|
||||
rdata.type, covers,
|
||||
count_action, &count));
|
||||
if (count >= max) {
|
||||
update_log(client, zone,
|
||||
LOGLEVEL_PROTOCOL,
|
||||
@@ -3203,9 +3268,13 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
/* Prepare the affected RRset for the addition. */
|
||||
{
|
||||
add_rr_prepare_ctx_t ctx;
|
||||
ctx.db = db;
|
||||
ctx.ver = ver;
|
||||
ctx.diff = &diff;
|
||||
ctx.db = updatedb;
|
||||
ctx.ver = updatever;
|
||||
if (securedb != NULL) {
|
||||
ctx.diff = &securediff;
|
||||
} else {
|
||||
ctx.diff = &diff;
|
||||
}
|
||||
ctx.name = name;
|
||||
ctx.oldname = name;
|
||||
ctx.update_rr = &rdata;
|
||||
@@ -3213,27 +3282,29 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
ctx.ignore_add = false;
|
||||
dns_diff_init(mctx, &ctx.del_diff);
|
||||
dns_diff_init(mctx, &ctx.add_diff);
|
||||
CHECK(foreach_rr(db, ver, name, rdata.type,
|
||||
covers, add_rr_prepare_action,
|
||||
&ctx));
|
||||
CHECK(foreach_rr(updatedb, updatever, name,
|
||||
rdata.type, covers,
|
||||
add_rr_prepare_action, &ctx));
|
||||
|
||||
if (ctx.ignore_add) {
|
||||
dns_diff_clear(&ctx.del_diff);
|
||||
dns_diff_clear(&ctx.add_diff);
|
||||
} else {
|
||||
result = do_diff(&ctx.del_diff, db, ver,
|
||||
&diff);
|
||||
result = do_diff(&ctx.del_diff,
|
||||
updatedb, updatever,
|
||||
ctx.diff);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = do_diff(&ctx.add_diff,
|
||||
db, ver,
|
||||
&diff);
|
||||
result = do_diff(
|
||||
&ctx.add_diff, updatedb,
|
||||
updatever, ctx.diff);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_diff_clear(&ctx.del_diff);
|
||||
dns_diff_clear(&ctx.add_diff);
|
||||
goto failure;
|
||||
}
|
||||
CHECK(update_one_rr(db, ver, &diff,
|
||||
CHECK(update_one_rr(updatedb, updatever,
|
||||
ctx.diff,
|
||||
DNS_DIFFOP_ADD,
|
||||
name, ttl, &rdata));
|
||||
}
|
||||
@@ -3251,16 +3322,36 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
"name '%s'",
|
||||
namestr);
|
||||
}
|
||||
if (dns_name_equal(name, zonename)) {
|
||||
CHECK(delete_if(type_not_soa_nor_ns_p,
|
||||
db, ver, name,
|
||||
dns_rdatatype_any, 0,
|
||||
&rdata, &diff));
|
||||
if (securedb != NULL) {
|
||||
if (dns_name_equal(name, zonename)) {
|
||||
CHECK(delete_if(
|
||||
type_not_soa_nor_ns_p,
|
||||
updatedb, updatever,
|
||||
name, dns_rdatatype_any,
|
||||
0, &rdata,
|
||||
&securediff));
|
||||
} else {
|
||||
CHECK(delete_if(
|
||||
type_not_dnssec,
|
||||
updatedb, updatever,
|
||||
name, dns_rdatatype_any,
|
||||
0, &rdata,
|
||||
&securediff));
|
||||
}
|
||||
} else {
|
||||
CHECK(delete_if(type_not_dnssec, db,
|
||||
ver, name,
|
||||
dns_rdatatype_any, 0,
|
||||
&rdata, &diff));
|
||||
if (dns_name_equal(name, zonename)) {
|
||||
CHECK(delete_if(
|
||||
type_not_soa_nor_ns_p,
|
||||
updatedb, updatever,
|
||||
name, dns_rdatatype_any,
|
||||
0, &rdata, &diff));
|
||||
} else {
|
||||
CHECK(delete_if(
|
||||
type_not_dnssec,
|
||||
updatedb, updatever,
|
||||
name, dns_rdatatype_any,
|
||||
0, &rdata, &diff));
|
||||
}
|
||||
}
|
||||
} else if (dns_name_equal(name, zonename) &&
|
||||
(rdata.type == dns_rdatatype_soa ||
|
||||
@@ -3285,9 +3376,17 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
"deleting rrset at '%s' %s",
|
||||
namestr, typestr);
|
||||
}
|
||||
CHECK(delete_if(true_p, db, ver, name,
|
||||
rdata.type, covers, &rdata,
|
||||
&diff));
|
||||
if (securedb != NULL) {
|
||||
CHECK(delete_if(true_p, updatedb,
|
||||
updatever, name,
|
||||
rdata.type, covers,
|
||||
&rdata, &securediff));
|
||||
} else {
|
||||
CHECK(delete_if(true_p, updatedb,
|
||||
updatever, name,
|
||||
rdata.type, covers,
|
||||
&rdata, &diff));
|
||||
}
|
||||
}
|
||||
} else if (update_class == dns_rdataclass_none) {
|
||||
char namestr[DNS_NAME_FORMATSIZE];
|
||||
@@ -3307,9 +3406,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
if (rdata.type == dns_rdatatype_ns) {
|
||||
int count;
|
||||
CHECK(rr_count(db, ver, name,
|
||||
dns_rdatatype_ns, 0,
|
||||
&count));
|
||||
CHECK(rr_count(updatedb, updatever,
|
||||
name, dns_rdatatype_ns,
|
||||
0, &count));
|
||||
if (count == 1) {
|
||||
update_log(client, zone,
|
||||
LOGLEVEL_PROTOCOL,
|
||||
@@ -3325,8 +3424,15 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
sizeof(typestr));
|
||||
update_log(client, zone, LOGLEVEL_PROTOCOL,
|
||||
"deleting an RR at %s %s", namestr, typestr);
|
||||
CHECK(delete_if(rr_equal_p, db, ver, name, rdata.type,
|
||||
covers, &rdata, &diff));
|
||||
if (securedb != NULL) {
|
||||
CHECK(delete_if(rr_equal_p, updatedb, updatever,
|
||||
name, rdata.type, covers,
|
||||
&rdata, &securediff));
|
||||
} else {
|
||||
CHECK(delete_if(rr_equal_p, updatedb, updatever,
|
||||
name, rdata.type, covers,
|
||||
&rdata, &diff));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != ISC_R_NOMORE) {
|
||||
@@ -3338,8 +3444,15 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
* If they don't then back out all changes to DNSKEY/NSEC3PARAM
|
||||
* records.
|
||||
*/
|
||||
if (!ISC_LIST_EMPTY(diff.tuples)) {
|
||||
CHECK(check_dnssec(client, zone, db, ver, &diff));
|
||||
if (securedb != NULL) {
|
||||
if (!ISC_LIST_EMPTY(securediff.tuples)) {
|
||||
CHECK(check_dnssec(client, zone, securedb, securever,
|
||||
&securediff));
|
||||
}
|
||||
} else {
|
||||
if (!ISC_LIST_EMPTY(diff.tuples)) {
|
||||
CHECK(check_dnssec(client, zone, db, ver, &diff));
|
||||
}
|
||||
}
|
||||
|
||||
if (!ISC_LIST_EMPTY(diff.tuples)) {
|
||||
@@ -3353,26 +3466,34 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
if (!ISC_LIST_EMPTY(diff.tuples)) {
|
||||
result = dns_zone_cdscheck(zone, db, ver);
|
||||
if (result == DNS_R_BADCDS || result == DNS_R_BADCDNSKEY) {
|
||||
update_log(client, zone, LOGLEVEL_PROTOCOL,
|
||||
"update rejected: bad %s RRset",
|
||||
result == DNS_R_BADCDS ? "CDS" : "CDNSKEY");
|
||||
result = DNS_R_REFUSED;
|
||||
goto failure;
|
||||
|
||||
if (securedb != NULL) {
|
||||
if (!ISC_LIST_EMPTY(securediff.tuples)) {
|
||||
result = dns_zone_cdscheck(zone, securedb, securever);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
} else {
|
||||
if (!ISC_LIST_EMPTY(diff.tuples)) {
|
||||
result = dns_zone_cdscheck(zone, db, ver);
|
||||
}
|
||||
}
|
||||
if (result == DNS_R_BADCDS || result == DNS_R_BADCDNSKEY) {
|
||||
update_log(client, zone, LOGLEVEL_PROTOCOL,
|
||||
"update rejected: bad %s RRset",
|
||||
result == DNS_R_BADCDS ? "CDS" : "CDNSKEY");
|
||||
result = DNS_R_REFUSED;
|
||||
goto failure;
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/*
|
||||
* If any changes were made, increment the SOA serial number,
|
||||
* update RRSIGs and NSECs (if zone is secure), and write the update
|
||||
* to the journal.
|
||||
*/
|
||||
if (!ISC_LIST_EMPTY(diff.tuples)) {
|
||||
if (!ISC_LIST_EMPTY(diff.tuples) || !ISC_LIST_EMPTY(securediff.tuples))
|
||||
{
|
||||
char *journalfile;
|
||||
dns_journal_t *journal;
|
||||
bool has_dnskey;
|
||||
@@ -3385,37 +3506,81 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
CHECK(update_soa_serial(
|
||||
db, ver, &diff, mctx,
|
||||
dns_zone_getserialupdatemethod(zone)));
|
||||
|
||||
if (securedb != NULL) {
|
||||
CHECK(update_soa_serial(
|
||||
securedb, securever, &securediff, mctx,
|
||||
dns_zone_getserialupdatemethod(
|
||||
securezone)));
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(check_mx(client, zone, db, ver, &diff));
|
||||
|
||||
CHECK(remove_orphaned_ds(db, ver, &diff));
|
||||
|
||||
CHECK(rrset_exists(db, ver, zonename, dns_rdatatype_dnskey, 0,
|
||||
&has_dnskey));
|
||||
if (securedb != NULL) {
|
||||
CHECK(rrset_exists(securedb, securever, zonename,
|
||||
dns_rdatatype_dnskey, 0,
|
||||
&has_dnskey));
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, zonename,
|
||||
dns_rdatatype_dnskey, 0,
|
||||
&has_dnskey));
|
||||
}
|
||||
|
||||
#define ALLOW_SECURE_TO_INSECURE(zone) \
|
||||
((dns_zone_getoptions(zone) & DNS_ZONEOPT_SECURETOINSECURE) != 0)
|
||||
|
||||
CHECK(rrset_exists(db, oldver, zonename, dns_rdatatype_dnskey,
|
||||
0, &had_dnskey));
|
||||
if (!ALLOW_SECURE_TO_INSECURE(zone)) {
|
||||
if (had_dnskey && !has_dnskey) {
|
||||
update_log(client, zone, LOGLEVEL_PROTOCOL,
|
||||
"update rejected: all DNSKEY "
|
||||
"records removed and "
|
||||
"'dnssec-secure-to-insecure' "
|
||||
"not set");
|
||||
result = DNS_R_REFUSED;
|
||||
goto failure;
|
||||
if (securedb != NULL) {
|
||||
CHECK(rrset_exists(securedb, secureoldver, zonename,
|
||||
dns_rdatatype_dnskey, 0,
|
||||
&had_dnskey));
|
||||
if (!ALLOW_SECURE_TO_INSECURE(zone)) {
|
||||
if (had_dnskey && !has_dnskey) {
|
||||
update_log(
|
||||
client, securezone,
|
||||
LOGLEVEL_PROTOCOL,
|
||||
"update rejected: all DNSKEY "
|
||||
"records removed and "
|
||||
"'dnssec-secure-to-insecure' "
|
||||
"not set");
|
||||
result = DNS_R_REFUSED;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CHECK(rrset_exists(db, oldver, zonename,
|
||||
dns_rdatatype_dnskey, 0,
|
||||
&had_dnskey));
|
||||
if (!ALLOW_SECURE_TO_INSECURE(zone)) {
|
||||
if (had_dnskey && !has_dnskey) {
|
||||
update_log(
|
||||
client, zone, LOGLEVEL_PROTOCOL,
|
||||
"update rejected: all DNSKEY "
|
||||
"records removed and "
|
||||
"'dnssec-secure-to-insecure' "
|
||||
"not set");
|
||||
result = DNS_R_REFUSED;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(rollback_private(db, privatetype, ver, &diff));
|
||||
|
||||
CHECK(add_signing_records(db, privatetype, ver, &diff));
|
||||
|
||||
CHECK(add_nsec3param_records(client, zone, db, ver, &diff));
|
||||
if (securedb != NULL) {
|
||||
CHECK(rollback_private(securedb, privatetype, securever,
|
||||
&securediff));
|
||||
CHECK(add_signing_records(securedb, privatetype,
|
||||
securever, &securediff));
|
||||
CHECK(add_nsec3param_records(client, securezone,
|
||||
securedb, securever,
|
||||
&securediff));
|
||||
} else {
|
||||
CHECK(rollback_private(db, privatetype, ver, &diff));
|
||||
CHECK(add_signing_records(db, privatetype, ver, &diff));
|
||||
CHECK(add_nsec3param_records(client, zone, updatedb,
|
||||
ver, &diff));
|
||||
}
|
||||
|
||||
if (had_dnskey && !has_dnskey) {
|
||||
/*
|
||||
@@ -3424,9 +3589,35 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
* the last signature for the DNSKEY records are
|
||||
* remove any NSEC chain present will also be removed.
|
||||
*/
|
||||
CHECK(dns_nsec3param_deletechains(db, ver, zone, true,
|
||||
&diff));
|
||||
} else if (has_dnskey && isdnssec(db, ver, privatetype)) {
|
||||
if (securedb != NULL) {
|
||||
CHECK(dns_nsec3param_deletechains(
|
||||
securedb, securever, securezone, true,
|
||||
&securediff));
|
||||
} else {
|
||||
CHECK(dns_nsec3param_deletechains(db, ver, zone,
|
||||
true, &diff));
|
||||
}
|
||||
} else if (securezone != NULL && has_dnskey &&
|
||||
isdnssec(securedb, securever, privatetype))
|
||||
{
|
||||
dns_update_log_t log;
|
||||
uint32_t interval =
|
||||
dns_zone_getsigvalidityinterval(securezone);
|
||||
|
||||
log.func = update_log_cb;
|
||||
log.arg = client;
|
||||
result = dns_update_signatures(
|
||||
&log, securezone, securedb, secureoldver,
|
||||
securever, &securediff, interval);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, securezone, ISC_LOG_ERROR,
|
||||
"RRSIG/NSEC/NSEC3 update failed: %s",
|
||||
isc_result_totext(result));
|
||||
goto failure;
|
||||
}
|
||||
} else if (zone != NULL && has_dnskey &&
|
||||
isdnssec(db, ver, privatetype)) {
|
||||
dns_update_log_t log;
|
||||
uint32_t interval =
|
||||
dns_zone_getsigvalidityinterval(zone);
|
||||
@@ -3444,11 +3635,24 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
}
|
||||
|
||||
maxrecords = dns_zone_getmaxrecords(zone);
|
||||
if (securezone != NULL) {
|
||||
updatezone = securezone;
|
||||
updatedb = securedb;
|
||||
updatever = securever;
|
||||
} else {
|
||||
updatezone = zone;
|
||||
updatedb = db;
|
||||
updatever = ver;
|
||||
rawzone_done = true;
|
||||
}
|
||||
|
||||
apply_update:
|
||||
maxrecords = dns_zone_getmaxrecords(updatezone);
|
||||
if (maxrecords != 0U) {
|
||||
result = dns_db_getsize(db, ver, &records, NULL);
|
||||
result = dns_db_getsize(updatedb, updatever, &records,
|
||||
NULL);
|
||||
if (result == ISC_R_SUCCESS && records > maxrecords) {
|
||||
update_log(client, zone, ISC_LOG_ERROR,
|
||||
update_log(client, updatezone, ISC_LOG_ERROR,
|
||||
"records in zone (%" PRIu64 ") "
|
||||
"exceeds"
|
||||
" max-"
|
||||
@@ -3460,9 +3664,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
}
|
||||
|
||||
journalfile = dns_zone_getjournal(zone);
|
||||
journalfile = dns_zone_getjournal(updatezone);
|
||||
if (journalfile != NULL) {
|
||||
update_log(client, zone, LOGLEVEL_DEBUG,
|
||||
update_log(client, updatezone, LOGLEVEL_DEBUG,
|
||||
"writing journal %s", journalfile);
|
||||
|
||||
journal = NULL;
|
||||
@@ -3472,7 +3676,13 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
FAILS(result, "journal open failed");
|
||||
}
|
||||
|
||||
result = dns_journal_write_transaction(journal, &diff);
|
||||
if (rawzone_done) {
|
||||
result = dns_journal_write_transaction(journal,
|
||||
&diff);
|
||||
} else {
|
||||
result = dns_journal_write_transaction(
|
||||
journal, &securediff);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_journal_destroy(&journal);
|
||||
FAILS(result, "journal write failed");
|
||||
@@ -3486,20 +3696,25 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
* to change to handle databases that need two-phase
|
||||
* commit, but this isn't a priority.
|
||||
*/
|
||||
update_log(client, zone, LOGLEVEL_DEBUG,
|
||||
update_log(client, updatezone, LOGLEVEL_DEBUG,
|
||||
"committing update transaction");
|
||||
|
||||
dns_db_closeversion(db, &ver, true);
|
||||
dns_db_closeversion(updatedb, &updatever, true);
|
||||
if (rawzone_done) {
|
||||
ver = NULL;
|
||||
} else {
|
||||
securever = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark the zone as dirty so that it will be written to disk.
|
||||
*/
|
||||
dns_zone_markdirty(zone);
|
||||
dns_zone_markdirty(updatezone);
|
||||
|
||||
/*
|
||||
* Notify secondaries of the change we just made.
|
||||
*/
|
||||
dns_zone_notify(zone);
|
||||
dns_zone_notify(updatezone);
|
||||
|
||||
/*
|
||||
* Cause the zone to be signed with the key that we
|
||||
@@ -3508,76 +3723,134 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
*
|
||||
* Note: we are already committed to this course of action.
|
||||
*/
|
||||
for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL;
|
||||
tuple = ISC_LIST_NEXT(tuple, link))
|
||||
{
|
||||
isc_region_t r;
|
||||
dns_secalg_t algorithm;
|
||||
uint16_t keyid;
|
||||
|
||||
if (tuple->rdata.type != dns_rdatatype_dnskey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
|
||||
if ((dnskey.flags &
|
||||
(DNS_KEYFLAG_OWNERMASK | DNS_KEYTYPE_NOAUTH)) !=
|
||||
DNS_KEYOWNER_ZONE)
|
||||
if (rawzone_done) {
|
||||
for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL;
|
||||
tuple = ISC_LIST_NEXT(tuple, link))
|
||||
{
|
||||
continue;
|
||||
isc_region_t r;
|
||||
dns_secalg_t algorithm;
|
||||
uint16_t keyid;
|
||||
|
||||
if (tuple->rdata.type != dns_rdatatype_dnskey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dns_rdata_tostruct(&tuple->rdata, &dnskey,
|
||||
NULL);
|
||||
if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK |
|
||||
DNS_KEYTYPE_NOAUTH)) !=
|
||||
DNS_KEYOWNER_ZONE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dns_rdata_toregion(&tuple->rdata, &r);
|
||||
algorithm = dnskey.algorithm;
|
||||
keyid = dst_region_computeid(&r);
|
||||
|
||||
result = dns_zone_signwithkey(
|
||||
updatezone, algorithm, keyid,
|
||||
(tuple->op == DNS_DIFFOP_DEL));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, updatezone,
|
||||
ISC_LOG_ERROR,
|
||||
"dns_zone_signwithkey "
|
||||
"failed: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (tuple = ISC_LIST_HEAD(securediff.tuples);
|
||||
tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link))
|
||||
{
|
||||
isc_region_t r;
|
||||
dns_secalg_t algorithm;
|
||||
uint16_t keyid;
|
||||
|
||||
if (tuple->rdata.type != dns_rdatatype_dnskey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dns_rdata_tostruct(&tuple->rdata, &dnskey,
|
||||
NULL);
|
||||
if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK |
|
||||
DNS_KEYTYPE_NOAUTH)) !=
|
||||
DNS_KEYOWNER_ZONE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dns_rdata_toregion(&tuple->rdata, &r);
|
||||
algorithm = dnskey.algorithm;
|
||||
keyid = dst_region_computeid(&r);
|
||||
|
||||
result = dns_zone_signwithkey(
|
||||
updatezone, algorithm, keyid,
|
||||
(tuple->op == DNS_DIFFOP_DEL));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, updatezone,
|
||||
ISC_LOG_ERROR,
|
||||
"dns_zone_signwithkey "
|
||||
"failed: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
}
|
||||
|
||||
dns_rdata_toregion(&tuple->rdata, &r);
|
||||
algorithm = dnskey.algorithm;
|
||||
keyid = dst_region_computeid(&r);
|
||||
/*
|
||||
* Cause the zone to add/delete NSEC3 chains for the
|
||||
* deferred NSEC3PARAM changes.
|
||||
*
|
||||
* Note: we are already committed to this course of
|
||||
* action.
|
||||
*/
|
||||
for (tuple = ISC_LIST_HEAD(securediff.tuples);
|
||||
tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link))
|
||||
{
|
||||
unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_nsec3param_t nsec3param;
|
||||
|
||||
result = dns_zone_signwithkey(
|
||||
zone, algorithm, keyid,
|
||||
(tuple->op == DNS_DIFFOP_DEL));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone, ISC_LOG_ERROR,
|
||||
"dns_zone_signwithkey failed: %s",
|
||||
isc_result_totext(result));
|
||||
if (tuple->rdata.type != privatetype ||
|
||||
tuple->op != DNS_DIFFOP_ADD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dns_nsec3param_fromprivate(&tuple->rdata,
|
||||
&rdata, buf,
|
||||
sizeof(buf))) {
|
||||
continue;
|
||||
}
|
||||
dns_rdata_tostruct(&rdata, &nsec3param, NULL);
|
||||
if (nsec3param.flags == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dns_zone_addnsec3chain(updatezone,
|
||||
&nsec3param);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, updatezone,
|
||||
ISC_LOG_ERROR,
|
||||
"dns_zone_addnsec3chain "
|
||||
"failed: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cause the zone to add/delete NSEC3 chains for the
|
||||
* deferred NSEC3PARAM changes.
|
||||
*
|
||||
* Note: we are already committed to this course of action.
|
||||
*/
|
||||
for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL;
|
||||
tuple = ISC_LIST_NEXT(tuple, link))
|
||||
{
|
||||
unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_nsec3param_t nsec3param;
|
||||
|
||||
if (tuple->rdata.type != privatetype ||
|
||||
tuple->op != DNS_DIFFOP_ADD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
|
||||
buf, sizeof(buf))) {
|
||||
continue;
|
||||
}
|
||||
dns_rdata_tostruct(&rdata, &nsec3param, NULL);
|
||||
if (nsec3param.flags == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dns_zone_addnsec3chain(zone, &nsec3param);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone, ISC_LOG_ERROR,
|
||||
"dns_zone_addnsec3chain failed: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
if (!rawzone_done) {
|
||||
updatezone = zone;
|
||||
updatedb = db;
|
||||
updatever = ver;
|
||||
rawzone_done = true;
|
||||
goto apply_update;
|
||||
}
|
||||
|
||||
} else {
|
||||
update_log(client, zone, LOGLEVEL_DEBUG, "redundant request");
|
||||
dns_db_closeversion(db, &ver, true);
|
||||
if (securedb != NULL) {
|
||||
dns_db_closeversion(securedb, &securever, true);
|
||||
}
|
||||
}
|
||||
result = ISC_R_SUCCESS;
|
||||
goto common;
|
||||
@@ -3590,6 +3863,10 @@ failure:
|
||||
update_log(client, zone, LOGLEVEL_DEBUG, "rolling back");
|
||||
dns_db_closeversion(db, &ver, false);
|
||||
}
|
||||
if (securever != NULL) {
|
||||
update_log(client, securezone, LOGLEVEL_DEBUG, "rolling back");
|
||||
dns_db_closeversion(securedb, &securever, false);
|
||||
}
|
||||
|
||||
common:
|
||||
dns_diff_clear(&temp);
|
||||
@@ -3598,10 +3875,16 @@ common:
|
||||
if (oldver != NULL) {
|
||||
dns_db_closeversion(db, &oldver, false);
|
||||
}
|
||||
if (secureoldver != NULL) {
|
||||
dns_db_closeversion(securedb, &secureoldver, false);
|
||||
}
|
||||
|
||||
if (db != NULL) {
|
||||
dns_db_detach(&db);
|
||||
}
|
||||
if (securedb != NULL) {
|
||||
dns_db_detach(&securedb);
|
||||
}
|
||||
|
||||
if (rules != NULL) {
|
||||
isc_mem_put(mctx, rules, sizeof(*rules) * ruleslen);
|
||||
@@ -3622,6 +3905,7 @@ common:
|
||||
isc_task_send(client->manager->task, &event);
|
||||
|
||||
INSIST(ver == NULL);
|
||||
INSIST(securever == NULL);
|
||||
INSIST(event == NULL);
|
||||
}
|
||||
|
||||
@@ -3649,6 +3933,11 @@ updatedone_action(isc_task_t *task, isc_event_t *event) {
|
||||
break;
|
||||
}
|
||||
if (uev->zone != NULL) {
|
||||
dns_zone_t *secure = NULL;
|
||||
if (dns_zone_israw(uev->zone)) {
|
||||
dns_zone_getsecure(uev->zone, &secure);
|
||||
dns_zone_detach(&secure);
|
||||
}
|
||||
dns_zone_detach(&uev->zone);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user