[master] 5011 tests and fixes

4056.	[bug]		Expanded automatic testing of trust anchor
			management and fixed several small bugs including
			a memory leak and a possible loss of key state
			information. [RT #38458]

4055.	[func]		"rndc managed-keys" can be used to check status
			of trust anchors or to force keys to be refreshed,
			Also, the managed keys data file has easier-to-read
			comments.  [RT #38458]
This commit is contained in:
Evan Hunt 2015-02-05 17:18:15 -08:00
parent de283bda6a
commit 591389c7d4
42 changed files with 2253 additions and 727 deletions

10
CHANGES
View file

@ -1,3 +1,13 @@
4056. [bug] Expanded automatic testing of trust anchor
management and fixed several small bugs including
a memory leak and a possible loss of key state
information. [RT #38458]
4055. [func] "rndc managed-keys" can be used to check status
of trust anchors or to force keys to be refreshed,
Also, the managed keys data file has easier-to-read
comments. [RT #38458]
4054. [func] Added a new tool 'mdig', a light weight clone of
dig able to send multiple pipelined queries.
[RT #38261]

View file

@ -160,7 +160,7 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t **text) {
ns_server_dumpdb(ns_g_server, command);
result = ISC_R_SUCCESS;
} else if (command_compare(command, NS_COMMAND_SECROOTS)) {
result = ns_server_dumpsecroots(ns_g_server, command);
result = ns_server_dumpsecroots(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_TRACE)) {
result = ns_server_setdebuglevel(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_NOTRACE)) {
@ -220,6 +220,8 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t **text) {
result = ns_server_nta(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_TESTGEN)) {
result = ns_server_testgen(command, text);
} else if (command_compare(command, NS_COMMAND_MKEYS)) {
result = ns_server_mkeys(ns_g_server, command, text);
} else {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,

View file

@ -71,6 +71,7 @@
#define NS_COMMAND_ZONESTATUS "zonestatus"
#define NS_COMMAND_NTA "nta"
#define NS_COMMAND_TESTGEN "testgen"
#define NS_COMMAND_MKEYS "managed-keys"
isc_result_t
ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);

View file

@ -175,7 +175,6 @@ EXTERN isc_boolean_t ns_g_notcp INIT(ISC_FALSE);
EXTERN isc_boolean_t ns_g_disable6 INIT(ISC_FALSE);
EXTERN isc_boolean_t ns_g_disable4 INIT(ISC_FALSE);
#ifdef HAVE_GEOIP
EXTERN dns_geoip_databases_t *ns_g_geoip INIT(NULL);
#endif

View file

@ -301,7 +301,7 @@ ns_server_dumpdb(ns_server_t *server, char *args);
* Dump the current security roots to the secroots file.
*/
isc_result_t
ns_server_dumpsecroots(ns_server_t *server, char *args);
ns_server_dumpsecroots(ns_server_t *server, char *args, isc_buffer_t **text);
/*%
* Change or increment the server debug level.
@ -426,4 +426,11 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t **text);
*/
isc_result_t
ns_server_testgen(char *args, isc_buffer_t **text);
/*%
* Force fefresh or print status for managed keys zones.
*/
isc_result_t
ns_server_mkeys(ns_server_t *server, char *args, isc_buffer_t **text);
#endif /* NAMED_SERVER_H */

View file

@ -106,6 +106,9 @@
#endif
extern int isc_dscp_check_value;
extern unsigned int dns_zone_mkey_hour;
extern unsigned int dns_zone_mkey_day;
extern unsigned int dns_zone_mkey_month;
static isc_boolean_t want_stats = ISC_FALSE;
static char program_name[ISC_DIR_NAMEMAX] = "named";
@ -562,7 +565,38 @@ parse_command_line(int argc, char *argv[]) {
else if (!strncmp(isc_commandline_argument, "dscp=", 5))
isc_dscp_check_value =
atoi(isc_commandline_argument + 5);
else if (!strcmp(isc_commandline_argument, "notcp"))
else if (!strncmp(isc_commandline_argument,
"mkeytimers=", 11))
{
p = strtok(isc_commandline_argument + 11, "/");
if (p == NULL)
ns_main_earlyfatal("bad mkeytimer");
dns_zone_mkey_hour = atoi(p);
if (dns_zone_mkey_hour == 0)
ns_main_earlyfatal("bad mkeytimer");
p = strtok(NULL, "/");
if (p == NULL) {
dns_zone_mkey_day =
(24 * dns_zone_mkey_hour);
dns_zone_mkey_month =
(30 * dns_zone_mkey_day);
break;
}
dns_zone_mkey_day = atoi(p);
if (dns_zone_mkey_day < dns_zone_mkey_hour)
ns_main_earlyfatal("bad mkeytimer");
p = strtok(NULL, "/");
if (p == NULL) {
dns_zone_mkey_month =
(30 * dns_zone_mkey_day);
break;
}
dns_zone_mkey_month = atoi(p);
if (dns_zone_mkey_month < dns_zone_mkey_day)
ns_main_earlyfatal("bad mkeytimer");
} else if (!strcmp(isc_commandline_argument, "notcp"))
ns_g_notcp = ISC_TRUE;
else
fprintf(stderr, "unknown -T flag '%s\n",

View file

@ -90,6 +90,7 @@
#include <dns/rdatastruct.h>
#include <dns/resolver.h>
#include <dns/rootns.h>
#include <dns/rriterator.h>
#include <dns/secalg.h>
#include <dns/soa.h>
#include <dns/stats.h>
@ -7857,7 +7858,7 @@ ns_server_dumpdb(ns_server_t *server, char *args) {
}
isc_result_t
ns_server_dumpsecroots(ns_server_t *server, char *args) {
ns_server_dumpsecroots(ns_server_t *server, char *args, isc_buffer_t **text) {
dns_view_t *view;
dns_keytable_t *secroots = NULL;
dns_ntatable_t *ntatable = NULL;
@ -7872,13 +7873,25 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
if (ptr == NULL)
return (ISC_R_UNEXPECTEDEND);
/* "-" here means print the output instead of dumping to file */
ptr = next_token(&args, " \t");
if (ptr != NULL && strcmp(ptr, "-") == 0)
ptr = next_token(&args, " \t");
else {
result = isc_stdio_open(server->secrootsfile, "w", &fp);
if (result != ISC_R_SUCCESS) {
(void) putstr(text, "could not open ");
(void) putstr(text, server->secrootsfile);
CHECKMF(result, "could not open secroots dump file",
server->secrootsfile);
}
}
CHECKMF(isc_stdio_open(server->secrootsfile, "w", &fp),
"could not open secroots dump file", server->secrootsfile);
TIME_NOW(&now);
isc_time_formattimestamp(&now, tbuf, sizeof(tbuf));
fprintf(fp, "%s\n", tbuf);
CHECK(putstr(text, "secure roots as of "));
CHECK(putstr(text, tbuf));
CHECK(putstr(text, ":\n"));
do {
for (view = ISC_LIST_HEAD(server->viewlist);
@ -7894,12 +7907,10 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
result = ISC_R_SUCCESS;
continue;
}
fprintf(fp, "\n Start view %s\n", view->name);
fprintf(fp, " Secure roots:\n\n");
result = dns_keytable_dump(secroots, fp);
if (result != ISC_R_SUCCESS)
fprintf(fp, " dumpsecroots failed: %s\n",
isc_result_totext(result));
CHECK(putstr(text, "\n Start view "));
CHECK(putstr(text, view->name));
CHECK(putstr(text, "\n Secure roots:\n\n"));
CHECK(dns_keytable_totext(secroots, text));
if (ntatable != NULL)
dns_ntatable_detach(&ntatable);
@ -7908,23 +7919,30 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
result = ISC_R_SUCCESS;
continue;
}
fprintf(fp, "\n Negative trust anchors:\n\n");
result = dns_ntatable_dump(ntatable, fp);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
fprintf(fp, " dumpntatable failed: %s\n",
isc_result_totext(result));
CHECK(putstr(text, "\n Negative trust anchors:\n\n"));
CHECK(dns_ntatable_totext(ntatable, text));
}
if (ptr != NULL)
ptr = next_token(&args, " \t");
} while (ptr != NULL);
cleanup:
if (isc_buffer_usedlength(*text) > 0) {
if (fp != NULL)
(void)putstr(text, "\n");
else
(void)putnull(text);
}
if (secroots != NULL)
dns_keytable_detach(&secroots);
if (ntatable != NULL)
dns_ntatable_detach(&ntatable);
if (fp != NULL)
if (fp != NULL) {
fprintf(fp, "%.*s", (int) isc_buffer_usedlength(*text),
(char *) isc_buffer_base(*text));
isc_buffer_clear(*text);
(void)isc_stdio_close(fp);
}
if (result == ISC_R_SUCCESS)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
@ -8297,7 +8315,9 @@ ns_server_status(ns_server_t *server, isc_buffer_t **text) {
unsigned int zonecount, xferrunning, xferdeferred, soaqueries;
unsigned int automatic;
const char *ob = "", *cb = "", *alt = "";
char boottime[80], configtime[80], line[1024];
char boottime[ISC_FORMATHTTPTIMESTAMP_SIZE];
char configtime[ISC_FORMATHTTPTIMESTAMP_SIZE];
char line[1024];
if (ns_g_server->version_set) {
ob = " (";
@ -10039,7 +10059,11 @@ ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t **text) {
const char *type, *file, *zonename = NULL;
isc_uint32_t serial, signed_serial, nodes;
char serbuf[16], sserbuf[16], nodebuf[16], resignbuf[512];
char lbuf[80], xbuf[80], rbuf[80], kbuf[80], rtbuf[80];
char lbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char xbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char kbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char rtbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
isc_time_t loadtime, expiretime, refreshtime;
isc_time_t refreshkeytime, resigntime;
dns_zonetype_t zonetype;
@ -10217,7 +10241,7 @@ ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t **text) {
}
if (! isc_time_isepoch(&refreshtime)) {
CHECK(putstr(text, "\nnext refresh: "));
CHECK(putstr(text, "\nnext managed-keys refresh: "));
CHECK(putstr(text, rbuf));
}
@ -10394,6 +10418,7 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t **text) {
}
CHECK(dns_ntatable_totext(ntatable, text));
}
CHECK(putnull(text));
goto cleanup;
}
@ -10555,3 +10580,275 @@ ns_server_loadnta(ns_server_t *server) {
return (ISC_R_SUCCESS);
}
static isc_result_t
mkey_refresh(dns_view_t *view, isc_buffer_t **text) {
isc_result_t result;
char msg[DNS_NAME_FORMATSIZE + 500] = "";
snprintf(msg, sizeof(msg),
"refreshing managed keys for '%s'", view->name);
CHECK(putstr(text, msg));
CHECK(dns_zone_synckeyzone(view->managed_keys));
cleanup:
return (result);
}
static isc_result_t
mkey_dumpzone(dns_view_t *view, isc_buffer_t **text) {
isc_result_t result;
dns_db_t *db = NULL;
dns_dbversion_t *ver = NULL;
dns_rriterator_t rrit;
isc_stdtime_t now;
dns_name_t *prevname = NULL;
isc_stdtime_get(&now);
CHECK(dns_zone_getdb(view->managed_keys, &db));
dns_db_currentversion(db, &ver);
dns_rriterator_init(&rrit, db, ver, 0);
for (result = dns_rriterator_first(&rrit);
result == ISC_R_SUCCESS;
result = dns_rriterator_nextrrset(&rrit))
{
char buf[DNS_NAME_FORMATSIZE + 500];
dns_name_t *name = NULL;
dns_rdataset_t *kdset = NULL;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_keydata_t kd;
isc_uint32_t ttl;
dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
!dns_rdataset_isassociated(kdset))
continue;
if (name != prevname) {
char nbuf[DNS_NAME_FORMATSIZE];
dns_name_format(name, nbuf, sizeof(nbuf));
snprintf(buf, sizeof(buf), "\n\n name: %s", nbuf);
CHECK(putstr(text, buf));
}
for (result = dns_rdataset_first(kdset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(kdset))
{
char alg[DNS_SECALG_FORMATSIZE];
char tbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
dns_keytag_t keyid;
isc_region_t r;
isc_time_t t;
isc_boolean_t revoked;
dns_rdata_reset(&rdata);
dns_rdataset_current(kdset, &rdata);
result = dns_rdata_tostruct(&rdata, &kd, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_rdata_toregion(&rdata, &r);
isc_region_consume(&r, 12);
keyid = dst_region_computeid(&r, kd.algorithm);
snprintf(buf, sizeof(buf), "\n keyid: %u", keyid);
CHECK(putstr(text, buf));
dns_secalg_format(kd.algorithm, alg, sizeof(alg));
snprintf(buf, sizeof(buf), "\n\talgorithm: %s", alg);
CHECK(putstr(text, buf));
revoked = ISC_TF((kd.flags & DNS_KEYFLAG_REVOKE) != 0);
snprintf(buf, sizeof(buf), "\n\tflags:%s%s%s",
revoked ? " REVOKE" : "",
((kd.flags & DNS_KEYFLAG_KSK) != 0)
? " SEP" : "",
(kd.flags == 0) ? " (none)" : "");
CHECK(putstr(text, buf));
isc_time_set(&t, kd.refresh, 0);
isc_time_formathttptimestamp(&t, tbuf, sizeof(tbuf));
snprintf(buf, sizeof(buf),
"\n\tnext refresh: %s", tbuf);
CHECK(putstr(text, buf));
if (kd.removehd != 0) {
isc_time_set(&t, kd.removehd, 0);
isc_time_formathttptimestamp(&t, tbuf,
sizeof(tbuf));
snprintf(buf, sizeof(buf),
"\n\tremove at: %s", tbuf);
CHECK(putstr(text, buf));
}
isc_time_set(&t, kd.addhd, 0);
isc_time_formathttptimestamp(&t, tbuf, sizeof(tbuf));
if (kd.addhd == 0)
snprintf(buf, sizeof(buf), "\n\tno trust");
else if (revoked)
snprintf(buf, sizeof(buf),
"\n\ttrust revoked");
else if (kd.addhd < now)
snprintf(buf, sizeof(buf),
"\n\ttrusted since: %s", tbuf);
else if (kd.addhd >= now)
snprintf(buf, sizeof(buf),
"\n\ttrust pending: %s", tbuf);
CHECK(putstr(text, buf));
}
}
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
cleanup:
if (ver != NULL) {
dns_rriterator_destroy(&rrit);
dns_db_closeversion(db, &ver, ISC_FALSE);
}
if (db != NULL)
dns_db_detach(&db);
return (result);
}
static isc_result_t
mkey_status(dns_view_t *view, isc_buffer_t **text) {
isc_result_t result;
char msg[ISC_FORMATHTTPTIMESTAMP_SIZE];
isc_time_t t;
CHECK(putstr(text, "view: "));
CHECK(putstr(text, view->name));
CHECK(putstr(text, "\nnext scheduled event: "));
dns_zone_getrefreshkeytime(view->managed_keys, &t);
if (isc_time_isepoch(&t)) {
CHECK(putstr(text, "never"));
} else {
isc_time_formathttptimestamp(&t, msg, sizeof(msg));
CHECK(putstr(text, msg));
}
CHECK(mkey_dumpzone(view, text));
cleanup:
return (result);
}
isc_result_t
ns_server_mkeys(ns_server_t *server, char *args, isc_buffer_t **text) {
char *cmd, *classtxt, *viewtxt = NULL;
isc_result_t result = ISC_R_SUCCESS;
dns_view_t *view = NULL;
dns_rdataclass_t rdclass;
char msg[DNS_NAME_FORMATSIZE + 500] = "";
enum { NONE, STATUS, REFRESH, SYNC } opt = NONE;
isc_boolean_t found = ISC_FALSE;
/* Skip rndc command name */
cmd = next_token(&args, " \t");
if (cmd == NULL)
return (ISC_R_UNEXPECTEDEND);
/* Get managed-keys subcommand */
cmd = next_token(&args, " \t");
if (cmd == NULL)
return (ISC_R_UNEXPECTEDEND);
if (strcasecmp(cmd, "status") == 0)
opt = STATUS;
else if (strcasecmp(cmd, "refresh") == 0)
opt = REFRESH;
else if (strcasecmp(cmd, "sync") == 0)
opt = SYNC;
else {
snprintf(msg, sizeof(msg), "unknown command '%s'", cmd);
(void) putstr(text, msg);
result = ISC_R_UNEXPECTED;
goto cleanup;
}
/* Look for the optional class name. */
classtxt = next_token(&args, " \t");
if (classtxt != NULL) {
/* Look for the optional view name. */
viewtxt = next_token(&args, " \t");
}
if (classtxt == NULL) {
rdclass = dns_rdataclass_in;
} else {
isc_textregion_t r;
r.base = classtxt;
r.length = strlen(classtxt);
result = dns_rdataclass_fromtext(&rdclass, &r);
if (result != ISC_R_SUCCESS) {
if (viewtxt == NULL) {
rdclass = dns_rdataclass_in;
viewtxt = classtxt;
result = ISC_R_SUCCESS;
} else {
snprintf(msg, sizeof(msg),
"unknown class '%s'", classtxt);
(void) putstr(text, msg);
goto cleanup;
}
}
}
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
isc_boolean_t first = ISC_TRUE;
if (viewtxt != NULL &&
(rdclass != view->rdclass ||
strcmp(view->name, viewtxt) != 0))
continue;
if (view->managed_keys == NULL) {
if (viewtxt != NULL) {
snprintf(msg, sizeof(msg),
"view '%s': no managed keys", viewtxt);
CHECK(putstr(text, msg));
goto cleanup;
} else
continue;
}
found = ISC_TRUE;
switch (opt) {
case REFRESH:
CHECK(mkey_refresh(view, text));
break;
case STATUS:
if (!first)
CHECK(putstr(text, "\n"));
CHECK(mkey_status(view, text));
first = ISC_FALSE;
break;
case SYNC:
CHECK(dns_zone_flush(view->managed_keys));
break;
default:
INSIST(0);
}
if (viewtxt != NULL)
break;
}
if (!found)
CHECK(putstr(text, "no views with managed keys"));
cleanup:
if (isc_buffer_usedlength(*text) > 0)
(void) putnull(text);
return (result);
}

File diff suppressed because it is too large Load diff

View file

@ -69,8 +69,9 @@ SUBDIRS="acl additional allow_query addzone autosign builtin
@COVERAGE@ database delv dlv dlvauto dlz dlzexternal dname
dns64 dnssec dsdigest dscp ecdsa ednscompliance emptyzones
filter-aaaa formerr forward geoip glue gost ixfr inline
legacy limits logfileconfig lwresd masterfile masterformat
metadata notify nslookup nsupdate pending pipelined @PKCS11_TEST@
legacy limits logfileconfig lwresd
masterfile masterformat metadata mkeys
notify nslookup nsupdate pending pipelined @PKCS11_TEST@
reclimit redirect resolver rndc rpz rrl rrchecker rrsetorder
rsabigexponent runtime sit sfcache smartsign sortlist spf
staticstub statistics stub tcp tkey tsig tsiggss unknown

View file

@ -16,7 +16,8 @@
# PERFORMANCE OF THIS SOFTWARE.
rm -f */K* */keyset-* */dsset-* */dlvset-* */signedkey-* */*.signed
rm -f */trusted.conf */managed.conf */tmp* */*.jnl */*.bk */*.jbk
rm -f */trusted.conf */managed.conf */revoked.conf
rm -f */tmp* */*.jnl */*.bk */*.jbk
rm -f ns1/root.db ns2/example.db ns3/secure.example.db
rm -f ns3/unsecure.example.db ns3/bogus.example.db ns3/keyless.example.db
rm -f ns3/dynamic.example.db ns3/dynamic.example.db.signed.jnl
@ -51,7 +52,7 @@ rm -f signer/*.db
rm -f signer/signer.out.*
rm -f ns2/algroll.db
rm -f ns3/kskonly.example.db
rm -f ns4/named.conf
rm -f ns4/named.conf ns5/named.conf
rm -f ns4/managed-keys.bind*
rm -f ns3/auto-nsec.example.db ns3/auto-nsec3.example.db
rm -f ns3/secure.below-cname.example.db
@ -83,3 +84,4 @@ rm -f ns3/dnskey-unknown.example.db
rm -f ns3/dnskey-unknown.example.db.tmp
rm -f ns*/named.lock
rm -f ns*/*.nta
rm -f named.secroots.test*

View file

@ -15,8 +15,6 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: sign.sh,v 1.43 2011/11/04 05:36:28 each Exp $
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
@ -520,5 +518,5 @@ zonefile=future.example.db
kskname=`$KEYGEN -q -r $RANDFILE -f KSK $zone`
zskname=`$KEYGEN -q -r $RANDFILE $zone`
cat $infile $kskname.key $zskname.key >$zonefile
$SIGNER -P -s +3600 -r $RANDFILE -o $zone $zonefile # > /dev/null 2>&1
$SIGNER -P -s +3600 -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
cp -f $kskname.key trusted-future.key

View file

@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named.conf,v 1.25 2007/06/18 23:47:28 tbox Exp $ */
// NS5
controls { /* empty */ };
@ -35,6 +33,16 @@ options {
dnssec-validation yes;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; };
};
zone "." {
type hint;
file "../../common/root.hint";

View file

@ -0,0 +1,58 @@
/*
* Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS5
controls { /* empty */ };
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; };
};
options {
query-source address 10.53.0.5;
notify-source 10.53.0.5;
transfer-source 10.53.0.5;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.5; 127.0.0.1; };
listen-on-v6 { none; };
recursion yes;
};
view root {
match-destinations { 127.0.0.1; };
zone "." {
type master;
file "root.db.signed";
};
};
view other {
include "revoked.conf";
zone "." {
type static-stub;
server-addresses { 127.0.0.1; };
};
};

View file

@ -0,0 +1,42 @@
#!/bin/sh -e
#
# Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
zone=.
infile=../ns1/root.db.in
zonefile=root.db.signed
keyname=`$KEYGEN -r $RANDFILE -qfk $zone`
# copy the KSK out first, then revoke it
cat $keyname.key | grep -v '^; ' | $PERL -n -e '
local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split;
local $key = join("", @rest);
print <<EOF
managed-keys {
"$dn" initial-key $flags $proto $alg "$key";
};
EOF
' > revoked.conf
$SETTIME -R now ${keyname}.key > /dev/null
# create a current set of keys, and sign the root zone
$KEYGEN -r $RANDFILE -q $zone > /dev/null
$KEYGEN -r $RANDFILE -qfk $zone > /dev/null
$SIGNER -S -r $RANDFILE -o $zone -f $zonefile $infile > /dev/null 2>&1

View file

@ -30,4 +30,8 @@ echo "c.bogus.example. A 10.0.0.23" >>../ns3/bogus.example.db.signed
cd ../ns3 && cp -f siginterval1.conf siginterval.conf
cd ../ns4 && cp -f named1.conf named.conf
cd ../ns5 && cp -f trusted.conf.bad trusted.conf
cd ../ns5 && {
cp -f trusted.conf.bad trusted.conf
cp -f named1.conf named.conf
$SHELL sign.sh
}

View file

@ -15,8 +15,6 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: tests.sh,v 1.109 2012/02/22 23:47:34 tbox Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
@ -1565,10 +1563,11 @@ echo "I:checking rndc secroots ($n)"
ret=0
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 secroots 2>&1 | sed 's/^/I:ns1 /'
keyid=`cat ns1/managed.key.id`
linecount=`grep "./RSAMD5/$keyid ; trusted" ns4/named.secroots | wc -l`
cp ns4/named.secroots named.secroots.test$n
linecount=`grep "./RSAMD5/$keyid ; trusted" named.secroots.test$n | wc -l`
[ "$linecount" -eq 1 ] || ret=1
linecount=`cat ns4/named.secroots | wc -l`
[ "$linecount" -eq 9 ] || ret=1
linecount=`cat named.secroots.test$n | wc -l`
[ "$linecount" -eq 10 ] || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
@ -2784,12 +2783,11 @@ if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:check KEYDATA records are printed in human readable form in key zone ($n)"
# force the zone to be written out
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc . ns4
# force the managed-keys zone to be written out
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 managed-keys sync 2>&1 | sed 's/^/I:ns4 /'
ret=0
grep KEYDATA ns4/managed-keys.bind > /dev/null || ret=1
# restart the server
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns4
grep "next refresh:" ns4/managed-keys.bind > /dev/null || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
@ -3034,5 +3032,16 @@ n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking initialization with a revoked managed key ($n)"
ret=0
cp ns5/named2.conf ns5/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.5 -p 9953 reconfig 2>&1 | sed 's/^/I:ns5 /'
sleep 3
$DIG $DIGOPTS +dnssec -p 5300 @10.53.0.5 SOA . > dig.out.ns5.test$n
grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status

View file

@ -0,0 +1,26 @@
This is for testing managed-keys, in particular with problems
with RFC 5011 Automated Updates of DNSSEC Trust Anchors.
ns1 is the root server that offers new KSKs and hosts one record for
testing. The TTL for the zone's records is 2 seconds.
ns2 is a validator uses managed-keys.
"named -T rfc5011holddown=4" switch is used so it will attempt to do
the automated updates frequently.
ns3 is a validator with a broken key in managed-keys.
Tests TODO:
- initial working KSK
TODO: test using delv with new trusted key too
- introduce a REVOKE bit
- later remove a signature
- corrupt a signature
TODO: also same things with dlv auto updates of trust anchor

View file

@ -0,0 +1,25 @@
#!/bin/sh
#
# Copyright (C) 2009-2014 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
rm -f */K* */*.signed */trusted.conf */*.jnl */*.bk
rm -f dsset-. ns1/dsset-.
rm -f ns*/named.lock
rm -f */managed-keys.bind*
rm -f */managed.conf ns1/managed.key ns1/managed.key.id
rm -f */named.memstats */named.run
rm -f dig.out* delv.out* rndc.out* signer.out*
rm -f ns1/named.secroots ns1/root.db.signed*
rm -f ns1/named.conf

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS1
controls { /* empty */ };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
notify no;
dnssec-enable yes;
dnssec-validation yes;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
};
zone "." {
type master;
file "root.db.signed";
allow-update { any; };
auto-dnssec maintain;
};

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS1
controls { /* empty */ };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
notify no;
dnssec-enable yes;
dnssec-validation yes;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
};
zone "." {
type master;
file "root.db.signed";
};

View file

@ -0,0 +1,29 @@
; Copyright (C) 2004, 2007, 2010, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
; Copyright (C) 2000, 2001 Internet Software Consortium.
;
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
$TTL 2
. IN SOA gson.nominum.com. a.root.servers.nil. (
2000042100 ; serial
600 ; refresh
600 ; retry
1200 ; expire
2 ; minimum
)
. NS a.root-servers.nil.
a.root-servers.nil. A 10.53.0.1
; no delegation
example. TXT "This is a test."

View file

@ -0,0 +1,58 @@
#!/bin/sh -e
#
# Copyright (C) 2004, 2006-2014 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
zone=.
zonefile=root.db
keyname=`$KEYGEN -qfk -r $RANDFILE $zone`
zskkeyname=`$KEYGEN -q -r $RANDFILE $zone`
$SIGNER -Sg -r $RANDFILE -o $zone $zonefile > /dev/null 2>&-
# Configure the resolving server with a managed trusted key.
cat $keyname.key | grep -v '^; ' | $PERL -n -e '
local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split;
local $key = join("", @rest);
print <<EOF
managed-keys {
"$dn" initial-key $flags $proto $alg "$key";
};
EOF
' > managed.conf
cp managed.conf ../ns2/managed.conf
# Configure a trusted key statement (used by delve)
cat $keyname.key | grep -v '^; ' | $PERL -n -e '
local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split;
local $key = join("", @rest);
print <<EOF
trusted-keys {
"$dn" $flags $proto $alg "$key";
};
EOF
' > trusted.conf
#
# Save keyname and keyid for managed key id test.
#
echo "$keyname" > managed.key
keyid=`expr $keyname : 'K\.+00.+\([0-9]*\)'`
keyid=`expr $keyid + 0`
echo "$keyid" > managed.key.id

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -X named.lock -g -T mkeytimers=2/10/15

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion yes;
notify no;
dnssec-enable yes;
dnssec-validation auto;
bindkeys-file "managed.conf";
servfail-ttl 0;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
zone "." {
type hint;
file "../../common/root.hint";
};

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -X named.lock -g -T mkeytimers=2/10/20

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS3
controls { /* empty */ };
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
recursion yes;
notify no;
dnssec-enable yes;
dnssec-validation yes;
bindkeys-file "managed.conf";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; };
};
zone "." {
type hint;
file "../../common/root.hint";
};
# purposely broken key for testing
managed-keys {
"." initial-key 257 3 5 "PURPOSELYBROKEN/xs9iVj7QekClcpzjCf0JrvXW1z07hNMqMm6Q2FtIXMbRgfvTtHF3/ZNvcewT9hpfczC+JACHsQSYYdr7UI8oe4nJfal9+2F3pz4a+HR6CqkgrR6WLWQI1Q==";
};

View file

@ -0,0 +1,27 @@
#!/bin/sh -e
#
# Copyright (C) 2004, 2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
$SHELL clean.sh
test -r $RANDFILE || $GENRANDOM 400 $RANDFILE
cp ns1/named1.conf ns1/named.conf
cd ns1 && $SHELL sign.sh

View file

@ -0,0 +1,435 @@
#!/bin/sh
#
# Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
status=0
n=1
rm -f dig.out.*
DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p 5300"
DELVOPTS="-a ns1/trusted.conf -p 5300"
echo "I: check for signed record ($n)"
ret=0
$DIG $DIGOPTS +norec example. @10.53.0.1 TXT > dig.out.ns1.test$n || ret=1
grep "^example\.[[:space:]]*[0-9].*[[:space:]]*IN[[:space:]]*TXT[[:space:]]*\"This is a test\.\"" dig.out.ns1.test$n > /dev/null || ret=1
grep "^example\.[[:space:]]*[0-9].*[[:space:]]*IN[[:space:]]*RRSIG[[:space:]]*TXT[[:space:]]" dig.out.ns1.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: check positive validation with valid trust anchor ($n)"
ret=0
$DIG $DIGOPTS +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1
grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
ret=0
echo "I: check positive validation using delv ($n)"
$DELV $DELVOPTS @10.53.0.1 txt example > delv.out$n || ret=1
grep "; fully validated" delv.out$n > /dev/null || ret=1 # redundant
grep "example..*TXT.*This is a test" delv.out$n > /dev/null || ret=1
grep "example..*.RRSIG..*TXT" delv.out$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: check for failed validation due to wrong key in managed-keys ($n)"
ret=0
$DIG $DIGOPTS +noauth example. @10.53.0.3 txt > dig.out.ns3.test$n || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1
grep "example..*.RRSIG..*TXT" dig.out.ns3.test$n > /dev/null && ret=1
grep "opcode: QUERY, status: SERVFAIL, id" dig.out.ns3.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: check new trust anchor can be added ($n)"
ret=0
standby1=`$KEYGEN -qfk -r $RANDFILE -K ns1 .`
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . | sed 's/^/I: ns1 /'
sleep 5
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# there should be two keys listed now
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# two lines indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# one indicates current trust
count=`grep -c "trusted since" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# one indicates pending trust
count=`grep -c "trust pending" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: check new trust anchor can't be added with bad initial key ($n)"
ret=0
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 managed-keys refresh | sed 's/^/I: ns3 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 managed-keys sync | sed 's/^/I: ns3 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 managed-keys status > rndc.out.$n 2>&1
# there should be one key listed now
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# one line indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# ... and the key is not trusted
count=`grep -c "no trust" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: remove untrusted standby key, check timer restarts ($n)"
ret=0
$SETTIME -D now -K ns1 $standby1 > /dev/null
t1=`grep "trust pending" ns2/managed-keys.bind`
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . | sed 's/^/I: ns1 /'
sleep 3
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
sleep 1
t2=`grep "trust pending" ns2/managed-keys.bind`
# trust pending date must be different
[ -n "$t2" ] || ret=1
[ "$t1" = "$t2" ] && ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
ret=0
echo "I: restore untrusted standby key, revoke original key ($n)"
t1=$t2
$SETTIME -D none -K ns1 $standby1 > /dev/null
$SETTIME -R now -K ns1 `cat ns1/managed.key` > /dev/null
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . | sed 's/^/I: ns1 /'
sleep 3
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# two keys listed
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# two lines indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# trust is revoked
count=`grep -c "trust revoked" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# removal scheduled
count=`grep -c "remove at" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# trust is still pending on the standby key
count=`grep -c "trust pending" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# pending date moved forward for the standby key
t2=`grep "trust pending" ns2/managed-keys.bind`
[ -n "$t2" ] || ret=1
[ "$t1" = "$t2" ] && ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
ret=0
echo "I: refresh managed-keys, ensure same result ($n)"
t1=$t2
sleep 2
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# two keys listed
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# two lines indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# trust is revoked
count=`grep -c "trust revoked" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# removal scheduled
count=`grep -c "remove at" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# trust is still pending on the standby key
count=`grep -c "trust pending" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# pending date moved forward for the standby key
t2=`grep "trust pending" ns2/managed-keys.bind`
[ -n "$t2" ] || ret=1
[ "$t1" = "$t2" ] && ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
ret=0
echo "I: restore revoked key, ensure same result ($n)"
t1=$t2
$SETTIME -R none -D now -K ns1 `cat ns1/managed.key` > /dev/null
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . | sed 's/^/I: ns1 /'
sleep 3
$SETTIME -D none -K ns1 `cat ns1/managed.key` > /dev/null
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . | sed 's/^/I: ns1 /'
sleep 3
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# two keys listed
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# two lines indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# trust is revoked
count=`grep -c "trust revoked" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# removal scheduled
count=`grep -c "remove at" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# trust is still pending on the standby key
count=`grep -c "trust pending" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# pending date moved forward for the standby key
t2=`grep "trust pending" ns2/managed-keys.bind`
[ -n "$t2" ] || ret=1
[ "$t1" = "$t2" ] && ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I: reinitialize trust anchors"
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc . ns2
rm -f ns2/managed-keys.bind*
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns2
n=`expr $n + 1`
echo "I: check that standby key is now trusted ($n)"
ret=0
sleep 3
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# two keys listed
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# two lines indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# both indicate current trust
count=`grep -c "trusted since" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: revoke original key, add new standby ($n)"
ret=0
standby2=`$KEYGEN -qfk -r $RANDFILE -K ns1 .`
$SETTIME -R now -K ns1 `cat ns1/managed.key` > /dev/null
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . | sed 's/^/I: ns1 /'
sleep 3
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# three keys listed
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 3 ] || ret=1
# one is revoked
count=`grep -c "REVOKE" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# three lines indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 3 ] || ret=1
# one indicates current trust
count=`grep -c "trusted since" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# one indicates revoked trust
count=`grep -c "trust revoked" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# one indicates trust pending
count=`grep -c "trust pending" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# removal scheduled
count=`grep -c "remove at" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: wait 15 seconds for key add/remove holddowns to expire ($n)"
ret=0
sleep 15
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# two keys listed
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# none revoked
count=`grep -c "REVOKE" rndc.out.$n`
[ "$count" -eq 0 ] || ret=1
# two lines indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# both indicate current trust
count=`grep -c "trusted since" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: revoke all keys, confirm roll to insecure ($n)"
ret=0
$SETTIME -D now -K ns1 `cat ns1/managed.key` > /dev/null
$SETTIME -R now -K ns1 $standby1 > /dev/null
$SETTIME -R now -K ns1 $standby2 > /dev/null
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . | sed 's/^/I: ns1 /'
sleep 3
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# two keys listed
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# both revoked
count=`grep -c "REVOKE" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# two lines indicating trust status
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# both indicate trust revoked
count=`grep -c "trust revoked" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
# both have removal scheduled
count=`grep -c "remove at" rndc.out.$n`
[ "$count" -eq 2 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: check for insecure response ($n)"
ret=0
$DIG $DIGOPTS +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I: reset the root server"
$SETTIME -D none -R none -K ns1 `cat ns1/managed.key` > /dev/null
$SETTIME -D now -K ns1 $standby1 > /dev/null
$SETTIME -D now -K ns1 $standby2 > /dev/null
$SIGNER -Sg -K ns1 -N unixtime -r $RANDFILE -o . ns1/root.db > /dev/null 2>&-
cp ns1/named2.conf ns1/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reconfig
echo "I: reinitialize trust anchors"
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc . ns2
rm -f ns2/managed-keys.bind*
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns2
n=`expr $n + 1`
echo "I: check positive validation ($n)"
ret=0
$DIG $DIGOPTS +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1
grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: revoke key with bad signature, check revocation is ignored ($n)"
ret=0
orig=`cat ns1/managed.key`
keyid=`cat ns1/managed.key.id`
revoked=`$REVOKE -K ns1 $orig`
rkeyid=`expr $revoked : 'ns1/K\.+00.+\([0-9]*\)'`
$SETTIME -R none -D none -K ns1 $standby1 > /dev/null
$SIGNER -Sg -K ns1 -N unixtime -r $RANDFILE -O full -o . -f signer.out.$n ns1/root.db > /dev/null 2>&-
cp -f ns1/root.db.signed ns1/root.db.tmp
BADSIG="SVn2tLDzpNX2rxR4xRceiCsiTqcWNKh7NQ0EQfCrVzp9WEmLw60sQ5kP xGk4FS/xSKfh89hO2O/H20Bzp0lMdtr2tKy8IMdU/mBZxQf2PXhUWRkg V2buVBKugTiOPTJSnaqYCN3rSfV1o7NtC1VNHKKK/D5g6bpDehdn5Gaq kpBhN+MSCCh9OZP2IT20luS1ARXxLlvuSVXJ3JYuuhTsQXUbX/SQpNoB Lo6ahCE55szJnmAxZEbb2KOVnSlZRA6ZBHDhdtO0S4OkvcmTutvcVV+7 w53CbKdaXhirvHIh0mZXmYk2PbPLDY7PU9wSH40UiWPOB9f00wwn6hUe uEQ1Qg=="
sed -e "/ $rkeyid \./s, \. .*$, . $BADSIG," signer.out.$n > ns1/root.db.signed
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reload . | sed 's/^/I: ns1 /'
sleep 3
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys sync | sed 's/^/I: ns2 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
# one key listed
count=`grep -c "keyid: " rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# it's the original key id
count=`grep -c "keyid: $keyid" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
# not revoked
count=`grep -c "REVOKE" rndc.out.$n`
[ "$count" -eq 0 ] || ret=1
# trust is still current
count=`grep -c "trust" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
count=`grep -c "trusted since" rndc.out.$n`
[ "$count" -eq 1 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: check validation fails with bad DNSKEY rrset ($n)"
ret=0
$DIG $DIGOPTS +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
grep "status: SERVFAIL" dig.out.ns2.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: restore DNSKEY rrset, check validation succeeds again ($n)"
ret=0
rm -f ${revoked}.key ${revoked}.private
$SETTIME -D none -R none -K ns1 `cat ns1/managed.key` > /dev/null
$SETTIME -D now -K ns1 $standby1 > /dev/null
$SETTIME -D now -K ns1 $standby2 > /dev/null
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 flush | sed 's/^/I: ns1 /'
sleep 1
$SIGNER -Sg -K ns1 -N unixtime -r $RANDFILE -o . ns1/root.db > /dev/null 2>&-
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reload . | sed 's/^/I: ns1 /'
sleep 3
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys refresh | sed 's/^/I: ns2 /'
sleep 1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
$DIG $DIGOPTS +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1
grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status

View file

@ -318,6 +318,15 @@
query and waiting the response before sending the next. [RT #38261]
</para>
</listitem>
<listitem>
<para>
To enable better monitoring and troubleshooting of RFC 5011
trust anchor management, the new <command>rndc managed-keys</command>
can be used to check status of trust anchors or to force keys
to be refreshed. Also, the managed-keys data file now has
easier-to-read comments. [RT #38458]
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="relnotes_changes">
@ -521,6 +530,13 @@
processes to grow to very large sizes. [RT #38454]
</para>
</listitem>
<listitem>
<para>
Fixed some bugs in RFC 5011 trust anchor management,
including a memory leak and a possible loss of state
information.[RT #38458]
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="end_of_life">

View file

@ -420,6 +420,12 @@ dns_keytable_dump(dns_keytable_t *keytable, FILE *fp);
* Dump the keytable on fp.
*/
isc_result_t
dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **buf);
/*%<
* Dump the keytable to buffer at 'buf'
*/
dst_key_t *
dns_keynode_key(dns_keynode_t *keynode);
/*%<

View file

@ -185,6 +185,11 @@ isc_result_t
dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf);
/*%<
* Dump the NTA table to buffer at 'buf'
*
* Requires:
* \li "ntatable" is a valid table.
*
* \li "*buf" is a valid buffer.
*/
isc_result_t

View file

@ -275,16 +275,17 @@ dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey) {
}
knode = node->data;
if (knode->next == NULL &&
(knode->key == NULL ||
dst_key_compare(knode->key, dstkey) == ISC_TRUE)) {
if (knode->next == NULL && knode->key != NULL &&
dst_key_compare(knode->key, dstkey) == ISC_TRUE)
{
result = dns_rbt_deletenode(keytable->table, node, ISC_FALSE);
goto finish;
}
kprev = (dns_keynode_t **) &node->data;
while (knode != NULL) {
if (dst_key_compare(knode->key, dstkey) == ISC_TRUE)
if (knode->key != NULL &&
dst_key_compare(knode->key, dstkey) == ISC_TRUE)
break;
kprev = &knode->next;
knode = knode->next;
@ -555,31 +556,80 @@ dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
return (result);
}
static isc_result_t
putstr(isc_buffer_t **b, const char *str) {
isc_result_t result;
result = isc_buffer_reserve(b, strlen(str));
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_putstr(*b, str);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_keytable_dump(dns_keytable_t *keytable, FILE *fp)
{
dns_keytable_dump(dns_keytable_t *keytable, FILE *fp) {
isc_result_t result;
isc_buffer_t *text = NULL;
REQUIRE(VALID_KEYTABLE(keytable));
REQUIRE(fp != NULL);
result = isc_buffer_allocate(keytable->mctx, &text, 4096);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_keytable_totext(keytable, &text);
if (isc_buffer_usedlength(text) != 0) {
(void) putstr(&text, "\n");
} else if (result == ISC_R_SUCCESS)
(void) putstr(&text, "none");
else {
(void) putstr(&text, "could not dump key table: ");
(void) putstr(&text, isc_result_totext(result));
}
fprintf(fp, "%.*s", (int) isc_buffer_usedlength(text),
(char *) isc_buffer_base(text));
isc_buffer_free(&text);
return (result);
}
isc_result_t
dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
isc_result_t result;
dns_keynode_t *knode;
dns_rbtnode_t *node;
dns_rbtnodechain_t chain;
REQUIRE(VALID_KEYTABLE(keytable));
REQUIRE(text != NULL && *text != NULL);
RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
dns_rbtnodechain_init(&chain, keytable->mctx);
result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
if (result == ISC_R_NOTFOUND)
result = ISC_R_SUCCESS;
goto cleanup;
}
for (;;) {
char pbuf[DST_KEY_FORMATSIZE];
dns_rbtnodechain_current(&chain, NULL, NULL, &node);
for (knode = node->data; knode != NULL; knode = knode->next) {
char obuf[DNS_NAME_FORMATSIZE + 200];
if (knode->key == NULL)
continue;
dst_key_format(knode->key, pbuf, sizeof(pbuf));
fprintf(fp, "%s ; %s\n", pbuf,
snprintf(obuf, sizeof(obuf), "%s ; %s\n", pbuf,
knode->managed ? "managed" : "trusted");
result = putstr(text, obuf);
if (result != ISC_R_SUCCESS)
break;
}
result = dns_rbtnodechain_next(&chain, NULL, NULL);
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {

View file

@ -503,6 +503,18 @@ dns_ntatable_covered(dns_ntatable_t *ntatable, isc_stdtime_t now,
return (answer);
}
static isc_result_t
putstr(isc_buffer_t **b, const char *str) {
isc_result_t result;
result = isc_buffer_reserve(b, strlen(str));
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_putstr(*b, str);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
isc_result_t result;
@ -518,14 +530,20 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
RWLOCK(&ntatable->rwlock, isc_rwlocktype_read);
dns_rbtnodechain_init(&chain, ntatable->view->mctx);
result = dns_rbtnodechain_first(&chain, ntatable->table, NULL, NULL);
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
if (result == ISC_R_NOTFOUND)
result = ISC_R_SUCCESS;
goto cleanup;
}
for (;;) {
dns_rbtnodechain_current(&chain, NULL, NULL, &node);
if (node->data != NULL) {
dns_nta_t *n = (dns_nta_t *) node->data;
char nbuf[DNS_NAME_FORMATSIZE], tbuf[80];
char obuf[DNS_NAME_FORMATSIZE + 200];
char nbuf[DNS_NAME_FORMATSIZE];
char tbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char obuf[DNS_NAME_FORMATSIZE +
ISC_FORMATHTTPTIMESTAMP_SIZE +
sizeof("expired: \n")];
dns_fixedname_t fn;
dns_name_t *name;
isc_time_t t;
@ -542,12 +560,9 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
n->expiry < now ? "expired" : "expiry",
tbuf);
first = ISC_FALSE;
result = isc_buffer_reserve(buf, strlen(obuf));
if (result != ISC_R_SUCCESS) {
result = ISC_R_NOSPACE;
result = putstr(buf, obuf);
if (result != ISC_R_SUCCESS)
goto cleanup;
}
isc_buffer_putstr(*buf, obuf);
}
result = dns_rbtnodechain_next(&chain, NULL, NULL);
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
@ -557,16 +572,13 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
}
}
isc_buffer_reserve(buf, 1);
if (isc_buffer_availablelength(*buf) != 0)
isc_buffer_putuint8(*buf, 0);
cleanup:
dns_rbtnodechain_invalidate(&chain);
RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_read);
return (result);
}
#if 0
isc_result_t
dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) {
isc_result_t result;
@ -615,6 +627,34 @@ dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) {
RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_read);
return (result);
}
#endif
isc_result_t
dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) {
isc_result_t result;
isc_buffer_t *text = NULL;
int len = 4096;
result = isc_buffer_allocate(ntatable->view->mctx, &text, len);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_ntatable_totext(ntatable, &text);
if (isc_buffer_usedlength(text) != 0) {
(void) putstr(&text, "\n");
} else if (result == ISC_R_SUCCESS) {
(void) putstr(&text, "none");
} else {
(void) putstr(&text, "could not dump NTA table: ");
(void) putstr(&text, isc_result_totext(result));
}
fprintf(fp, "%.*s", (int) isc_buffer_usedlength(text),
(char *) isc_buffer_base(text));
isc_buffer_free(&text);
return (result);
}
isc_result_t
dns_ntatable_save(dns_ntatable_t *ntatable, FILE *fp) {

View file

@ -14,11 +14,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id$ */
#ifndef GENERIC_KEYDATA_65533_C
#define GENERIC_KEYDATA_65533_C 1
#include <isc/time.h>
#include <isc/stdtime.h>
#include <dst/dst.h>
#define RRTYPE_KEYDATA_ATTRIBUTES (0)
@ -97,7 +98,7 @@ totext_keydata(ARGS_TOTEXT) {
char buf[sizeof("64000")];
unsigned int flags;
unsigned char algorithm;
unsigned long when;
unsigned long refresh, add, remove;
char algbuf[DNS_NAME_FORMATSIZE];
const char *keyinfo;
@ -109,21 +110,21 @@ totext_keydata(ARGS_TOTEXT) {
dns_rdata_toregion(rdata, &sr);
/* refresh timer */
when = uint32_fromregion(&sr);
refresh = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
RETERR(dns_time32_totext(when, target));
RETERR(dns_time32_totext(refresh, target));
RETERR(str_totext(" ", target));
/* add hold-down */
when = uint32_fromregion(&sr);
add = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
RETERR(dns_time32_totext(when, target));
RETERR(dns_time32_totext(add, target));
RETERR(str_totext(" ", target));
/* remove hold-down */
when = uint32_fromregion(&sr);
remove = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
RETERR(dns_time32_totext(when, target));
RETERR(dns_time32_totext(remove, target));
RETERR(str_totext(" ", target));
/* flags */
@ -176,6 +177,10 @@ totext_keydata(ARGS_TOTEXT) {
if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
isc_region_t tmpr;
char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
isc_time_t t;
RETERR(str_totext(" ; ", target));
RETERR(str_totext(keyinfo, target));
@ -189,6 +194,47 @@ totext_keydata(ARGS_TOTEXT) {
isc_region_consume(&tmpr, 12);
sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
RETERR(str_totext(buf, target));
if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
isc_stdtime_t now;
isc_stdtime_get(&now);
RETERR(str_totext(tctx->linebreak, target));
RETERR(str_totext("; next refresh: ", target));
isc_time_set(&t, refresh, 0);
isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf));
RETERR(str_totext(rbuf, target));
if (add == 0) {
RETERR(str_totext(tctx->linebreak, target));
RETERR(str_totext("; no trust", target));
} else {
RETERR(str_totext(tctx->linebreak, target));
if (add < now) {
RETERR(str_totext("; trusted since: ",
target));
} else {
RETERR(str_totext("; trust pending: ",
target));
}
isc_time_set(&t, add, 0);
isc_time_formathttptimestamp(&t, abuf,
sizeof(abuf));
RETERR(str_totext(abuf, target));
}
if (remove != 0) {
RETERR(str_totext(tctx->linebreak, target));
RETERR(str_totext("; removal pending: ",
target));
isc_time_set(&t, remove, 0);
isc_time_formathttptimestamp(&t, dbuf,
sizeof(dbuf));
RETERR(str_totext(dbuf, target));
}
}
}
return (ISC_R_SUCCESS);
}

View file

@ -383,6 +383,7 @@ dns_keytable_findnextkeynode
dns_keytable_issecuredomain
dns_keytable_marksecure
dns_keytable_nextkeynode
dns_keytable_totext
dns_lib_init
dns_lib_initmsgcat
dns_lib_shutdown

View file

@ -704,6 +704,16 @@ struct dns_include {
#define DAY (24*HOUR)
#define MONTH (30*DAY)
/*
* These can be overridden by the -T mkeytimers option on the command
* line, so that we can test with shorter periods than specified in
* RFC 5011.
*/
unsigned int dns_zone_mkey_hour = HOUR;
unsigned int dns_zone_mkey_day = (24 * HOUR);
unsigned int dns_zone_mkey_month = (30 * DAY);
#define SEND_BUFFER_SIZE 2048
static void zone_settimer(dns_zone_t *, isc_time_t *);
@ -3459,7 +3469,7 @@ check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
*/
static void
set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
isc_stdtime_t now)
isc_stdtime_t now, isc_boolean_t force)
{
const char me[] = "set_refreshkeytimer";
isc_stdtime_t then;
@ -3468,6 +3478,8 @@ set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
ENTER;
then = key->refresh;
if (force)
then = now;
if (key->addhd > now && key->addhd < then)
then = key->addhd;
if (key->removehd > now && key->removehd < then)
@ -3547,8 +3559,9 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
dst_key_name(key), 0, &rdata));
*changed = ISC_TRUE;
/* Refresh new keys from the zone apex as soon as possible. */
set_refreshkeytimer(zone, &keydata, now);
set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
skip:
result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
@ -3704,8 +3717,8 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
continue;
RUNTIME_CHECK(result == ISC_R_SUCCESS);
/* Set the key refresh timer. */
set_refreshkeytimer(zone, &keydata, now);
/* Set the key refresh timer to force a fast refresh. */
set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
/* If the removal timer is nonzero, this key was revoked. */
if (keydata.removehd != 0) {
@ -3973,7 +3986,8 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
result = dns_keytable_find(sr, rrname, &keynode);
if ((result != ISC_R_SUCCESS &&
result != DNS_R_PARTIALMATCH) ||
dns_keynode_managed(keynode) == ISC_FALSE) {
dns_keynode_managed(keynode) == ISC_FALSE)
{
CHECK(delete_keydata(db, ver, &diff,
rrname, rdataset));
changed = ISC_TRUE;
@ -8382,7 +8396,8 @@ zone_sign(dns_zone_t *zone) {
static isc_result_t
normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
unsigned char *data, int size) {
unsigned char *data, int size)
{
dns_rdata_dnskey_t dnskey;
dns_rdata_keydata_t keydata;
isc_buffer_t buf;
@ -8479,11 +8494,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
rdset = &kfetch->dnskeysigset;
else
return (now + HOUR);
return (now + dns_zone_mkey_hour);
result = dns_rdataset_first(rdset);
if (result != ISC_R_SUCCESS)
return (now + HOUR);
return (now + dns_zone_mkey_hour);
dns_rdataset_current(rdset, &sigrr);
result = dns_rdata_tostruct(&sigrr, &sig, NULL);
@ -8498,11 +8513,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
t = exp;
}
if (t > (15*DAY))
t = (15*DAY);
if (t > (15 * dns_zone_mkey_day))
t = (15 * dns_zone_mkey_day);
if (t < HOUR)
t = HOUR;
if (t < dns_zone_mkey_hour)
t = dns_zone_mkey_hour;
} else {
t = sig.originalttl / 10;
@ -8512,11 +8527,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
t = exp;
}
if (t > DAY)
t = DAY;
if (t > dns_zone_mkey_day)
t = dns_zone_mkey_day;
if (t < HOUR)
t = HOUR;
if (t < dns_zone_mkey_hour)
t = dns_zone_mkey_hour;
}
return (now + t);
@ -8559,7 +8574,7 @@ minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
if (result != ISC_R_SUCCESS)
goto failure;
keydata.refresh = refresh_time(kfetch, ISC_TRUE);
set_refreshkeytimer(zone, &keydata, now);
set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
dns_rdata_reset(&rdata);
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
@ -8602,8 +8617,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
/* Generate a key from keydata */
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
dns_keydata_todnskey(keydata, &dnskey, NULL);
dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
&dnskey, &keyb);
dns_rdata_fromstruct(&rr, keydata->common.rdclass,
dns_rdatatype_dnskey, &dnskey, &keyb);
result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
if (result != ISC_R_SUCCESS)
return (ISC_FALSE);
@ -8611,7 +8626,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
/* See if that key generated any of the signatures */
for (result = dns_rdataset_first(&kfetch->dnskeysigset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&kfetch->dnskeysigset)) {
result = dns_rdataset_next(&kfetch->dnskeysigset))
{
dns_fixedname_t fixed;
dns_fixedname_init(&fixed);
@ -8621,8 +8637,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (dst_key_alg(dstkey) == sig.algorithm &&
(dst_key_id(dstkey) == sig.keyid ||
dst_key_rid(dstkey) == sig.keyid)) {
dst_key_rid(dstkey) == sig.keyid)
{
result = dns_dnssec_verify2(keyname,
&kfetch->dnskeyset,
dstkey, ISC_FALSE, mctx, &sigrr,
@ -8784,8 +8800,6 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
dns_trust_secure;
kfetch->dnskeysigset.trust =
dns_trust_secure;
dns_keytable_detachkeynode(secroots,
&keynode);
break;
}
}
@ -8796,6 +8810,9 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
keynode = nextnode;
}
if (keynode != NULL)
dns_keytable_detachkeynode(secroots, &keynode);
if (kfetch->dnskeyset.trust == dns_trust_secure)
break;
}
@ -8840,31 +8857,34 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
isc_boolean_t deletekey = ISC_FALSE;
if (!secure) {
if (now > keydata.removehd)
if (keydata.removehd != 0 &&
keydata.removehd <= now)
deletekey = ISC_TRUE;
} else if (now < keydata.addhd) {
} else if (keydata.addhd == 0) {
deletekey = ISC_TRUE;
} else if (keydata.addhd > now) {
dns_zone_log(zone, ISC_LOG_WARNING,
"Pending key unexpectedly missing "
"from %s; restarting acceptance "
"timer", namebuf);
keydata.addhd = now + MONTH;
if (keydata.addhd < now + dns_zone_mkey_month)
keydata.addhd =
now + dns_zone_mkey_month;
keydata.refresh = refresh_time(kfetch,
ISC_FALSE);
} else if (keydata.addhd == 0) {
keydata.addhd = now;
} else if (keydata.removehd == 0) {
dns_zone_log(zone, ISC_LOG_WARNING,
"Active key unexpectedly missing "
"from %s", namebuf);
keydata.refresh = now + HOUR;
} else if (now > keydata.removehd) {
keydata.refresh = now + dns_zone_mkey_hour;
} else if (keydata.removehd <= now) {
deletekey = ISC_TRUE;
} else {
keydata.refresh = refresh_time(kfetch,
ISC_FALSE);
}
if (secure || deletekey) {
if (secure || deletekey) {
/* Delete old version */
CHECK(update_one_rr(kfetch->db, ver, &diff,
DNS_DIFFOP_DEL, keyname, 0,
@ -8885,7 +8905,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
DNS_DIFFOP_ADD, keyname, 0,
&keydatarr));
set_refreshkeytimer(zone, &keydata, now);
set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
}
}
@ -8907,7 +8927,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
*/
for (result = dns_rdataset_first(&kfetch->dnskeyset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&kfetch->dnskeyset)) {
result = dns_rdataset_next(&kfetch->dnskeyset))
{
isc_boolean_t revoked = ISC_FALSE;
isc_boolean_t newkey = ISC_FALSE;
isc_boolean_t updatekey = ISC_FALSE;
@ -8943,34 +8964,43 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
dns_view_untrust(zone->view, keyname,
&dnskey, mctx);
/* But ensure there's a null key */
fail_secure(zone, keyname);
/* If initializing, delete now */
if (keydata.addhd == 0)
deletekey = ISC_TRUE;
else
keydata.removehd = now + MONTH;
else {
keydata.removehd = now +
dns_zone_mkey_month;
keydata.flags |=
DNS_KEYFLAG_REVOKE;
}
} else if (keydata.removehd < now) {
/* Scheduled for removal */
deletekey = ISC_TRUE;
}
} else if (revoked) {
if (secure && keydata.removehd == 0) {
dns_zone_log(zone, ISC_LOG_WARNING,
"Active key for zone "
"'%s' is revoked but "
"did not self-sign; "
"ignoring.", namebuf);
continue;
}
} else if (revoked && keydata.removehd == 0) {
dns_zone_log(zone, ISC_LOG_WARNING,
"Active key for zone "
"'%s' is revoked but "
"did not self-sign; "
"ignoring.", namebuf);
continue;
} else if (secure) {
if (keydata.removehd != 0) {
/*
* Key isn't revoked--but it
* seems it used to be.
* Remove it now and add it
* back as if it were a fresh key.
* back as if it were a fresh key,
* with a 30 day acceptance timer.
*/
deletekey = ISC_TRUE;
newkey = ISC_TRUE;
keydata.removehd = 0;
keydata.addhd =
now + dns_zone_mkey_month;
} else if (keydata.addhd > now)
pending++;
else if (keydata.addhd == 0)
@ -8978,6 +9008,13 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
if (keydata.addhd <= now)
trustkey = ISC_TRUE;
} else if (keydata.addhd > now) {
/*
* Not secure, and key is pending:
* reset the acceptance timer
*/
pending++;
keydata.addhd = now + dns_zone_mkey_month;
}
if (!deletekey && !newkey)
@ -9039,7 +9076,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
NULL);
keydata.addhd = initializing ? now : now + MONTH;
keydata.addhd = initializing
? now : now + dns_zone_mkey_month;
keydata.refresh = refresh_time(kfetch, ISC_FALSE);
dns_rdata_reset(&keydatarr);
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
@ -9062,7 +9100,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
if (secure && !deletekey) {
INSIST(newkey || updatekey);
set_refreshkeytimer(zone, &keydata, now);
set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
}
}
@ -9276,7 +9314,7 @@ zone_refreshkeys(dns_zone_t *zone) {
char timebuf[80];
TIME_NOW(&timenow);
DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
zone->refreshkeytime = timethen;
zone_settimer(zone, &timenow);

View file

@ -471,6 +471,7 @@ isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length) {
REQUIRE(dynbuffer != NULL);
REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
REQUIRE((*dynbuffer)->mctx != NULL);
if ((*dynbuffer)->length > length)
return (ISC_R_NOSPACE);
@ -502,12 +503,16 @@ isc_result_t
isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size) {
isc_uint64_t len;
REQUIRE(dynbuffer != NULL);
REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
len = (*dynbuffer)->length;
if ((len - (*dynbuffer)->used) >= size)
return (ISC_R_SUCCESS);
if ((*dynbuffer)->mctx == NULL)
return (ISC_R_NOSPACE);
/* Round to nearest buffer size increment */
len = size + (*dynbuffer)->used;
len = (len + ISC_BUFFER_INCR - 1 - ((len - 1) % ISC_BUFFER_INCR));

View file

@ -648,7 +648,7 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
isc_socketevent_t *sev = (isc_socketevent_t *)ev;
isc_httpdurl_t *url;
isc_time_t now;
char datebuf[32]; /* Only need 30, but safety first */
char datebuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
ENTER("recv");
@ -729,7 +729,7 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
isc_httpd_addheader(httpd, "Expires", datebuf);
if (url != NULL && url->isstatic) {
char loadbuf[32];
char loadbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
isc_time_formathttptimestamp(&url->loadtime,
loadbuf, sizeof(loadbuf));
isc_httpd_addheader(httpd, "Last-Modified", loadbuf);

View file

@ -29,7 +29,7 @@ ATF_TC_HEAD(isc_time_parsehttptimestamp, tc) {
ATF_TC_BODY(isc_time_parsehttptimestamp, tc) {
isc_result_t result;
isc_time_t t, x;
char buf[100];
char buf[ISC_FORMATHTTPTIMESTAMP_SIZE];
setenv("TZ", "PST8PDT", 1);
result = isc_time_now(&t);

View file

@ -43,6 +43,13 @@ struct isc_interval {
extern const isc_interval_t * const isc_interval_zero;
/*
* ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially
* more for other locales to handle longer national abbreviations when
* expanding strftime's %a and %b.
*/
#define ISC_FORMATHTTPTIMESTAMP_SIZE 50
ISC_LANG_BEGINDECLS
void

View file

@ -406,6 +406,9 @@ isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
REQUIRE(len > 0);
/*
* 5 spaces, 1 comma, 3 GMT, 2 %d, 4 %Y, 8 %H:%M:%S, 3+ %a, 3+ %b (29+)
*/
now = (time_t)t->seconds;
flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
INSIST(flen < len);

View file

@ -41,6 +41,13 @@ struct isc_interval {
LIBISC_EXTERNAL_DATA extern const isc_interval_t * const isc_interval_zero;
/*
* ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially
* more for other locales to handle longer national abbreviations when
* expanding strftime's %a and %b.
*/
#define ISC_FORMATHTTPTIMESTAMP_SIZE 50
ISC_LANG_BEGINDECLS
void