diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 8c30438cc2..97b53f1b2f 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -884,8 +884,8 @@ setup_text_key(void) { } result = dns_tsigkey_create(&keyname, hmacname, secretstore, - (int)secretsize, false, NULL, 0, 0, mctx, - NULL, &tsigkey); + (int)secretsize, false, false, NULL, 0, 0, + mctx, NULL, &tsigkey); failure: if (result != ISC_R_SUCCESS) { printf(";; Couldn't create key %s: %s\n", keynametext, @@ -1186,8 +1186,8 @@ setup_file_key(void) { if (hmacname != NULL) { result = dns_tsigkey_createfromkey( - dst_key_name(dstkey), hmacname, dstkey, false, NULL, 0, - 0, mctx, NULL, &tsigkey); + dst_key_name(dstkey), hmacname, dstkey, false, false, + NULL, 0, 0, mctx, NULL, &tsigkey); if (result != ISC_R_SUCCESS) { printf(";; Couldn't create key %s: %s\n", keynametext, isc_result_totext(result)); diff --git a/bin/named/server.c b/bin/named/server.c index 8ca6872ded..f40a641e32 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -7548,7 +7548,8 @@ generate_session_key(const char *filename, const char *keynamestr, /* Store the key in tsigkey. */ isc_stdtime_get(&now); CHECK(dns_tsigkey_createfromkey(dst_key_name(key), algname, key, false, - NULL, now, now, mctx, NULL, &tsigkey)); + false, NULL, now, now, mctx, NULL, + &tsigkey)); /* Dump the key to the key file. */ fp = named_os_openfile(filename, S_IRUSR | S_IWUSR, first_time); diff --git a/bin/named/tsigconf.c b/bin/named/tsigconf.c index 6d596ab27f..d20ab72103 100644 --- a/bin/named/tsigconf.c +++ b/bin/named/tsigconf.c @@ -106,8 +106,8 @@ add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring, isc_stdtime_get(&now); ret = dns_tsigkey_create(&keyname, alg, secret, secretlen, - false, NULL, now, now, mctx, ring, - &tsigkey); + false, false, NULL, now, now, mctx, + ring, &tsigkey); isc_mem_put(mctx, secret, secretalloc); secret = NULL; if (ret != ISC_R_SUCCESS) { diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 60a3874a6a..e93b8abc2b 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -542,7 +542,8 @@ setup_keystr(void) { debug("keycreate"); result = dns_tsigkey_create(mykeyname, hmacname, secret, secretlen, - false, NULL, 0, 0, gmctx, NULL, &tsigkey); + false, false, NULL, 0, 0, gmctx, NULL, + &tsigkey); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s: %s\n", keystr, isc_result_totext(result)); @@ -676,8 +677,8 @@ setup_keyfile(isc_mem_t *mctx, isc_log_t *lctx) { } if (hmacname != NULL) { result = dns_tsigkey_createfromkey( - dst_key_name(dstkey), hmacname, dstkey, false, NULL, 0, - 0, mctx, NULL, &tsigkey); + dst_key_name(dstkey), hmacname, dstkey, false, false, + NULL, 0, 0, mctx, NULL, &tsigkey); dst_key_free(&dstkey); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s: %s\n", @@ -1710,7 +1711,8 @@ evaluate_key(char *cmdline) { dns_tsigkey_detach(&tsigkey); } result = dns_tsigkey_create(mykeyname, hmacname, secret, secretlen, - false, NULL, 0, 0, gmctx, NULL, &tsigkey); + false, false, NULL, 0, 0, gmctx, NULL, + &tsigkey); isc_mem_free(gmctx, secret); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s %s: %s\n", diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index 3969495821..ebf4d52522 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -56,8 +56,6 @@ export WIRETEST=$TOP_BUILDDIR/bin/tests/wire_test export BIGKEY=$TOP_BUILDDIR/bin/tests/system/rsabigexponent/bigkey export GENCHECK=$TOP_BUILDDIR/bin/tests/system/rndc/gencheck -export KEYCREATE=$TOP_BUILDDIR/bin/tests/system/tkey/keycreate -export KEYDELETE=$TOP_BUILDDIR/bin/tests/system/tkey/keydelete export MAKEJOURNAL=$TOP_BUILDDIR/bin/tests/system/makejournal export PIPEQUERIES=$TOP_BUILDDIR/bin/tests/system/pipelined/pipequeries diff --git a/bin/tests/system/tsiggss/tests.sh b/bin/tests/system/tsiggss/tests.sh index ee592bb470..32abb28f95 100644 --- a/bin/tests/system/tsiggss/tests.sh +++ b/bin/tests/system/tsiggss/tests.sh @@ -168,6 +168,18 @@ n=$((n+1)) if [ "$ret" -ne 0 ]; then echo_i "failed"; fi status=$((status+ret)) +echo_i "stop and start server to check key restoration ($n)" +ret=0 +gss_keys=$(grep 'tsig key.*generated' ns1/named.run | wc -l) +stop_server --use-rndc --port "${CONTROLPORT}" ns1 +start_server --noclean --restart --port "${PORT}" ns1 +restored_keys=$(grep 'tsig key.*restored from file' ns1/named.run | wc -l) +[ "$gss_keys" -ne 0 ] || ret=1 +[ "$restored_keys" -ne 0 ] || ret=1 +[ "$gss_keys" -eq "$restored_keys" ] || ret=1 +if [ "$ret" -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + [ $status -eq 0 ] && echo_i "tsiggss tests all OK" kill `cat authsock.pid` diff --git a/fuzz/dns_message_checksig.c b/fuzz/dns_message_checksig.c index b7407f3dd6..5c8f81aeb9 100644 --- a/fuzz/dns_message_checksig.c +++ b/fuzz/dns_message_checksig.c @@ -263,8 +263,8 @@ LLVMFuzzerInitialize(int *argc __attribute__((unused)), } result = dns_tsigkey_create(name, dns_tsig_hmacsha256_name, secret, - sizeof(secret), false, NULL, 0, 0, mctx, - ring, &tsigkey); + sizeof(secret), false, false, NULL, 0, 0, + mctx, ring, &tsigkey); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_tsigkey_create failed: %s\n", isc_result_totext(result)); diff --git a/lib/dns/include/dns/tsig.h b/lib/dns/include/dns/tsig.h index 48292a1da4..bb72d01e17 100644 --- a/lib/dns/include/dns/tsig.h +++ b/lib/dns/include/dns/tsig.h @@ -72,15 +72,16 @@ struct dns_tsigkey { /* Unlocked */ unsigned int magic; /*%< Magic number. */ isc_mem_t *mctx; - dst_key_t *key; /*%< Key */ - dns_name_t name; /*%< Key name */ - const dns_name_t *algorithm; /*%< Algorithm name */ - dns_name_t *creator; /*%< name that created secret */ - bool generated; /*%< was this generated? */ - isc_stdtime_t inception; /*%< start of validity period */ - isc_stdtime_t expire; /*%< end of validity period */ - dns_tsig_keyring_t *ring; /*%< the enclosing keyring */ - isc_refcount_t refs; /*%< reference counter */ + dst_key_t *key; /*%< Key */ + dns_name_t name; /*%< Key name */ + const dns_name_t *algorithm; /*%< Algorithm name */ + dns_name_t *creator; /*%< name that created secret */ + bool generated : 1; /*%< key was auto-generated */ + bool restored : 1; /*%< key was restored at startup */ + isc_stdtime_t inception; /*%< start of validity period */ + isc_stdtime_t expire; /*%< end of validity period */ + dns_tsig_keyring_t *ring; /*%< the enclosing keyring */ + isc_refcount_t refs; /*%< reference counter */ ISC_LINK(dns_tsigkey_t) link; }; @@ -102,13 +103,14 @@ dns_tsigkey_identity(const dns_tsigkey_t *tsigkey); isc_result_t dns_tsigkey_create(const dns_name_t *name, const dns_name_t *algorithm, unsigned char *secret, int length, bool generated, - const dns_name_t *creator, isc_stdtime_t inception, - isc_stdtime_t expire, isc_mem_t *mctx, - dns_tsig_keyring_t *ring, dns_tsigkey_t **key); + bool restored, const dns_name_t *creator, + isc_stdtime_t inception, isc_stdtime_t expire, + isc_mem_t *mctx, dns_tsig_keyring_t *ring, + dns_tsigkey_t **key); isc_result_t dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, - dst_key_t *dstkey, bool generated, + dst_key_t *dstkey, bool generated, bool restored, const dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key); diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c index a452c45b11..45ac21c003 100644 --- a/lib/dns/tkey.c +++ b/lib/dns/tkey.c @@ -269,8 +269,8 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin, } #endif /* HAVE_GSSAPI */ RETERR(dns_tsigkey_createfromkey( - name, &tkeyin->algorithm, dstkey, true, principal, now, - expire, ring->mctx, ring, &tsigkey)); + name, &tkeyin->algorithm, dstkey, true, false, + principal, now, expire, ring->mctx, ring, &tsigkey)); dst_key_free(&dstkey); tkeyout->inception = now; tkeyout->expire = expire; @@ -861,8 +861,8 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, RETERR(dns_tsigkey_createfromkey( tkeyname, (win2k ? DNS_TSIG_GSSAPIMS_NAME : DNS_TSIG_GSSAPI_NAME), dstkey, - true, NULL, rtkey.inception, rtkey.expire, ring->mctx, ring, - outkey)); + true, false, NULL, rtkey.inception, rtkey.expire, ring->mctx, + ring, outkey)); dst_key_free(&dstkey); dns_rdata_freestruct(&rtkey); return (result); diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c index 54f3d2e5df..8eef675b82 100644 --- a/lib/dns/tsig.c +++ b/lib/dns/tsig.c @@ -150,7 +150,7 @@ tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) { strlcpy(namestr, "", sizeof(namestr)); } - if (key != NULL && key->generated && key->creator) { + if (key != NULL && key->generated && key->creator != NULL) { dns_name_format(key->creator, creatorstr, sizeof(creatorstr)); } else { strlcpy(creatorstr, "", sizeof(creatorstr)); @@ -239,11 +239,11 @@ keyring_add(dns_tsig_keyring_t *ring, const dns_name_t *name, isc_result_t dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, - dst_key_t *dstkey, bool generated, + dst_key_t *dstkey, bool generated, bool restored, const dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { - dns_tsigkey_t *tkey; + dns_tsigkey_t *tkey = NULL; isc_result_t ret; unsigned int refs = 0; unsigned int dstalg = 0; @@ -255,8 +255,16 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, REQUIRE(key != NULL || ring != NULL); tkey = isc_mem_get(mctx, sizeof(dns_tsigkey_t)); + *tkey = (dns_tsigkey_t){ + .generated = generated, + .restored = restored, + .ring = ring, + .inception = inception, + .expire = expire, + .name = DNS_NAME_INITEMPTY, + .link = ISC_LINK_INITIALIZER, + }; - dns_name_init(&tkey->name, NULL); dns_name_dup(name, mctx, &tkey->name); (void)dns_name_downcase(&tkey->name, &tkey->name, NULL); @@ -273,7 +281,7 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, goto cleanup_name; } } else { - dns_name_t *tmpname; + dns_name_t *tmpname = NULL; if (dstkey != NULL) { ret = DNS_R_BADALG; goto cleanup_name; @@ -289,15 +297,11 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t)); dns_name_init(tkey->creator, NULL); dns_name_dup(creator, mctx, tkey->creator); - } else { - tkey->creator = NULL; } - tkey->key = NULL; if (dstkey != NULL) { dst_key_attach(dstkey, &tkey->key); } - tkey->ring = ring; if (key != NULL) { refs = 1; @@ -307,13 +311,7 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, } isc_refcount_init(&tkey->refs, refs); - - tkey->generated = generated; - tkey->inception = inception; - tkey->expire = expire; - tkey->mctx = NULL; isc_mem_attach(mctx, &tkey->mctx); - ISC_LINK_INIT(tkey, link); tkey->magic = TSIG_MAGIC; @@ -342,6 +340,14 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, *key = tkey; } + if (tkey->restored) { + tsig_log(tkey, ISC_LOG_DEBUG(3), "restored from file"); + } else if (tkey->generated) { + tsig_log(tkey, ISC_LOG_DEBUG(3), "generated"); + } else { + tsig_log(tkey, ISC_LOG_DEBUG(3), "statically configured"); + } + return (ISC_R_SUCCESS); cleanup_refs: @@ -553,7 +559,7 @@ restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) { return (result); } - result = dns_tsigkey_createfromkey(name, algorithm, dstkey, true, + result = dns_tsigkey_createfromkey(name, algorithm, dstkey, true, true, creator, inception, expire, ring->mctx, ring, NULL); if (dstkey != NULL) { @@ -658,9 +664,10 @@ dns_tsigkey_identity(const dns_tsigkey_t *tsigkey) { isc_result_t dns_tsigkey_create(const dns_name_t *name, const dns_name_t *algorithm, unsigned char *secret, int length, bool generated, - const dns_name_t *creator, isc_stdtime_t inception, - isc_stdtime_t expire, isc_mem_t *mctx, - dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { + bool restored, const dns_name_t *creator, + isc_stdtime_t inception, isc_stdtime_t expire, + isc_mem_t *mctx, dns_tsig_keyring_t *ring, + dns_tsigkey_t **key) { dst_key_t *dstkey = NULL; isc_result_t result; unsigned int dstalg = 0; @@ -690,8 +697,8 @@ dns_tsigkey_create(const dns_name_t *name, const dns_name_t *algorithm, } result = dns_tsigkey_createfromkey(name, algorithm, dstkey, generated, - creator, inception, expire, mctx, - ring, key); + restored, creator, inception, expire, + mctx, ring, key); if (dstkey != NULL) { dst_key_free(&dstkey); } @@ -1170,9 +1177,9 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, } if (ret != ISC_R_SUCCESS) { msg->tsigstatus = dns_tsigerror_badkey; - ret = dns_tsigkey_create(keyname, &tsig.algorithm, NULL, - 0, false, NULL, now, now, mctx, - NULL, &msg->tsigkey); + ret = dns_tsigkey_create( + keyname, &tsig.algorithm, NULL, 0, false, false, + NULL, now, now, mctx, NULL, &msg->tsigkey); if (ret != ISC_R_SUCCESS) { return (ret); } diff --git a/tests/dns/tsig_test.c b/tests/dns/tsig_test.c index d00266bf14..02b5926f0c 100644 --- a/tests/dns/tsig_test.c +++ b/tests/dns/tsig_test.c @@ -295,8 +295,8 @@ ISC_RUN_TEST_IMPL(tsig_tcp) { assert_int_equal(result, ISC_R_SUCCESS); result = dns_tsigkey_create(keyname, dns_tsig_hmacsha256_name, secret, - sizeof(secret), false, NULL, 0, 0, mctx, - ring, &key); + sizeof(secret), false, false, NULL, 0, 0, + mctx, ring, &key); assert_int_equal(result, ISC_R_SUCCESS); assert_non_null(key);