diff --git a/CHANGES b/CHANGES index 8d89c6f8f3..d927bb1b6d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4688. [protocol] Check and display EDNS KEY TAG options (RFC 8145) in + messages. [RT #44804] + 4687. [func] Refactor tracklines code. [RT #45126] 4686. [bug] dnssec-settime -p could print a bogus warning about diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index d9d674a493..f0147f34f5 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -1436,6 +1436,7 @@ dig_ednsoptname_t optnames[] = { { 12, "PADDING" }, /* RFC 7830 */ { 12, "PAD" }, /* shorthand */ { 13, "CHAIN" }, /* RFC 7901 */ + { 14, "KEY-TAG" }, /* RFC 8145 */ { 26946, "DEVICEID" }, /* Brian Hartvigsen */ }; diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index e82b39af15..ffdb5714d5 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -425,6 +425,7 @@ if [ -x ${DIG} ] ; then echo "I:skipping 'dig +idnout' as IDN support is not enabled ($n)" fi + n=`expr $n + 1` echo "I:checking that dig warns about .local queries ($n)" ret=0 $DIG $DIGOPTS @10.53.0.3 local soa > dig.out.test$n 2>&1 || ret=1 @@ -432,6 +433,31 @@ if [ -x ${DIG} ] ; then if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` + n=`expr $n + 1` + echo "I:check that dig processes +ednsopt=key-tag and FORMERR is returned ($n)" + $DIG $DIGOPTS @10.53.0.3 +ednsopt=key-tag a.example +qr > dig.out.test$n 2>&1 || ret=1 + grep "; KEY-TAG$" dig.out.test$n > /dev/null || ret=1 + grep "status: FORMERR" dig.out.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 that dig processes +ednsopt=key-tag: ($n)" + $DIG $DIGOPTS @10.53.0.3 +ednsopt=key-tag:00010002 a.example +qr > dig.out.test$n 2>&1 || ret=1 + grep "; KEY-TAG: 1, 2$" dig.out.test$n > /dev/null || ret=1 + grep "status: FORMERR" dig.out.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 that dig processes +ednsopt=key-tag: and FORMERR is returned ($n)" + ret=0 + $DIG $DIGOPTS @10.53.0.3 +ednsopt=key-tag:0001000201 a.example +qr > dig.out.test$n 2>&1 || ret=1 + grep "; KEY-TAG: 00 01 00 02 01" dig.out.test$n > /dev/null || ret=1 + grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1 + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` + else echo "$DIG is needed, so skipping these dig tests" fi diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 2192017ad1..4871a1b459 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -269,10 +269,6 @@ records for a name, but omits types RRSIG, NSEC and NSEC3. - - - - Several areas of code have been refactored for improved @@ -405,6 +401,11 @@ [RT #44696] + + + EDNS KEY TAG options are verified and printed. + + diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index 50fe235643..547a827aa1 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -99,6 +99,7 @@ #define DNS_OPT_COOKIE 10 /*%< COOKIE opt code */ #define DNS_OPT_TCP_KEEPALIVE 11 /*%< TCP keepalive opt code */ #define DNS_OPT_PAD 12 /*%< PAD opt code */ +#define DNS_OPT_KEY_TAG 14 /*%< Key tag opt code */ /*%< Experimental options [65001...65534] as per RFC6891 */ diff --git a/lib/dns/message.c b/lib/dns/message.c index a167c3aeeb..b53a473896 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -3608,6 +3608,23 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg, } else if (optcode == DNS_OPT_PAD) { INDENT(style); ADD_STRING(target, "PAD"); + } else if (optcode == DNS_OPT_KEY_TAG) { + INDENT(style); + ADD_STRING(target, "KEY-TAG"); + if (optlen > 0U && (optlen % 2U) == 0U) { + const char *sep = ": "; + isc_uint16_t id; + while (optlen > 0U) { + id = isc_buffer_getuint16(&optbuf); + snprintf(buf, sizeof(buf), "%s%u", + sep, id); + ADD_STRING(target, buf); + sep = ", "; + optlen -= 2; + } + ADD_STRING(target, "\n"); + continue; + } } else { INDENT(style); ADD_STRING(target, "OPT: "); @@ -3860,6 +3877,22 @@ dns_message_pseudosectiontotext(dns_message_t *msg, } ADD_STRING(target, "\n"); continue; + } else if (optcode == DNS_OPT_KEY_TAG) { + ADD_STRING(target, "; KEY-TAG"); + if (optlen > 0U && (optlen % 2U) == 0U) { + const char *sep = ": "; + isc_uint16_t id; + while (optlen > 0U) { + id = isc_buffer_getuint16(&optbuf); + snprintf(buf, sizeof(buf), "%s%u", + sep, id); + ADD_STRING(target, buf); + sep = ", "; + optlen -= 2; + } + ADD_STRING(target, "\n"); + continue; + } } else { ADD_STRING(target, "; OPT="); snprintf(buf, sizeof(buf), "%u", optcode); diff --git a/lib/dns/rdata/generic/opt_41.c b/lib/dns/rdata/generic/opt_41.c index 9a741ea98c..c437b67a59 100644 --- a/lib/dns/rdata/generic/opt_41.c +++ b/lib/dns/rdata/generic/opt_41.c @@ -176,6 +176,11 @@ fromwire_opt(ARGS_FROMWIRE) { return (DNS_R_OPTERR); isc_region_consume(&sregion, length); break; + case DNS_OPT_KEY_TAG: + if (length == 0 || (length % 2) != 0) + return (DNS_R_OPTERR); + isc_region_consume(&sregion, length); + break; default: isc_region_consume(&sregion, length); break;