mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[9.20] fix: dev: Fix possible truncation in dns_keymgr_status()
If the generated status output exceeds 4096 it was silently truncated, now we output that the status was truncated. Closes #4180 Backport of MR !9905 Merge branch 'backport-4180-possible-truncation-in-dns_keymgr_status-9.20' into 'bind-9.20' See merge request isc-projects/bind9!9981
This commit is contained in:
commit
1333dac316
3 changed files with 99 additions and 74 deletions
|
|
@ -15228,10 +15228,16 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
|
|||
/*
|
||||
* Output the DNSSEC status of the key and signing policy.
|
||||
*/
|
||||
isc_result_t r;
|
||||
LOCK(&kasp->lock);
|
||||
dns_keymgr_status(kasp, &keys, now, &output[0], sizeof(output));
|
||||
r = dns_keymgr_status(kasp, &keys, now, &output[0],
|
||||
sizeof(output));
|
||||
UNLOCK(&kasp->lock);
|
||||
CHECK(putstr(text, output));
|
||||
if (r != ISC_R_SUCCESS) {
|
||||
CHECK(putstr(text,
|
||||
"\n\nStatus output is truncated..."));
|
||||
}
|
||||
} else if (checkds) {
|
||||
/*
|
||||
* Mark DS record has been seen, so it may move to the
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
|
|||
*
|
||||
*/
|
||||
|
||||
void
|
||||
isc_result_t
|
||||
dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
|
||||
isc_stdtime_t now, char *out, size_t out_len);
|
||||
/*%<
|
||||
|
|
@ -155,6 +155,9 @@ dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
|
|||
*\li 'out' is not NULL.
|
||||
*
|
||||
* Returns:
|
||||
*\li ISC_R_SUCCESS on success.
|
||||
*\li ISC_R_NOSPACE if the 'out' buffer is too small.
|
||||
*\li ISC_R_FAILURE if other error occurred.
|
||||
*\li Printable status in 'out'.
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
160
lib/dns/keymgr.c
160
lib/dns/keymgr.c
|
|
@ -61,7 +61,7 @@
|
|||
ISC_LOG_DEBUG(3), \
|
||||
"keymgr: DNSKEY %s (%s) initialize " \
|
||||
"%s state to %s (policy %s)", \
|
||||
keystr, keymgr_keyrole((key)), \
|
||||
keystr, keymgr_keyrole(key), \
|
||||
keystatetags[state], \
|
||||
keystatestrings[target], \
|
||||
dns_kasp_getname(kasp)); \
|
||||
|
|
@ -2400,36 +2400,38 @@ dns_keymgr_checkds_id(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
|
|||
true);
|
||||
}
|
||||
|
||||
static void
|
||||
static isc_result_t
|
||||
keytime_status(dst_key_t *key, isc_stdtime_t now, isc_buffer_t *buf,
|
||||
const char *pre, int ks, int kt) {
|
||||
char timestr[26]; /* Minimal buf as per ctime_r() spec. */
|
||||
isc_result_t ret;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_stdtime_t when = 0;
|
||||
dst_key_state_t state = NA;
|
||||
|
||||
isc_buffer_printf(buf, "%s", pre);
|
||||
RETERR(isc_buffer_printf(buf, "%s", pre));
|
||||
(void)dst_key_getstate(key, ks, &state);
|
||||
ret = dst_key_gettime(key, kt, &when);
|
||||
isc_result_t r = dst_key_gettime(key, kt, &when);
|
||||
if (state == RUMOURED || state == OMNIPRESENT) {
|
||||
isc_buffer_printf(buf, "yes - since ");
|
||||
RETERR(isc_buffer_printf(buf, "yes - since "));
|
||||
} else if (now < when) {
|
||||
isc_buffer_printf(buf, "no - scheduled ");
|
||||
RETERR(isc_buffer_printf(buf, "no - scheduled "));
|
||||
} else {
|
||||
isc_buffer_printf(buf, "no\n");
|
||||
return;
|
||||
return isc_buffer_printf(buf, "no\n");
|
||||
}
|
||||
if (ret == ISC_R_SUCCESS) {
|
||||
if (r == ISC_R_SUCCESS) {
|
||||
isc_stdtime_tostring(when, timestr, sizeof(timestr));
|
||||
isc_buffer_printf(buf, "%s\n", timestr);
|
||||
RETERR(isc_buffer_printf(buf, "%s\n", timestr));
|
||||
}
|
||||
|
||||
failure:
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
static isc_result_t
|
||||
rollover_status(dns_dnsseckey_t *dkey, dns_kasp_t *kasp, isc_stdtime_t now,
|
||||
isc_buffer_t *buf, bool zsk) {
|
||||
char timestr[26]; /* Minimal buf as per ctime_r() spec. */
|
||||
isc_result_t ret = ISC_R_SUCCESS;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_stdtime_t active_time = 0;
|
||||
dst_key_state_t state = NA, goal = NA;
|
||||
int rrsig, active, retire;
|
||||
|
|
@ -2445,14 +2447,14 @@ rollover_status(dns_dnsseckey_t *dkey, dns_kasp_t *kasp, isc_stdtime_t now,
|
|||
retire = DST_TIME_DELETE;
|
||||
}
|
||||
|
||||
isc_buffer_printf(buf, "\n");
|
||||
RETERR(isc_buffer_printf(buf, "\n"));
|
||||
|
||||
(void)dst_key_getstate(key, DST_KEY_GOAL, &goal);
|
||||
(void)dst_key_getstate(key, rrsig, &state);
|
||||
(void)dst_key_gettime(key, active, &active_time);
|
||||
if (active_time == 0) {
|
||||
// only interested in keys that were once active.
|
||||
return;
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
if (goal == HIDDEN && (state == UNRETENTIVE || state == HIDDEN)) {
|
||||
|
|
@ -2461,79 +2463,89 @@ rollover_status(dns_dnsseckey_t *dkey, dns_kasp_t *kasp, isc_stdtime_t now,
|
|||
state = NA;
|
||||
(void)dst_key_getstate(key, DST_KEY_DNSKEY, &state);
|
||||
if (state == RUMOURED || state == OMNIPRESENT) {
|
||||
ret = dst_key_gettime(key, DST_TIME_DELETE,
|
||||
&remove_time);
|
||||
if (ret == ISC_R_SUCCESS) {
|
||||
isc_buffer_printf(buf, " Key is retired, will "
|
||||
"be removed on ");
|
||||
result = dst_key_gettime(key, DST_TIME_DELETE,
|
||||
&remove_time);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
RETERR(isc_buffer_printf(
|
||||
buf, " Key is retired, will be "
|
||||
"removed on "));
|
||||
isc_stdtime_tostring(remove_time, timestr,
|
||||
sizeof(timestr));
|
||||
isc_buffer_printf(buf, "%s", timestr);
|
||||
RETERR(isc_buffer_printf(buf, "%s", timestr));
|
||||
}
|
||||
} else {
|
||||
isc_buffer_printf(
|
||||
buf, " Key has been removed from the zone");
|
||||
RETERR(isc_buffer_printf(buf, " Key has been removed "
|
||||
"from the zone"));
|
||||
}
|
||||
} else {
|
||||
isc_stdtime_t retire_time = 0;
|
||||
ret = dst_key_gettime(key, retire, &retire_time);
|
||||
if (ret == ISC_R_SUCCESS) {
|
||||
result = dst_key_gettime(key, retire, &retire_time);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (now < retire_time) {
|
||||
if (goal == OMNIPRESENT) {
|
||||
isc_buffer_printf(buf,
|
||||
" Next rollover "
|
||||
"scheduled on ");
|
||||
RETERR(isc_buffer_printf(
|
||||
buf, " Next rollover "
|
||||
"scheduled on "));
|
||||
retire_time = keymgr_prepublication_time(
|
||||
dkey, kasp,
|
||||
(retire_time - active_time),
|
||||
now);
|
||||
} else {
|
||||
isc_buffer_printf(
|
||||
buf, " Key will retire on ");
|
||||
RETERR(isc_buffer_printf(
|
||||
buf, " Key will retire on "));
|
||||
}
|
||||
} else {
|
||||
isc_buffer_printf(buf,
|
||||
" Rollover is due since ");
|
||||
RETERR(isc_buffer_printf(buf, " Rollover is "
|
||||
"due since "));
|
||||
}
|
||||
isc_stdtime_tostring(retire_time, timestr,
|
||||
sizeof(timestr));
|
||||
isc_buffer_printf(buf, "%s", timestr);
|
||||
RETERR(isc_buffer_printf(buf, "%s", timestr));
|
||||
} else {
|
||||
isc_buffer_printf(buf, " No rollover scheduled");
|
||||
RETERR(isc_buffer_printf(buf,
|
||||
" No rollover scheduled"));
|
||||
}
|
||||
}
|
||||
isc_buffer_printf(buf, "\n");
|
||||
RETERR(isc_buffer_printf(buf, "\n"));
|
||||
|
||||
failure:
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
static isc_result_t
|
||||
keystate_status(dst_key_t *key, isc_buffer_t *buf, const char *pre, int ks) {
|
||||
dst_key_state_t state = NA;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
(void)dst_key_getstate(key, ks, &state);
|
||||
switch (state) {
|
||||
case HIDDEN:
|
||||
isc_buffer_printf(buf, " - %shidden\n", pre);
|
||||
RETERR(isc_buffer_printf(buf, " - %shidden\n", pre));
|
||||
break;
|
||||
case RUMOURED:
|
||||
isc_buffer_printf(buf, " - %srumoured\n", pre);
|
||||
RETERR(isc_buffer_printf(buf, " - %srumoured\n", pre));
|
||||
break;
|
||||
case OMNIPRESENT:
|
||||
isc_buffer_printf(buf, " - %somnipresent\n", pre);
|
||||
RETERR(isc_buffer_printf(buf, " - %somnipresent\n", pre));
|
||||
break;
|
||||
case UNRETENTIVE:
|
||||
isc_buffer_printf(buf, " - %sunretentive\n", pre);
|
||||
RETERR(isc_buffer_printf(buf, " - %sunretentive\n", pre));
|
||||
break;
|
||||
case NA:
|
||||
default:
|
||||
/* print nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
failure:
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
isc_result_t
|
||||
dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
|
||||
isc_stdtime_t now, char *out, size_t out_len) {
|
||||
isc_buffer_t buf;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
char timestr[26]; /* Minimal buf as per ctime_r() spec. */
|
||||
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
|
|
@ -2543,17 +2555,17 @@ dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
|
|||
isc_buffer_init(&buf, out, out_len);
|
||||
|
||||
// policy name
|
||||
isc_buffer_printf(&buf, "dnssec-policy: %s\n", dns_kasp_getname(kasp));
|
||||
isc_buffer_printf(&buf, "current time: ");
|
||||
RETERR(isc_buffer_printf(&buf, "dnssec-policy: %s\n",
|
||||
dns_kasp_getname(kasp)));
|
||||
RETERR(isc_buffer_printf(&buf, "current time: "));
|
||||
isc_stdtime_tostring(now, timestr, sizeof(timestr));
|
||||
isc_buffer_printf(&buf, "%s\n", timestr);
|
||||
RETERR(isc_buffer_printf(&buf, "%s\n", timestr));
|
||||
|
||||
for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL;
|
||||
dkey = ISC_LIST_NEXT(dkey, link))
|
||||
{
|
||||
char algstr[DNS_NAME_FORMATSIZE];
|
||||
bool ksk = false, zsk = false;
|
||||
isc_result_t ret;
|
||||
|
||||
if (dst_key_is_unused(dkey->key)) {
|
||||
continue;
|
||||
|
|
@ -2562,44 +2574,48 @@ dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
|
|||
// key data
|
||||
dns_secalg_format((dns_secalg_t)dst_key_alg(dkey->key), algstr,
|
||||
sizeof(algstr));
|
||||
isc_buffer_printf(&buf, "\nkey: %d (%s), %s\n",
|
||||
dst_key_id(dkey->key), algstr,
|
||||
keymgr_keyrole(dkey->key));
|
||||
RETERR(isc_buffer_printf(&buf, "\nkey: %d (%s), %s\n",
|
||||
dst_key_id(dkey->key), algstr,
|
||||
keymgr_keyrole(dkey->key)));
|
||||
|
||||
// publish status
|
||||
keytime_status(dkey->key, now, &buf,
|
||||
" published: ", DST_KEY_DNSKEY,
|
||||
DST_TIME_PUBLISH);
|
||||
RETERR(keytime_status(dkey->key, now, &buf,
|
||||
" published: ", DST_KEY_DNSKEY,
|
||||
DST_TIME_PUBLISH));
|
||||
|
||||
// signing status
|
||||
ret = dst_key_getbool(dkey->key, DST_BOOL_KSK, &ksk);
|
||||
if (ret == ISC_R_SUCCESS && ksk) {
|
||||
keytime_status(dkey->key, now, &buf,
|
||||
" key signing: ", DST_KEY_KRRSIG,
|
||||
DST_TIME_PUBLISH);
|
||||
result = dst_key_getbool(dkey->key, DST_BOOL_KSK, &ksk);
|
||||
if (result == ISC_R_SUCCESS && ksk) {
|
||||
RETERR(keytime_status(
|
||||
dkey->key, now, &buf, " key signing: ",
|
||||
DST_KEY_KRRSIG, DST_TIME_PUBLISH));
|
||||
}
|
||||
ret = dst_key_getbool(dkey->key, DST_BOOL_ZSK, &zsk);
|
||||
if (ret == ISC_R_SUCCESS && zsk) {
|
||||
keytime_status(dkey->key, now, &buf,
|
||||
" zone signing: ", DST_KEY_ZRRSIG,
|
||||
DST_TIME_ACTIVATE);
|
||||
result = dst_key_getbool(dkey->key, DST_BOOL_ZSK, &zsk);
|
||||
if (result == ISC_R_SUCCESS && zsk) {
|
||||
RETERR(keytime_status(
|
||||
dkey->key, now, &buf, " zone signing: ",
|
||||
DST_KEY_ZRRSIG, DST_TIME_ACTIVATE));
|
||||
}
|
||||
|
||||
// rollover status
|
||||
rollover_status(dkey, kasp, now, &buf, zsk);
|
||||
RETERR(rollover_status(dkey, kasp, now, &buf, zsk));
|
||||
|
||||
// key states
|
||||
keystate_status(dkey->key, &buf,
|
||||
"goal: ", DST_KEY_GOAL);
|
||||
keystate_status(dkey->key, &buf,
|
||||
"dnskey: ", DST_KEY_DNSKEY);
|
||||
keystate_status(dkey->key, &buf,
|
||||
"ds: ", DST_KEY_DS);
|
||||
keystate_status(dkey->key, &buf,
|
||||
"zone rrsig: ", DST_KEY_ZRRSIG);
|
||||
keystate_status(dkey->key, &buf,
|
||||
"key rrsig: ", DST_KEY_KRRSIG);
|
||||
RETERR(keystate_status(dkey->key, &buf,
|
||||
"goal: ", DST_KEY_GOAL));
|
||||
RETERR(keystate_status(dkey->key, &buf,
|
||||
"dnskey: ", DST_KEY_DNSKEY));
|
||||
RETERR(keystate_status(dkey->key, &buf,
|
||||
"ds: ", DST_KEY_DS));
|
||||
RETERR(keystate_status(dkey->key, &buf,
|
||||
"zone rrsig: ", DST_KEY_ZRRSIG));
|
||||
RETERR(keystate_status(dkey->key, &buf,
|
||||
"key rrsig: ", DST_KEY_KRRSIG));
|
||||
}
|
||||
|
||||
failure:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
|
|||
Loading…
Reference in a new issue