From 9e03f8e8feb9b794a769612afb0eaf417c35c5e3 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 17 Jun 2020 14:00:09 +0200 Subject: [PATCH 1/4] Move dst key printtime in separate function I'd like to use the same functionality (pretty print the datetime of keytime metadata) in the 'rndc dnssec -status' command. So it is better that this logic is done in a separate function. Since the stdtime.c code have differernt files for unix and win32, I think the "#ifdef WIN32" define can be dropped. --- lib/dns/dst_api.c | 14 +------------- lib/isc/unix/include/isc/stdtime.h | 15 +++++++++++++++ lib/isc/unix/stdtime.c | 15 +++++++++++++++ lib/isc/win32/include/isc/stdtime.h | 15 +++++++++++++++ lib/isc/win32/libisc.def.in | 1 + lib/isc/win32/stdtime.c | 14 ++++++++++++++ 6 files changed, 61 insertions(+), 13 deletions(-) diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 65afc771d3..7d7940a851 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -1906,7 +1906,6 @@ printtime(const dst_key_t *key, int type, const char *tag, FILE *stream) { isc_result_t result; char output[26]; /* Minimum buffer as per ctime_r() specification. */ isc_stdtime_t when; - time_t t; char utc[sizeof("YYYYMMDDHHSSMM")]; isc_buffer_t b; isc_region_t r; @@ -1916,18 +1915,7 @@ printtime(const dst_key_t *key, int type, const char *tag, FILE *stream) { return; } - /* time_t and isc_stdtime_t might be different sizes */ - t = when; -#ifdef WIN32 - if (ctime_s(output, sizeof(output), &t) != 0) { - goto error; - } -#else /* ifdef WIN32 */ - if (ctime_r(&t, output) == NULL) { - goto error; - } -#endif /* ifdef WIN32 */ - + isc_stdtime_tostring(when, output, sizeof(output)); isc_buffer_init(&b, utc, sizeof(utc)); result = dns_time32_totext(when, &b); if (result != ISC_R_SUCCESS) { diff --git a/lib/isc/unix/include/isc/stdtime.h b/lib/isc/unix/include/isc/stdtime.h index 0503a28501..08d737ee8c 100644 --- a/lib/isc/unix/include/isc/stdtime.h +++ b/lib/isc/unix/include/isc/stdtime.h @@ -15,6 +15,7 @@ /*! \file */ #include +#include #include @@ -37,6 +38,20 @@ isc_stdtime_get(isc_stdtime_t *t); *\li 't' is a valid pointer. */ +void +isc_stdtime_tostring(isc_stdtime_t t, char *out, size_t outlen); +/* + * Convert 't' into a null-terminated string of the form + * "Wed Jun 30 21:49:08 1993". Store the string in the 'out' + * buffer. + * + * Requires: + * + * 't' is a valid time. + * 'out' is a valid pointer. + * 'outlen' is at least 26. + */ + #define isc_stdtime_convert32(t, t32p) (*(t32p) = t) /* * Convert the standard time to its 32-bit version. diff --git a/lib/isc/unix/stdtime.c b/lib/isc/unix/stdtime.c index e3fefad500..24c071d76c 100644 --- a/lib/isc/unix/stdtime.c +++ b/lib/isc/unix/stdtime.c @@ -49,3 +49,18 @@ isc_stdtime_get(isc_stdtime_t *t) { *t = (isc_stdtime_t)ts.tv_sec; } + +void +isc_stdtime_tostring(isc_stdtime_t t, char *out, size_t outlen) { + time_t when; + + REQUIRE(out != NULL); + REQUIRE(outlen >= 26); + + UNUSED(outlen); + + /* time_t and isc_stdtime_t might be different sizes */ + when = t; + INSIST((ctime_r(&when, out) != NULL)); + *(out + strlen(out) - 1) = '\0'; +} diff --git a/lib/isc/win32/include/isc/stdtime.h b/lib/isc/win32/include/isc/stdtime.h index 5a845bd55f..74ad0151fc 100644 --- a/lib/isc/win32/include/isc/stdtime.h +++ b/lib/isc/win32/include/isc/stdtime.h @@ -13,6 +13,7 @@ #define ISC_STDTIME_H 1 #include +#include #include @@ -35,6 +36,20 @@ isc_stdtime_get(isc_stdtime_t *t); * 't' is a valid pointer. */ +void +isc_stdtime_tostring(isc_stdtime_t t, char *out, size_t outlen); +/* + * Convert 't' into a null-terminated string of the form + * "Wed Jun 30 21:49:08 1993". Store the string in the 'out' + * buffer. + * + * Requires: + * + * 't' is a valid time. + * 'out' is a valid pointer. + * 'outlen' is at least 26. + */ + #define isc_stdtime_convert32(t, t32p) (*(t32p) = t) /* * Convert the standard time to its 32-bit version. diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 4d6705feec..3f37ede289 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -605,6 +605,7 @@ isc_stdio_sync isc_stdio_tell isc_stdio_write isc_stdtime_get +isc_stdtime_tostring isc_string_strerror_r isc_symtab_count isc_symtab_create diff --git a/lib/isc/win32/stdtime.c b/lib/isc/win32/stdtime.c index 55bd123952..23364624ae 100644 --- a/lib/isc/win32/stdtime.c +++ b/lib/isc/win32/stdtime.c @@ -25,3 +25,17 @@ isc_stdtime_get(isc_stdtime_t *t) { (void)_time32(t); } + +void +isc_stdtime_tostring(isc_stdtime_t t, char *out, size_t outlen) { + time_t when; + + REQUIRE(out != NULL); + /* Minimum buffer as per ctime_r() specification. */ + REQUIRE(outlen >= 26); + + /* time_t and isc_stdtime_t might be different sizes */ + when = t; + INSIST((ctime_s(out, outlen, &when) == 0)); + *(out + strlen(out) - 1) = '\0'; +} From e1ba1bea7c89b025773022ae4d18ad16188443f0 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 17 Jun 2020 14:58:57 +0200 Subject: [PATCH 2/4] Implement dummy 'rndc dnssec -status' command Add the code and documentation required to provide DNSSEC signing status through rndc. This does not yet show any useful information, just provide the command that will output some dummy string. --- bin/named/control.c | 2 ++ bin/named/include/named/control.h | 1 + bin/named/include/named/server.h | 7 +++++ bin/named/server.c | 49 +++++++++++++++++++++++++++++++ bin/rndc/rndc.c | 3 ++ bin/rndc/rndc.rst | 4 +++ doc/man/rndc.8in | 4 +++ 7 files changed, 70 insertions(+) diff --git a/bin/named/control.c b/bin/named/control.c index 7bb146017f..035a8833f7 100644 --- a/bin/named/control.c +++ b/bin/named/control.c @@ -209,6 +209,8 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly, result = named_server_changezone(named_g_server, cmdline, text); } else if (command_compare(command, NAMED_COMMAND_DELZONE)) { result = named_server_delzone(named_g_server, lex, text); + } else if (command_compare(command, NAMED_COMMAND_DNSSEC)) { + result = named_server_dnssec(named_g_server, lex, text); } else if (command_compare(command, NAMED_COMMAND_DNSTAP) || command_compare(command, NAMED_COMMAND_DNSTAPREOPEN)) { diff --git a/bin/named/include/named/control.h b/bin/named/include/named/control.h index 99fe916d0e..b97f07ac73 100644 --- a/bin/named/include/named/control.h +++ b/bin/named/include/named/control.h @@ -61,6 +61,7 @@ #define NAMED_COMMAND_SHOWZONE "showzone" #define NAMED_COMMAND_SYNC "sync" #define NAMED_COMMAND_SIGNING "signing" +#define NAMED_COMMAND_DNSSEC "dnssec" #define NAMED_COMMAND_ZONESTATUS "zonestatus" #define NAMED_COMMAND_NTA "nta" #define NAMED_COMMAND_TESTGEN "testgen" diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index e89c3b66be..fdc89958a3 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -333,6 +333,13 @@ isc_result_t named_server_signing(named_server_t *server, isc_lex_t *lex, isc_buffer_t **text); +/*% + * Lists the DNSSEC status for a given zone. + */ +isc_result_t +named_server_dnssec(named_server_t *server, isc_lex_t *lex, + isc_buffer_t **text); + /*% * Lists status information for a given zone (e.g., name, type, files, * load time, expiry, etc). diff --git a/bin/named/server.c b/bin/named/server.c index c6d8238ac6..ecacb9d321 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -14463,6 +14465,53 @@ cleanup: return (result); } +isc_result_t +named_server_dnssec(named_server_t *server, isc_lex_t *lex, + isc_buffer_t **text) { + isc_result_t result = ISC_R_SUCCESS; + dns_zone_t *zone = NULL; + dns_kasp_t *kasp = NULL; + bool status = false; + const char *ptr; + + /* Skip the command name. */ + ptr = next_token(lex, text); + if (ptr == NULL) { + return (ISC_R_UNEXPECTEDEND); + } + + /* Find out what we are to do. */ + ptr = next_token(lex, text); + if (ptr == NULL) { + return (ISC_R_UNEXPECTEDEND); + } + + if (strcasecmp(ptr, "-status") == 0) { + status = true; + } else { + CHECK(DNS_R_SYNTAX); + } + + CHECK(zone_from_args(server, lex, NULL, &zone, NULL, text, false)); + if (zone == NULL) { + CHECK(ISC_R_UNEXPECTEDEND); + } + + kasp = dns_zone_getkasp(zone); + + if (status) { + CHECK(putstr(text, "-status command not implemented")); + CHECK(putnull(text)); + } + +cleanup: + if (zone != NULL) { + dns_zone_detach(&zone); + } + + return (result); +} + static isc_result_t putmem(isc_buffer_t **b, const char *str, size_t len) { isc_result_t result; diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index ba91747657..7a3123e19a 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -105,6 +105,9 @@ command is one of the following:\n\ Add zone to given view. Requires allow-new-zones option.\n\ delzone [-clean] zone [class [view]]\n\ Removes zone from given view.\n\ + dnssec -status zone [class [view]]\n\ + Show the DNSSEC signing state for the specified zone.\n\ + Requires the zone to have a dnssec-policy.\n\ dnstap -reopen\n\ Close, truncate and re-open the DNSTAP output file.\n\ dnstap -roll count\n\ diff --git a/bin/rndc/rndc.rst b/bin/rndc/rndc.rst index ab4d806865..ef5febb259 100644 --- a/bin/rndc/rndc.rst +++ b/bin/rndc/rndc.rst @@ -162,6 +162,10 @@ Currently supported commands are: See also ``rndc addzone`` and ``rndc modzone``. +``dnssec`` [**-status** *zone* [*class* [*view*]] + Show the DNSSEC signing state for the specified zone. Requires the + zone to have a "dnssec-policy". + ``dnstap`` ( **-reopen** | **-roll** [*number*] ) Close and re-open DNSTAP output files. ``rndc dnstap -reopen`` allows the output file to be renamed externally, so that :manpage:`named(8)` can diff --git a/doc/man/rndc.8in b/doc/man/rndc.8in index 43079e8435..01f5ab3729 100644 --- a/doc/man/rndc.8in +++ b/doc/man/rndc.8in @@ -162,6 +162,10 @@ back. To remove it permanently, it must also be removed from .sp See also \fBrndc addzone\fP and \fBrndc modzone\fP\&. .TP +\fBdnssec\fP [\fB\-status\fP \fIzone\fP [\fIclass\fP [\fIview\fP]] +Show the DNSSEC signing state for the specified zone. Requires the +zone to have a \fBdnssec-policy\fP. +.TP \fBdnstap\fP ( \fB\-reopen\fP | \fB\-roll\fP [\fInumber\fP] ) Close and re\-open DNSTAP output files. \fBrndc dnstap \-reopen\fP allows the output file to be renamed externally, so that \fBnamed(8)\fP can From 19ce9ec1d4ac72b5e0858a80036289938d0796fd Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 18 Jun 2020 17:07:52 +0200 Subject: [PATCH 3/4] Output rndc dnssec -status Implement the 'rndc dnssec -status' command that will output some information about the key states, such as which policy is used for the zone, what keys are in use, and when rollover is scheduled. Add loose testing in the kasp system test, the actual times are already tested via key file inspection. --- bin/named/server.c | 46 +++++- bin/tests/system/kasp/clean.sh | 1 + bin/tests/system/kasp/ns4/named.conf.in | 9 ++ bin/tests/system/kasp/ns5/named.conf.in | 9 ++ bin/tests/system/kasp/tests.sh | 132 ++++++++++++++++ lib/dns/include/dns/keymgr.h | 17 ++ lib/dns/keymgr.c | 201 ++++++++++++++++++++++++ lib/dns/win32/libdns.def.in | 1 + 8 files changed, 408 insertions(+), 8 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index ecacb9d321..eebaba3b30 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -14471,8 +14471,14 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex, isc_result_t result = ISC_R_SUCCESS; dns_zone_t *zone = NULL; dns_kasp_t *kasp = NULL; - bool status = false; + dns_dnsseckeylist_t keys; + dns_dnsseckey_t *key; const char *ptr; + /* variables for -status */ + char output[BUFSIZ]; + isc_stdtime_t now; + isc_time_t timenow; + const char *dir; /* Skip the command name. */ ptr = next_token(lex, text); @@ -14486,25 +14492,49 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex, return (ISC_R_UNEXPECTEDEND); } - if (strcasecmp(ptr, "-status") == 0) { - status = true; - } else { - CHECK(DNS_R_SYNTAX); + if (strcasecmp(ptr, "-status") != 0) { + return (DNS_R_SYNTAX); } + ISC_LIST_INIT(keys); + CHECK(zone_from_args(server, lex, NULL, &zone, NULL, text, false)); if (zone == NULL) { CHECK(ISC_R_UNEXPECTEDEND); } kasp = dns_zone_getkasp(zone); - - if (status) { - CHECK(putstr(text, "-status command not implemented")); + if (kasp == NULL) { + CHECK(putstr(text, "zone does not have dnssec-policy")); CHECK(putnull(text)); + goto cleanup; } + /* -status */ + TIME_NOW(&timenow); + now = isc_time_seconds(&timenow); + dir = dns_zone_getkeydirectory(zone); + LOCK(&kasp->lock); + result = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone), dir, now, + dns_zone_getmctx(zone), &keys); + UNLOCK(&kasp->lock); + + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { + goto cleanup; + } + LOCK(&kasp->lock); + dns_keymgr_status(kasp, &keys, now, &output[0], sizeof(output)); + UNLOCK(&kasp->lock); + CHECK(putstr(text, output)); + CHECK(putnull(text)); + cleanup: + while (!ISC_LIST_EMPTY(keys)) { + key = ISC_LIST_HEAD(keys); + ISC_LIST_UNLINK(keys, key, link); + dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); + } + if (zone != NULL) { dns_zone_detach(&zone); } diff --git a/bin/tests/system/kasp/clean.sh b/bin/tests/system/kasp/clean.sh index b3c097326e..65907690db 100644 --- a/bin/tests/system/kasp/clean.sh +++ b/bin/tests/system/kasp/clean.sh @@ -24,4 +24,5 @@ rm -f ns*/managed-keys.bind rm -f ns*/*.mkeys rm -f ns*/zones ns*/*.db.infile rm -f *.created published.test* retired.test* +rm -f rndc.dnssec.status.out.* rm -f python.out.* diff --git a/bin/tests/system/kasp/ns4/named.conf.in b/bin/tests/system/kasp/ns4/named.conf.in index 8d209aef63..5f9b8c9fae 100644 --- a/bin/tests/system/kasp/ns4/named.conf.in +++ b/bin/tests/system/kasp/ns4/named.conf.in @@ -11,6 +11,15 @@ // NS4 +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + key "sha1" { algorithm "hmac-sha1"; secret "FrSt77yPTFx6hTs4i2tKLB9LmE0="; diff --git a/bin/tests/system/kasp/ns5/named.conf.in b/bin/tests/system/kasp/ns5/named.conf.in index 2c9c8f6214..3601c7b16f 100644 --- a/bin/tests/system/kasp/ns5/named.conf.in +++ b/bin/tests/system/kasp/ns5/named.conf.in @@ -11,6 +11,15 @@ // NS5 +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.5 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + key "sha1" { algorithm "hmac-sha1"; secret "FrSt77yPTFx6hTs4i2tKLB9LmE0="; diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index 0432977eac..5528d5b8e6 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -919,6 +919,46 @@ check_keys() status=$((status+ret)) } +# Call rndc dnssec -status on server $1 for zone $2 and check output. +# This is a loose verification, it just tests if the right policy +# name is returned, and if all expected keys are listed. The rndc +# dnssec -status output also lists whether a key is published, +# used for signing, is retired, or is removed, and if not when +# it is scheduled to do so, and it shows the states for the various +# DNSSEC records. +check_dnssecstatus() { + _server=$1 + _zone=$2 + _view=$3 + + n=$((n+1)) + echo_i "check rndc dnssec -status output for ${_zone} ($n)" + ret=0 + + rndccmd $_server dnssec -status $_zone in $_view > rndc.dnssec.status.out.$_zone.$n || log_error "rndc dnssec -status zone ${_zone} failed" + + if [ "$POLICY" = "none" ]; then + grep "zone does not have dnssec-policy" rndc.dnssec.status.out.$_zone.$n > /dev/null || log_error "bad dnssec status for zone ${_zone}" + else + grep "dnssec-policy: ${POLICY}" rndc.dnssec.status.out.$_zone.$n > /dev/null || log_error "bad dnssec status for zone ${_zone}" + if [ "$(key_get KEY1 EXPECT)" = "yes" ]; then + grep "key: $(key_get KEY1 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || log_error "missing key $(key_get KEY1 ID) from dnssec status" + fi + if [ "$(key_get KEY2 EXPECT)" = "yes" ]; then + grep "key: $(key_get KEY2 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || log_error "missing key $(key_get KEY2 ID) from dnssec status" + fi + if [ "$(key_get KEY3 EXPECT)" = "yes" ]; then + grep "key: $(key_get KEY3 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || log_error "missing key $(key_get KEY3 ID) from dnssec status" + fi + if [ "$(key_get KEY4 EXPECT)" = "yes" ]; then + grep "key: $(key_get KEY4 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || log_error "missing key $(key_get KEY4 ID) from dnssec status" + fi + fi + + test "$ret" -eq 0 || echo_i "failed" + status=$((status+ret)) +} + # Check if RRset of type $1 in file $2 is signed with the right keys. # The right keys are the ones that expect a signature and matches the role $3. check_signatures() { @@ -1165,6 +1205,7 @@ set_keystate "KEY1" "STATE_ZRRSIG" "rumoured" set_keystate "KEY1" "STATE_DS" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -1206,6 +1247,7 @@ set_policy "default" "1" "3600" set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -1238,6 +1280,7 @@ set_policy "default" "1" "3600" set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -1265,6 +1308,7 @@ set_policy "default" "1" "3600" set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -1390,6 +1434,7 @@ set_keystate "KEY3" "STATE_ZRRSIG" "rumoured" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1409,6 +1454,7 @@ key_clear "KEY3" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -1432,6 +1478,7 @@ set_keystate "KEY1" "STATE_ZRRSIG" "rumoured" set_keystate "KEY1" "STATE_DS" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -1484,6 +1531,7 @@ set_keystate "KEY3" "STATE_ZRRSIG" "rumoured" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1499,6 +1547,7 @@ set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1514,6 +1563,7 @@ set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy "pregenerated" check_keytimes check_apex @@ -1529,6 +1579,7 @@ set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1546,6 +1597,7 @@ set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy "pregenerated" check_keytimes check_apex @@ -1562,6 +1614,7 @@ set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy # Activation date is a day later. set_addkeytime "KEY1" "ACTIVE" $(key_get KEY1 ACTIVE) 86400 @@ -1587,6 +1640,7 @@ set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1635,6 +1689,7 @@ set_keyalgorithm "KEY3" "7" "NSEC3RSASHA1" "2000" # Key timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1654,6 +1709,7 @@ set_keyalgorithm "KEY3" "8" "RSASHA256" "2000" # Key timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1673,6 +1729,7 @@ set_keyalgorithm "KEY3" "10" "RSASHA512" "2000" # Key timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1692,6 +1749,7 @@ set_keyalgorithm "KEY3" "13" "ECDSAP256SHA256" "256" # Key timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1711,6 +1769,7 @@ set_keyalgorithm "KEY3" "14" "ECDSAP384SHA384" "384" # Key timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_algorithm_policy check_keytimes check_apex @@ -1787,6 +1846,7 @@ key_clear "KEY3" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_autosign_policy check_keytimes check_apex @@ -1844,6 +1904,7 @@ set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_autosign_policy check_keytimes check_apex @@ -1901,6 +1962,7 @@ set_server "ns3" "10.53.0.3" # Key properties, timings and states same as above. check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_autosign_policy check_keytimes check_apex @@ -1941,6 +2003,7 @@ set_keystate "KEY3" "STATE_DNSKEY" "rumoured" set_keystate "KEY3" "STATE_ZRRSIG" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_autosign_policy # The old ZSK is retired. @@ -1995,6 +2058,7 @@ set_policy "none" "0" "0" set_server "ns2" "10.53.0.2" TSIG="" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2003,6 +2067,7 @@ set_policy "none" "0" "0" set_server "ns4" "10.53.0.4" TSIG="hmac-sha1:sha1:$SHA1" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2011,6 +2076,7 @@ set_policy "none" "0" "0" set_server "ns4" "10.53.0.4" TSIG="hmac-sha224:sha224:$SHA224" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2019,6 +2085,7 @@ set_policy "none" "0" "0" set_server "ns4" "10.53.0.4" TSIG="hmac-sha256:sha256:$SHA256" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2027,6 +2094,7 @@ set_policy "none" "0" "0" set_server "ns4" "10.53.0.4" TSIG="hmac-sha256:sha256:$SHA256" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2035,6 +2103,7 @@ set_policy "none" "0" "0" set_server "ns5" "10.53.0.5" TSIG="hmac-sha1:sha1:$SHA1" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2043,6 +2112,7 @@ set_policy "none" "0" "0" set_server "ns5" "10.53.0.5" TSIG="hmac-sha1:sha1:$SHA1" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2051,6 +2121,7 @@ set_policy "none" "0" "0" set_server "ns5" "10.53.0.5" TSIG="hmac-sha224:sha224:$SHA224" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2059,6 +2130,7 @@ set_policy "none" "0" "0" set_server "ns5" "10.53.0.5" TSIG="hmac-sha256:sha256:$SHA256" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2067,6 +2139,7 @@ set_policy "none" "0" "0" set_server "ns5" "10.53.0.5" TSIG="hmac-sha256:sha256:$SHA256" check_keys +check_dnssecstatus "$SERVER" "$ZONE" check_apex check_subdomain @@ -2093,6 +2166,7 @@ set_policy "default" "1" "3600" set_server "ns2" "10.53.0.2" TSIG="" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2104,6 +2178,7 @@ set_policy "default" "1" "3600" set_server "ns4" "10.53.0.4" TSIG="hmac-sha1:sha1:$SHA1" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2115,6 +2190,7 @@ set_policy "default" "1" "3600" set_server "ns4" "10.53.0.4" TSIG="hmac-sha224:sha224:$SHA224" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2126,6 +2202,7 @@ set_policy "default" "1" "3600" set_server "ns5" "10.53.0.5" TSIG="hmac-sha1:sha1:$SHA1" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2137,6 +2214,7 @@ set_policy "default" "1" "3600" set_server "ns5" "10.53.0.5" TSIG="hmac-sha224:sha224:$SHA224" check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2162,6 +2240,7 @@ set_server "ns4" "10.53.0.4" TSIG="hmac-sha1:sha1:$SHA1" wait_for_nsec check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2174,6 +2253,7 @@ set_server "ns4" "10.53.0.4" TSIG="hmac-sha224:sha224:$SHA224" wait_for_nsec check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2186,6 +2266,7 @@ set_server "ns4" "10.53.0.4" TSIG="hmac-sha256:sha256:$SHA256" wait_for_nsec check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2198,6 +2279,7 @@ set_server "ns5" "10.53.0.5" TSIG="hmac-sha224:sha224:$SHA224" wait_for_nsec check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2210,6 +2292,7 @@ set_server "ns5" "10.53.0.5" TSIG="hmac-sha256:sha256:$SHA256" wait_for_nsec check_keys +check_dnssecstatus "$SERVER" "$ZONE" set_keytimes_csk_policy check_keytimes check_apex @@ -2221,6 +2304,7 @@ set_server "ns4" "10.53.0.4" TSIG="hmac-sha1:keyforview1:$VIEW1" wait_for_nsec check_keys +check_dnssecstatus "$SERVER" "$ZONE" "example1" set_keytimes_csk_policy check_keytimes check_apex @@ -2239,6 +2323,7 @@ status=$((status+ret)) TSIG="hmac-sha1:keyforview2:$VIEW2" wait_for_nsec check_keys +check_dnssecstatus "$SERVER" "$ZONE" "example2" check_apex dnssec_verify n=$((n+1)) @@ -2284,6 +2369,7 @@ key_clear "KEY3" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The first key is immediately published and activated. created=$(key_get KEY1 CREATED) @@ -2340,6 +2426,7 @@ set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The key was published and activated 900 seconds ago (with settime). created=$(key_get KEY1 CREATED) @@ -2368,6 +2455,7 @@ set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent" set_keystate "KEY1" "STATE_DS" "rumoured" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The key was published and activated 44700 seconds ago (with settime). created=$(key_get KEY1 CREATED) @@ -2395,6 +2483,7 @@ set_server "ns3" "10.53.0.3" set_keystate "KEY1" "STATE_DS" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The key was published and activated 143100 seconds ago (with settime). created=$(key_get KEY1 CREATED) @@ -2487,6 +2576,7 @@ key_clear "KEY3" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # These keys are immediately published and activated. rollover_predecessor_keytimes 0 @@ -2521,6 +2611,7 @@ set_keystate "KEY3" "STATE_DNSKEY" "rumoured" set_keystate "KEY3" "STATE_ZRRSIG" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 694 hours ago (2498400 seconds). rollover_predecessor_keytimes -2498400 @@ -2558,6 +2649,7 @@ set_keystate "KEY3" "STATE_DNSKEY" "omnipresent" set_keystate "KEY3" "STATE_ZRRSIG" "rumoured" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The old keys are activated 30 days ago (2592000 seconds). rollover_predecessor_keytimes -2592000 @@ -2599,6 +2691,7 @@ set_keystate "KEY2" "STATE_ZRRSIG" "hidden" set_keystate "KEY3" "STATE_ZRRSIG" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The old keys are activated 961 hours ago (3459600 seconds). rollover_predecessor_keytimes -3459600 @@ -2628,6 +2721,7 @@ set_server "ns3" "10.53.0.3" set_keystate "KEY2" "STATE_DNSKEY" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The old keys are activated 962 hours ago (3463200 seconds). rollover_predecessor_keytimes -3463200 @@ -2697,6 +2791,7 @@ key_clear "KEY3" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # These keys are immediately published and activated. rollover_predecessor_keytimes 0 @@ -2733,6 +2828,7 @@ set_keystate "KEY3" "STATE_KRRSIG" "rumoured" set_keystate "KEY3" "STATE_DS" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 1413 hours ago (5086800 seconds). rollover_predecessor_keytimes -5086800 @@ -2776,6 +2872,7 @@ set_keystate "KEY3" "STATE_KRRSIG" "omnipresent" set_keystate "KEY3" "STATE_DS" "rumoured" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 59 days ago (5097600 seconds). rollover_predecessor_keytimes -5097600 @@ -2817,6 +2914,7 @@ set_keystate "KEY1" "STATE_DS" "hidden" set_keystate "KEY3" "STATE_DS" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 1490 hours ago (5364000 seconds). rollover_predecessor_keytimes -5364000 @@ -2849,6 +2947,7 @@ set_keystate "KEY1" "STATE_DNSKEY" "hidden" set_keystate "KEY1" "STATE_KRRSIG" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The old KSK is activated 1492 hours ago (5371200 seconds). rollover_predecessor_keytimes -5371200 @@ -2922,6 +3021,7 @@ key_clear "KEY3" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key is immediately published and activated. csk_rollover_predecessor_keytimes 0 0 @@ -2958,6 +3058,7 @@ set_keystate "KEY2" "STATE_ZRRSIG" "hidden" set_keystate "KEY2" "STATE_DS" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 4437 hours ago (15973200 seconds) # and started signing 4461 hours ago (16059600 seconds). @@ -3001,6 +3102,7 @@ set_keystate "KEY2" "STATE_ZRRSIG" "rumoured" set_keystate "KEY2" "STATE_DS" "rumoured" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 185 days ago (15984000 seconds) # and started signing 186 days ago (16070400 seconds). @@ -3049,6 +3151,7 @@ set_keystate "KEY1" "STATE_DS" "hidden" set_keystate "KEY2" "STATE_DS" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 4468 hours ago (16084800 seconds) # and started signing 4492 hours ago (16171200 seconds). @@ -3080,6 +3183,7 @@ set_server "ns3" "10.53.0.3" set_keystate "KEY1" "STATE_KRRSIG" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 4470 hours ago (16092000 seconds) # and started signing 4494 hours ago (16178400 seconds). @@ -3117,6 +3221,7 @@ set_keystate "KEY1" "STATE_ZRRSIG" "hidden" set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 5067 hours ago (18241200 seconds) # and started signing 5091 hours ago (18327600 seconds). @@ -3148,6 +3253,7 @@ set_server "ns3" "10.53.0.3" set_keystate "KEY1" "STATE_DNSKEY" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 5069 hours ago (18248400 seconds) # and started signing 5093 hours ago (18334800 seconds). @@ -3214,6 +3320,7 @@ key_clear "KEY3" key_clear "KEY4" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key is immediately published and activated. csk_rollover_predecessor_keytimes 0 0 @@ -3250,6 +3357,7 @@ set_keystate "KEY2" "STATE_ZRRSIG" "hidden" set_keystate "KEY2" "STATE_DS" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 4293 hours ago (15454800 seconds) # and started signing 4461 hours ago (16059600 seconds). @@ -3292,6 +3400,7 @@ set_keystate "KEY2" "STATE_ZRRSIG" "rumoured" set_keystate "KEY2" "STATE_DS" "rumoured" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 179 days ago (15465600 seconds) # and started signing 186 days ago (16070400 seconds). @@ -3337,6 +3446,7 @@ set_keystate "KEY1" "STATE_ZRRSIG" "hidden" set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 4334 hours ago (15602400 seconds) # and started signing 4502 hours ago (16207200 seconds). @@ -3377,6 +3487,7 @@ set_keystate "KEY1" "STATE_DS" "hidden" set_keystate "KEY2" "STATE_DS" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 4467 hours ago (16081200 seconds) # and started signing 4635 hours ago (16686000 seconds). @@ -3409,6 +3520,7 @@ set_keystate "KEY1" "STATE_DNSKEY" "hidden" set_keystate "KEY1" "STATE_KRRSIG" "hidden" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key was activated 4469 hours ago (16088400 seconds) # and started signing 4637 hours ago (16693200 seconds). @@ -3469,6 +3581,7 @@ set_keystate "KEY2" "STATE_DNSKEY" "omnipresent" set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # These keys are immediately published and activated. Lksk=0 @@ -3510,6 +3623,7 @@ set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent" set_keystate "KEY1" "STATE_DS" "omnipresent" check_keys +check_dnssecstatus "$SERVER" "$ZONE" # This key is immediately published and activated. Lcsk=0 @@ -3565,6 +3679,7 @@ init_migration_match # Make sure the zone is signed with legacy keys. check_keys +check_dnssecstatus "$SERVER" "$ZONE" # These keys are immediately published and activated. rollover_predecessor_keytimes 0 @@ -3615,6 +3730,7 @@ init_migration_nomatch_algnum # Make sure the zone is signed with legacy keys. check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The KSK is immediately published and activated. # -P : now-3900s @@ -3677,6 +3793,7 @@ init_migration_nomatch_alglen # Make sure the zone is signed with legacy keys. check_keys +check_dnssecstatus "$SERVER" "$ZONE" # The KSK is immediately published and activated. # -P : now-3900s @@ -3765,6 +3882,7 @@ key_set "KEY2" "LEGACY" "no" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" rollover_predecessor_keytimes 0 # Key now has lifetime of 60 days (5184000 seconds). @@ -3831,6 +3949,7 @@ set_keystate "KEY4" "STATE_ZRRSIG" "rumoured" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # KSK must be retired since it no longer matches the policy. # -P : now-3900s @@ -3947,6 +4066,7 @@ set_keystate "KEY4" "STATE_ZRRSIG" "hidden" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # KSK must be retired since it no longer matches the policy. # -P : now-3900s @@ -4088,6 +4208,7 @@ set_keystate "KEY4" "STATE_ZRRSIG" "rumoured" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old keys are published and activated. rollover_predecessor_keytimes 0 @@ -4167,6 +4288,7 @@ set_keystate "KEY4" "STATE_DNSKEY" "omnipresent" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated three hours ago (10800 seconds). rollover_predecessor_keytimes -10800 @@ -4222,6 +4344,7 @@ set_keystate "KEY4" "STATE_ZRRSIG" "omnipresent" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 9 hours ago (32400 seconds) # and retired 6 hours ago (21600 seconds). @@ -4279,6 +4402,7 @@ set_keystate "KEY3" "STATE_DS" "omnipresent" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 38 hours ago (136800 seconds) # and retired 35 hours ago (126000 seconds). @@ -4327,6 +4451,7 @@ set_keystate "KEY2" "STATE_DNSKEY" "hidden" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 40 hours ago (144000 seconds) # and retired 35 hours ago (133200 seconds). @@ -4378,6 +4503,7 @@ set_keystate "KEY2" "STATE_ZRRSIG" "hidden" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 47 hours ago (169200 seconds) # and retired 34 hours ago (158400 seconds). @@ -4458,6 +4584,7 @@ set_keystate "KEY2" "STATE_DS" "hidden" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # CSK must be retired since it no longer matches the policy. csk_rollover_predecessor_keytimes 0 0 @@ -4515,6 +4642,7 @@ set_keystate "KEY2" "STATE_KRRSIG" "omnipresent" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old key was activated three hours ago (10800 seconds). csk_rollover_predecessor_keytimes -10800 -10800 @@ -4561,6 +4689,7 @@ set_keystate "KEY2" "STATE_DS" "rumoured" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old key was activated 9 hours ago (10800 seconds) # and retired 6 hours ago (21600 seconds). @@ -4605,6 +4734,7 @@ set_keystate "KEY2" "STATE_DS" "omnipresent" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old key was activated 38 hours ago (136800 seconds) # and retired 35 hours ago (126000 seconds). @@ -4642,6 +4772,7 @@ set_keystate "KEY1" "STATE_KRRSIG" "hidden" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old key was activated 40 hours ago (144000 seconds) # and retired 37 hours ago (133200 seconds). @@ -4683,6 +4814,7 @@ set_keystate "KEY1" "STATE_ZRRSIG" "hidden" check_keys wait_for_done_signing +check_dnssecstatus "$SERVER" "$ZONE" # The old keys were activated 47 hours ago (169200 seconds) # and retired 44 hours ago (158400 seconds). diff --git a/lib/dns/include/dns/keymgr.h b/lib/dns/include/dns/keymgr.h index 98317a4d71..df48b792bf 100644 --- a/lib/dns/include/dns/keymgr.h +++ b/lib/dns/include/dns/keymgr.h @@ -51,6 +51,23 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass, *\li On error, keypool is unchanged */ +void +dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring, + isc_stdtime_t now, char *out, size_t out_len); +/*%< + * Retrieve the status of given 'kasp' policy and keys in the + * 'keyring' and store the printable output in the 'out' buffer. + * + * Requires: + *\li 'kasp' is not NULL. + *\li 'keyring' is not NULL. + *\li 'out' is not NULL. + * + * Returns: + *\li Printable status in 'out'. + * + */ + ISC_LANG_ENDDECLS #endif /* DNS_KEYMGR_H */ diff --git a/lib/dns/keymgr.c b/lib/dns/keymgr.c index 6ede7f975b..5defbe44e7 100644 --- a/lib/dns/keymgr.c +++ b/lib/dns/keymgr.c @@ -1841,3 +1841,204 @@ failure: return (result); } + +static void +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_stdtime_t when = 0; + dst_key_state_t state; + + isc_buffer_printf(buf, "%s", pre); + (void)dst_key_getstate(key, ks, &state); + ret = dst_key_gettime(key, kt, &when); + if (state == RUMOURED || state == OMNIPRESENT) { + isc_buffer_printf(buf, "yes - since "); + } else if (now < when) { + isc_buffer_printf(buf, "no - scheduled "); + } else { + isc_buffer_printf(buf, "no\n"); + return; + } + if (ret == ISC_R_SUCCESS) { + isc_stdtime_tostring(when, timestr, sizeof(timestr)); + isc_buffer_printf(buf, "%s\n", timestr); + } +} + +static void +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_stdtime_t active_time = 0; + dst_key_state_t state = NA, goal = NA; + int rrsig, active, retire; + dst_key_t *key = dkey->key; + + if (zsk) { + rrsig = DST_KEY_ZRRSIG; + active = DST_TIME_ACTIVATE; + retire = DST_TIME_INACTIVE; + } else { + rrsig = DST_KEY_KRRSIG; + active = DST_TIME_PUBLISH; + retire = DST_TIME_DELETE; + } + + 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; + } + + if (goal == HIDDEN && (state == UNRETENTIVE || state == HIDDEN)) { + isc_stdtime_t remove_time = 0; + // is the key removed yet? + 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 "); + isc_stdtime_tostring(remove_time, timestr, + sizeof(timestr)); + isc_buffer_printf(buf, "%s", timestr); + } + } else { + isc_buffer_printf( + buf, " Key has been removed from the zone"); + } + } else { + isc_stdtime_t retire_time = 0; + uint32_t lifetime = 0; + (void)dst_key_getnum(key, DST_NUM_LIFETIME, &lifetime); + ret = dst_key_gettime(key, retire, &retire_time); + if (ret == ISC_R_SUCCESS) { + if (now < retire_time) { + if (goal == OMNIPRESENT) { + isc_buffer_printf(buf, + " Next rollover " + "scheduled on "); + retire_time = keymgr_prepublication_time( + dkey, kasp, lifetime, now); + } else { + isc_buffer_printf( + buf, " Key will retire on "); + } + } else { + isc_buffer_printf(buf, + " Rollover is due since "); + } + isc_stdtime_tostring(retire_time, timestr, + sizeof(timestr)); + isc_buffer_printf(buf, "%s", timestr); + } else { + isc_buffer_printf(buf, " No rollover scheduled"); + } + } + isc_buffer_printf(buf, "\n"); +} + +static void +keystate_status(dst_key_t *key, isc_buffer_t *buf, const char *pre, int ks) { + dst_key_state_t state = NA; + + (void)dst_key_getstate(key, ks, &state); + switch (state) { + case HIDDEN: + isc_buffer_printf(buf, " - %shidden\n", pre); + break; + case RUMOURED: + isc_buffer_printf(buf, " - %srumoured\n", pre); + break; + case OMNIPRESENT: + isc_buffer_printf(buf, " - %somnipresent\n", pre); + break; + case UNRETENTIVE: + isc_buffer_printf(buf, " - %sunretentive\n", pre); + break; + case NA: + default: + /* print nothing */ + break; + } +} + +void +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; + char timestr[26]; /* Minimal buf as per ctime_r() spec. */ + + REQUIRE(DNS_KASP_VALID(kasp)); + REQUIRE(keyring != NULL); + REQUIRE(out != NULL); + + 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: "); + isc_stdtime_tostring(now, timestr, sizeof(timestr)); + 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; + + if (dst_key_is_unused(dkey->key)) { + continue; + } + + // key data + dst_key_getbool(dkey->key, DST_BOOL_KSK, &ksk); + dst_key_getbool(dkey->key, DST_BOOL_ZSK, &zsk); + 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)); + + // publish status + keytime_status(dkey->key, now, &buf, + " published: ", DST_KEY_DNSKEY, + DST_TIME_PUBLISH); + + // signing status + if (ksk) { + keytime_status(dkey->key, now, &buf, + " key signing: ", DST_KEY_KRRSIG, + DST_TIME_PUBLISH); + } + if (zsk) { + keytime_status(dkey->key, now, &buf, + " zone signing: ", DST_KEY_ZRRSIG, + DST_TIME_ACTIVATE); + } + + // rollover status + 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); + } +} diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 2d1c23b2ed..5f5505288d 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -470,6 +470,7 @@ dns_keydata_fromdnskey dns_keydata_todnskey dns_keyflags_fromtext dns_keymgr_run +dns_keymgr_status dns_keynode_dsset dns_keynode_initial dns_keynode_managed From e273b95a8b2e2e232391da967e5cc2bd0b65fda5 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 18 Jun 2020 17:10:34 +0200 Subject: [PATCH 4/4] Update notes, changes for #1612 --- CHANGES | 2 ++ doc/man/rndc.8in | 2 +- doc/notes/notes-current.rst | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 1d53a4f525..19b891cad0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +5451. [func] Add 'rndc dnssec -status' command. [GL #1612] + 5450. [placeholder] 5449. [bug] Fix a socket shutdown race in netmgr udp. [GL #1938] diff --git a/doc/man/rndc.8in b/doc/man/rndc.8in index 01f5ab3729..6403302a59 100644 --- a/doc/man/rndc.8in +++ b/doc/man/rndc.8in @@ -164,7 +164,7 @@ See also \fBrndc addzone\fP and \fBrndc modzone\fP\&. .TP \fBdnssec\fP [\fB\-status\fP \fIzone\fP [\fIclass\fP [\fIview\fP]] Show the DNSSEC signing state for the specified zone. Requires the -zone to have a \fBdnssec-policy\fP. +zone to have a "dnssec\-policy". .TP \fBdnstap\fP ( \fB\-reopen\fP | \fB\-roll\fP [\fInumber\fP] ) Close and re\-open DNSTAP output files. \fBrndc dnstap \-reopen\fP allows diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index ce8ddc72b4..7d161d4709 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -29,6 +29,10 @@ New Features Feature Changes ~~~~~~~~~~~~~~~ +- New ``rndc`` command ``rndc dnssec -status`` that shows the current + DNSSEC policy and keys in use, the key states and rollover status. + [GL #1612] + - Disable and disallow static linking of BIND 9 binaries and libraries as BIND 9 modules require ``dlopen()`` support and static linking also prevents using security features like read-only relocations (RELRO) or