summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/bin/dnssec/dnssectool.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/bin/dnssec/dnssectool.c')
-rw-r--r--contrib/bind9/bin/dnssec/dnssectool.c223
1 files changed, 187 insertions, 36 deletions
diff --git a/contrib/bind9/bin/dnssec/dnssectool.c b/contrib/bind9/bin/dnssec/dnssectool.c
index 81120e3..da6b0b2 100644
--- a/contrib/bind9/bin/dnssec/dnssectool.c
+++ b/contrib/bind9/bin/dnssec/dnssectool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.c,v 1.45.334.5 2009-06-22 05:05:00 marka Exp $ */
+/* $Id: dnssectool.c,v 1.60 2010-01-19 23:48:56 tbox Exp $ */
/*! \file */
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <isc/buffer.h>
+#include <isc/dir.h>
#include <isc/entropy.h>
#include <isc/list.h>
#include <isc/mem.h>
@@ -36,6 +37,8 @@
#include <isc/util.h>
#include <isc/print.h>
+#include <dns/dnssec.h>
+#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/name.h>
#include <dns/rdatastruct.h>
@@ -111,39 +114,16 @@ type_format(const dns_rdatatype_t type, char *cp, unsigned int size) {
}
void
-alg_format(const dns_secalg_t alg, char *cp, unsigned int size) {
- isc_buffer_t b;
- isc_region_t r;
- isc_result_t result;
-
- isc_buffer_init(&b, cp, size - 1);
- result = dns_secalg_totext(alg, &b);
- check_result(result, "dns_secalg_totext()");
- isc_buffer_usedregion(&b, &r);
- r.base[r.length] = 0;
-}
-
-void
sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) {
char namestr[DNS_NAME_FORMATSIZE];
char algstr[DNS_NAME_FORMATSIZE];
dns_name_format(&sig->signer, namestr, sizeof(namestr));
- alg_format(sig->algorithm, algstr, sizeof(algstr));
+ dns_secalg_format(sig->algorithm, algstr, sizeof(algstr));
snprintf(cp, size, "%s/%s/%d", namestr, algstr, sig->keyid);
}
void
-key_format(const dst_key_t *key, char *cp, unsigned int size) {
- char namestr[DNS_NAME_FORMATSIZE];
- char algstr[DNS_NAME_FORMATSIZE];
-
- dns_name_format(dst_key_name(key), namestr, sizeof(namestr));
- alg_format((dns_secalg_t) dst_key_alg(key), algstr, sizeof(algstr));
- snprintf(cp, size, "%s/%s/%d", namestr, algstr, dst_key_id(key));
-}
-
-void
setup_logging(int verbose, isc_mem_t *mctx, isc_log_t **logp) {
isc_result_t result;
isc_logdestination_t destination;
@@ -265,32 +245,92 @@ cleanup_entropy(isc_entropy_t **ectx) {
isc_entropy_detach(ectx);
}
+static isc_stdtime_t
+time_units(isc_stdtime_t offset, char *suffix, const char *str) {
+ switch (suffix[0]) {
+ case 'Y': case 'y':
+ return (offset * (365 * 24 * 3600));
+ case 'M': case 'm':
+ switch (suffix[1]) {
+ case 'O': case 'o':
+ return (offset * (30 * 24 * 3600));
+ case 'I': case 'i':
+ return (offset * 60);
+ case '\0':
+ fatal("'%s' ambiguous: use 'mi' for minutes "
+ "or 'mo' for months", str);
+ default:
+ fatal("time value %s is invalid", str);
+ }
+ /* NOTREACHED */
+ break;
+ case 'W': case 'w':
+ return (offset * (7 * 24 * 3600));
+ case 'D': case 'd':
+ return (offset * (24 * 3600));
+ case 'H': case 'h':
+ return (offset * 3600);
+ case 'S': case 's': case '\0':
+ return (offset);
+ default:
+ fatal("time value %s is invalid", str);
+ }
+ /* NOTREACHED */
+ return(0); /* silence compiler warning */
+}
+
+dns_ttl_t
+strtottl(const char *str) {
+ const char *orig = str;
+ dns_ttl_t ttl;
+ char *endp;
+
+ ttl = strtol(str, &endp, 0);
+ if (ttl == 0 && endp == str)
+ fatal("TTL must be numeric");
+ ttl = time_units(ttl, endp, orig);
+ return (ttl);
+}
+
isc_stdtime_t
strtotime(const char *str, isc_int64_t now, isc_int64_t base) {
isc_int64_t val, offset;
isc_result_t result;
+ const char *orig = str;
char *endp;
- if (str[0] == '+') {
+ if ((str[0] == '0' || str[0] == '-') && str[1] == '\0')
+ return ((isc_stdtime_t) 0);
+
+ if (strncmp(str, "now", 3) == 0) {
+ base = now;
+ str += 3;
+ }
+
+ if (str[0] == '\0')
+ return ((isc_stdtime_t) base);
+ else if (str[0] == '+') {
offset = strtol(str + 1, &endp, 0);
- if (*endp != '\0')
- fatal("time value %s is invalid", str);
+ offset = time_units((isc_stdtime_t) offset, endp, orig);
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 if (str[0] == '-') {
+ offset = strtol(str + 1, &endp, 0);
+ offset = time_units((isc_stdtime_t) offset, endp, orig);
+ val = base - offset;
} else if (strlen(str) == 8U) {
char timestr[15];
sprintf(timestr, "%s000000", str);
result = dns_time64_fromtext(timestr, &val);
if (result != ISC_R_SUCCESS)
- fatal("time value %s is invalid", str);
+ fatal("time value %s is invalid: %s", orig,
+ isc_result_totext(result));
+ } else if (strlen(str) > 14U) {
+ fatal("time value %s is invalid", orig);
} else {
result = dns_time64_fromtext(str, &val);
if (result != ISC_R_SUCCESS)
- fatal("time value %s is invalid", str);
+ fatal("time value %s is invalid: %s", orig,
+ isc_result_totext(result));
}
return ((isc_stdtime_t) val);
@@ -311,3 +351,114 @@ strtoclass(const char *str) {
fatal("unknown class %s", str);
return (rdclass);
}
+
+isc_result_t
+try_dir(const char *dirname) {
+ isc_result_t result;
+ isc_dir_t d;
+
+ isc_dir_init(&d);
+ result = isc_dir_open(&d, dirname);
+ if (result == ISC_R_SUCCESS) {
+ isc_dir_close(&d);
+ }
+ return (result);
+}
+
+/*
+ * Check private key version compatibility.
+ */
+void
+check_keyversion(dst_key_t *key, char *keystr) {
+ int major, minor;
+ dst_key_getprivateformat(key, &major, &minor);
+ INSIST(major <= DST_MAJOR_VERSION); /* invalid private key */
+
+ if (major < DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d, "
+ "use -f to force upgrade to new version.",
+ keystr, major, minor);
+ if (minor > DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d, "
+ "use -f to force downgrade to current version.",
+ keystr, major, minor);
+}
+
+void
+set_keyversion(dst_key_t *key) {
+ int major, minor;
+ dst_key_getprivateformat(key, &major, &minor);
+ INSIST(major <= DST_MAJOR_VERSION);
+
+ if (major != DST_MAJOR_VERSION || minor != DST_MINOR_VERSION)
+ dst_key_setprivateformat(key, DST_MAJOR_VERSION,
+ DST_MINOR_VERSION);
+
+ /*
+ * If the key is from a version older than 1.3, set
+ * set the creation date
+ */
+ if (major < 1 || (major == 1 && minor <= 2)) {
+ isc_stdtime_t now;
+ isc_stdtime_get(&now);
+ dst_key_settime(key, DST_TIME_CREATED, now);
+ }
+}
+
+isc_boolean_t
+key_collision(isc_uint16_t id, dns_name_t *name, const char *dir,
+ dns_secalg_t alg, isc_mem_t *mctx, isc_boolean_t *exact)
+{
+ isc_result_t result;
+ isc_boolean_t conflict = ISC_FALSE;
+ dns_dnsseckeylist_t matchkeys;
+ dns_dnsseckey_t *key = NULL;
+ isc_uint16_t oldid, diff;
+ isc_uint16_t bits = DNS_KEYFLAG_REVOKE; /* flag bits to look for */
+
+ if (exact != NULL)
+ *exact = ISC_FALSE;
+
+ ISC_LIST_INIT(matchkeys);
+ result = dns_dnssec_findmatchingkeys(name, dir, mctx, &matchkeys);
+ if (result == ISC_R_NOTFOUND)
+ return (ISC_FALSE);
+
+ while (!ISC_LIST_EMPTY(matchkeys) && !conflict) {
+ key = ISC_LIST_HEAD(matchkeys);
+ if (dst_key_alg(key->key) != alg)
+ goto next;
+
+ oldid = dst_key_id(key->key);
+ diff = (oldid > id) ? (oldid - id) : (id - oldid);
+ if ((diff & ~bits) == 0) {
+ conflict = ISC_TRUE;
+ if (diff != 0) {
+ if (verbose > 1)
+ fprintf(stderr, "Key ID %d could "
+ "collide with %d\n",
+ id, oldid);
+ } else {
+ if (exact != NULL)
+ *exact = ISC_TRUE;
+ if (verbose > 1)
+ fprintf(stderr, "Key ID %d exists\n",
+ id);
+ }
+ }
+
+ next:
+ ISC_LIST_UNLINK(matchkeys, key, link);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
+
+ /* Finish freeing the list */
+ while (!ISC_LIST_EMPTY(matchkeys)) {
+ key = ISC_LIST_HEAD(matchkeys);
+ ISC_LIST_UNLINK(matchkeys, key, link);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
+
+ return (conflict);
+}
+
OpenPOWER on IntegriCloud