2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 10:10:06 +00:00

Check if key metadata is modified before writing

Add a new parameter to the dst_key structure, mark a key modified if
dst_key_(un)set[bool,num,state,time] is called. Only write out key
files during a keymgr run if the metadata has changed.
This commit is contained in:
Matthijs Mekking 2022-05-03 12:28:31 +02:00
parent 7249bad706
commit 1da91b3ab4
4 changed files with 63 additions and 1 deletions

View File

@ -469,6 +469,16 @@ dst_key_isexternal(dst_key_t *key) {
return (key->external);
}
void
dst_key_setmodified(dst_key_t *key, bool value) {
key->modified = value;
}
bool
dst_key_ismodified(dst_key_t *key) {
return (key->modified);
}
isc_result_t
dst_key_getfilename(dns_name_t *name, dns_keytag_t id, unsigned int alg,
int type, const char *directory, isc_mem_t *mctx,
@ -610,6 +620,7 @@ dst_key_fromnamedfile(const char *filename, const char *dirname, int type,
(pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY)
{
RETERR(computeid(pubkey));
pubkey->modified = false;
*keyp = pubkey;
pubkey = NULL;
goto out;
@ -663,6 +674,7 @@ dst_key_fromnamedfile(const char *filename, const char *dirname, int type,
RETERR(DST_R_INVALIDPRIVATEKEY);
}
key->modified = false;
*keyp = key;
key = NULL;
@ -1016,6 +1028,8 @@ dst_key_setbool(dst_key_t *key, int type, bool value) {
REQUIRE(type <= DST_MAX_BOOLEAN);
isc_mutex_lock(&key->mdlock);
key->modified = key->modified || !key->boolset[type] ||
key->bools[type] != value;
key->bools[type] = value;
key->boolset[type] = true;
isc_mutex_unlock(&key->mdlock);
@ -1027,6 +1041,7 @@ dst_key_unsetbool(dst_key_t *key, int type) {
REQUIRE(type <= DST_MAX_BOOLEAN);
isc_mutex_lock(&key->mdlock);
key->modified = key->modified || key->boolset[type];
key->boolset[type] = false;
isc_mutex_unlock(&key->mdlock);
}
@ -1054,6 +1069,8 @@ dst_key_setnum(dst_key_t *key, int type, uint32_t value) {
REQUIRE(type <= DST_MAX_NUMERIC);
isc_mutex_lock(&key->mdlock);
key->modified = key->modified || !key->numset[type] ||
key->nums[type] != value;
key->nums[type] = value;
key->numset[type] = true;
isc_mutex_unlock(&key->mdlock);
@ -1065,6 +1082,7 @@ dst_key_unsetnum(dst_key_t *key, int type) {
REQUIRE(type <= DST_MAX_NUMERIC);
isc_mutex_lock(&key->mdlock);
key->modified = key->modified || key->numset[type];
key->numset[type] = false;
isc_mutex_unlock(&key->mdlock);
}
@ -1091,6 +1109,8 @@ dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when) {
REQUIRE(type <= DST_MAX_TIMES);
isc_mutex_lock(&key->mdlock);
key->modified = key->modified || !key->timeset[type] ||
key->times[type] != when;
key->times[type] = when;
key->timeset[type] = true;
isc_mutex_unlock(&key->mdlock);
@ -1102,6 +1122,7 @@ dst_key_unsettime(dst_key_t *key, int type) {
REQUIRE(type <= DST_MAX_TIMES);
isc_mutex_lock(&key->mdlock);
key->modified = key->modified || key->timeset[type];
key->timeset[type] = false;
isc_mutex_unlock(&key->mdlock);
}
@ -1129,6 +1150,8 @@ dst_key_setstate(dst_key_t *key, int type, dst_key_state_t state) {
REQUIRE(type <= DST_MAX_KEYSTATES);
isc_mutex_lock(&key->mdlock);
key->modified = key->modified || !key->keystateset[type] ||
key->keystates[type] != state;
key->keystates[type] = state;
key->keystateset[type] = true;
isc_mutex_unlock(&key->mdlock);
@ -1140,6 +1163,7 @@ dst_key_unsetstate(dst_key_t *key, int type) {
REQUIRE(type <= DST_MAX_KEYSTATES);
isc_mutex_lock(&key->mdlock);
key->modified = key->modified || key->keystateset[type];
key->keystateset[type] = false;
isc_mutex_unlock(&key->mdlock);
}
@ -2704,4 +2728,6 @@ dst_key_copy_metadata(dst_key_t *to, dst_key_t *from) {
dst_key_unsetstate(to, i);
}
}
dst_key_setmodified(to, dst_key_ismodified(from));
}

View File

@ -122,6 +122,7 @@ struct dst_key {
bool inactive; /*%< private key not present as it is
* inactive */
bool external; /*%< external key */
bool modified; /*%< set to true if key file metadata has changed */
int fmt_major; /*%< private key format, major version
* */

View File

@ -1106,6 +1106,26 @@ dst_key_isexternal(dst_key_t *key);
* 'key' to be valid.
*/
void
dst_key_setmodified(dst_key_t *key, bool value);
/*%<
* If 'value' is true, this marks the key to indicate that key file metadata
* has been modified. If 'value' is false, this resets the value, for example
* after you have written the key to file.
*
* Requires:
* 'key' to be valid.
*/
bool
dst_key_ismodified(dst_key_t *key);
/*%<
* Check if the key file has been modified.
*
* Requires:
* 'key' to be valid.
*/
bool
dst_key_haskasp(dst_key_t *key);
/*%<

View File

@ -1511,6 +1511,7 @@ transition:
/* It is safe to make the transition. */
dst_key_setstate(dkey->key, i, next_state);
dst_key_settime(dkey->key, keystatetimes[i], now);
INSIST(dst_key_ismodified(dkey->key));
changed = true;
}
}
@ -2179,9 +2180,10 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL;
dkey = ISC_LIST_NEXT(dkey, link))
{
if (!dkey->purge) {
if (dst_key_ismodified(dkey->key) && !dkey->purge) {
dns_dnssec_get_hints(dkey, now);
RETERR(dst_key_tofile(dkey->key, options, directory));
dst_key_setmodified(dkey->key, false);
}
}
@ -2201,6 +2203,13 @@ failure:
}
}
if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(origin, namebuf, sizeof(namebuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(3),
"keymgr: %s done", namebuf);
}
return (result);
}
@ -2278,6 +2287,9 @@ keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
dns_dnssec_get_hints(ksk_key, now);
result = dst_key_tofile(ksk_key->key, options, directory);
if (result == ISC_R_SUCCESS) {
dst_key_setmodified(ksk_key->key, false);
}
isc_dir_close(&dir);
return (result);
@ -2578,6 +2590,9 @@ dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
dns_dnssec_get_hints(key, now);
result = dst_key_tofile(key->key, options, directory);
if (result == ISC_R_SUCCESS) {
dst_key_setmodified(key->key, false);
}
isc_dir_close(&dir);
return (result);