dnssec-signzone.c revision 7f35bf8e1702d751e949390d93b0b9cbb8fda8a2
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein/*
5347c0fcb04eaea19d9f39795646239f487c6207Tinderbox User * Portions Copyright (C) 1999, 2000 Internet Software Consortium.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
5347c0fcb04eaea19d9f39795646239f487c6207Tinderbox User *
5347c0fcb04eaea19d9f39795646239f487c6207Tinderbox User * Permission to use, copy, modify, and distribute this software for any
5347c0fcb04eaea19d9f39795646239f487c6207Tinderbox User * purpose with or without fee is hereby granted, provided that the above
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * copyright notice and this permission notice appear in all copies.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM AND
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * NETWORK ASSOCIATES DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
cd32f419a8a5432fbb139f56ee73cbf68b9350ccTinderbox User * SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE CONSORTIUM OR NETWORK
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
cd32f419a8a5432fbb139f56ee73cbf68b9350ccTinderbox User * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * PERFORMANCE OF THIS SOFTWARE.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <config.h>
cd32f419a8a5432fbb139f56ee73cbf68b9350ccTinderbox User
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <stdlib.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/commandline.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/entropy.h>
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews#include <isc/mem.h>
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews#include <isc/string.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/util.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <dns/db.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <dns/dbiterator.h>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User#include <dns/dnssec.h>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User#include <dns/keyvalues.h>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User#include <dns/log.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dns/nxt.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dns/rdata.h>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User#include <dns/rdatalist.h>
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User#include <dns/rdataset.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dns/rdatasetiter.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dns/rdatastruct.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dns/rdatatype.h>
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User#include <dns/result.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dns/secalg.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dns/time.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dst/dst.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include <dst/result.h>
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#include "dnssectool.h"
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntconst char *program = "dnssec-signzone";
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinint verbose;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
f9ce6280cec79deb16ff6d9807aa493ff23e10d9Tinderbox User/*#define USE_ZONESTATUS*/
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User
f9ce6280cec79deb16ff6d9807aa493ff23e10d9Tinderbox User#define BUFSIZE 2048
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunttypedef struct signer_key_struct signer_key_t;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Usertypedef struct signer_array_struct signer_array_t;
46472a450e043434d78fa18edc73bca8c47f3981Tinderbox User
46472a450e043434d78fa18edc73bca8c47f3981Tinderbox Userstruct signer_key_struct {
e285c11870c6263cd79b418e104c7eb3e2d96952Tinderbox User dst_key_t *key;
46472a450e043434d78fa18edc73bca8c47f3981Tinderbox User isc_boolean_t isdefault;
46472a450e043434d78fa18edc73bca8c47f3981Tinderbox User ISC_LINK(signer_key_t) link;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt};
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userstruct signer_array_struct {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt unsigned char array[BUFSIZE];
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt ISC_LINK(signer_array_t) link;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User};
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userstatic ISC_LIST(signer_key_t) keylist;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic isc_stdtime_t starttime = 0, endtime = 0, now;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic int cycle = -1;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic isc_boolean_t tryverify = ISC_FALSE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic isc_mem_t *mctx = NULL;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userstatic isc_entropy_t *ectx = NULL;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic inline void
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox Userset_bit(unsigned char *array, unsigned int index, unsigned int bit) {
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User unsigned int shift, mask;
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User shift = 7 - (index % 8);
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User mask = 1 << shift;
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User if (bit != 0)
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User array[index / 8] |= mask;
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User else
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User array[index / 8] &= (~mask & 0xFF);
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User}
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox Userstatic void
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox Usersignwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata,
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User dst_key_t *key, isc_buffer_t *b)
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User{
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User isc_result_t result;
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User dns_rdata_init(rdata);
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User result = dns_dnssec_sign(name, rdataset, key, &starttime, &endtime,
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User mctx, b, rdata);
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User if (result != ISC_R_SUCCESS)
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User fatal("key '%s/%s/%d' failed to sign data: %s",
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User nametostr(dst_key_name(key)), algtostr(dst_key_alg(key)),
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User dst_key_id(key), isc_result_totext(result));
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User if (tryverify) {
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User result = dns_dnssec_verify(name, rdataset, key,
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User ISC_TRUE, mctx, rdata);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result == ISC_R_SUCCESS)
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User vbprintf(3, "\tsignature verified\n");
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User else
e2f974003e61b59321a99f01a6f43576d9b76231Tinderbox User vbprintf(3, "\tsignature failed to verify\n");
e2f974003e61b59321a99f01a6f43576d9b76231Tinderbox User }
576bce9d7331498ca5453f8743f94ed8e2e59d9fTinderbox User}
576bce9d7331498ca5453f8743f94ed8e2e59d9fTinderbox User
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox Userstatic inline isc_boolean_t
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userissigningkey(signer_key_t *key) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User return (key->isdefault);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt}
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userstatic inline isc_boolean_t
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox Useriszonekey(signer_key_t *key, dns_db_t *db) {
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User return (ISC_TF(dns_name_equal(dst_key_name(key->key),
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User dns_db_origin(db)) &&
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User (dst_key_flags(key->key) & DNS_KEYFLAG_OWNERMASK) ==
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User DNS_KEYOWNER_ZONE));
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User}
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User
1ffe3f29e3cd0d8355500e9fd34de918ad9b4a01Tinderbox User/*
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User * Finds the key that generated a SIG, if possible. First look at the keys
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User * that we've loaded already, and then see if there's a key on disk.
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User */
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox Userstatic signer_key_t *
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox Userkeythatsigned(dns_rdata_sig_t *sig) {
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User isc_result_t result;
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User dst_key_t *pubkey = NULL, *privkey = NULL;
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User signer_key_t *key;
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User key = ISC_LIST_HEAD(keylist);
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User while (key != NULL) {
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User if (sig->keyid == dst_key_id(key->key) &&
1ffe3f29e3cd0d8355500e9fd34de918ad9b4a01Tinderbox User sig->algorithm == dst_key_alg(key->key) &&
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User dns_name_equal(&sig->signer, dst_key_name(key->key)))
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User return key;
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User key = ISC_LIST_NEXT(key, link);
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User }
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User result = dst_key_fromfile(&sig->signer, sig->keyid, sig->algorithm,
1ffe3f29e3cd0d8355500e9fd34de918ad9b4a01Tinderbox User DST_TYPE_PUBLIC, NULL, mctx, &pubkey);
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User if (result != ISC_R_SUCCESS)
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User return (NULL);
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User key = isc_mem_get(mctx, sizeof(signer_key_t));
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User if (key == NULL)
3ba1f79ade054aa6a0dc5032502bcdcf357cd7bdTinderbox User fatal("out of memory");
3ba1f79ade054aa6a0dc5032502bcdcf357cd7bdTinderbox User
3ba1f79ade054aa6a0dc5032502bcdcf357cd7bdTinderbox User result = dst_key_fromfile(&sig->signer, sig->keyid, sig->algorithm,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt DST_TYPE_PRIVATE, NULL, mctx, &privkey);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (result == ISC_R_SUCCESS) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt key->key = privkey;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dst_key_free(&pubkey);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt else
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt key->key = pubkey;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User key->isdefault = ISC_FALSE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt ISC_LIST_APPEND(keylist, key, link);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt return key;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt}
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt/*
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * Check to see if we expect to find a key at this name. If we see a SIG
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * and can't find the signing key that we expect to find, we drop the sig.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * I'm not sure if this is completely correct, but it seems to work.
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt */
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic isc_boolean_t
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntexpecttofindkey(dns_name_t *name, dns_db_t *db, dns_dbversion_t *version) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt unsigned int options = DNS_DBFIND_NOWILD;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_fixedname_t fname;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_result_t result;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_fixedname_init(&fname);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User result = dns_db_find(db, name, version, dns_rdatatype_key, options,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt 0, NULL, dns_fixedname_name(&fname), NULL, NULL);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt switch (result) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt case ISC_R_SUCCESS:
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt case DNS_R_NXDOMAIN:
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt case DNS_R_NXRRSET:
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User return ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt case DNS_R_DELEGATION:
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt case DNS_R_CNAME:
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User case DNS_R_DNAME:
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User return ISC_FALSE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt default:
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt fatal("failure looking for '%s KEY' in database: %s",
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt nametostr(name), isc_result_totext(result));
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt return ISC_FALSE; /* removes a warning */
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt}
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userstatic inline isc_boolean_t
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Usersetverifies(dns_name_t *name, dns_rdataset_t *set, signer_key_t *key,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdata_t *sig)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt{
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_result_t result;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_dnssec_verify(name, set, key->key, ISC_FALSE, mctx, sig);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User return (ISC_TF(result == ISC_R_SUCCESS));
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt}
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#define allocbufferandrdata \
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_buffer_t b; \
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt trdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); \
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User tdata = isc_mem_get(mctx, sizeof(signer_array_t)); \
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt ISC_LIST_APPEND(arraylist, tdata, link); \
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (trdata == NULL || tdata == NULL) \
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt fatal("out of memory"); \
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_buffer_init(&b, tdata->array, sizeof(tdata->array));
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt/*
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * Signs a set. Goes through contortions to decide if each SIG should
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * be dropped or retained, and then determines if any new SIGs need to
9d557856c2a19ec95ee73245f60a92f8675cf5baTinderbox User * be generated.
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt */
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic void
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntsignset(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_name_t *name, dns_rdataset_t *set)
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User{
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdatalist_t siglist;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_t sigset, oldsigset;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdata_t oldsigrdata;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdata_t *trdata;
76cf91b5df7a1bc450afcb9ce7585c61bb87de68Tinderbox User dns_rdata_sig_t sig;
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User signer_key_t *key;
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User isc_result_t result;
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User isc_boolean_t notsigned = ISC_TRUE, nosigs = ISC_FALSE;
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User isc_boolean_t wassignedby[256], nowsignedby[256];
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User signer_array_t *tdata;
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User ISC_LIST(signer_array_t) arraylist;
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User int i;
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User ISC_LIST_INIT(siglist.rdata);
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User ISC_LIST_INIT(arraylist);
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User for (i = 0; i < 256; i++)
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User wassignedby[i] = nowsignedby[i] = ISC_FALSE;
76cf91b5df7a1bc450afcb9ce7585c61bb87de68Tinderbox User
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdataset_init(&oldsigset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_db_findrdataset(db, node, version, dns_rdatatype_sig,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User set->type, 0, &oldsigset, NULL);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result == ISC_R_NOTFOUND) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User result = ISC_R_SUCCESS;
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User nosigs = ISC_TRUE;
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result != ISC_R_SUCCESS)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt fatal("failed while looking for '%s SIG %s': %s",
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt nametostr(name), typetostr(set->type),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_result_totext(result));
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt vbprintf(1, "%s/%s:\n", nametostr(name), typetostr(set->type));
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (!nosigs) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_rdataset_first(&oldsigset);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User while (result == ISC_R_SUCCESS) {
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User isc_boolean_t expired, future;
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User isc_boolean_t keep = ISC_FALSE, resign = ISC_FALSE;
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User dns_rdataset_current(&oldsigset, &oldsigrdata);
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User result = dns_rdata_tostruct(&oldsigrdata, &sig, mctx);
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User check_result(result, "dns_rdata_tostruct");
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User expired = ISC_TF(now + cycle > sig.timeexpire);
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User future = ISC_TF(now < sig.timesigned);
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User key = keythatsigned(&sig);
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User if (sig.timesigned > sig.timeexpire) {
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User /* sig is dropped and not replaced */
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User vbprintf(2, "\tsig by %s/%s/%d dropped - "
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User "invalid validity period\n",
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User nametostr(&sig.signer),
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User algtostr(sig.algorithm),
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User sig.keyid);
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User }
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User else if (key == NULL && !future &&
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User expecttofindkey(&sig.signer, db, version))
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User {
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User /* sig is dropped and not replaced */
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User vbprintf(2, "\tsig by %s/%s/%d dropped - "
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User "private key not found\n",
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User nametostr(&sig.signer),
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User algtostr(sig.algorithm),
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User sig.keyid);
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User }
a1ff871f78b7d907d6fc3a382beea2a640fe8423Tinderbox User else if (key == NULL || future) {
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User vbprintf(2, "\tsig by %s/%s/%d %s - "
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User "key not found\n",
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User expired ? "retained" : "dropped",
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User nametostr(&sig.signer),
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User algtostr(sig.algorithm),
3241ddcf9354c5ab50f4df5a656e72a5c68e172bTinderbox User sig.keyid);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (!expired)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt keep = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt else if (issigningkey(key)) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (!expired &&
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt setverifies(name, set, key, &oldsigrdata))
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt vbprintf(2,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User "\tsig by %s/%s/%d retained\n",
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User nametostr(&sig.signer),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt algtostr(sig.algorithm),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt sig.keyid);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt keep = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt wassignedby[sig.algorithm] = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User else {
e2b184f84e846bbcb764b6f0aef5dcd583d3d7a1Tinderbox User vbprintf(2,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt "\tsig by %s/%s/%d dropped - "
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User "%s\n",
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User nametostr(&sig.signer),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt algtostr(sig.algorithm),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt sig.keyid,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt expired ? "expired" :
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt "failed to verify");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt wassignedby[sig.algorithm] = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt resign = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt else if (iszonekey(key, db)) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (!expired &&
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt setverifies(name, set, key, &oldsigrdata))
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User vbprintf(2,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt "\tsig by %s/%s/%d retained\n",
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt nametostr(&sig.signer),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt algtostr(sig.algorithm),
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User sig.keyid);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt keep = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt wassignedby[sig.algorithm] = ISC_TRUE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User nowsignedby[sig.algorithm] = ISC_TRUE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt else {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt vbprintf(2,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt "\tsig by %s/%s/%d "
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt "dropped - %s\n",
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User nametostr(&sig.signer),
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User algtostr(sig.algorithm),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt sig.keyid,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt expired ? "expired" :
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt "failed to verify");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt wassignedby[sig.algorithm] = ISC_TRUE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (dst_key_isprivate(key->key))
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User resign = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User else if (!expired) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User vbprintf(2, "\tsig by %s/%s/%d retained\n",
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt nametostr(&sig.signer),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt algtostr(sig.algorithm),
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User sig.keyid);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User keep = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt else {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User vbprintf(2, "\tsig by %s/%s/%d expired\n",
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User nametostr(&sig.signer),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt algtostr(sig.algorithm),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt sig.keyid);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (keep) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt allocbufferandrdata;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_rdata_fromstruct(trdata,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User set->rdclass,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdatatype_sig,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt &sig, &b);
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User nowsignedby[sig.algorithm] = ISC_TRUE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User ISC_LIST_APPEND(siglist.rdata, trdata, link);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt else if (resign) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt allocbufferandrdata;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt vbprintf(1, "\tresigning with key %s/%s/%d\n",
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User nametostr(dst_key_name(key->key)),
0226754d9e537fd56b690d5890cfe215a6c59f89Tinderbox User algtostr(dst_key_alg(key->key)),
0226754d9e537fd56b690d5890cfe215a6c59f89Tinderbox User dst_key_id(key->key));
0226754d9e537fd56b690d5890cfe215a6c59f89Tinderbox User signwithkey(name, set, trdata, key->key, &b);
0226754d9e537fd56b690d5890cfe215a6c59f89Tinderbox User nowsignedby[sig.algorithm] = ISC_TRUE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User ISC_LIST_APPEND(siglist.rdata, trdata, link);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdata_freestruct(&sig);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User result = dns_rdataset_next(&oldsigset);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result == ISC_R_NOMORE)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = ISC_R_SUCCESS;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User check_result(result, "dns_db_dns_rdataset_first()/next()");
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdataset_disassociate(&oldsigset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User for (i = 0; i < 256; i++)
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (wassignedby[i] != 0) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User notsigned = ISC_FALSE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt break;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt key = ISC_LIST_HEAD(keylist);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt while (key != NULL) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt unsigned int alg = dst_key_alg(key->key);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (key->isdefault &&
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User (notsigned || (wassignedby[alg] && !nowsignedby[alg])))
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt allocbufferandrdata;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt vbprintf(1, "\tsigning with key %s/%s/%d\n",
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt nametostr(dst_key_name(key->key)),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt algtostr(dst_key_alg(key->key)),
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dst_key_id(key->key));
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User signwithkey(name, set, trdata, key->key, &b);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User ISC_LIST_APPEND(siglist.rdata, trdata, link);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt key = ISC_LIST_NEXT(key, link);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (!ISC_LIST_EMPTY(siglist.rdata)) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt siglist.rdclass = set->rdclass;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User siglist.type = dns_rdatatype_sig;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User siglist.covers = set->type;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (endtime - starttime < set->ttl)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt siglist.ttl = endtime - starttime;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt else
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt siglist.ttl = set->ttl;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_init(&sigset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_rdatalist_tordataset(&siglist, &sigset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt check_result(result, "dns_rdatalist_tordataset");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_db_addrdataset(db, node, version, 0, &sigset,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt 0, NULL);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result == DNS_R_UNCHANGED)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = ISC_R_SUCCESS;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User check_result(result, "dns_db_addrdataset");
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdataset_disassociate(&sigset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt else if (!nosigs) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#if 0
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt /*
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * If this is compiled in, running a signed set through the
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * signer with no private keys causes DNS_R_BADDB to occur
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * later. This is bad.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User */
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User result = dns_db_deleterdataset(db, node, version,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdatatype_sig, set->type);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result == ISC_R_NOTFOUND)
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User result = ISC_R_SUCCESS;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User check_result(result, "dns_db_deleterdataset");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#endif
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt fatal("File is currently signed but no private keys were "
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User "found. This won't work.");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt trdata = ISC_LIST_HEAD(siglist.rdata);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt while (trdata != NULL) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdata_t *next = ISC_LIST_NEXT(trdata, link);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_mem_put(mctx, trdata, sizeof(dns_rdata_t));
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt trdata = next;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt tdata = ISC_LIST_HEAD(arraylist);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt while (tdata != NULL) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt signer_array_t *next = ISC_LIST_NEXT(tdata, link);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_mem_put(mctx, tdata, sizeof(signer_array_t));
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt tdata = next;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User}
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#ifndef USE_ZONESTATUS
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt/* Determine if a KEY set contains a null key */
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic isc_boolean_t
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userhasnullkey(dns_rdataset_t *rdataset) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User isc_result_t result;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdata_t rdata;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_boolean_t found = ISC_FALSE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_rdataset_first(rdataset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt while (result == ISC_R_SUCCESS) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dst_key_t *key = NULL;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_current(rdataset, &rdata);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_dnssec_keyfromrdata(dns_rootname,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt &rdata, mctx, &key);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result != ISC_R_SUCCESS)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt fatal("could not convert KEY into internal format");
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (dst_key_isnullkey(key))
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User found = ISC_TRUE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dst_key_free(&key);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (found == ISC_TRUE)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt return (ISC_TRUE);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_rdataset_next(rdataset);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (result != ISC_R_NOMORE)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt fatal("failure looking for null keys");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt return (ISC_FALSE);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt}
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#endif
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt/*
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * Looks for signatures of the zone keys by the parent, and imports them
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * if found.
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt */
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userstatic void
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userimportparentsig(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_name_t *name, dns_rdataset_t *set)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt{
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User unsigned char filename[256];
e62b9c9ce6413fb183c8116381e75dcd07ca5517Tinderbox User isc_buffer_t b;
e62b9c9ce6413fb183c8116381e75dcd07ca5517Tinderbox User isc_region_t r;
e62b9c9ce6413fb183c8116381e75dcd07ca5517Tinderbox User dns_db_t *newdb = NULL;
e62b9c9ce6413fb183c8116381e75dcd07ca5517Tinderbox User dns_dbnode_t *newnode = NULL;
e62b9c9ce6413fb183c8116381e75dcd07ca5517Tinderbox User dns_rdataset_t newset, sigset;
e62b9c9ce6413fb183c8116381e75dcd07ca5517Tinderbox User dns_rdata_t rdata, newrdata;
e62b9c9ce6413fb183c8116381e75dcd07ca5517Tinderbox User isc_result_t result;
d7a61cfbe56ebfa1682e949e48b4d08840234d8fTinderbox User
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User isc_buffer_init(&b, filename, sizeof(filename) - 10);
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User result = dns_name_totext(name, ISC_FALSE, &b);
d7a61cfbe56ebfa1682e949e48b4d08840234d8fTinderbox User check_result(result, "dns_name_totext()");
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User isc_buffer_usedregion(&b, &r);
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User strcpy((char *)r.base + r.length, "signedkey");
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User dns_db_class(db), 0, NULL, &newdb);
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User check_result(result, "dns_db_create()");
d7a61cfbe56ebfa1682e949e48b4d08840234d8fTinderbox User result = dns_db_load(newdb, (char *)filename);
832fa787d4a13fa89d64f868e51016ff4adb0d89Tinderbox User if (result != ISC_R_SUCCESS)
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User goto failure;
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User result = dns_db_findnode(newdb, name, ISC_FALSE, &newnode);
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User if (result != ISC_R_SUCCESS)
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User goto failure;
832fa787d4a13fa89d64f868e51016ff4adb0d89Tinderbox User dns_rdataset_init(&newset);
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User dns_rdataset_init(&sigset);
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User result = dns_db_findrdataset(newdb, newnode, NULL, dns_rdatatype_key,
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User 0, 0, &newset, &sigset);
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User if (result != ISC_R_SUCCESS)
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User goto failure;
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User if (dns_rdataset_count(set) != dns_rdataset_count(&newset))
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User goto failure;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdata_init(&rdata);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdata_init(&newrdata);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_rdataset_first(set);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User check_result(result, "dns_rdataset_first()");
006283c42350464bc285c4481bce0a3b5a3dd8d0Tinderbox User for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(set)) {
006283c42350464bc285c4481bce0a3b5a3dd8d0Tinderbox User dns_rdataset_current(set, &rdata);
006283c42350464bc285c4481bce0a3b5a3dd8d0Tinderbox User result = dns_rdataset_first(&newset);
006283c42350464bc285c4481bce0a3b5a3dd8d0Tinderbox User check_result(result, "dns_rdataset_first()");
006283c42350464bc285c4481bce0a3b5a3dd8d0Tinderbox User for (;
006283c42350464bc285c4481bce0a3b5a3dd8d0Tinderbox User result == ISC_R_SUCCESS;
006283c42350464bc285c4481bce0a3b5a3dd8d0Tinderbox User result = dns_rdataset_next(&newset))
6758b59e57af88bdf466e63c0856043df44f8dd0Tinderbox User {
6758b59e57af88bdf466e63c0856043df44f8dd0Tinderbox User dns_rdataset_current(&newset, &newrdata);
6758b59e57af88bdf466e63c0856043df44f8dd0Tinderbox User if (dns_rdata_compare(&rdata, &newrdata) == 0)
6758b59e57af88bdf466e63c0856043df44f8dd0Tinderbox User break;
6758b59e57af88bdf466e63c0856043df44f8dd0Tinderbox User }
dec590a3deb8e87380a8bd3a77d535dba3729bf6Tinderbox User if (result != ISC_R_SUCCESS)
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User break;
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User }
dec590a3deb8e87380a8bd3a77d535dba3729bf6Tinderbox User if (result != ISC_R_NOMORE)
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User goto failure;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt vbprintf(2, "found the parent's signature of our zone key\n");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_db_addrdataset(db, node, version, 0, &sigset, 0, NULL);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt check_result(result, "dns_db_addrdataset");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_disassociate(&newset);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdataset_disassociate(&sigset);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt failure:
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (newnode != NULL)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_db_detachnode(newdb, &newnode);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (newdb != NULL)
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_db_detach(&newdb);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt}
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt/*
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * Looks for our signatures of child keys. If present, inform the caller,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * who will set the zone status (KEY) bit in the NXT record.
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt */
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic isc_boolean_t
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunthaschildkey(dns_db_t *db, dns_name_t *name) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt unsigned char filename[256];
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User isc_buffer_t b;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User isc_region_t r;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_db_t *newdb = NULL;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_dbnode_t *newnode = NULL;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdataset_t set, sigset;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdata_t sigrdata;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_result_t result;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_boolean_t found = ISC_FALSE;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdata_sig_t sig;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt signer_key_t *key;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User isc_buffer_init(&b, filename, sizeof(filename) - 10);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_name_totext(name, ISC_FALSE, &b);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User check_result(result, "dns_name_totext()");
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User isc_buffer_usedregion(&b, &r);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt strcpy((char *)r.base + r.length, "signedkey");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_db_class(db), 0, NULL, &newdb);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt check_result(result, "dns_db_create()");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_db_load(newdb, (char *)filename);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result != ISC_R_SUCCESS)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt goto failure;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_db_findnode(newdb, name, ISC_FALSE, &newnode);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result != ISC_R_SUCCESS)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt goto failure;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_init(&set);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_init(&sigset);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User result = dns_db_findrdataset(newdb, newnode, NULL, dns_rdatatype_key,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User 0, 0, &set, &sigset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result != ISC_R_SUCCESS)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt goto failure;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (!dns_rdataset_isassociated(&set) ||
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User !dns_rdataset_isassociated(&sigset))
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User goto disfail;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_rdataset_first(&sigset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt check_result(result, "dns_rdataset_first()");
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdata_init(&sigrdata);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(&sigset)) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_current(&sigset, &sigrdata);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_rdata_tostruct(&sigrdata, &sig, mctx);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result != ISC_R_SUCCESS)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt goto disfail;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt key = keythatsigned(&sig);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdata_freestruct(&sig);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (key == NULL)
e285c11870c6263cd79b418e104c7eb3e2d96952Tinderbox User goto disfail;
46472a450e043434d78fa18edc73bca8c47f3981Tinderbox User result = dns_dnssec_verify(name, &set, key->key,
46472a450e043434d78fa18edc73bca8c47f3981Tinderbox User ISC_FALSE, mctx, &sigrdata);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result == ISC_R_SUCCESS) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt found = ISC_TRUE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User break;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt disfail:
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (dns_rdataset_isassociated(&set))
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_disassociate(&set);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (dns_rdataset_isassociated(&sigset))
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_disassociate(&sigset);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt failure:
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (newnode != NULL)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_db_detachnode(newdb, &newnode);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (newdb != NULL)
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_db_detach(&newdb);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User return (found);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt}
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt/*
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * Signs all records at a name. This mostly just signs each set individually,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * but also adds the SIG bit to any NXTs generated earlier, deals with
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * parent/child KEY signatures, and handles other exceptional cases.
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt */
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntstatic void
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntsignname(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_name_t *name, isc_boolean_t atorigin)
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User{
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User isc_result_t result;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdata_t rdata;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_t rdataset;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdatasetiter_t *rdsiter;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_boolean_t isdelegation = ISC_FALSE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User isc_boolean_t childkey = ISC_FALSE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User static int warnwild = 0;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (dns_name_iswildcard(name)) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (warnwild++ == 0) {
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User fprintf(stderr, "%s: warning: BIND 9 doesn't properly "
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User "handle wildcards in secure zones:\n",
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User program);
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User fprintf(stderr, "\t- wildcard nonexistence proof is "
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User "not generated by the server\n");
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User fprintf(stderr, "\t- wildcard nonexistence proof is "
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User "not required by the resolver\n");
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User }
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User fprintf(stderr, "%s: warning: wildcard name seen: %s\n",
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User program, nametostr(name));
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User }
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User if (!atorigin) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdataset_t nsset;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_init(&nsset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt result = dns_db_findrdataset(db, node, version,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdatatype_ns, 0, 0, &nsset,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User NULL);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt /* Is this a delegation point? */
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (result == ISC_R_SUCCESS) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User isdelegation = ISC_TRUE;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdataset_disassociate(&nsset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt }
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_init(&rdataset);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User rdsiter = NULL;
a179cbdf652095d00e7774320592f25eab0210d8Tinderbox User result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
a179cbdf652095d00e7774320592f25eab0210d8Tinderbox User check_result(result, "dns_db_allrdatasets()");
a179cbdf652095d00e7774320592f25eab0210d8Tinderbox User result = dns_rdatasetiter_first(rdsiter);
a179cbdf652095d00e7774320592f25eab0210d8Tinderbox User while (result == ISC_R_SUCCESS) {
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User dns_rdatasetiter_current(rdsiter, &rdataset);
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User /* If this is a SIG set, skip it. */
6b7cba2b10d6cb5363d94b434b0d22ecfb33a6f3Tinderbox User if (rdataset.type == dns_rdatatype_sig)
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User goto skip;
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User
8a48b6b9b6fa8486f24b22d1972b2b6ebb36a4a4Tinderbox User /*
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User * If this is a KEY set at the apex, look for a signedkey file.
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User */
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User if (rdataset.type == dns_rdatatype_key && atorigin) {
f33abec8a62ab6f2b867d7189dfffa72592c027bTinderbox User importparentsig(db, version, node, name, &rdataset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt goto skip;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt /*
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * If this name is a delegation point, skip all records
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * except an NXT set, unless we're using null keys, in
46472a450e043434d78fa18edc73bca8c47f3981Tinderbox User * which case we need to check for a null key and add one
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * if it's not present.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User */
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (isdelegation) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt switch (rdataset.type) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt case dns_rdatatype_nxt:
221870ba7bf08daf55db5a69a4de4bbdc4f2a93cTinderbox User childkey = haschildkey(db, name);
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User break;
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User#ifndef USE_ZONESTATUS
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User case dns_rdatatype_key:
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User if (hasnullkey(&rdataset))
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User break;
221870ba7bf08daf55db5a69a4de4bbdc4f2a93cTinderbox User goto skip;
221870ba7bf08daf55db5a69a4de4bbdc4f2a93cTinderbox User#endif
221870ba7bf08daf55db5a69a4de4bbdc4f2a93cTinderbox User default:
221870ba7bf08daf55db5a69a4de4bbdc4f2a93cTinderbox User goto skip;
221870ba7bf08daf55db5a69a4de4bbdc4f2a93cTinderbox User }
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User }
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User /*
260e8e04b0dc24cb884c789b5d9eb046457f264eTinderbox User * There probably should be a dns_nxtsetbit, but it can get
221870ba7bf08daf55db5a69a4de4bbdc4f2a93cTinderbox User * complicated if we need to extend the length of the
221870ba7bf08daf55db5a69a4de4bbdc4f2a93cTinderbox User * bit set. In this case, since the NXT bit is set and
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * SIG < NXT and KEY < NXT, the easy way works.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User */
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt if (rdataset.type == dns_rdatatype_nxt) {
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt unsigned char *nxt_bits;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_name_t nxtname;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_region_t r, r2;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt unsigned char keydata[4];
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dst_key_t *dstkey;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt isc_buffer_t b;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User result = dns_rdataset_first(&rdataset);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt check_result(result, "dns_rdataset_first()");
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_rdataset_current(&rdataset, &rdata);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User dns_rdata_toregion(&rdata, &r);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_name_init(&nxtname, NULL);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_name_fromregion(&nxtname, &r);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt dns_name_toregion(&nxtname, &r2);
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User nxt_bits = r.base + r2.length;
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt set_bit(nxt_bits, dns_rdatatype_sig, 1);
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#ifdef USE_ZONESTATUS
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (isdelegation && childkey) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User set_bit(nxt_bits, dns_rdatatype_key, 1);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein vbprintf(2, "found a child key for %s, "
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein "setting KEY bit in NXT\n",
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein nametostr(name));
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#else
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (isdelegation && !childkey) {
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews dns_rdataset_t keyset;
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews dns_rdatalist_t keyrdatalist;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein dns_rdata_t keyrdata;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein dns_rdataset_init(&keyset);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein result = dns_db_findrdataset(db, node, version,
cd32f419a8a5432fbb139f56ee73cbf68b9350ccTinderbox User dns_rdatatype_key,
cd32f419a8a5432fbb139f56ee73cbf68b9350ccTinderbox User 0, 0, &keyset,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein NULL);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (result == ISC_R_SUCCESS &&
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein hasnullkey(&keyset))
1700442a7751c2bbdafe2d039cebbd8316496957Tinderbox User goto alreadyhavenullkey;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (result == ISC_R_NOTFOUND)
result = ISC_R_SUCCESS;
if (result != ISC_R_SUCCESS)
fatal("failure looking for null key "
"at '%s': %s", nametostr(name),
isc_result_totext(result));
if (dns_rdataset_isassociated(&keyset))
dns_rdataset_disassociate(&keyset);
vbprintf(2, "no child key for %s, "
"adding null key\n",
nametostr(name));
dns_rdatalist_init(&keyrdatalist);
dstkey = NULL;
result = dst_key_generate(name, DNS_KEYALG_DSA,
0, 0,
DNS_KEYTYPE_NOKEY |
DNS_KEYOWNER_ZONE,
DNS_KEYPROTO_DNSSEC,
mctx, &dstkey);
if (result != ISC_R_SUCCESS)
fatal("failed to generate null key");
isc_buffer_init(&b, keydata, sizeof keydata);
result = dst_key_todns(dstkey, &b);
dst_key_free(&dstkey);
isc_buffer_usedregion(&b, &r);
dns_rdata_fromregion(&keyrdata,
rdataset.rdclass,
dns_rdatatype_key, &r);
ISC_LIST_APPEND(keyrdatalist.rdata, &keyrdata,
link);
keyrdatalist.rdclass = rdataset.rdclass;
keyrdatalist.type = dns_rdatatype_key;
keyrdatalist.covers = 0;
keyrdatalist.ttl = rdataset.ttl;
result =
dns_rdatalist_tordataset(&keyrdatalist,
&keyset);
check_result(result,
"dns_rdatalist_tordataset");
dns_db_addrdataset(db, node, version, 0,
&keyset, DNS_DBADD_MERGE,
NULL);
set_bit(nxt_bits, dns_rdatatype_key, 1);
signset(db, version, node, name, &keyset);
dns_rdataset_disassociate(&keyset);
alreadyhavenullkey:
;
}
#endif
}
signset(db, version, node, name, &rdataset);
skip:
dns_rdataset_disassociate(&rdataset);
result = dns_rdatasetiter_next(rdsiter);
}
if (result != ISC_R_NOMORE)
fatal("rdataset iteration for name '%s' failed: %s",
nametostr(name), isc_result_totext(result));
dns_rdatasetiter_destroy(&rdsiter);
}
static inline isc_boolean_t
active_node(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
dns_rdatasetiter_t *rdsiter;
isc_boolean_t active = ISC_FALSE;
isc_result_t result;
dns_rdataset_t rdataset;
dns_rdataset_init(&rdataset);
rdsiter = NULL;
result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
check_result(result, "dns_db_allrdatasets()");
result = dns_rdatasetiter_first(rdsiter);
while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, &rdataset);
if (rdataset.type != dns_rdatatype_nxt)
active = ISC_TRUE;
dns_rdataset_disassociate(&rdataset);
if (!active)
result = dns_rdatasetiter_next(rdsiter);
else
result = ISC_R_NOMORE;
}
if (result != ISC_R_NOMORE)
fatal("rdataset iteration failed: %s",
isc_result_totext(result));
dns_rdatasetiter_destroy(&rdsiter);
if (!active) {
/*
* Make sure there is no NXT record for this node.
*/
result = dns_db_deleterdataset(db, node, version,
dns_rdatatype_nxt, 0);
if (result == DNS_R_UNCHANGED)
result = ISC_R_SUCCESS;
check_result(result, "dns_db_deleterdataset");
}
return (active);
}
static inline isc_result_t
next_active(dns_db_t *db, dns_dbversion_t *version, dns_dbiterator_t *dbiter,
dns_name_t *name, dns_dbnode_t **nodep)
{
isc_result_t result;
isc_boolean_t active;
do {
active = ISC_FALSE;
result = dns_dbiterator_current(dbiter, nodep, name);
if (result == ISC_R_SUCCESS) {
active = active_node(db, version, *nodep);
if (!active) {
dns_db_detachnode(db, nodep);
result = dns_dbiterator_next(dbiter);
}
}
} while (result == ISC_R_SUCCESS && !active);
return (result);
}
static inline isc_result_t
next_nonglue(dns_db_t *db, dns_dbversion_t *version, dns_dbiterator_t *dbiter,
dns_name_t *name, dns_dbnode_t **nodep, dns_name_t *origin,
dns_name_t *lastcut)
{
isc_result_t result;
do {
result = next_active(db, version, dbiter, name, nodep);
if (result == ISC_R_SUCCESS) {
if (dns_name_issubdomain(name, origin) &&
(lastcut == NULL ||
!dns_name_issubdomain(name, lastcut)))
return (ISC_R_SUCCESS);
dns_db_detachnode(db, nodep);
result = dns_dbiterator_next(dbiter);
}
} while (result == ISC_R_SUCCESS);
return (result);
}
/*
* Generates NXTs and SIGs for each non-glue name in the zone.
*/
static void
signzone(dns_db_t *db, dns_dbversion_t *version) {
isc_result_t result, nxtresult;
dns_dbnode_t *node, *nextnode, *curnode;
dns_fixedname_t fname, fnextname, fcurname;
dns_name_t *name, *nextname, *target, *curname, *lastcut;
dns_dbiterator_t *dbiter;
isc_boolean_t atorigin = ISC_TRUE;
dns_name_t *origin;
dns_rdataset_t soaset;
dns_rdata_t soarr;
dns_rdata_soa_t soa;
dns_ttl_t zonettl;
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
dns_fixedname_init(&fnextname);
nextname = dns_fixedname_name(&fnextname);
dns_fixedname_init(&fcurname);
curname = dns_fixedname_name(&fcurname);
origin = dns_db_origin(db);
dns_rdataset_init(&soaset);
result = dns_db_find(db, origin, version, dns_rdatatype_soa,
0, 0, NULL, name, &soaset, NULL);
if (result != ISC_R_SUCCESS)
fatal("failed to find '%s SOA' in the zone: %s",
nametostr(name), isc_result_totext(result));
result = dns_rdataset_first(&soaset);
check_result(result, "dns_rdataset_first()");
dns_rdataset_current(&soaset, &soarr);
result = dns_rdata_tostruct(&soarr, &soa, mctx);
check_result(result, "dns_rdataset_tostruct()");
zonettl = soa.minimum;
dns_rdata_freestruct(&soa);
dns_rdataset_disassociate(&soaset);
lastcut = NULL;
dbiter = NULL;
result = dns_db_createiterator(db, ISC_FALSE, &dbiter);
check_result(result, "dns_db_createiterator()");
result = dns_dbiterator_first(dbiter);
node = NULL;
dns_name_clone(origin, name);
result = next_nonglue(db, version, dbiter, name, &node, origin,
lastcut);
while (result == ISC_R_SUCCESS) {
nextnode = NULL;
curnode = NULL;
dns_dbiterator_current(dbiter, &curnode, curname);
if (!atorigin) {
dns_rdatasetiter_t *rdsiter = NULL;
dns_rdataset_t set;
dns_rdataset_init(&set);
result = dns_db_allrdatasets(db, curnode, version,
0, &rdsiter);
check_result(result, "dns_db_allrdatasets");
result = dns_rdatasetiter_first(rdsiter);
while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, &set);
if (set.type == dns_rdatatype_ns) {
dns_rdataset_disassociate(&set);
break;
}
dns_rdataset_disassociate(&set);
result = dns_rdatasetiter_next(rdsiter);
}
if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
fatal("rdataset iteration failed: %s",
isc_result_totext(result));
if (result == ISC_R_SUCCESS) {
if (lastcut != NULL)
dns_name_free(lastcut, mctx);
else {
lastcut = isc_mem_get(mctx,
sizeof(dns_name_t));
if (lastcut == NULL)
fatal("out of memory");
}
dns_name_init(lastcut, NULL);
result = dns_name_dup(curname, mctx, lastcut);
check_result(result, "dns_name_dup()");
}
dns_rdatasetiter_destroy(&rdsiter);
}
result = dns_dbiterator_next(dbiter);
if (result == ISC_R_SUCCESS)
result = next_nonglue(db, version, dbiter, nextname,
&nextnode, origin, lastcut);
if (result == ISC_R_SUCCESS)
target = nextname;
else if (result == ISC_R_NOMORE)
target = origin;
else {
target = NULL; /* Make compiler happy. */
fatal("iterating through the database failed: %s",
isc_result_totext(result));
}
nxtresult = dns_buildnxt(db, version, node, target, zonettl);
check_result(nxtresult, "dns_buildnxt()");
signname(db, version, node, curname, atorigin);
atorigin = ISC_FALSE;
dns_db_detachnode(db, &node);
dns_db_detachnode(db, &curnode);
node = nextnode;
}
if (result != ISC_R_NOMORE)
fatal("iterating through the database failed: %s",
isc_result_totext(result));
if (lastcut != NULL) {
dns_name_free(lastcut, mctx);
isc_mem_put(mctx, lastcut, sizeof(dns_name_t));
}
dns_dbiterator_destroy(&dbiter);
}
static void
loadzone(char *file, char *origin, dns_db_t **db) {
isc_buffer_t b, b2;
unsigned char namedata[1024];
int len;
dns_name_t name;
isc_result_t result;
len = strlen(origin);
isc_buffer_init(&b, origin, len);
isc_buffer_add(&b, len);
isc_buffer_init(&b2, namedata, sizeof(namedata));
dns_name_init(&name, NULL);
result = dns_name_fromtext(&name, &b, dns_rootname, ISC_FALSE, &b2);
if (result != ISC_R_SUCCESS)
fatal("failed converting name '%s' to dns format: %s",
origin, isc_result_totext(result));
result = dns_db_create(mctx, "rbt", &name, dns_dbtype_zone,
dns_rdataclass_in, 0, NULL, db);
check_result(result, "dns_db_create()");
result = dns_db_load(*db, file);
if (result != ISC_R_SUCCESS)
fatal("failed loading zone from '%s': %s",
file, isc_result_totext(result));
}
static void
getversion(dns_db_t *db, dns_dbversion_t **version) {
isc_result_t result;
result = dns_db_newversion(db, version);
check_result(result, "dns_db_newversion()");
}
/*
* Finds all public zone keys in the zone, and attempts to load the
* private keys from disk.
*/
static void
loadzonekeys(dns_db_t *db, dns_dbversion_t *version) {
dns_name_t *origin;
dns_dbnode_t *node;
isc_result_t result;
dst_key_t *keys[20];
unsigned int nkeys, i;
origin = dns_db_origin(db);
node = NULL;
result = dns_db_findnode(db, origin, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS)
fatal("failed to find the zone's origin: %s",
isc_result_totext(result));
result = dns_dnssec_findzonekeys(db, version, node, origin, mctx,
20, keys, &nkeys);
if (result == ISC_R_NOTFOUND)
result = ISC_R_SUCCESS;
if (result != ISC_R_SUCCESS)
fatal("failed to find the zone keys: %s",
isc_result_totext(result));
for (i = 0; i < nkeys; i++) {
signer_key_t *key;
key = isc_mem_get(mctx, sizeof(signer_key_t));
if (key == NULL)
fatal("out of memory");
key->key = keys[i];
key->isdefault = ISC_FALSE;
ISC_LIST_APPEND(keylist, key, link);
}
dns_db_detachnode(db, &node);
}
static isc_stdtime_t
strtotime(char *str, isc_int64_t now, isc_int64_t base) {
isc_int64_t val, offset;
isc_result_t result;
char *endp;
if (str[0] == '+') {
offset = strtol(str + 1, &endp, 0);
if (*endp != '\0')
fatal("time value %s is invalid", str);
val = base + offset;
} else if (strncmp(str, "now+", 4) == 0) {
offset = strtol(str + 4, &endp, 0);
if (*endp != '\0')
fatal("time value %s is invalid", str);
val = now + offset;
} else {
result = dns_time64_fromtext(str, &val);
if (result != ISC_R_SUCCESS)
fatal("time %s must be numeric", str);
}
return ((isc_stdtime_t) val);
}
static void
usage(void) {
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\t%s [options] zonefile [keys]\n", program);
fprintf(stderr, "\n");
fprintf(stderr, "Options: (default value in parenthesis) \n");
fprintf(stderr, "\t-s YYYYMMDDHHMMSS|+offset:\n");
fprintf(stderr, "\t\tSIG start time - absolute|offset (now)\n");
fprintf(stderr, "\t-e YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
fprintf(stderr, "\t\tSIG end time - absolute|from start|from now "
"(now + 30 days)\n");
fprintf(stderr, "\t-c ttl:\n");
fprintf(stderr, "\t\tcycle period - regenerate "
"if < cycle from end ( (end-start)/4 )\n");
fprintf(stderr, "\t-v level:\n");
fprintf(stderr, "\t\tverbose level (0)\n");
fprintf(stderr, "\t-o origin:\n");
fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
fprintf(stderr, "\t-f outfile:\n");
fprintf(stderr, "\t\tfile the signed zone is written in "
"(zonefile + .signed)\n");
fprintf(stderr, "\t-a\n");
fprintf(stderr, "\t\tverify generated signatures\n");
fprintf(stderr, "\t-p\n");
fprintf(stderr, "\t\tuse pseudorandom data (faster but less secure)\n");
fprintf(stderr, "\t-r randomdev:\n");
fprintf(stderr, "\t\ta file containing random data\n");
fprintf(stderr, "\n");
fprintf(stderr, "Signing Keys: ");
fprintf(stderr, "(default: all zone keys that have private keys)\n");
fprintf(stderr, "\tkeyfile (Kname+alg+id)\n");
exit(0);
}
int
main(int argc, char *argv[]) {
int i, ch;
char *startstr = NULL, *endstr = NULL;
char *origin = NULL, *file = NULL, *output = NULL;
char *randomfile = NULL;
char *endp;
dns_db_t *db;
dns_dbversion_t *version;
signer_key_t *key;
isc_result_t result;
isc_log_t *log = NULL;
isc_boolean_t pseudorandom = ISC_FALSE;
unsigned int eflags;
result = isc_mem_create(0, 0, &mctx);
if (result != ISC_R_SUCCESS)
fatal("out of memory");
dns_result_register();
while ((ch = isc_commandline_parse(argc, argv, "s:e:c:v:o:f:ahpr:"))
!= -1) {
switch (ch) {
case 's':
startstr = isc_mem_strdup(mctx,
isc_commandline_argument);
if (startstr == NULL)
fatal("out of memory");
break;
case 'e':
endstr = isc_mem_strdup(mctx,
isc_commandline_argument);
if (endstr == NULL)
fatal("out of memory");
break;
case 'c':
endp = NULL;
cycle = strtol(isc_commandline_argument, &endp, 0);
if (*endp != '\0')
fatal("cycle period must be numeric");
break;
case 'p':
pseudorandom = ISC_TRUE;
break;
case 'r':
randomfile = isc_mem_strdup(mctx,
isc_commandline_argument);
if (randomfile == NULL)
fatal("out of memory");
break;
case 'v':
endp = NULL;
verbose = strtol(isc_commandline_argument, &endp, 0);
if (*endp != '\0')
fatal("verbose level must be numeric");
break;
case 'o':
origin = isc_mem_strdup(mctx,
isc_commandline_argument);
if (origin == NULL)
fatal("out of memory");
break;
case 'f':
output = isc_mem_strdup(mctx,
isc_commandline_argument);
if (output == NULL)
fatal("out of memory");
break;
case 'a':
tryverify = ISC_TRUE;
break;
case 'h':
default:
usage();
}
}
setup_entropy(mctx, randomfile, &ectx);
if (randomfile != NULL)
isc_mem_free(mctx, randomfile);
eflags = ISC_ENTROPY_BLOCKING;
if (!pseudorandom)
eflags |= ISC_ENTROPY_GOODONLY;
result = dst_lib_init(mctx, ectx, eflags);
if (result != ISC_R_SUCCESS)
fatal("could not initialize dst");
isc_stdtime_get(&now);
if (startstr != NULL) {
starttime = strtotime(startstr, now, now);
isc_mem_free(mctx, startstr);
}
else
starttime = now;
if (endstr != NULL) {
endtime = strtotime(endstr, now, starttime);
isc_mem_free(mctx, endstr);
}
else
endtime = starttime + (30 * 24 * 60 * 60);
if (cycle == -1) {
cycle = (endtime - starttime) / 4;
}
setup_logging(verbose, mctx, &log);
argc -= isc_commandline_index;
argv += isc_commandline_index;
if (argc < 1)
usage();
file = isc_mem_strdup(mctx, argv[0]);
if (file == NULL)
fatal("out of memory");
argc -= 1;
argv += 1;
if (output == NULL) {
output = isc_mem_allocate(mctx,
strlen(file) + strlen(".signed") + 1);
if (output == NULL)
fatal("out of memory");
sprintf(output, "%s.signed", file);
}
if (origin == NULL) {
origin = isc_mem_allocate(mctx, strlen(file) + 2);
if (origin == NULL)
fatal("out of memory");
strcpy(origin, file);
if (file[strlen(file) - 1] != '.')
strcat(origin, ".");
}
db = NULL;
loadzone(file, origin, &db);
version = NULL;
getversion(db, &version);
ISC_LIST_INIT(keylist);
loadzonekeys(db, version);
if (argc == 0) {
signer_key_t *key;
key = ISC_LIST_HEAD(keylist);
while (key != NULL) {
key->isdefault = ISC_TRUE;
key = ISC_LIST_NEXT(key, link);
}
}
else {
for (i = 0; i < argc; i++) {
dst_key_t *newkey = NULL;
result = dst_key_fromnamedfile(argv[i],
DST_TYPE_PRIVATE,
mctx, &newkey);
if (result != ISC_R_SUCCESS)
usage();
key = ISC_LIST_HEAD(keylist);
while (key != NULL) {
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),
dst_key_name(newkey)))
{
key->isdefault = ISC_TRUE;
if (!dst_key_isprivate(dkey))
fatal("cannot sign zone with "
"non-private key %s",
argv[i]);
break;
}
key = ISC_LIST_NEXT(key, link);
}
if (key == NULL) {
key = isc_mem_get(mctx, sizeof(signer_key_t));
if (key == NULL)
fatal("out of memory");
key->key = newkey;
key->isdefault = ISC_TRUE;
ISC_LIST_APPEND(keylist, key, link);
}
else
dst_key_free(&newkey);
}
}
signzone(db, version);
/*
* Should we update the SOA serial?
*/
result = dns_db_dump(db, version, output);
if (result != ISC_R_SUCCESS)
fatal("failed to write new database to '%s': %s",
output, isc_result_totext(result));
dns_db_closeversion(db, &version, ISC_TRUE);
dns_db_detach(&db);
key = ISC_LIST_HEAD(keylist);
while (key != NULL) {
signer_key_t *next = ISC_LIST_NEXT(key, link);
dst_key_free(&key->key);
isc_mem_put(mctx, key, sizeof(signer_key_t));
key = next;
}
isc_mem_free(mctx, origin);
isc_mem_free(mctx, file);
isc_mem_free(mctx, output);
if (log != NULL)
isc_log_destroy(&log);
cleanup_entropy(&ectx);
dst_lib_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
isc_mem_destroy(&mctx);
return (0);
}