]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Recognise EDNS Client Tag and EDNS Server Tag
authorMark Andrews <marka@isc.org>
Wed, 27 Mar 2019 06:16:57 +0000 (17:16 +1100)
committerMark Andrews <marka@isc.org>
Thu, 9 May 2019 08:24:57 +0000 (18:24 +1000)
(cherry picked from commit ee7cf180b3b4fc027a2c627bfc32684f31a0a152)

CHANGES
bin/dig/dighost.c
bin/tests/system/digdelv/tests.sh
lib/dns/include/dns/message.h
lib/dns/message.c
lib/dns/rdata/generic/opt_41.c

diff --git a/CHANGES b/CHANGES
index 431b7846cbdc1e591f82be6e35022fdd96499aa0..da1287242bff915c57db8adf23351bd2bce71fa0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+5231.  [protocol]      Add support for displaying CLIENT-TAG and SERVER-TAG.
+                       [GL #960]
+
 5229.  [protocol]      Enforce known SSHFP fingerprint lengths. [GL #852]
 
 5228.  [cleanup]       If trusted-keys and managed-keys are configured
index c54439f41b2557ec47a7ed50a276033e4a5cf437..c06c804141542b59541d88af7d271e885eaeb63d 100644 (file)
@@ -1682,6 +1682,8 @@ dig_ednsoptname_t optnames[] = {
        { 12, "PAD" },          /* shorthand */
        { 13, "CHAIN" },        /* RFC 7901 */
        { 14, "KEY-TAG" },      /* RFC 8145 */
+       { 16, "CLIENT-TAG" },   /* draft-bellis-dnsop-edns-tags */
+       { 17, "SERVER-TAG" },   /* draft-bellis-dnsop-edns-tags */
        { 26946, "DEVICEID" },  /* Brian Hartvigsen */
 };
 
index 89bfaf1da78845b12e20a5bf099585a0c5d8facf..1657dfdb2abf86681c7ed747c179f7b8a234e3fc 100644 (file)
@@ -483,6 +483,54 @@ ret=0
   if [ $ret != 0 ]; then echo_i "failed"; fi
   status=`expr $status + $ret`
 
+  n=`expr $n + 1`
+  echo_i "check that dig processes +ednsopt=client-tag:value ($n)"
+  $DIG $DIGOPTS @10.53.0.3 +ednsopt=client-tag:0001 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; CLIENT-TAG: 1$" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null && ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=`expr $status + $ret`
+
+  n=`expr $n + 1`
+  echo_i "check that FORMERR is returned for a too short client-tag ($n)"
+  $DIG $DIGOPTS @10.53.0.3 +ednsopt=client-tag:01 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; CLIENT-TAG" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=`expr $status + $ret`
+
+  n=`expr $n + 1`
+  echo_i "check that FORMERR is returned for a too long client-tag ($n)"
+  $DIG $DIGOPTS @10.53.0.3 +ednsopt=client-tag:000001 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; CLIENT-TAG" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=`expr $status + $ret`
+
+  n=`expr $n + 1`
+  echo_i "check that dig processes +ednsopt=server-tag:value ($n)"
+  $DIG $DIGOPTS @10.53.0.3 +ednsopt=server-tag:0001 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; SERVER-TAG: 1$" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null && ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=`expr $status + $ret`
+
+  n=`expr $n + 1`
+  echo_i "check that FORMERR is returned for a too short server-tag ($n)"
+  $DIG $DIGOPTS @10.53.0.3 +ednsopt=server-tag:01 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; SERVER-TAG" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=`expr $status + $ret`
+
+  n=`expr $n + 1`
+  echo_i "check that FORMERR is returned for a too long server-tag ($n)"
+  $DIG $DIGOPTS @10.53.0.3 +ednsopt=server-tag:000001 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; SERVER-TAG" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=`expr $status + $ret`
+
   n=`expr $n + 1`
   echo_i "check that dig handles malformed option '+ednsopt=:' gracefully ($n)"
   ret=0
index dcccd55fef08d95e3181081345ab30fb87f01eb2..2e8cc36ce98dbbc1417f6116bea14703815e3523 100644 (file)
 #define DNS_OPT_COOKIE         10              /*%< COOKIE opt code */
 #define DNS_OPT_PAD            12              /*%< PAD opt code */
 #define DNS_OPT_KEY_TAG                14              /*%< Key tag opt code */
+#define DNS_OPT_CLIENT_TAG     16              /*%< Client tag opt code */
+#define DNS_OPT_SERVER_TAG     17              /*%< Server tag opt code */
 
 /*%< Experimental options [65001...65534] as per RFC6891 */
 
index cc49b01219001451527b4ac362f2d09aa3f2b3a9..d92a5d39cbcccbcec0a40df28fbf7b6c7bdf1491 100644 (file)
@@ -3584,6 +3584,30 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
                                        ADD_STRING(target, "\n");
                                        continue;
                                }
+                       } else if (optcode == DNS_OPT_CLIENT_TAG) {
+                               uint16_t id;
+                               INDENT(style);
+                               ADD_STRING(target, "CLIENT-TAG");
+                               if (optlen == 2U) {
+                                       id = isc_buffer_getuint16(&optbuf);
+                                       snprintf(buf, sizeof(buf), ": %u\n",
+                                                id);
+                                       ADD_STRING(target, buf);
+                                       optlen -= 2;
+                                       continue;
+                               }
+                       } else if (optcode == DNS_OPT_SERVER_TAG) {
+                               uint16_t id;
+                               INDENT(style);
+                               ADD_STRING(target, "SERVER-TAG");
+                               if (optlen == 2U) {
+                                       id = isc_buffer_getuint16(&optbuf);
+                                       snprintf(buf, sizeof(buf), ": %u\n",
+                                                id);
+                                       ADD_STRING(target, buf);
+                                       optlen -= 2;
+                                       continue;
+                               }
                        } else {
                                INDENT(style);
                                ADD_STRING(target, "OPT: ");
@@ -3831,6 +3855,28 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
                                        ADD_STRING(target, "\n");
                                        continue;
                                }
+                       } else if (optcode == DNS_OPT_CLIENT_TAG) {
+                               uint16_t id;
+                               ADD_STRING(target, "; CLIENT-TAG");
+                               if (optlen == 2U) {
+                                       id = isc_buffer_getuint16(&optbuf);
+                                       snprintf(buf, sizeof(buf), ": %u\n",
+                                                id);
+                                       ADD_STRING(target, buf);
+                                       optlen -= 2;
+                                       continue;
+                               }
+                       } else if (optcode == DNS_OPT_SERVER_TAG) {
+                               uint16_t id;
+                               ADD_STRING(target, "; SERVER-TAG");
+                               if (optlen == 2U) {
+                                       id = isc_buffer_getuint16(&optbuf);
+                                       snprintf(buf, sizeof(buf), ": %u\n",
+                                                id);
+                                       ADD_STRING(target, buf);
+                                       optlen -= 2;
+                                       continue;
+                               }
                        } else {
                                ADD_STRING(target, "; OPT=");
                                snprintf(buf, sizeof(buf), "%u", optcode);
index b102cf2f42c14b6966aac9df4a8618571eef226e..b8b7f53656ba3a36d026549769e4afb46c8818f1 100644 (file)
@@ -99,19 +99,22 @@ fromwire_opt(ARGS_FROMWIRE) {
        UNUSED(options);
 
        isc_buffer_activeregion(source, &sregion);
-       if (sregion.length == 0)
+       if (sregion.length == 0) {
                return (ISC_R_SUCCESS);
+       }
        total = 0;
        while (sregion.length != 0) {
-               if (sregion.length < 4)
+               if (sregion.length < 4) {
                        return (ISC_R_UNEXPECTEDEND);
+               }
                opt = uint16_fromregion(&sregion);
                isc_region_consume(&sregion, 2);
                length = uint16_fromregion(&sregion);
                isc_region_consume(&sregion, 2);
                total += 4;
-               if (sregion.length < length)
+               if (sregion.length < length) {
                        return (ISC_R_UNEXPECTEDEND);
+               }
                switch (opt) {
                case DNS_OPT_CLIENT_SUBNET: {
                        uint16_t family;
@@ -119,8 +122,9 @@ fromwire_opt(ARGS_FROMWIRE) {
                        uint8_t scope;
                        uint8_t addrbytes;
 
-                       if (length < 4)
+                       if (length < 4) {
                                return (DNS_R_OPTERR);
+                       }
                        family = uint16_fromregion(&sregion);
                        isc_region_consume(&sregion, 2);
                        addrlen = uint8_fromregion(&sregion);
@@ -139,29 +143,34 @@ fromwire_opt(ARGS_FROMWIRE) {
                                 * lengths don't make sense because the
                                 * family is unknown.
                                 */
-                               if (addrlen != 0U || scope != 0U)
+                               if (addrlen != 0U || scope != 0U) {
                                        return (DNS_R_OPTERR);
+                               }
                                break;
                        case 1:
-                               if (addrlen > 32U || scope > 32U)
+                               if (addrlen > 32U || scope > 32U) {
                                        return (DNS_R_OPTERR);
+                               }
                                break;
                        case 2:
-                               if (addrlen > 128U || scope > 128U)
+                               if (addrlen > 128U || scope > 128U) {
                                        return (DNS_R_OPTERR);
+                               }
                                break;
                        default:
                                return (DNS_R_OPTERR);
                        }
                        addrbytes = (addrlen + 7) / 8;
-                       if (addrbytes + 4 != length)
+                       if (addrbytes + 4 != length) {
                                return (DNS_R_OPTERR);
+                       }
 
                        if (addrbytes != 0U && (addrlen % 8) != 0) {
                                uint8_t bits = ~0U << (8 - (addrlen % 8));
                                bits &= sregion.base[addrbytes - 1];
-                               if (bits != sregion.base[addrbytes - 1])
+                               if (bits != sregion.base[addrbytes - 1]) {
                                        return (DNS_R_OPTERR);
+                               }
                        }
                        isc_region_consume(&sregion, addrbytes);
                        break;
@@ -170,18 +179,29 @@ fromwire_opt(ARGS_FROMWIRE) {
                        /*
                         * Request has zero length.  Response is 32 bits.
                         */
-                       if (length != 0 && length != 4)
+                       if (length != 0 && length != 4) {
                                return (DNS_R_OPTERR);
+                       }
                        isc_region_consume(&sregion, length);
                        break;
                case DNS_OPT_COOKIE:
-                       if (length != 8 && (length < 16 || length > 40))
+                       if (length != 8 && (length < 16 || length > 40)) {
                                return (DNS_R_OPTERR);
+                       }
                        isc_region_consume(&sregion, length);
                        break;
                case DNS_OPT_KEY_TAG:
-                       if (length == 0 || (length % 2) != 0)
+                       if (length == 0 || (length % 2) != 0) {
                                return (DNS_R_OPTERR);
+                       }
+                       isc_region_consume(&sregion, length);
+                       break;
+               case DNS_OPT_CLIENT_TAG:
+                       /* FALLTHROUGH */
+               case DNS_OPT_SERVER_TAG:
+                       if (length != 2) {
+                               return (DNS_R_OPTERR);
+                       }
                        isc_region_consume(&sregion, length);
                        break;
                default:
@@ -193,8 +213,9 @@ fromwire_opt(ARGS_FROMWIRE) {
 
        isc_buffer_activeregion(source, &sregion);
        isc_buffer_availableregion(target, &tregion);
-       if (tregion.length < total)
+       if (tregion.length < total) {
                return (ISC_R_NOSPACE);
+       }
        memmove(tregion.base, sregion.base, total);
        isc_buffer_forward(source, total);
        isc_buffer_add(target, total);