mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 16:15:27 +00:00
2735. [bug] dnssec-signzone could fail to read keys
that were specified on the command line with full paths, but weren't in the current directory. [RT #20421]
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,3 +1,8 @@
|
|||||||
|
2735. [bug] dnssec-signzone could fail to read keys
|
||||||
|
that were specified on the command line with
|
||||||
|
full paths, but weren't in the current
|
||||||
|
directory. [RT #20421]
|
||||||
|
|
||||||
2734. [port] cygwin: arpaname did not compile. [RT #20473]
|
2734. [port] cygwin: arpaname did not compile. [RT #20473]
|
||||||
|
|
||||||
2733. [cleanup] Clean up coding style in pkcs11-* tools. [RT #20355]
|
2733. [cleanup] Clean up coding style in pkcs11-* tools. [RT #20355]
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dnssec-signzone.c,v 1.248 2009/10/24 00:00:06 each Exp $ */
|
/* $Id: dnssec-signzone.c,v 1.249 2009/10/27 03:59:45 each Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -2634,12 +2634,9 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
|
|||||||
static void
|
static void
|
||||||
loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
|
loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
|
||||||
dns_dbnode_t *node;
|
dns_dbnode_t *node;
|
||||||
dns_dbversion_t *currentversion;
|
dns_dbversion_t *currentversion = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_rdataset_t rdataset;
|
dns_rdataset_t rdataset, keysigs, soasigs;
|
||||||
|
|
||||||
currentversion = NULL;
|
|
||||||
dns_db_currentversion(gdb, ¤tversion);
|
|
||||||
|
|
||||||
node = NULL;
|
node = NULL;
|
||||||
result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
|
result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
|
||||||
@@ -2647,11 +2644,24 @@ loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
|
|||||||
fatal("failed to find the zone's origin: %s",
|
fatal("failed to find the zone's origin: %s",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
|
|
||||||
/* Preserve the TTL of the DNSKEY RRset, if any */
|
dns_db_currentversion(gdb, ¤tversion);
|
||||||
|
|
||||||
dns_rdataset_init(&rdataset);
|
dns_rdataset_init(&rdataset);
|
||||||
|
dns_rdataset_init(&soasigs);
|
||||||
|
dns_rdataset_init(&keysigs);
|
||||||
|
|
||||||
|
/* Make note of the keys which signed the SOA, if any */
|
||||||
|
result = dns_db_findrdataset(gdb, node, currentversion,
|
||||||
|
dns_rdatatype_soa, 0, 0,
|
||||||
|
&rdataset, &soasigs);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Preserve the TTL of the DNSKEY RRset, if any */
|
||||||
|
dns_rdataset_disassociate(&rdataset);
|
||||||
result = dns_db_findrdataset(gdb, node, currentversion,
|
result = dns_db_findrdataset(gdb, node, currentversion,
|
||||||
dns_rdatatype_dnskey, 0, 0,
|
dns_rdatatype_dnskey, 0, 0,
|
||||||
&rdataset, NULL);
|
&rdataset, &keysigs);
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -2668,8 +2678,9 @@ loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
|
|||||||
|
|
||||||
/* Load keys corresponding to the existing DNSKEY RRset */
|
/* Load keys corresponding to the existing DNSKEY RRset */
|
||||||
result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx,
|
result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx,
|
||||||
&rdataset, NULL, preserve_keys,
|
&rdataset, &keysigs, &soasigs,
|
||||||
load_public, &keylist);
|
preserve_keys, load_public,
|
||||||
|
&keylist);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
fatal("failed to load the zone keys: %s",
|
fatal("failed to load the zone keys: %s",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
@@ -2677,10 +2688,65 @@ loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
|
|||||||
cleanup:
|
cleanup:
|
||||||
if (dns_rdataset_isassociated(&rdataset))
|
if (dns_rdataset_isassociated(&rdataset))
|
||||||
dns_rdataset_disassociate(&rdataset);
|
dns_rdataset_disassociate(&rdataset);
|
||||||
|
if (dns_rdataset_isassociated(&keysigs))
|
||||||
|
dns_rdataset_disassociate(&keysigs);
|
||||||
|
if (dns_rdataset_isassociated(&soasigs))
|
||||||
|
dns_rdataset_disassociate(&soasigs);
|
||||||
dns_db_detachnode(gdb, &node);
|
dns_db_detachnode(gdb, &node);
|
||||||
dns_db_closeversion(gdb, ¤tversion, ISC_FALSE);
|
dns_db_closeversion(gdb, ¤tversion, ISC_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
loadexplicitkeys(char *keyfiles[], int n, isc_boolean_t setksk) {
|
||||||
|
isc_result_t result;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
dns_dnsseckey_t *key = NULL;
|
||||||
|
dst_key_t *newkey = NULL;
|
||||||
|
|
||||||
|
result = dst_key_fromnamedfile(keyfiles[i], directory,
|
||||||
|
DST_TYPE_PUBLIC |
|
||||||
|
DST_TYPE_PRIVATE,
|
||||||
|
mctx, &newkey);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
fatal("cannot load dnskey %s: %s", keyfiles[i],
|
||||||
|
isc_result_totext(result));
|
||||||
|
|
||||||
|
if (!dns_name_equal(gorigin, dst_key_name(newkey)))
|
||||||
|
fatal("key %s not at origin\n", keyfiles[i]);
|
||||||
|
|
||||||
|
if (!dst_key_isprivate(newkey))
|
||||||
|
fatal("cannot sign zone with non-private dnskey %s",
|
||||||
|
keyfiles[i]);
|
||||||
|
|
||||||
|
/* Skip any duplicates */
|
||||||
|
for (key = ISC_LIST_HEAD(keylist);
|
||||||
|
key != NULL;
|
||||||
|
key = ISC_LIST_NEXT(key, link)) {
|
||||||
|
if (dst_key_id(key->key) == dst_key_id(newkey) &&
|
||||||
|
dst_key_alg(key->key) == dst_key_alg(newkey))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == NULL) {
|
||||||
|
/* We haven't seen this key before */
|
||||||
|
dns_dnsseckey_create(mctx, &newkey, &key);
|
||||||
|
ISC_LIST_APPEND(keylist, key, link);
|
||||||
|
key->source = dns_keysource_user;
|
||||||
|
} else {
|
||||||
|
dst_key_free(&key->key);
|
||||||
|
key->key = newkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
key->force_publish = ISC_TRUE;
|
||||||
|
key->force_sign = ISC_TRUE;
|
||||||
|
|
||||||
|
if (setksk)
|
||||||
|
key->ksk = ISC_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
report(const char *format, ...) {
|
report(const char *format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -2690,7 +2756,7 @@ report(const char *format, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_final_keylist(dns_db_t *db, const char *directory, isc_mem_t *mctx) {
|
build_final_keylist() {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_dbversion_t *ver = NULL;
|
dns_dbversion_t *ver = NULL;
|
||||||
dns_diff_t del, add;
|
dns_diff_t del, add;
|
||||||
@@ -2707,7 +2773,7 @@ build_final_keylist(dns_db_t *db, const char *directory, isc_mem_t *mctx) {
|
|||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
check_result(result, "dns_dnssec_findmatchingkeys");
|
check_result(result, "dns_dnssec_findmatchingkeys");
|
||||||
|
|
||||||
result = dns_db_newversion(db, &ver);
|
result = dns_db_newversion(gdb, &ver);
|
||||||
check_result(result, "dns_db_newversion");
|
check_result(result, "dns_db_newversion");
|
||||||
|
|
||||||
dns_diff_init(mctx, &del);
|
dns_diff_init(mctx, &del);
|
||||||
@@ -2721,17 +2787,17 @@ build_final_keylist(dns_db_t *db, const char *directory, isc_mem_t *mctx) {
|
|||||||
|
|
||||||
dns_name_format(gorigin, name, sizeof(name));
|
dns_name_format(gorigin, name, sizeof(name));
|
||||||
|
|
||||||
result = dns_diff_applysilently(&del, db, ver);
|
result = dns_diff_applysilently(&del, gdb, ver);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
fatal("failed to delete DNSKEYs at node '%s': %s",
|
fatal("failed to delete DNSKEYs at node '%s': %s",
|
||||||
name, isc_result_totext(result));
|
name, isc_result_totext(result));
|
||||||
|
|
||||||
result = dns_diff_applysilently(&add, db, ver);
|
result = dns_diff_applysilently(&add, gdb, ver);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
fatal("failed to add DNSKEYs at node '%s': %s",
|
fatal("failed to add DNSKEYs at node '%s': %s",
|
||||||
name, isc_result_totext(result));
|
name, isc_result_totext(result));
|
||||||
|
|
||||||
dns_db_closeversion(db, &ver, ISC_TRUE);
|
dns_db_closeversion(gdb, &ver, ISC_TRUE);
|
||||||
|
|
||||||
dns_diff_clear(&del);
|
dns_diff_clear(&del);
|
||||||
dns_diff_clear(&add);
|
dns_diff_clear(&add);
|
||||||
@@ -3580,90 +3646,20 @@ main(int argc, char *argv[]) {
|
|||||||
ISC_LIST_INIT(keylist);
|
ISC_LIST_INIT(keylist);
|
||||||
isc_rwlock_init(&keylist_lock, 0, 0);
|
isc_rwlock_init(&keylist_lock, 0, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill keylist with:
|
||||||
|
* 1) Keys listed in the DNSKEY set that have
|
||||||
|
* private keys associated
|
||||||
|
* 2) KSKs set on the command line
|
||||||
|
* 3) ZSKs set on the command line
|
||||||
|
* 4) Any keys remaining in the DNSKEY set which
|
||||||
|
* do not have private keys associated and were
|
||||||
|
* not specified on the command line.
|
||||||
|
*/
|
||||||
loadzonekeys(!smartsign, ISC_FALSE);
|
loadzonekeys(!smartsign, ISC_FALSE);
|
||||||
|
loadexplicitkeys(dskeyfile, ndskeys, ISC_TRUE);
|
||||||
for (i = 0; i < ndskeys; i++) {
|
loadexplicitkeys(argv, argc, ISC_FALSE);
|
||||||
dst_key_t *newkey = NULL;
|
loadzonekeys(!smartsign, ISC_TRUE);
|
||||||
|
|
||||||
result = dst_key_fromnamedfile(dskeyfile[i], directory,
|
|
||||||
DST_TYPE_PUBLIC |
|
|
||||||
DST_TYPE_PRIVATE,
|
|
||||||
mctx, &newkey);
|
|
||||||
if (result != ISC_R_SUCCESS)
|
|
||||||
fatal("cannot load dnskey %s: %s", dskeyfile[i],
|
|
||||||
isc_result_totext(result));
|
|
||||||
|
|
||||||
if (!dns_name_equal(gorigin, dst_key_name(newkey)))
|
|
||||||
fatal("key %s not at origin\n", dskeyfile[i]);
|
|
||||||
|
|
||||||
/* Skip any duplicates */
|
|
||||||
for (key = ISC_LIST_HEAD(keylist);
|
|
||||||
key != NULL;
|
|
||||||
key = ISC_LIST_NEXT(key, link)) {
|
|
||||||
if (dst_key_id(key->key) == dst_key_id(newkey) &&
|
|
||||||
dst_key_alg(key->key) == dst_key_alg(newkey) &&
|
|
||||||
dns_name_equal(dst_key_name(key->key), gorigin))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key == NULL) {
|
|
||||||
/* We haven't seen this key before */
|
|
||||||
dns_dnsseckey_create(mctx, &newkey, &key);
|
|
||||||
ISC_LIST_APPEND(keylist, key, link);
|
|
||||||
key->source = dns_keysource_user;
|
|
||||||
} else {
|
|
||||||
dst_key_free(&key->key);
|
|
||||||
key->key = newkey;
|
|
||||||
}
|
|
||||||
key->force_publish = ISC_TRUE;
|
|
||||||
key->force_sign = ISC_TRUE;
|
|
||||||
key->ksk = ISC_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
dst_key_t *newkey = NULL;
|
|
||||||
|
|
||||||
result = dst_key_fromnamedfile(argv[i], directory,
|
|
||||||
DST_TYPE_PUBLIC |
|
|
||||||
DST_TYPE_PRIVATE,
|
|
||||||
mctx, &newkey);
|
|
||||||
if (result != ISC_R_SUCCESS)
|
|
||||||
fatal("cannot load dnskey %s: %s", argv[i],
|
|
||||||
isc_result_totext(result));
|
|
||||||
|
|
||||||
if (!dns_name_equal(gorigin, dst_key_name(newkey)))
|
|
||||||
fatal("key %s not at origin\n", argv[i]);
|
|
||||||
|
|
||||||
/* Skip any duplicates */
|
|
||||||
for (key = ISC_LIST_HEAD(keylist);
|
|
||||||
key != NULL;
|
|
||||||
key = ISC_LIST_NEXT(key, link)) {
|
|
||||||
dst_key_t *dkey = key->key;
|
|
||||||
if (dst_key_id(dkey) == dst_key_id(newkey) &&
|
|
||||||
dst_key_alg(dkey) == dst_key_alg(newkey) &&
|
|
||||||
dns_name_equal(dst_key_name(dkey), gorigin)) {
|
|
||||||
if (!dst_key_isprivate(dkey))
|
|
||||||
fatal("cannot sign zone with "
|
|
||||||
"non-private dnskey %s",
|
|
||||||
argv[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key == NULL) {
|
|
||||||
/* We haven't seen this key before */
|
|
||||||
dns_dnsseckey_create(mctx, &newkey, &key);
|
|
||||||
key->force_publish = ISC_TRUE;
|
|
||||||
key->force_sign = ISC_TRUE;
|
|
||||||
key->source = dns_keysource_user;
|
|
||||||
ISC_LIST_APPEND(keylist, key, link);
|
|
||||||
} else {
|
|
||||||
dst_key_free(&newkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc != 0)
|
|
||||||
loadzonekeys(!smartsign, ISC_TRUE);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're doing smart signing, look in the key repository for
|
* If we're doing smart signing, look in the key repository for
|
||||||
@@ -3671,7 +3667,7 @@ main(int argc, char *argv[]) {
|
|||||||
* we have now.
|
* we have now.
|
||||||
*/
|
*/
|
||||||
if (smartsign)
|
if (smartsign)
|
||||||
build_final_keylist(gdb, directory, mctx);
|
build_final_keylist();
|
||||||
|
|
||||||
/* Now enumerate the key list */
|
/* Now enumerate the key list */
|
||||||
for (key = ISC_LIST_HEAD(keylist);
|
for (key = ISC_LIST_HEAD(keylist);
|
||||||
|
175
lib/dns/dnssec.c
175
lib/dns/dnssec.c
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: dnssec.c,v 1.107 2009/10/26 21:18:24 each Exp $
|
* $Id: dnssec.c,v 1.108 2009/10/27 03:59:45 each Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@@ -1202,7 +1202,8 @@ addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey,
|
|||||||
/*
|
/*
|
||||||
* Found a match. If the old key was only public and the
|
* Found a match. If the old key was only public and the
|
||||||
* new key is private, replace the old one; otherwise
|
* new key is private, replace the old one; otherwise
|
||||||
* we're done.
|
* leave it. But either way, mark the key as having
|
||||||
|
* been found in the zone.
|
||||||
*/
|
*/
|
||||||
if (dst_key_isprivate(key->key)) {
|
if (dst_key_isprivate(key->key)) {
|
||||||
dst_key_free(newkey);
|
dst_key_free(newkey);
|
||||||
@@ -1211,6 +1212,7 @@ addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey,
|
|||||||
key->key = *newkey;
|
key->key = *newkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key->source = dns_keysource_zoneapex;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1224,49 +1226,95 @@ addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey,
|
|||||||
*newkey = NULL;
|
*newkey = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Mark all keys which signed the DNSKEY/SOA RRsets as "active",
|
||||||
|
* for future reference.
|
||||||
|
*/
|
||||||
|
static isc_result_t
|
||||||
|
mark_active_keys(dns_dnsseckeylist_t *keylist, dns_rdataset_t *rrsigs) {
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
|
dns_rdataset_t sigs;
|
||||||
|
dns_dnsseckey_t *key;
|
||||||
|
|
||||||
|
REQUIRE(rrsigs != NULL && dns_rdataset_isassociated(rrsigs));
|
||||||
|
|
||||||
|
dns_rdataset_init(&sigs);
|
||||||
|
dns_rdataset_clone(rrsigs, &sigs);
|
||||||
|
for (key = ISC_LIST_HEAD(*keylist);
|
||||||
|
key != NULL;
|
||||||
|
key = ISC_LIST_NEXT(key, link)) {
|
||||||
|
isc_uint16_t keyid, sigid;
|
||||||
|
dns_secalg_t keyalg, sigalg;
|
||||||
|
keyid = dst_key_id(key->key);
|
||||||
|
keyalg = dst_key_alg(key->key);
|
||||||
|
|
||||||
|
for (result = dns_rdataset_first(&sigs);
|
||||||
|
result == ISC_R_SUCCESS;
|
||||||
|
result = dns_rdataset_next(&sigs)) {
|
||||||
|
dns_rdata_rrsig_t sig;
|
||||||
|
|
||||||
|
dns_rdata_reset(&rdata);
|
||||||
|
dns_rdataset_current(&sigs, &rdata);
|
||||||
|
result = dns_rdata_tostruct(&rdata, &sig, NULL);
|
||||||
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
sigalg = sig.algorithm;
|
||||||
|
sigid = sig.keyid;
|
||||||
|
if (keyid == sigid && keyalg == sigalg) {
|
||||||
|
key->is_active = ISC_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == ISC_R_NOMORE)
|
||||||
|
result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
if (dns_rdataset_isassociated(&sigs))
|
||||||
|
dns_rdataset_disassociate(&sigs);
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Add the contents of a DNSKEY rdataset 'keyset' to 'keylist'.
|
* Add the contents of a DNSKEY rdataset 'keyset' to 'keylist'.
|
||||||
*/
|
*/
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_dnssec_keylistfromrdataset(dns_name_t *origin,
|
dns_dnssec_keylistfromrdataset(dns_name_t *origin,
|
||||||
const char *directory, isc_mem_t *mctx,
|
const char *directory, isc_mem_t *mctx,
|
||||||
dns_rdataset_t *keyset, dns_rdataset_t *sigset,
|
dns_rdataset_t *keyset, dns_rdataset_t *keysigs,
|
||||||
isc_boolean_t savekeys, isc_boolean_t public,
|
dns_rdataset_t *soasigs, isc_boolean_t savekeys,
|
||||||
|
isc_boolean_t public,
|
||||||
dns_dnsseckeylist_t *keylist)
|
dns_dnsseckeylist_t *keylist)
|
||||||
{
|
{
|
||||||
dns_rdataset_t keys, sigs;
|
dns_rdataset_t keys;
|
||||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
dst_key_t *pubkey, *privkey;
|
dst_key_t *pubkey = NULL, *privkey = NULL;
|
||||||
dns_dnsseckey_t *key;
|
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
dns_rdataset_init(&keys);
|
|
||||||
dns_rdataset_init(&sigs);
|
|
||||||
|
|
||||||
REQUIRE(keyset != NULL && dns_rdataset_isassociated(keyset));
|
REQUIRE(keyset != NULL && dns_rdataset_isassociated(keyset));
|
||||||
dns_rdataset_clone(keyset, &keys);
|
|
||||||
|
|
||||||
|
dns_rdataset_init(&keys);
|
||||||
|
|
||||||
|
dns_rdataset_clone(keyset, &keys);
|
||||||
for (result = dns_rdataset_first(&keys);
|
for (result = dns_rdataset_first(&keys);
|
||||||
result == ISC_R_SUCCESS;
|
result == ISC_R_SUCCESS;
|
||||||
result = dns_rdataset_next(&keys)) {
|
result = dns_rdataset_next(&keys)) {
|
||||||
pubkey = NULL;
|
|
||||||
privkey = NULL;
|
|
||||||
|
|
||||||
dns_rdata_reset(&rdata);
|
dns_rdata_reset(&rdata);
|
||||||
dns_rdataset_current(&keys, &rdata);
|
dns_rdataset_current(&keys, &rdata);
|
||||||
RETERR(dns_dnssec_keyfromrdata(origin, &rdata, mctx, &pubkey));
|
RETERR(dns_dnssec_keyfromrdata(origin, &rdata, mctx, &pubkey));
|
||||||
|
|
||||||
if (!is_zone_key(pubkey) ||
|
if (!is_zone_key(pubkey) ||
|
||||||
(dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0)
|
(dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0)
|
||||||
goto again;
|
goto skip;
|
||||||
|
|
||||||
/* Corrupted .key file? */
|
/* Corrupted .key file? */
|
||||||
if (!dns_name_equal(origin, dst_key_name(pubkey)))
|
if (!dns_name_equal(origin, dst_key_name(pubkey)))
|
||||||
goto again;
|
goto skip;
|
||||||
|
|
||||||
if (public) {
|
if (public) {
|
||||||
addkey(keylist, &pubkey, savekeys, mctx);
|
addkey(keylist, &pubkey, savekeys, mctx);
|
||||||
goto again;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = dst_key_fromfile(dst_key_name(pubkey),
|
result = dst_key_fromfile(dst_key_name(pubkey),
|
||||||
@@ -1276,65 +1324,36 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin,
|
|||||||
directory, mctx, &privkey);
|
directory, mctx, &privkey);
|
||||||
if (result == ISC_R_FILENOTFOUND) {
|
if (result == ISC_R_FILENOTFOUND) {
|
||||||
addkey(keylist, &pubkey, savekeys, mctx);
|
addkey(keylist, &pubkey, savekeys, mctx);
|
||||||
goto again;
|
goto skip;
|
||||||
}
|
}
|
||||||
RETERR(result);
|
RETERR(result);
|
||||||
|
|
||||||
/* This should never happen. */
|
/* This should never happen. */
|
||||||
if ((dst_key_flags(privkey) & DNS_KEYTYPE_NOAUTH) != 0)
|
if ((dst_key_flags(privkey) & DNS_KEYTYPE_NOAUTH) != 0)
|
||||||
goto again;
|
goto skip;
|
||||||
|
|
||||||
addkey(keylist, &privkey, savekeys, mctx);
|
addkey(keylist, &privkey, savekeys, mctx);
|
||||||
again:
|
skip:
|
||||||
if (pubkey != NULL)
|
if (pubkey != NULL)
|
||||||
dst_key_free(&pubkey);
|
dst_key_free(&pubkey);
|
||||||
if (privkey != NULL)
|
if (privkey != NULL)
|
||||||
dst_key_free(&privkey);
|
dst_key_free(&privkey);
|
||||||
}
|
}
|
||||||
if (result == ISC_R_NOMORE)
|
|
||||||
result = ISC_R_SUCCESS;
|
|
||||||
else if (result != ISC_R_SUCCESS)
|
|
||||||
goto failure;
|
|
||||||
|
|
||||||
if (sigset == NULL || !dns_rdataset_isassociated(sigset))
|
if (result != ISC_R_NOMORE)
|
||||||
goto success;
|
RETERR(result);
|
||||||
|
|
||||||
dns_rdataset_clone(sigset, &sigs);
|
if (keysigs != NULL && dns_rdataset_isassociated(keysigs))
|
||||||
|
RETERR(mark_active_keys(keylist, keysigs));
|
||||||
|
|
||||||
/*
|
if (soasigs != NULL && dns_rdataset_isassociated(soasigs))
|
||||||
* Mark all keys which signed the DNSKEY set, for future reference.
|
RETERR(mark_active_keys(keylist, soasigs));
|
||||||
*/
|
|
||||||
for (key = ISC_LIST_HEAD(*keylist);
|
|
||||||
key != NULL;
|
|
||||||
key = ISC_LIST_NEXT(key, link)) {
|
|
||||||
isc_uint16_t keyid, sigid;
|
|
||||||
isc_uint8_t keyalg, sigalg;
|
|
||||||
keyid = dst_key_id(key->key);
|
|
||||||
keyalg = dst_key_alg(key->key);
|
|
||||||
|
|
||||||
for (result = dns_rdataset_first(&sigs);
|
result = ISC_R_SUCCESS;
|
||||||
result == ISC_R_SUCCESS;
|
|
||||||
result = dns_rdataset_next(&sigs)) {
|
|
||||||
dns_rdata_reset(&rdata);
|
|
||||||
dns_rdataset_current(&sigs, &rdata);
|
|
||||||
sigalg = rdata.data[2];
|
|
||||||
sigid = (rdata.data[16] << 8) | rdata.data[17];
|
|
||||||
if (keyid == sigid && keyalg == sigalg) {
|
|
||||||
key->is_active = ISC_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == ISC_R_NOMORE)
|
|
||||||
success:
|
|
||||||
result = ISC_R_SUCCESS;
|
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
if (dns_rdataset_isassociated(&keys))
|
if (dns_rdataset_isassociated(&keys))
|
||||||
dns_rdataset_disassociate(&keys);
|
dns_rdataset_disassociate(&keys);
|
||||||
if (dns_rdataset_isassociated(&sigs))
|
|
||||||
dns_rdataset_disassociate(&sigs);
|
|
||||||
if (pubkey != NULL)
|
if (pubkey != NULL)
|
||||||
dst_key_free(&pubkey);
|
dst_key_free(&pubkey);
|
||||||
if (privkey != NULL)
|
if (privkey != NULL)
|
||||||
@@ -1342,7 +1361,6 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin,
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
make_dnskey(dst_key_t *key, dns_rdata_t *target) {
|
make_dnskey(dst_key_t *key, dns_rdata_t *target) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@@ -1441,11 +1459,32 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||||||
void (*report)(const char *, ...))
|
void (*report)(const char *, ...))
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_dnsseckey_t *key1, *key2;
|
dns_dnsseckey_t *key, *key1, *key2, *next;
|
||||||
|
|
||||||
key1 = ISC_LIST_HEAD(*newkeys);
|
/*
|
||||||
while (key1 != NULL) {
|
* First, look through the existing key list to find keys
|
||||||
|
* supplied from the command line which are not in the zone.
|
||||||
|
* Update the zone to include them.
|
||||||
|
*/
|
||||||
|
for (key = ISC_LIST_HEAD(*keys);
|
||||||
|
key != NULL;
|
||||||
|
key = ISC_LIST_NEXT(key, link)) {
|
||||||
|
if (key->source == dns_keysource_user &&
|
||||||
|
(key->hint_publish || key->force_publish)) {
|
||||||
|
RETERR(publish_key(add, key, origin, ttl,
|
||||||
|
mctx, allzsk, report));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Second, scan the list of newly found keys looking for matches
|
||||||
|
* with known keys, and update accordingly.
|
||||||
|
*/
|
||||||
|
for (key1 = ISC_LIST_HEAD(*newkeys); key1 != NULL; key1 = next) {
|
||||||
isc_boolean_t key_revoked = ISC_FALSE;
|
isc_boolean_t key_revoked = ISC_FALSE;
|
||||||
|
|
||||||
|
next = ISC_LIST_NEXT(key1, link);
|
||||||
|
|
||||||
for (key2 = ISC_LIST_HEAD(*keys);
|
for (key2 = ISC_LIST_HEAD(*keys);
|
||||||
key2 != NULL;
|
key2 != NULL;
|
||||||
key2 = ISC_LIST_NEXT(key2, link)) {
|
key2 = ISC_LIST_NEXT(key2, link)) {
|
||||||
@@ -1477,7 +1516,6 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||||||
key1->first_sign = ISC_TRUE;
|
key1->first_sign = ISC_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
key1 = next;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1492,7 +1530,6 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||||||
dns_dnsseckey_destroy(mctx, &key2);
|
dns_dnsseckey_destroy(mctx, &key2);
|
||||||
} else if (key_revoked &&
|
} else if (key_revoked &&
|
||||||
(dst_key_flags(key1->key) & DNS_KEYFLAG_REVOKE) != 0) {
|
(dst_key_flags(key1->key) & DNS_KEYFLAG_REVOKE) != 0) {
|
||||||
dns_dnsseckey_t *next;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A previously valid key has been revoked.
|
* A previously valid key has been revoked.
|
||||||
@@ -1509,7 +1546,6 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||||||
|
|
||||||
RETERR(publish_key(add, key1, origin, ttl,
|
RETERR(publish_key(add, key1, origin, ttl,
|
||||||
mctx, allzsk, report));
|
mctx, allzsk, report));
|
||||||
next = ISC_LIST_NEXT(key1, link);
|
|
||||||
ISC_LIST_UNLINK(*newkeys, key1, link);
|
ISC_LIST_UNLINK(*newkeys, key1, link);
|
||||||
ISC_LIST_APPEND(*keys, key1, link);
|
ISC_LIST_APPEND(*keys, key1, link);
|
||||||
|
|
||||||
@@ -1522,27 +1558,14 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||||||
* sign other records with it.
|
* sign other records with it.
|
||||||
*/
|
*/
|
||||||
key1->ksk = ISC_TRUE;
|
key1->ksk = ISC_TRUE;
|
||||||
key1 = next;
|
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (!key2->is_active &&
|
if (!key2->is_active &&
|
||||||
(key1->hint_sign || key1->force_sign))
|
(key1->hint_sign || key1->force_sign))
|
||||||
key2->first_sign = ISC_TRUE;
|
key2->first_sign = ISC_TRUE;
|
||||||
key2->hint_sign = key1->hint_sign;
|
key2->hint_sign = key1->hint_sign;
|
||||||
|
|
||||||
/*
|
|
||||||
* If a key was specified on the command line,
|
|
||||||
* not in the zone, it can be imported into the
|
|
||||||
* zone now.
|
|
||||||
*/
|
|
||||||
key2->hint_publish = key1->hint_publish;
|
key2->hint_publish = key1->hint_publish;
|
||||||
if (key2->source == dns_keysource_user &&
|
|
||||||
(key2->hint_publish || key2->force_publish))
|
|
||||||
RETERR(publish_key(add, key2, origin, ttl,
|
|
||||||
mctx, allzsk, report));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
key1 = ISC_LIST_NEXT(key1, link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free any leftover keys in newkeys */
|
/* Free any leftover keys in newkeys */
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dnssec.h,v 1.38 2009/10/12 23:48:02 tbox Exp $ */
|
/* $Id: dnssec.h,v 1.39 2009/10/27 03:59:45 each Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_DNSSEC_H
|
#ifndef DNS_DNSSEC_H
|
||||||
#define DNS_DNSSEC_H 1
|
#define DNS_DNSSEC_H 1
|
||||||
@@ -271,8 +271,9 @@ dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory,
|
|||||||
isc_result_t
|
isc_result_t
|
||||||
dns_dnssec_keylistfromrdataset(dns_name_t *origin,
|
dns_dnssec_keylistfromrdataset(dns_name_t *origin,
|
||||||
const char *directory, isc_mem_t *mctx,
|
const char *directory, isc_mem_t *mctx,
|
||||||
dns_rdataset_t *keyset, dns_rdataset_t *sigset,
|
dns_rdataset_t *keyset, dns_rdataset_t *keysigs,
|
||||||
isc_boolean_t savekeys, isc_boolean_t public,
|
dns_rdataset_t *soasigs, isc_boolean_t savekeys,
|
||||||
|
isc_boolean_t public,
|
||||||
dns_dnsseckeylist_t *keylist);
|
dns_dnsseckeylist_t *keylist);
|
||||||
/*%<
|
/*%<
|
||||||
* Append the contents of a DNSKEY rdataset 'keyset' to 'keylist'.
|
* Append the contents of a DNSKEY rdataset 'keyset' to 'keylist'.
|
||||||
@@ -280,6 +281,10 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin,
|
|||||||
* matching key files, and load the private keys that go with
|
* matching key files, and load the private keys that go with
|
||||||
* the public ones. If 'savekeys' is ISC_TRUE, mark the keys so
|
* the public ones. If 'savekeys' is ISC_TRUE, mark the keys so
|
||||||
* they will not be deleted or inactivated regardless of metadata.
|
* they will not be deleted or inactivated regardless of metadata.
|
||||||
|
*
|
||||||
|
* 'keysigs' and 'soasigs', if not NULL and associated, contain the
|
||||||
|
* RRSIGS for the DNSKEY and SOA records respectively and are used to mark
|
||||||
|
* whether a key is already active int eh zone.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: zone.c,v 1.520 2009/10/20 23:47:32 tbox Exp $ */
|
/* $Id: zone.c,v 1.521 2009/10/27 03:59:45 each Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -13279,7 +13279,7 @@ zone_rekey(dns_zone_t *zone) {
|
|||||||
dns_db_t *db = NULL;
|
dns_db_t *db = NULL;
|
||||||
dns_dbnode_t *node = NULL;
|
dns_dbnode_t *node = NULL;
|
||||||
dns_dbversion_t *ver = NULL;
|
dns_dbversion_t *ver = NULL;
|
||||||
dns_rdataset_t soaset, keyset, sigset;
|
dns_rdataset_t soaset, soasigs, keyset, keysigs;
|
||||||
dns_dnsseckeylist_t dnskeys, keys, oldkeys;
|
dns_dnsseckeylist_t dnskeys, keys, oldkeys;
|
||||||
dns_dnsseckey_t *key;
|
dns_dnsseckey_t *key;
|
||||||
dns_diff_t add, del;
|
dns_diff_t add, del;
|
||||||
@@ -13295,8 +13295,9 @@ zone_rekey(dns_zone_t *zone) {
|
|||||||
ISC_LIST_INIT(keys);
|
ISC_LIST_INIT(keys);
|
||||||
ISC_LIST_INIT(oldkeys);
|
ISC_LIST_INIT(oldkeys);
|
||||||
dns_rdataset_init(&soaset);
|
dns_rdataset_init(&soaset);
|
||||||
|
dns_rdataset_init(&soasigs);
|
||||||
dns_rdataset_init(&keyset);
|
dns_rdataset_init(&keyset);
|
||||||
dns_rdataset_init(&sigset);
|
dns_rdataset_init(&keysigs);
|
||||||
dir = dns_zone_getkeydirectory(zone);
|
dir = dns_zone_getkeydirectory(zone);
|
||||||
mctx = zone->mctx;
|
mctx = zone->mctx;
|
||||||
dns_diff_init(mctx, &add);
|
dns_diff_init(mctx, &add);
|
||||||
@@ -13309,17 +13310,18 @@ zone_rekey(dns_zone_t *zone) {
|
|||||||
|
|
||||||
/* Get the SOA record's TTL */
|
/* Get the SOA record's TTL */
|
||||||
CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
|
CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
|
||||||
dns_rdatatype_none, 0, &soaset, NULL));
|
dns_rdatatype_none, 0, &soaset, &soasigs));
|
||||||
ttl = soaset.ttl;
|
ttl = soaset.ttl;
|
||||||
dns_rdataset_disassociate(&soaset);
|
dns_rdataset_disassociate(&soaset);
|
||||||
|
|
||||||
/* Get the DNSKEY rdataset */
|
/* Get the DNSKEY rdataset */
|
||||||
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
|
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
|
||||||
dns_rdatatype_none, 0, &keyset, &sigset);
|
dns_rdatatype_none, 0, &keyset, &keysigs);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
ttl = keyset.ttl;
|
ttl = keyset.ttl;
|
||||||
CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
|
CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
|
||||||
mctx, &keyset, &sigset,
|
mctx, &keyset,
|
||||||
|
&keysigs, &soasigs,
|
||||||
ISC_FALSE, ISC_FALSE,
|
ISC_FALSE, ISC_FALSE,
|
||||||
&dnskeys));
|
&dnskeys));
|
||||||
} else if (result != ISC_R_NOTFOUND)
|
} else if (result != ISC_R_NOTFOUND)
|
||||||
@@ -13414,8 +13416,10 @@ zone_rekey(dns_zone_t *zone) {
|
|||||||
dns_db_closeversion(db, &ver, ISC_FALSE);
|
dns_db_closeversion(db, &ver, ISC_FALSE);
|
||||||
if (dns_rdataset_isassociated(&keyset))
|
if (dns_rdataset_isassociated(&keyset))
|
||||||
dns_rdataset_disassociate(&keyset);
|
dns_rdataset_disassociate(&keyset);
|
||||||
if (dns_rdataset_isassociated(&sigset))
|
if (dns_rdataset_isassociated(&keysigs))
|
||||||
dns_rdataset_disassociate(&sigset);
|
dns_rdataset_disassociate(&keysigs);
|
||||||
|
if (dns_rdataset_isassociated(&soasigs))
|
||||||
|
dns_rdataset_disassociate(&soasigs);
|
||||||
if (node != NULL)
|
if (node != NULL)
|
||||||
dns_db_detachnode(db, &node);
|
dns_db_detachnode(db, &node);
|
||||||
if (db != NULL)
|
if (db != NULL)
|
||||||
|
Reference in New Issue
Block a user