summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/bin/dnssec/dnssec-signzone.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/bin/dnssec/dnssec-signzone.c')
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.c892
1 files changed, 286 insertions, 606 deletions
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.c b/contrib/bind9/bin/dnssec/dnssec-signzone.c
index 86c3aee..83456a7 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.c
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.262.110.9 2011/07/19 23:47:12 tbox Exp $ */
+/* $Id: dnssec-signzone.c,v 1.285 2011/12/22 07:32:39 each Exp $ */
/*! \file */
@@ -37,6 +37,7 @@
#include <stdlib.h>
#include <time.h>
+#include <unistd.h>
#include <isc/app.h>
#include <isc/base32.h>
@@ -124,7 +125,7 @@ struct signer_event {
static dns_dnsseckeylist_t keylist;
static unsigned int keycount = 0;
isc_rwlock_t keylist_lock;
-static isc_stdtime_t starttime = 0, endtime = 0, now;
+static isc_stdtime_t starttime = 0, endtime = 0, dnskey_endtime = 0, now;
static int cycle = -1;
static int jitter = 0;
static isc_boolean_t tryverify = ISC_FALSE;
@@ -133,11 +134,13 @@ static isc_mem_t *mctx = NULL;
static isc_entropy_t *ectx = NULL;
static dns_ttl_t zone_soa_min_ttl;
static dns_ttl_t soa_ttl;
-static FILE *fp;
+static FILE *fp = NULL;
static char *tempfile = NULL;
static const dns_master_style_t *masterstyle;
static dns_masterformat_t inputformat = dns_masterformat_text;
static dns_masterformat_t outputformat = dns_masterformat_text;
+static isc_uint32_t rawversion = 1, serialnum = 0;
+static isc_boolean_t snset = ISC_FALSE;
static unsigned int nsigned = 0, nretained = 0, ndropped = 0;
static unsigned int nverified = 0, nverifyfailed = 0;
static const char *directory = NULL, *dsdir = NULL;
@@ -171,6 +174,10 @@ static isc_boolean_t disable_zone_check = ISC_FALSE;
static isc_boolean_t update_chain = ISC_FALSE;
static isc_boolean_t set_keyttl = ISC_FALSE;
static dns_ttl_t keyttl;
+static isc_boolean_t smartsign = ISC_FALSE;
+static isc_boolean_t remove_orphans = ISC_FALSE;
+static isc_boolean_t output_dnssec_only = ISC_FALSE;
+static isc_boolean_t output_stdout = ISC_FALSE;
#define INCSTAT(counter) \
if (printstats) { \
@@ -182,19 +189,71 @@ static dns_ttl_t keyttl;
static void
sign(isc_task_t *task, isc_event_t *event);
-#define check_dns_dbiterator_current(result) \
- check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \
- "dns_dbiterator_current()")
-
static void
dumpnode(dns_name_t *name, dns_dbnode_t *node) {
+ dns_rdataset_t rds;
+ dns_rdatasetiter_t *iter = NULL;
+ isc_buffer_t *buffer = NULL;
+ isc_region_t r;
isc_result_t result;
+ unsigned bufsize = 4096;
if (outputformat != dns_masterformat_text)
return;
- result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, name,
- masterstyle, fp);
- check_result(result, "dns_master_dumpnodetostream");
+
+ if (!output_dnssec_only) {
+ result = dns_master_dumpnodetostream(mctx, gdb, gversion, node,
+ name, masterstyle, fp);
+ check_result(result, "dns_master_dumpnodetostream");
+ return;
+ }
+
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &iter);
+ check_result(result, "dns_db_allrdatasets");
+
+ dns_rdataset_init(&rds);
+
+ result = isc_buffer_allocate(mctx, &buffer, bufsize);
+ check_result(result, "isc_buffer_allocate");
+
+ for (result = dns_rdatasetiter_first(iter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(iter)) {
+
+ dns_rdatasetiter_current(iter, &rds);
+
+ if (rds.type != dns_rdatatype_rrsig &&
+ rds.type != dns_rdatatype_nsec &&
+ rds.type != dns_rdatatype_nsec3 &&
+ rds.type != dns_rdatatype_nsec3param &&
+ (!smartsign || rds.type != dns_rdatatype_dnskey)) {
+ dns_rdataset_disassociate(&rds);
+ continue;
+ }
+
+ for (;;) {
+ result = dns_master_rdatasettotext(name, &rds,
+ masterstyle, buffer);
+ if (result != ISC_R_NOSPACE)
+ break;
+
+ bufsize <<= 1;
+ isc_buffer_free(&buffer);
+ result = isc_buffer_allocate(mctx, &buffer, bufsize);
+ check_result(result, "isc_buffer_allocate");
+ }
+ check_result(result, "dns_master_rdatasettotext");
+
+ isc_buffer_usedregion(buffer, &r);
+ result = isc_stdio_write(r.base, 1, r.length, fp, NULL);
+ check_result(result, "isc_stdio_write");
+ isc_buffer_clear(buffer);
+
+ dns_rdataset_disassociate(&rds);
+ }
+
+ isc_buffer_free(&buffer);
+ dns_rdatasetiter_destroy(&iter);
}
/*%
@@ -206,7 +265,7 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
dns_ttl_t ttl, dns_diff_t *add, const char *logmsg)
{
isc_result_t result;
- isc_stdtime_t jendtime;
+ isc_stdtime_t jendtime, expiry;
char keystr[DST_KEY_FORMATSIZE];
dns_rdata_t trdata = DNS_RDATA_INIT;
unsigned char array[BUFSIZE];
@@ -216,7 +275,12 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
dst_key_format(key, keystr, sizeof(keystr));
vbprintf(1, "\t%s %s\n", logmsg, keystr);
- jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime;
+ if (rdataset->type == dns_rdatatype_dnskey)
+ expiry = dnskey_endtime;
+ else
+ expiry = endtime;
+
+ jendtime = (jitter != 0) ? isc_random_jitter(expiry, jitter) : expiry;
isc_buffer_init(&b, array, sizeof(array));
result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime,
mctx, &b, &trdata);
@@ -254,6 +318,12 @@ issigningkey(dns_dnsseckey_t *key) {
}
static inline isc_boolean_t
+ispublishedkey(dns_dnsseckey_t *key) {
+ return ((key->force_publish || key->hint_publish) &&
+ !key->hint_remove);
+}
+
+static inline isc_boolean_t
iszonekey(dns_dnsseckey_t *key) {
return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&
dst_key_iszonekey(key->key)));
@@ -334,13 +404,16 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
directory, mctx, &privkey);
if (result == ISC_R_SUCCESS) {
dst_key_free(&pubkey);
- dns_dnsseckey_create(mctx, &privkey, &key);
- } else {
- dns_dnsseckey_create(mctx, &pubkey, &key);
+ result = dns_dnsseckey_create(mctx, &privkey, &key);
+ } else
+ result = dns_dnsseckey_create(mctx, &pubkey, &key);
+
+ if (result == ISC_R_SUCCESS) {
+ key->force_publish = ISC_FALSE;
+ key->force_sign = ISC_FALSE;
+ key->index = keycount++;
+ ISC_LIST_APPEND(keylist, key, link);
}
- key->force_publish = ISC_FALSE;
- key->force_sign = ISC_FALSE;
- ISC_LIST_APPEND(keylist, key, link);
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
return (key);
@@ -481,38 +554,38 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
"private dnskey not found\n",
sigstr);
} else if (key == NULL || future) {
+ keep = (!expired && !remove_orphans);
vbprintf(2, "\trrsig by %s %s - dnskey not found\n",
- expired ? "retained" : "dropped", sigstr);
- if (!expired)
- keep = ISC_TRUE;
+ keep ? "retained" : "dropped", sigstr);
} else if (issigningkey(key)) {
+ wassignedby[key->index] = ISC_TRUE;
+
if (!expired && rrsig.originalttl == set->ttl &&
setverifies(name, set, key->key, &sigrdata)) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
keep = ISC_TRUE;
- wassignedby[key->index] = ISC_TRUE;
- nowsignedby[key->index] = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr, expired ? "expired" :
rrsig.originalttl != set->ttl ?
"ttl change" : "failed to verify");
- wassignedby[key->index] = ISC_TRUE;
resign = ISC_TRUE;
}
+ } else if (!ispublishedkey(key) && remove_orphans) {
+ vbprintf(2, "\trrsig by %s dropped - dnskey removed\n",
+ sigstr);
} else if (iszonekey(key)) {
+ wassignedby[key->index] = ISC_TRUE;
+
if (!expired && rrsig.originalttl == set->ttl &&
setverifies(name, set, key->key, &sigrdata)) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
keep = ISC_TRUE;
- wassignedby[key->index] = ISC_TRUE;
- nowsignedby[key->index] = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr, expired ? "expired" :
rrsig.originalttl != set->ttl ?
"ttl change" : "failed to verify");
- wassignedby[key->index] = ISC_TRUE;
}
} else if (!expired) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
@@ -545,6 +618,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
}
} else {
tuple = NULL;
+ vbprintf(2, "removing signature by %s\n", sigstr);
result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL,
name, sigset.ttl,
&sigrdata, &tuple);
@@ -922,26 +996,6 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
}
static isc_boolean_t
-delegation(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) {
- dns_rdataset_t nsset;
- isc_result_t result;
-
- if (dns_name_equal(name, gorigin))
- return (ISC_FALSE);
-
- dns_rdataset_init(&nsset);
- result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ns,
- 0, 0, &nsset, NULL);
- if (dns_rdataset_isassociated(&nsset)) {
- if (ttlp != NULL)
- *ttlp = nsset.ttl;
- dns_rdataset_disassociate(&nsset);
- }
-
- return (ISC_TF(result == ISC_R_SUCCESS));
-}
-
-static isc_boolean_t
secure(dns_name_t *name, dns_dbnode_t *node) {
dns_rdataset_t dsset;
isc_result_t result;
@@ -976,7 +1030,7 @@ signname(dns_dbnode_t *node, dns_name_t *name) {
/*
* Determine if this is a delegation point.
*/
- if (delegation(name, node, NULL))
+ if (is_delegation(gdb, gversion, gorigin, name, node, NULL))
isdelegation = ISC_TRUE;
/*
@@ -1309,485 +1363,6 @@ postsign(void) {
dns_dbiterator_destroy(&gdbiter);
}
-static isc_boolean_t
-goodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset,
- dns_rdataset_t *rdataset)
-{
- dns_rdata_dnskey_t key;
- dns_rdata_rrsig_t sig;
- dst_key_t *dstkey = NULL;
- isc_result_t result;
-
- dns_rdata_tostruct(sigrdata, &sig, NULL);
-
- for (result = dns_rdataset_first(keyrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(keyrdataset)) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_current(keyrdataset, &rdata);
- dns_rdata_tostruct(&rdata, &key, NULL);
- result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
- &dstkey);
- if (result != ISC_R_SUCCESS)
- return (ISC_FALSE);
- if (sig.algorithm != key.algorithm ||
- sig.keyid != dst_key_id(dstkey) ||
- !dns_name_equal(&sig.signer, gorigin)) {
- dst_key_free(&dstkey);
- continue;
- }
- result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
- mctx, sigrdata);
- dst_key_free(&dstkey);
- if (result == ISC_R_SUCCESS)
- return(ISC_TRUE);
- }
- return (ISC_FALSE);
-}
-
-static void
-verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
- dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
- unsigned char *bad_algorithms)
-{
- unsigned char set_algorithms[256];
- char namebuf[DNS_NAME_FORMATSIZE];
- char algbuf[80];
- char typebuf[80];
- dns_rdataset_t sigrdataset;
- dns_rdatasetiter_t *rdsiter = NULL;
- isc_result_t result;
- int i;
-
- dns_rdataset_init(&sigrdataset);
- result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
- check_result(result, "dns_db_allrdatasets()");
- for (result = dns_rdatasetiter_first(rdsiter);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(rdsiter)) {
- dns_rdatasetiter_current(rdsiter, &sigrdataset);
- if (sigrdataset.type == dns_rdatatype_rrsig &&
- sigrdataset.covers == rdataset->type)
- break;
- dns_rdataset_disassociate(&sigrdataset);
- }
- if (result != ISC_R_SUCCESS) {
- dns_name_format(name, namebuf, sizeof(namebuf));
- type_format(rdataset->type, typebuf, sizeof(typebuf));
- fprintf(stderr, "no signatures for %s/%s\n", namebuf, typebuf);
- for (i = 0; i < 256; i++)
- if (ksk_algorithms[i] != 0)
- bad_algorithms[i] = 1;
- return;
- }
-
- memset(set_algorithms, 0, sizeof(set_algorithms));
- for (result = dns_rdataset_first(&sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&sigrdataset)) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_rrsig_t sig;
-
- dns_rdataset_current(&sigrdataset, &rdata);
- dns_rdata_tostruct(&rdata, &sig, NULL);
- if (rdataset->ttl != sig.originalttl) {
- dns_name_format(name, namebuf, sizeof(namebuf));
- type_format(rdataset->type, typebuf, sizeof(typebuf));
- fprintf(stderr, "TTL mismatch for %s %s keytag %u\n",
- namebuf, typebuf, sig.keyid);
- continue;
- }
- if ((set_algorithms[sig.algorithm] != 0) ||
- (ksk_algorithms[sig.algorithm] == 0))
- continue;
- if (goodsig(&rdata, name, keyrdataset, rdataset))
- set_algorithms[sig.algorithm] = 1;
- }
- dns_rdatasetiter_destroy(&rdsiter);
- if (memcmp(set_algorithms, ksk_algorithms, sizeof(set_algorithms))) {
- dns_name_format(name, namebuf, sizeof(namebuf));
- type_format(rdataset->type, typebuf, sizeof(typebuf));
- for (i = 0; i < 256; i++)
- if ((ksk_algorithms[i] != 0) &&
- (set_algorithms[i] == 0)) {
- dns_secalg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Missing %s signature for "
- "%s %s\n", algbuf, namebuf, typebuf);
- bad_algorithms[i] = 1;
- }
- }
- dns_rdataset_disassociate(&sigrdataset);
-}
-
-static void
-verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
- dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
- unsigned char *bad_algorithms)
-{
- dns_rdataset_t rdataset;
- dns_rdatasetiter_t *rdsiter = NULL;
- isc_result_t result;
-
- result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
- check_result(result, "dns_db_allrdatasets()");
- result = dns_rdatasetiter_first(rdsiter);
- dns_rdataset_init(&rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdatasetiter_current(rdsiter, &rdataset);
- if (rdataset.type != dns_rdatatype_rrsig &&
- rdataset.type != dns_rdatatype_dnskey &&
- (!delegation || rdataset.type == dns_rdatatype_ds ||
- rdataset.type == dns_rdatatype_nsec)) {
- verifyset(&rdataset, name, node, keyrdataset,
- ksk_algorithms, bad_algorithms);
- }
- dns_rdataset_disassociate(&rdataset);
- result = dns_rdatasetiter_next(rdsiter);
- }
- if (result != ISC_R_NOMORE)
- fatal("rdataset iteration failed: %s",
- isc_result_totext(result));
- dns_rdatasetiter_destroy(&rdsiter);
-}
-
-/*%
- * Verify that certain things are sane:
- *
- * The apex has a DNSKEY RRset with at least one KSK, and at least
- * one ZSK if the -x flag was not used.
- *
- * The DNSKEY record was signed with at least one of the KSKs in
- * the DNSKEY RRset.
- *
- * The rest of the zone was signed with at least one of the ZSKs
- * present in the DNSKEY RRset.
- */
-static void
-verifyzone(void) {
- char algbuf[80];
- dns_dbiterator_t *dbiter = NULL;
- dns_dbnode_t *node = NULL, *nextnode = NULL;
- dns_fixedname_t fname, fnextname, fzonecut;
- dns_name_t *name, *nextname, *zonecut;
- dns_rdata_dnskey_t dnskey;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t keyset, soaset;
- dns_rdataset_t keysigs, soasigs;
- int i;
- isc_boolean_t done = ISC_FALSE;
- isc_boolean_t first = ISC_TRUE;
- isc_boolean_t goodksk = ISC_FALSE;
- isc_result_t result;
- unsigned char revoked_ksk[256];
- unsigned char revoked_zsk[256];
- unsigned char standby_ksk[256];
- unsigned char standby_zsk[256];
- unsigned char ksk_algorithms[256];
- unsigned char zsk_algorithms[256];
- unsigned char bad_algorithms[256];
-#ifdef ALLOW_KSKLESS_ZONES
- isc_boolean_t allzsksigned = ISC_TRUE;
- unsigned char self_algorithms[256];
-#endif
-
- if (disable_zone_check)
- return;
-
- result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- fatal("failed to find the zone's origin: %s",
- isc_result_totext(result));
-
- dns_rdataset_init(&keyset);
- dns_rdataset_init(&keysigs);
- dns_rdataset_init(&soaset);
- dns_rdataset_init(&soasigs);
-
- result = dns_db_findrdataset(gdb, node, gversion,
- dns_rdatatype_dnskey,
- 0, 0, &keyset, &keysigs);
- if (result != ISC_R_SUCCESS)
- fatal("cannot find DNSKEY rrset\n");
-
- result = dns_db_findrdataset(gdb, node, gversion,
- dns_rdatatype_soa,
- 0, 0, &soaset, &soasigs);
- dns_db_detachnode(gdb, &node);
- if (result != ISC_R_SUCCESS)
- fatal("cannot find SOA rrset\n");
-
- if (!dns_rdataset_isassociated(&keysigs))
- fatal("cannot find DNSKEY RRSIGs\n");
-
- if (!dns_rdataset_isassociated(&soasigs))
- fatal("cannot find SOA RRSIGs\n");
-
- memset(revoked_ksk, 0, sizeof(revoked_ksk));
- memset(revoked_zsk, 0, sizeof(revoked_zsk));
- memset(standby_ksk, 0, sizeof(standby_ksk));
- memset(standby_zsk, 0, sizeof(standby_zsk));
- memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
- memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
- memset(bad_algorithms, 0, sizeof(bad_algorithms));
-#ifdef ALLOW_KSKLESS_ZONES
- memset(self_algorithms, 0, sizeof(self_algorithms));
-#endif
-
- /*
- * Check that the DNSKEY RR has at least one self signing KSK
- * and one ZSK per algorithm in it (or, if -x was used, one
- * self-signing KSK).
- */
- for (result = dns_rdataset_first(&keyset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&keyset)) {
- dns_rdataset_current(&keyset, &rdata);
- result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
- check_result(result, "dns_rdata_tostruct");
-
- if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0)
- ;
- else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
- if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
- !dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
- &keysigs, ISC_FALSE,
- mctx)) {
- char namebuf[DNS_NAME_FORMATSIZE];
- char buffer[1024];
- isc_buffer_t buf;
-
- dns_name_format(gorigin, namebuf,
- sizeof(namebuf));
- isc_buffer_init(&buf, buffer, sizeof(buffer));
- result = dns_rdata_totext(&rdata, NULL, &buf);
- check_result(result, "dns_rdata_totext");
- fatal("revoked KSK is not self signed:\n"
- "%s DNSKEY %.*s", namebuf,
- (int)isc_buffer_usedlength(&buf), buffer);
- }
- if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
- revoked_ksk[dnskey.algorithm] != 255)
- revoked_ksk[dnskey.algorithm]++;
- else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
- revoked_zsk[dnskey.algorithm] != 255)
- revoked_zsk[dnskey.algorithm]++;
- } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
- if (dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
- &keysigs, ISC_FALSE, mctx)) {
- if (ksk_algorithms[dnskey.algorithm] != 255)
- ksk_algorithms[dnskey.algorithm]++;
- goodksk = ISC_TRUE;
- } else {
- if (standby_ksk[dnskey.algorithm] != 255)
- standby_ksk[dnskey.algorithm]++;
- }
- } else if (dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
- &keysigs, ISC_FALSE,
- mctx)) {
-#ifdef ALLOW_KSKLESS_ZONES
- if (self_algorithms[dnskey.algorithm] != 255)
- self_algorithms[dnskey.algorithm]++;
-#endif
- if (zsk_algorithms[dnskey.algorithm] != 255)
- zsk_algorithms[dnskey.algorithm]++;
- } else if (dns_dnssec_signs(&rdata, gorigin, &soaset,
- &soasigs, ISC_FALSE, mctx)) {
- if (zsk_algorithms[dnskey.algorithm] != 255)
- zsk_algorithms[dnskey.algorithm]++;
- } else {
- if (standby_zsk[dnskey.algorithm] != 255)
- standby_zsk[dnskey.algorithm]++;
-#ifdef ALLOW_KSKLESS_ZONES
- allzsksigned = ISC_FALSE;
-#endif
- }
- dns_rdata_freestruct(&dnskey);
- dns_rdata_reset(&rdata);
- }
- dns_rdataset_disassociate(&keysigs);
- dns_rdataset_disassociate(&soaset);
- dns_rdataset_disassociate(&soasigs);
-
-#ifdef ALLOW_KSKLESS_ZONES
- if (!goodksk) {
- if (!ignore_kskflag)
- fprintf(stderr, "No self signing KSK found. Using "
- "self signed ZSK's for active "
- "algorithm list.\n");
- memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms));
- if (!allzsksigned)
- fprintf(stderr, "warning: not all ZSK's are self "
- "signed.\n");
- }
-#else
- if (!goodksk) {
- fatal("No self signed KSK's found");
- }
-#endif
-
- fprintf(stderr, "Verifying the zone using the following algorithms:");
- for (i = 0; i < 256; i++) {
-#ifdef ALLOW_KSKLESS_ZONES
- if (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0)
-#else
- if (ksk_algorithms[i] != 0)
-#endif
- {
- dns_secalg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, " %s", algbuf);
- }
- }
- fprintf(stderr, ".\n");
-
- if (!ignore_kskflag && !keyset_kskonly) {
- for (i = 0; i < 256; i++) {
- /*
- * The counts should both be zero or both be non-zero.
- * Mark the algorithm as bad if this is not met.
- */
- if ((ksk_algorithms[i] != 0) ==
- (zsk_algorithms[i] != 0))
- continue;
- dns_secalg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Missing %s for algorithm %s\n",
- (ksk_algorithms[i] != 0)
- ? "ZSK"
- : "self signing KSK",
- algbuf);
- bad_algorithms[i] = 1;
- }
- }
-
- /*
- * Check that all the other records were signed by keys that are
- * present in the DNSKEY RRSET.
- */
-
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
- dns_fixedname_init(&fnextname);
- nextname = dns_fixedname_name(&fnextname);
- dns_fixedname_init(&fzonecut);
- zonecut = NULL;
-
- result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
- check_result(result, "dns_db_createiterator()");
-
- result = dns_dbiterator_first(dbiter);
- check_result(result, "dns_dbiterator_first()");
-
- while (!done) {
- isc_boolean_t isdelegation = ISC_FALSE;
-
- result = dns_dbiterator_current(dbiter, &node, name);
- check_dns_dbiterator_current(result);
- if (!dns_name_issubdomain(name, gorigin)) {
- dns_db_detachnode(gdb, &node);
- result = dns_dbiterator_next(dbiter);
- if (result == ISC_R_NOMORE)
- done = ISC_TRUE;
- else
- check_result(result, "dns_dbiterator_next()");
- continue;
- }
- if (delegation(name, node, NULL)) {
- zonecut = dns_fixedname_name(&fzonecut);
- dns_name_copy(name, zonecut, NULL);
- isdelegation = ISC_TRUE;
- }
- verifynode(name, node, isdelegation, &keyset,
- ksk_algorithms, bad_algorithms);
- result = dns_dbiterator_next(dbiter);
- nextnode = NULL;
- while (result == ISC_R_SUCCESS) {
- result = dns_dbiterator_current(dbiter, &nextnode,
- nextname);
- check_dns_dbiterator_current(result);
- if (!dns_name_issubdomain(nextname, gorigin) ||
- (zonecut != NULL &&
- dns_name_issubdomain(nextname, zonecut)))
- {
- dns_db_detachnode(gdb, &nextnode);
- result = dns_dbiterator_next(dbiter);
- continue;
- }
- dns_db_detachnode(gdb, &nextnode);
- break;
- }
- if (result == ISC_R_NOMORE) {
- done = ISC_TRUE;
- } else if (result != ISC_R_SUCCESS)
- fatal("iterating through the database failed: %s",
- isc_result_totext(result));
- dns_db_detachnode(gdb, &node);
- }
-
- dns_dbiterator_destroy(&dbiter);
-
- result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
- check_result(result, "dns_db_createiterator()");
-
- for (result = dns_dbiterator_first(dbiter);
- result == ISC_R_SUCCESS;
- result = dns_dbiterator_next(dbiter) ) {
- result = dns_dbiterator_current(dbiter, &node, name);
- check_dns_dbiterator_current(result);
- verifynode(name, node, ISC_FALSE, &keyset,
- ksk_algorithms, bad_algorithms);
- dns_db_detachnode(gdb, &node);
- }
- dns_dbiterator_destroy(&dbiter);
-
- dns_rdataset_disassociate(&keyset);
-
- /*
- * If we made it this far, we have what we consider a properly signed
- * zone. Set the good flag.
- */
- for (i = 0; i < 256; i++) {
- if (bad_algorithms[i] != 0) {
- if (first)
- fprintf(stderr, "The zone is not fully signed "
- "for the following algorithms:");
- dns_secalg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, " %s", algbuf);
- first = ISC_FALSE;
- }
- }
- if (!first) {
- fprintf(stderr, ".\n");
- fatal("DNSSEC completeness test failed.");
- }
-
- if (goodksk || ignore_kskflag) {
- /*
- * Print the success summary.
- */
- fprintf(stderr, "Zone signing complete:\n");
- for (i = 0; i < 256; i++) {
- if ((ksk_algorithms[i] != 0) ||
- (standby_ksk[i] != 0) ||
- (revoked_zsk[i] != 0) ||
- (zsk_algorithms[i] != 0) ||
- (standby_zsk[i] != 0) ||
- (revoked_zsk[i] != 0)) {
- dns_secalg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Algorithm: %s: KSKs: "
- "%u active, %u stand-by, %u revoked\n",
- algbuf, ksk_algorithms[i],
- standby_ksk[i], revoked_ksk[i]);
- fprintf(stderr, "%*sZSKs: "
- "%u active, %u %s, %u revoked\n",
- (int) strlen(algbuf) + 13, "",
- zsk_algorithms[i],
- standby_zsk[i],
- keyset_kskonly ? "present" : "stand-by",
- revoked_zsk[i]);
- }
- }
- }
-}
-
/*%
* Sign the apex of the zone.
* Note the origin may not be the first node if there are out of zone
@@ -1885,7 +1460,7 @@ assignwork(isc_task_t *task, isc_task_t *worker) {
if (dns_name_issubdomain(name, gorigin) &&
(zonecut == NULL ||
!dns_name_issubdomain(name, zonecut))) {
- if (delegation(name, node, NULL)) {
+ if (is_delegation(gdb, gversion, gorigin, name, node, NULL)) {
dns_fixedname_init(&fzonecut);
zonecut = dns_fixedname_name(&fzonecut);
dns_name_copy(name, zonecut, NULL);
@@ -2181,7 +1756,7 @@ nsecify(void) {
remove_records(node, dns_rdatatype_nsec3param,
ISC_TRUE);
- if (delegation(name, node, &nsttl)) {
+ if (is_delegation(gdb, gversion, gorigin, name, node, &nsttl)) {
zonecut = dns_fixedname_name(&fzonecut);
dns_name_copy(name, zonecut, NULL);
remove_sigs(node, 0);
@@ -2622,7 +2197,9 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
result = dns_dbiterator_next(dbiter);
continue;
}
- if (delegation(nextname, nextnode, &nsttl)) {
+ if (is_delegation(gdb, gversion, gorigin,
+ nextname, nextnode, &nsttl))
+ {
zonecut = dns_fixedname_name(&fzonecut);
dns_name_copy(nextname, zonecut, NULL);
remove_sigs(nextnode, 0);
@@ -2751,7 +2328,9 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
result = dns_dbiterator_next(dbiter);
continue;
}
- if (delegation(nextname, nextnode, NULL)) {
+ if (is_delegation(gdb, gversion, gorigin,
+ nextname, nextnode, NULL))
+ {
zonecut = dns_fixedname_name(&fzonecut);
dns_name_copy(nextname, zonecut, NULL);
if (OPTOUT(nsec3flags) &&
@@ -3324,10 +2903,16 @@ usage(void) {
fprintf(stderr, "update DS records based on child zones' "
"dsset-* files\n");
fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n");
- fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n");
+ fprintf(stderr, "\t\tRRSIG start time "
+ "- absolute|offset (now - 1 hour)\n");
fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
- fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now "
+ fprintf(stderr, "\t\tRRSIG end time "
+ "- absolute|from start|from now "
"(now + 30 days)\n");
+ fprintf(stderr, "\t-X [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
+ fprintf(stderr, "\t\tDNSKEY RRSIG end "
+ "- absolute|from start|from now "
+ "(matches -e)\n");
fprintf(stderr, "\t-i interval:\n");
fprintf(stderr, "\t\tcycle interval - resign "
"if < interval from end ( (end-start)/4 )\n");
@@ -3345,6 +2930,8 @@ usage(void) {
fprintf(stderr, "\t\tfile format of signed zone file (text)\n");
fprintf(stderr, "\t-N format:\n");
fprintf(stderr, "\t\tsoa serial format of signed zone file (keep)\n");
+ fprintf(stderr, "\t-D:\n");
+ fprintf(stderr, "\t\toutput only DNSSEC-related records\n");
fprintf(stderr, "\t-r randomdev:\n");
fprintf(stderr, "\t\ta file containing random data\n");
fprintf(stderr, "\t-a:\t");
@@ -3361,6 +2948,8 @@ usage(void) {
fprintf(stderr, "use pseudorandom data (faster but less secure)\n");
fprintf(stderr, "\t-P:\t");
fprintf(stderr, "disable post-sign verification\n");
+ fprintf(stderr, "\t-R:\t");
+ fprintf(stderr, "remove signatures from keys that no longer exist\n");
fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n");
fprintf(stderr, "\t-t:\t");
fprintf(stderr, "print statistics\n");
@@ -3398,36 +2987,39 @@ print_stats(isc_time_t *timer_start, isc_time_t *timer_finish,
isc_uint64_t time_us; /* Time in microseconds */
isc_uint64_t time_ms; /* Time in milliseconds */
isc_uint64_t sig_ms; /* Signatures per millisecond */
+ FILE *out = output_stdout ? stderr : stdout;
- printf("Signatures generated: %10d\n", nsigned);
- printf("Signatures retained: %10d\n", nretained);
- printf("Signatures dropped: %10d\n", ndropped);
- printf("Signatures successfully verified: %10d\n", nverified);
- printf("Signatures unsuccessfully verified: %10d\n", nverifyfailed);
+ fprintf(out, "Signatures generated: %10d\n", nsigned);
+ fprintf(out, "Signatures retained: %10d\n", nretained);
+ fprintf(out, "Signatures dropped: %10d\n", ndropped);
+ fprintf(out, "Signatures successfully verified: %10d\n", nverified);
+ fprintf(out, "Signatures unsuccessfully "
+ "verified: %10d\n", nverifyfailed);
time_us = isc_time_microdiff(sign_finish, sign_start);
time_ms = time_us / 1000;
- printf("Signing time in seconds: %7u.%03u\n",
- (unsigned int) (time_ms / 1000),
- (unsigned int) (time_ms % 1000));
+ fprintf(out, "Signing time in seconds: %7u.%03u\n",
+ (unsigned int) (time_ms / 1000),
+ (unsigned int) (time_ms % 1000));
if (time_us > 0) {
sig_ms = ((isc_uint64_t)nsigned * 1000000000) / time_us;
- printf("Signatures per second: %7u.%03u\n",
- (unsigned int) sig_ms / 1000,
- (unsigned int) sig_ms % 1000);
+ fprintf(out, "Signatures per second: %7u.%03u\n",
+ (unsigned int) sig_ms / 1000,
+ (unsigned int) sig_ms % 1000);
}
time_us = isc_time_microdiff(timer_finish, timer_start);
time_ms = time_us / 1000;
- printf("Runtime in seconds: %7u.%03u\n",
- (unsigned int) (time_ms / 1000),
- (unsigned int) (time_ms % 1000));
+ fprintf(out, "Runtime in seconds: %7u.%03u\n",
+ (unsigned int) (time_ms / 1000),
+ (unsigned int) (time_ms % 1000));
}
int
main(int argc, char *argv[]) {
int i, ch;
char *startstr = NULL, *endstr = NULL, *classname = NULL;
+ char *dnskey_endstr = NULL;
char *origin = NULL, *file = NULL, *output = NULL;
char *inputformatstr = NULL, *outputformatstr = NULL;
char *serialformatstr = NULL;
@@ -3447,20 +3039,20 @@ main(int argc, char *argv[]) {
#endif
unsigned int eflags;
isc_boolean_t free_output = ISC_FALSE;
- int tempfilelen;
+ int tempfilelen = 0;
dns_rdataclass_t rdclass;
isc_task_t **tasks = NULL;
isc_buffer_t b;
int len;
hashlist_t hashlist;
- isc_boolean_t smartsign = ISC_FALSE;
isc_boolean_t make_keyset = ISC_FALSE;
isc_boolean_t set_salt = ISC_FALSE;
isc_boolean_t set_optout = ISC_FALSE;
isc_boolean_t set_iter = ISC_FALSE;
+ isc_boolean_t nonsecify = ISC_FALSE;
#define CMDLINE_FLAGS \
- "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:xz"
+ "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:n:N:o:O:PpRr:s:ST:tuUv:X:xzZ:"
/*
* Process memory debugging argument first.
@@ -3546,6 +3138,10 @@ main(int argc, char *argv[]) {
dsdir, isc_result_totext(result));
break;
+ case 'D':
+ output_dnssec_only = ISC_TRUE;
+ break;
+
case 'E':
engine = isc_commandline_argument;
break;
@@ -3556,6 +3152,8 @@ main(int argc, char *argv[]) {
case 'f':
output = isc_commandline_argument;
+ if (strcmp(output, "-") == 0)
+ output_stdout = ISC_TRUE;
break;
case 'g':
@@ -3604,6 +3202,17 @@ main(int argc, char *argv[]) {
dskeyfile[ndskeys++] = isc_commandline_argument;
break;
+ case 'L':
+ snset = ISC_TRUE;
+ endp = NULL;
+ serialnum = strtol(isc_commandline_argument, &endp, 0);
+ if (*endp != '\0') {
+ fprintf(stderr, "source serial number "
+ "must be numeric");
+ exit(1);
+ }
+ break;
+
case 'l':
len = strlen(isc_commandline_argument);
isc_buffer_init(&b, isc_commandline_argument, len);
@@ -3646,6 +3255,10 @@ main(int argc, char *argv[]) {
pseudorandom = ISC_TRUE;
break;
+ case 'R':
+ remove_orphans = ISC_TRUE;
+ break;
+
case 'r':
setup_entropy(mctx, isc_commandline_argument, &ectx);
break;
@@ -3683,6 +3296,10 @@ main(int argc, char *argv[]) {
fatal("verbose level must be numeric");
break;
+ case 'X':
+ dnskey_endstr = isc_commandline_argument;
+ break;
+
case 'x':
keyset_kskonly = ISC_TRUE;
break;
@@ -3705,6 +3322,10 @@ main(int argc, char *argv[]) {
fprintf(stderr, "%s: unhandled option -%c\n",
program, isc_commandline_option);
exit(1);
+ case 'Z': /* Undocumented test options */
+ if (!strcmp(isc_commandline_argument, "nonsecify"))
+ nonsecify = ISC_TRUE;
+ break;
}
}
@@ -3730,11 +3351,19 @@ main(int argc, char *argv[]) {
} else
starttime = now - 3600; /* Allow for some clock skew. */
- if (endstr != NULL) {
+ if (endstr != NULL)
endtime = strtotime(endstr, now, starttime);
- } else
+ else
endtime = starttime + (30 * 24 * 60 * 60);
+ if (dnskey_endstr != NULL) {
+ dnskey_endtime = strtotime(dnskey_endstr, now, starttime);
+ if (endstr != NULL && dnskey_endtime == endtime)
+ fprintf(stderr, "WARNING: -e and -X were both set, "
+ "but have identical values.\n");
+ } else
+ dnskey_endtime = endtime;
+
if (cycle == -1)
cycle = (endtime - starttime) / 4;
@@ -3777,16 +3406,36 @@ main(int argc, char *argv[]) {
inputformat = dns_masterformat_text;
else if (strcasecmp(inputformatstr, "raw") == 0)
inputformat = dns_masterformat_raw;
- else
- fatal("unknown file format: %s\n", inputformatstr);
+ else if (strncasecmp(inputformatstr, "raw=", 4) == 0) {
+ inputformat = dns_masterformat_raw;
+ fprintf(stderr,
+ "WARNING: input format version ignored\n");
+ } else
+ fatal("unknown file format: %s", inputformatstr);
+
}
if (outputformatstr != NULL) {
- if (strcasecmp(outputformatstr, "text") == 0)
+ if (strcasecmp(outputformatstr, "text") == 0) {
outputformat = dns_masterformat_text;
- else if (strcasecmp(outputformatstr, "raw") == 0)
+ } else if (strcasecmp(outputformatstr, "full") == 0) {
+ outputformat = dns_masterformat_text;
+ masterstyle = &dns_master_style_full;
+ } else if (strcasecmp(outputformatstr, "raw") == 0) {
outputformat = dns_masterformat_raw;
- else
+ } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) {
+ char *end;
+ outputformat = dns_masterformat_raw;
+
+ outputformat = dns_masterformat_raw;
+ rawversion = strtol(outputformatstr + 4, &end, 10);
+ if (end == outputformatstr + 4 || *end != '\0' ||
+ rawversion > 1U) {
+ fprintf(stderr,
+ "unknown raw format version\n");
+ exit(1);
+ }
+ } else
fatal("unknown file format: %s\n", outputformatstr);
}
@@ -3803,6 +3452,12 @@ main(int argc, char *argv[]) {
serialformatstr);
}
+ if (output_dnssec_only && outputformat != dns_masterformat_text)
+ fatal("option -D can only be used with \"-O text\"\n");
+
+ if (output_dnssec_only && serialformat != SOA_SERIAL_KEEP)
+ fatal("option -D can only be used with \"-N keep\"\n");
+
result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL,
0, 24, 0, 0, 0, 8, mctx);
check_result(result, "dns_master_stylecreate");
@@ -3826,18 +3481,6 @@ main(int argc, char *argv[]) {
else
set_nsec3params(update_chain, set_salt, set_optout, set_iter);
- if (IS_NSEC3) {
- isc_boolean_t answer;
- hash_length = dns_nsec3_hashlength(dns_hash_sha1);
- hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2,
- hash_length);
- result = dns_nsec_nseconly(gdb, gversion, &answer);
- check_result(result, "dns_nsec_nseconly");
- if (answer)
- fatal("NSEC3 generation requested with "
- "NSEC only DNSKEY");
- }
-
/*
* We need to do this early on, as we start messing with the list
* of keys rather early.
@@ -3890,6 +3533,22 @@ main(int argc, char *argv[]) {
if (IS_NSEC3) {
unsigned int max;
+ isc_boolean_t answer;
+
+ hash_length = dns_nsec3_hashlength(dns_hash_sha1);
+ hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2,
+ hash_length);
+ result = dns_nsec_nseconly(gdb, gversion, &answer);
+ if (result == ISC_R_NOTFOUND)
+ fprintf(stderr, "%s: warning: NSEC3 generation "
+ "requested with no DNSKEY; ignoring\n",
+ program);
+ else if (result != ISC_R_SUCCESS)
+ check_result(result, "dns_nsec_nseconly");
+ else if (answer)
+ fatal("NSEC3 generation requested with "
+ "NSEC-only DNSKEY");
+
result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max);
check_result(result, "dns_nsec3_maxiterations()");
if (nsec3iter > max)
@@ -3916,11 +3575,13 @@ main(int argc, char *argv[]) {
remove_duplicates();
- if (IS_NSEC3)
- nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
- &hashlist);
- else
- nsecify();
+ if (!nonsecify) {
+ if (IS_NSEC3)
+ nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
+ &hashlist);
+ else
+ nsecify();
+ }
if (!nokeys) {
writeset("dsset-", dns_rdatatype_ds);
@@ -3931,24 +3592,29 @@ main(int argc, char *argv[]) {
}
}
- tempfilelen = strlen(output) + 20;
- tempfile = isc_mem_get(mctx, tempfilelen);
- if (tempfile == NULL)
- fatal("out of memory");
+ if (output_stdout) {
+ fp = stdout;
+ if (outputformatstr == NULL)
+ masterstyle = &dns_master_style_full;
+ } else {
+ tempfilelen = strlen(output) + 20;
+ tempfile = isc_mem_get(mctx, tempfilelen);
+ if (tempfile == NULL)
+ fatal("out of memory");
- result = isc_file_mktemplate(output, tempfile, tempfilelen);
- check_result(result, "isc_file_mktemplate");
+ result = isc_file_mktemplate(output, tempfile, tempfilelen);
+ check_result(result, "isc_file_mktemplate");
- fp = NULL;
- if (outputformat == dns_masterformat_text)
- result = isc_file_openunique(tempfile, &fp);
- else
- result = isc_file_bopenunique(tempfile, &fp);
- if (result != ISC_R_SUCCESS)
- fatal("failed to open temporary output file: %s",
- isc_result_totext(result));
- removefile = ISC_TRUE;
- setfatalcallback(&removetempfile);
+ if (outputformat == dns_masterformat_text)
+ result = isc_file_openunique(tempfile, &fp);
+ else
+ result = isc_file_bopenunique(tempfile, &fp);
+ if (result != ISC_R_SUCCESS)
+ fatal("failed to open temporary output file: %s",
+ isc_result_totext(result));
+ removefile = ISC_TRUE;
+ setfatalcallback(&removetempfile);
+ }
print_time(fp);
print_version(fp);
@@ -4005,29 +3671,42 @@ main(int argc, char *argv[]) {
isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *));
postsign();
TIME_NOW(&sign_finish);
- verifyzone();
+
+ if (!disable_zone_check)
+ verifyzone(gdb, gversion, gorigin, mctx,
+ ignore_kskflag, keyset_kskonly);
if (outputformat != dns_masterformat_text) {
- result = dns_master_dumptostream2(mctx, gdb, gversion,
+ dns_masterrawheader_t header;
+ dns_master_initrawheader(&header);
+ if (rawversion == 0U)
+ header.flags = DNS_MASTERRAW_COMPAT;
+ else if (snset) {
+ header.flags = DNS_MASTERRAW_SOURCESERIALSET;
+ header.sourceserial = serialnum;
+ }
+ result = dns_master_dumptostream3(mctx, gdb, gversion,
masterstyle, outputformat,
- fp);
- check_result(result, "dns_master_dumptostream2");
+ &header, fp);
+ check_result(result, "dns_master_dumptostream3");
}
- result = isc_stdio_close(fp);
- check_result(result, "isc_stdio_close");
- removefile = ISC_FALSE;
-
- result = isc_file_rename(tempfile, output);
- if (result != ISC_R_SUCCESS)
- fatal("failed to rename temp file to %s: %s\n",
- output, isc_result_totext(result));
-
DESTROYLOCK(&namelock);
if (printstats)
DESTROYLOCK(&statslock);
- printf("%s\n", output);
+ if (!output_stdout) {
+ result = isc_stdio_close(fp);
+ check_result(result, "isc_stdio_close");
+ removefile = ISC_FALSE;
+
+ result = isc_file_rename(tempfile, output);
+ if (result != ISC_R_SUCCESS)
+ fatal("failed to rename temp file to %s: %s\n",
+ output, isc_result_totext(result));
+
+ printf("%s\n", output);
+ }
dns_db_closeversion(gdb, &gversion, ISC_FALSE);
dns_db_detach(&gdb);
@@ -4038,7 +3717,8 @@ main(int argc, char *argv[]) {
dns_dnsseckey_destroy(mctx, &key);
}
- isc_mem_put(mctx, tempfile, tempfilelen);
+ if (tempfilelen != 0)
+ isc_mem_put(mctx, tempfile, tempfilelen);
if (free_output)
isc_mem_free(mctx, output);
OpenPOWER on IntegriCloud