2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 18:19:42 +00:00
bind/lib/dns/private.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

414 lines
11 KiB
C
Raw Normal View History

/*
2011-02-15 23:47:36 +00:00
* 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.
*/
#include <stdbool.h>
#include <isc/base64.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/types.h>
#include <isc/util.h>
#include <dns/nsec3.h>
#include <dns/private.h>
/*
* We need to build the relevant chain if there exists a NSEC/NSEC3PARAM
* at the apex; normally only one or the other of NSEC/NSEC3PARAM will exist.
*
* If a NSEC3PARAM RRset exists then we will need to build a NSEC chain
* if all the NSEC3PARAM records (and associated chains) are slated for
* destruction and we have not been told to NOT build the NSEC chain.
*
* If the NSEC set exist then check to see if there is a request to create
* a NSEC3 chain.
*
* If neither NSEC/NSEC3PARAM RRsets exist at the origin and the private
* type exists then we need to examine it to determine if NSEC3 chain has
* been requested to be built otherwise a NSEC chain needs to be built.
*/
#define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
#define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
#define NONSEC(x) (((x) & DNS_NSEC3FLAG_NONSEC) != 0)
#define CHECK(x) \
do { \
result = (x); \
if (result != ISC_R_SUCCESS) \
goto failure; \
} while (0)
/*
* Work out if 'param' should be ignored or not (i.e. it is in the process
* of being removed).
*
* Note: we 'belt-and-braces' here by also checking for a CREATE private
* record and keep the param record in this case.
*/
static bool
ignore(dns_rdata_t *param, dns_rdataset_t *privateset) {
DNS_RDATASET_FOREACH(privateset) {
unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
dns_rdata_t private = DNS_RDATA_INIT;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(privateset, &private);
if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
2022-11-02 19:33:14 +01:00
sizeof(buf)))
{
continue;
}
/*
2009-10-09 23:48:09 +00:00
* We are going to create a new NSEC3 chain so it
* doesn't matter if we are removing this one.
*/
if (CREATE(rdata.data[1])) {
return false;
}
if (rdata.data[0] != param->data[0] ||
rdata.data[2] != param->data[2] ||
rdata.data[3] != param->data[3] ||
rdata.data[4] != param->data[4] ||
memcmp(&rdata.data[5], &param->data[5], param->data[4]))
{
continue;
}
/*
* The removal of this NSEC3 chain does NOT cause a
* NSEC chain to be created so we don't need to tell
* the caller that it will be removed.
*/
if (NONSEC(rdata.data[1])) {
return false;
}
return true;
}
return false;
}
isc_result_t
dns_private_chains(dns_db_t *db, dns_dbversion_t *ver,
dns_rdatatype_t privatetype, bool *build_nsec,
bool *build_nsec3) {
dns_dbnode_t *node;
dns_rdataset_t nsecset, nsec3paramset, privateset;
bool nsec3chain;
bool signing;
isc_result_t result;
unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
unsigned int count;
node = NULL;
dns_rdataset_init(&nsecset);
dns_rdataset_init(&nsec3paramset);
dns_rdataset_init(&privateset);
CHECK(dns_db_getoriginnode(db, &node));
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0,
(isc_stdtime_t)0, &nsecset, NULL);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
goto failure;
}
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
(isc_stdtime_t)0, &nsec3paramset, NULL);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
goto failure;
}
if (dns_rdataset_isassociated(&nsecset) &&
dns_rdataset_isassociated(&nsec3paramset))
{
SET_IF_NOT_NULL(build_nsec, true);
SET_IF_NOT_NULL(build_nsec3, true);
goto success;
}
if (privatetype != (dns_rdatatype_t)0) {
result = dns_db_findrdataset(db, node, ver, privatetype, 0,
(isc_stdtime_t)0, &privateset,
NULL);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
goto failure;
}
}
/*
2011-02-15 18:23:34 +00:00
* Look to see if we also need to be creating a NSEC3 chain.
*/
if (dns_rdataset_isassociated(&nsecset)) {
SET_IF_NOT_NULL(build_nsec, true);
SET_IF_NOT_NULL(build_nsec3, false);
if (!dns_rdataset_isassociated(&privateset)) {
goto success;
}
DNS_RDATASET_FOREACH(&privateset) {
dns_rdata_t private = DNS_RDATA_INIT;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&privateset, &private);
if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
2022-11-02 19:33:14 +01:00
sizeof(buf)))
{
continue;
}
if (REMOVE(rdata.data[1])) {
continue;
}
if (build_nsec3 != NULL) {
*build_nsec3 = true;
}
break;
}
goto success;
}
2009-10-09 23:48:09 +00:00
if (dns_rdataset_isassociated(&nsec3paramset)) {
SET_IF_NOT_NULL(build_nsec3, true);
SET_IF_NOT_NULL(build_nsec, false);
if (!dns_rdataset_isassociated(&privateset)) {
goto success;
}
/*
* If we are in the process of building a new NSEC3 chain
* then we don't need to build a NSEC chain.
*/
DNS_RDATASET_FOREACH(&privateset) {
dns_rdata_t private = DNS_RDATA_INIT;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&privateset, &private);
if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
2022-11-02 19:33:14 +01:00
sizeof(buf)))
{
continue;
}
if (CREATE(rdata.data[1])) {
goto success;
}
}
2009-10-09 23:48:09 +00:00
/*
* Check to see if there will be a active NSEC3CHAIN once
* the changes queued complete.
*/
count = 0;
DNS_RDATASET_FOREACH(&nsec3paramset) {
dns_rdata_t rdata = DNS_RDATA_INIT;
/*
* If there is more that one NSEC3 chain present then
* we don't need to construct a NSEC chain.
*/
if (++count > 1) {
goto success;
}
dns_rdataset_current(&nsec3paramset, &rdata);
if (ignore(&rdata, &privateset)) {
2009-10-09 23:48:09 +00:00
continue;
}
/*
* We still have a good NSEC3 chain or we are
* not creating a NSEC chain as NONSEC is set.
*/
goto success;
}
/*
* The last NSEC3 chain is being removed and does not have
* have NONSEC set.
*/
if (build_nsec != NULL) {
*build_nsec = true;
}
goto success;
}
SET_IF_NOT_NULL(build_nsec, false);
SET_IF_NOT_NULL(build_nsec3, false);
if (!dns_rdataset_isassociated(&privateset)) {
goto success;
}
signing = false;
nsec3chain = false;
DNS_RDATASET_FOREACH(&privateset) {
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_t private = DNS_RDATA_INIT;
dns_rdataset_current(&privateset, &private);
if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
2022-11-02 19:33:14 +01:00
sizeof(buf)))
{
/*
* Look for record that says we are signing the
* zone with a key.
*/
if (private.length == 5 && private.data[0] != 0 &&
private.data[3] == 0 && private.data[4] == 0)
{
signing = true;
}
} else {
if (CREATE(rdata.data[1])) {
nsec3chain = true;
}
}
}
if (signing) {
if (nsec3chain) {
if (build_nsec3 != NULL) {
*build_nsec3 = true;
}
} else {
if (build_nsec != NULL) {
*build_nsec = true;
}
}
}
success:
result = ISC_R_SUCCESS;
failure:
if (dns_rdataset_isassociated(&nsecset)) {
dns_rdataset_disassociate(&nsecset);
}
if (dns_rdataset_isassociated(&nsec3paramset)) {
dns_rdataset_disassociate(&nsec3paramset);
}
if (dns_rdataset_isassociated(&privateset)) {
dns_rdataset_disassociate(&privateset);
}
if (node != NULL) {
dns_db_detachnode(&node);
}
return result;
}
isc_result_t
dns_private_totext(dns_rdata_t *private, isc_buffer_t *buf) {
isc_result_t result;
3410. [bug] Addressed Coverity warnings. [RT #31626] Squashed commit of the following: commit bce2efe66d69d60b746b85df49974ca341723169 Author: Mark Andrews <marka@isc.org> Date: Mon Oct 29 12:59:25 2012 +1100 use 'static dns_rdata_xxxx_t xxxx' commit 704d3c29acbf2dd350a26f2df82a57cb077ba72e Author: Mark Andrews <marka@isc.org> Date: Mon Oct 29 12:35:16 2012 +1100 return ISC_R_NOTFOUND if private record length does not make sense commit 7596610c12c5685336fc0909860173d2fae359af Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:41:17 2012 +1100 check private->length == 5 commit 3836365a3e3e83b057bd940350f032279e080296 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:40:50 2012 +1100 properly set private->length commit a295778ac53109d39ef3a8b233751100edae678b Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:13:30 2012 +1100 check dns_rdata_tostruct result commit e33c37ca9112159e0b2363615bb018d27fa7d1a5 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:10:43 2012 +1100 check remove/fopen/chmod return values commit 3a675e0666aae25d1c51f51ec7bd3fbe25545aae Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:59:10 2012 +1100 check isc_socket_accept result commit 696923344f4b07ce0dba4cf2675b1cbb6eba7e8e Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:55:40 2012 +1100 change variable scopes commit b9e9d9ad58270271003e463f10744e0ceaf9ad97 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:53:19 2012 +1100 check inet_pton return value commit 70698e9589da77e3745efb6ea24b8830addd6ae4 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:52:40 2012 +1100 break -> /* NOTREACHED */ commit 88de9de2e8e201ab2fef16a868f241e8206ea826 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:52:06 2012 +1100 strcpy -> strlcpy commit 6ba79c7cec0e48014cdfa76e8a9406b7a921556e Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:51:26 2012 +1100 check dns_rdata_tostruct return values
2012-10-29 20:04:59 +11:00
if (private->length < 5) {
return ISC_R_NOTFOUND;
}
3410. [bug] Addressed Coverity warnings. [RT #31626] Squashed commit of the following: commit bce2efe66d69d60b746b85df49974ca341723169 Author: Mark Andrews <marka@isc.org> Date: Mon Oct 29 12:59:25 2012 +1100 use 'static dns_rdata_xxxx_t xxxx' commit 704d3c29acbf2dd350a26f2df82a57cb077ba72e Author: Mark Andrews <marka@isc.org> Date: Mon Oct 29 12:35:16 2012 +1100 return ISC_R_NOTFOUND if private record length does not make sense commit 7596610c12c5685336fc0909860173d2fae359af Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:41:17 2012 +1100 check private->length == 5 commit 3836365a3e3e83b057bd940350f032279e080296 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:40:50 2012 +1100 properly set private->length commit a295778ac53109d39ef3a8b233751100edae678b Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:13:30 2012 +1100 check dns_rdata_tostruct result commit e33c37ca9112159e0b2363615bb018d27fa7d1a5 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:10:43 2012 +1100 check remove/fopen/chmod return values commit 3a675e0666aae25d1c51f51ec7bd3fbe25545aae Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:59:10 2012 +1100 check isc_socket_accept result commit 696923344f4b07ce0dba4cf2675b1cbb6eba7e8e Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:55:40 2012 +1100 change variable scopes commit b9e9d9ad58270271003e463f10744e0ceaf9ad97 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:53:19 2012 +1100 check inet_pton return value commit 70698e9589da77e3745efb6ea24b8830addd6ae4 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:52:40 2012 +1100 break -> /* NOTREACHED */ commit 88de9de2e8e201ab2fef16a868f241e8206ea826 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:52:06 2012 +1100 strcpy -> strlcpy commit 6ba79c7cec0e48014cdfa76e8a9406b7a921556e Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:51:26 2012 +1100 check dns_rdata_tostruct return values
2012-10-29 20:04:59 +11:00
if (private->data[0] == 0) {
unsigned char nsec3buf[DNS_NSEC3PARAM_BUFFERSIZE];
unsigned char newbuf[DNS_NSEC3PARAM_BUFFERSIZE];
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nsec3param_t nsec3param;
bool del, init, nonsec;
isc_buffer_t b;
if (!dns_nsec3param_fromprivate(private, &rdata, nsec3buf,
2022-11-02 19:33:14 +01:00
sizeof(nsec3buf)))
{
CHECK(ISC_R_FAILURE);
}
CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
del = ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0);
init = ((nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0);
nonsec = ((nsec3param.flags & DNS_NSEC3FLAG_NONSEC) != 0);
nsec3param.flags &=
~(DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_REMOVE |
DNS_NSEC3FLAG_INITIAL | DNS_NSEC3FLAG_NONSEC);
if (init) {
isc_buffer_putstr(buf, "Pending NSEC3 chain ");
} else if (del) {
isc_buffer_putstr(buf, "Removing NSEC3 chain ");
} else {
isc_buffer_putstr(buf, "Creating NSEC3 chain ");
}
dns_rdata_reset(&rdata);
isc_buffer_init(&b, newbuf, sizeof(newbuf));
CHECK(dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
dns_rdatatype_nsec3param,
&nsec3param, &b));
CHECK(dns_rdata_totext(&rdata, NULL, buf));
if (del && !nonsec) {
isc_buffer_putstr(buf, " / creating NSEC chain");
}
3410. [bug] Addressed Coverity warnings. [RT #31626] Squashed commit of the following: commit bce2efe66d69d60b746b85df49974ca341723169 Author: Mark Andrews <marka@isc.org> Date: Mon Oct 29 12:59:25 2012 +1100 use 'static dns_rdata_xxxx_t xxxx' commit 704d3c29acbf2dd350a26f2df82a57cb077ba72e Author: Mark Andrews <marka@isc.org> Date: Mon Oct 29 12:35:16 2012 +1100 return ISC_R_NOTFOUND if private record length does not make sense commit 7596610c12c5685336fc0909860173d2fae359af Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:41:17 2012 +1100 check private->length == 5 commit 3836365a3e3e83b057bd940350f032279e080296 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:40:50 2012 +1100 properly set private->length commit a295778ac53109d39ef3a8b233751100edae678b Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:13:30 2012 +1100 check dns_rdata_tostruct result commit e33c37ca9112159e0b2363615bb018d27fa7d1a5 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:10:43 2012 +1100 check remove/fopen/chmod return values commit 3a675e0666aae25d1c51f51ec7bd3fbe25545aae Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:59:10 2012 +1100 check isc_socket_accept result commit 696923344f4b07ce0dba4cf2675b1cbb6eba7e8e Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:55:40 2012 +1100 change variable scopes commit b9e9d9ad58270271003e463f10744e0ceaf9ad97 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:53:19 2012 +1100 check inet_pton return value commit 70698e9589da77e3745efb6ea24b8830addd6ae4 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:52:40 2012 +1100 break -> /* NOTREACHED */ commit 88de9de2e8e201ab2fef16a868f241e8206ea826 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:52:06 2012 +1100 strcpy -> strlcpy commit 6ba79c7cec0e48014cdfa76e8a9406b7a921556e Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:51:26 2012 +1100 check dns_rdata_tostruct return values
2012-10-29 20:04:59 +11:00
} else if (private->length == 5) {
/* Old Form */
unsigned char alg = private->data[0];
dns_keytag_t keyid = (private->data[2] | private->data[1] << 8);
char keybuf[DNS_SECALG_FORMATSIZE + BUFSIZ],
algbuf[DNS_SECALG_FORMATSIZE];
bool del = private->data[3];
bool complete = private->data[4];
if (del && complete) {
isc_buffer_putstr(buf, "Done removing signatures for ");
} else if (del) {
isc_buffer_putstr(buf, "Removing signatures for ");
} else if (complete) {
isc_buffer_putstr(buf, "Done signing with ");
} else {
isc_buffer_putstr(buf, "Signing with ");
}
dns_secalg_format(alg, algbuf, sizeof(algbuf));
snprintf(keybuf, sizeof(keybuf), "key %d/%s", keyid, algbuf);
isc_buffer_putstr(buf, keybuf);
} else if (private->length == 7) {
/* New Form - supports private types */
dns_keytag_t keyid = private->data[2] | (private->data[1] << 8);
char keybuf[DNS_SECALG_FORMATSIZE + BUFSIZ],
algbuf[DNS_SECALG_FORMATSIZE];
bool del = private->data[3];
bool complete = private->data[4];
dst_algorithm_t alg = private->data[6] |
(private->data[5] << 8);
if (dst_algorithm_tosecalg(alg) != private->data[0]) {
return ISC_R_NOTFOUND;
}
if (del && complete) {
isc_buffer_putstr(buf, "Done removing signatures for ");
} else if (del) {
isc_buffer_putstr(buf, "Removing signatures for ");
} else if (complete) {
isc_buffer_putstr(buf, "Done signing with ");
} else {
isc_buffer_putstr(buf, "Signing with ");
}
dns_secalg_format(alg, algbuf, sizeof(algbuf));
snprintf(keybuf, sizeof(keybuf), "key %d/%s", keyid, algbuf);
isc_buffer_putstr(buf, keybuf);
3410. [bug] Addressed Coverity warnings. [RT #31626] Squashed commit of the following: commit bce2efe66d69d60b746b85df49974ca341723169 Author: Mark Andrews <marka@isc.org> Date: Mon Oct 29 12:59:25 2012 +1100 use 'static dns_rdata_xxxx_t xxxx' commit 704d3c29acbf2dd350a26f2df82a57cb077ba72e Author: Mark Andrews <marka@isc.org> Date: Mon Oct 29 12:35:16 2012 +1100 return ISC_R_NOTFOUND if private record length does not make sense commit 7596610c12c5685336fc0909860173d2fae359af Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:41:17 2012 +1100 check private->length == 5 commit 3836365a3e3e83b057bd940350f032279e080296 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:40:50 2012 +1100 properly set private->length commit a295778ac53109d39ef3a8b233751100edae678b Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:13:30 2012 +1100 check dns_rdata_tostruct result commit e33c37ca9112159e0b2363615bb018d27fa7d1a5 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 21:10:43 2012 +1100 check remove/fopen/chmod return values commit 3a675e0666aae25d1c51f51ec7bd3fbe25545aae Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:59:10 2012 +1100 check isc_socket_accept result commit 696923344f4b07ce0dba4cf2675b1cbb6eba7e8e Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:55:40 2012 +1100 change variable scopes commit b9e9d9ad58270271003e463f10744e0ceaf9ad97 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:53:19 2012 +1100 check inet_pton return value commit 70698e9589da77e3745efb6ea24b8830addd6ae4 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:52:40 2012 +1100 break -> /* NOTREACHED */ commit 88de9de2e8e201ab2fef16a868f241e8206ea826 Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:52:06 2012 +1100 strcpy -> strlcpy commit 6ba79c7cec0e48014cdfa76e8a9406b7a921556e Author: Mark Andrews <marka@isc.org> Date: Sat Oct 27 20:51:26 2012 +1100 check dns_rdata_tostruct return values
2012-10-29 20:04:59 +11:00
} else {
return ISC_R_NOTFOUND;
}
isc_buffer_putuint8(buf, 0);
result = ISC_R_SUCCESS;
failure:
return result;
}