]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3273. [bug] AAAA responses could be returned in the additional
authorMark Andrews <marka@isc.org>
Fri, 27 Apr 2012 03:02:03 +0000 (13:02 +1000)
committerMark Andrews <marka@isc.org>
Fri, 27 Apr 2012 03:02:03 +0000 (13:02 +1000)
                        section even when filter-aaaa-on-v4 was in use.
                        [RT #27292]

12 files changed:
.gitignore
bin/named/.gitignore
bin/named/client.c
bin/named/include/named/client.h
bin/named/query.c
bin/tests/system/filter-aaaa/ns1/root.db
bin/tests/system/filter-aaaa/ns1/signed.db.in
bin/tests/system/filter-aaaa/ns1/unsigned.db
bin/tests/system/filter-aaaa/ns4/root.db
bin/tests/system/filter-aaaa/ns4/signed.db.in
bin/tests/system/filter-aaaa/ns4/unsigned.db
bin/tests/system/filter-aaaa/tests.sh

index 09977ff4b2d8fa1ac1733d66d5c078f7316a02d0..b09e161f1bec0d3642efdb130fd7df33365b0e55 100644 (file)
@@ -48,3 +48,4 @@ unit/atf-src/stamp-h1
 unit/atf-src/test-programs/c_helpers
 unit/atf-src/test-programs/cpp_helpers
 unit/atf-src/test-programs/sh_helpers
+bin/named/named
index 33d5f1cfe7fd71f8423754a13d98ff849e741ac9..4353b49a39076bfd2b568c60d44ee2c266d603cc 100644 (file)
@@ -1,4 +1,3 @@
 .libs
-named
 named-symtbl.c
 lwresd
index f025a358ff79bef362d49858c7ded24d18582455..bb59200970910d0ea375dfc6f5bdca94e72c39eb 100644 (file)
@@ -929,6 +929,15 @@ ns_client_send(ns_client_t *client) {
                render_opts = 0;
        else
                render_opts = DNS_MESSAGERENDER_OMITDNSSEC;
+
+       preferred_glue = 0;
+       if (client->view != NULL) {
+               if (client->view->preferred_glue == dns_rdatatype_a)
+                       preferred_glue = DNS_MESSAGERENDER_PREFER_A;
+               else if (client->view->preferred_glue == dns_rdatatype_aaaa)
+                       preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;
+       }
+
 #ifdef ALLOW_FILTER_AAAA_ON_V4
        /*
         * filter-aaaa-on-v4 yes or break-dnssec option to suppress
@@ -937,17 +946,15 @@ ns_client_send(ns_client_t *client) {
         * that we have both AAAA and A records,
         * and that we either have no signatures that the client wants
         * or we are supposed to break DNSSEC.
+        *
+        * Override preferred glue if necessary.
         */
-       if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0)
+       if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0) {
                render_opts |= DNS_MESSAGERENDER_FILTER_AAAA;
-#endif
-       preferred_glue = 0;
-       if (client->view != NULL) {
-               if (client->view->preferred_glue == dns_rdatatype_a)
+               if (preferred_glue == DNS_MESSAGERENDER_PREFER_AAAA)
                        preferred_glue = DNS_MESSAGERENDER_PREFER_A;
-               else if (client->view->preferred_glue == dns_rdatatype_aaaa)
-                       preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;
        }
+#endif
 
        /*
         * XXXRTH  The following doesn't deal with TCP buffer resizing.
@@ -2110,6 +2117,9 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
        client->recursionquota = NULL;
        client->interface = NULL;
        client->peeraddr_valid = ISC_FALSE;
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+       client->filter_aaaa = dns_v4_aaaa_ok;
+#endif
        ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
                       NS_EVENT_CLIENTCONTROL, client_start, client, client,
                       NULL, NULL);
index a3d076bd8ed12a50ca4a715fa0c1ba33743d79fe..8254e15746839184fc17d2cd5f722f4465b7847d 100644 (file)
@@ -141,6 +141,9 @@ struct ns_client {
        isc_netaddr_t           destaddr;
        struct in6_pktinfo      pktinfo;
        isc_event_t             ctlevent;
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+       dns_v4_aaaa_t           filter_aaaa;
+#endif
        /*%
         * Information about recent FORMERR response(s), for
         * FORMERR loop avoidance.  This is separate for each
index 0a0f8d2b12d5279880b5ef1dbdad66fc0bd1c318..c681a57549f821d2282dedf47a99dec00087c668 100644 (file)
@@ -1352,6 +1352,10 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
        }
 
        if (qtype == dns_rdatatype_a) {
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+               isc_boolean_t have_a = ISC_FALSE;
+#endif
+
                /*
                 * We now go looking for A and AAAA records, along with
                 * their signatures.
@@ -1390,6 +1394,9 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
                }
                if (result == ISC_R_SUCCESS) {
                        mname = NULL;
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+                       have_a = ISC_TRUE;
+#endif
                        if (!query_isduplicate(client, fname,
                                               dns_rdatatype_a, &mname)) {
                                if (mname != NULL) {
@@ -1436,6 +1443,17 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
                }
                if (result == ISC_R_SUCCESS) {
                        mname = NULL;
+                       /*
+                        * There's an A; check whether we're filtering AAAA
+                        */
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+                       if (have_a && 
+                           (client->filter_aaaa == dns_v4_aaaa_break_dnssec ||
+                           (client->filter_aaaa == dns_v4_aaaa_filter &&
+                            (!WANTDNSSEC(client) || sigrdataset == NULL ||
+                             !dns_rdataset_isassociated(sigrdataset)))))
+                               goto addname;
+#endif
                        if (!query_isduplicate(client, fname,
                                               dns_rdatatype_aaaa, &mname)) {
                                if (mname != NULL) {
@@ -6643,9 +6661,21 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                need_wildcardproof = ISC_TRUE;
        }
 
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+       if (client->view->v4_aaaa != dns_v4_aaaa_ok &&
+           is_v4_client(client) &&
+           ns_client_checkaclsilent(client, NULL,
+                                    client->view->v4_aaaa_acl,
+                                    ISC_TRUE) == ISC_R_SUCCESS)
+               client->filter_aaaa = client->view->v4_aaaa;
+       else
+               client->filter_aaaa = dns_v4_aaaa_ok;
+
+#endif
+
        if (type == dns_rdatatype_any) {
 #ifdef ALLOW_FILTER_AAAA_ON_V4
-               isc_boolean_t have_aaaa, have_a, have_sig, filter_aaaa;
+               isc_boolean_t have_aaaa, have_a, have_sig;
 
                /*
                 * The filter-aaaa-on-v4 option should
@@ -6657,14 +6687,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                have_aaaa = ISC_FALSE;
                have_a = !authoritative;
                have_sig = ISC_FALSE;
-               if (client->view->v4_aaaa != dns_v4_aaaa_ok &&
-                   is_v4_client(client) &&
-                   ns_client_checkaclsilent(client, NULL,
-                                            client->view->v4_aaaa_acl,
-                                            ISC_TRUE) == ISC_R_SUCCESS)
-                       filter_aaaa = ISC_TRUE;
-               else
-                       filter_aaaa = ISC_FALSE;
 #endif
                /*
                 * XXXRTH  Need to handle zonecuts with special case
@@ -6699,7 +6721,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                         * Notice the presence of A and AAAAs so
                         * that AAAAs can be hidden from IPv4 clients.
                         */
-                       if (filter_aaaa) {
+                       if (client->filter_aaaa != dns_v4_aaaa_ok) {
                                if (rdataset->type == dns_rdatatype_aaaa)
                                        have_aaaa = ISC_TRUE;
                                else if (rdataset->type == dns_rdatatype_a)
@@ -6756,10 +6778,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                 * Filter AAAAs if there is an A and there is no signature
                 * or we are supposed to break DNSSEC.
                 */
-               if (filter_aaaa && have_aaaa && have_a &&
-                   (!have_sig || !WANTDNSSEC(client) ||
-                    client->view->v4_aaaa == dns_v4_aaaa_break_dnssec))
+               if (client->filter_aaaa == dns_v4_aaaa_break_dnssec)
                        client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
+               else if (client->filter_aaaa != dns_v4_aaaa_ok &&
+                        have_aaaa && have_a &&
+                        (!have_sig || !WANTDNSSEC(client)))
+                         client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
 #endif
                if (fname != NULL)
                        dns_message_puttempname(client->message, &fname);
@@ -6820,15 +6844,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                 * so fundamentally wrong, unavoidably inaccurate, and
                 * unneeded that it is best to keep it as short as possible.
                 */
-               if (client->view->v4_aaaa != dns_v4_aaaa_ok &&
-                   is_v4_client(client) &&
-                   ns_client_checkaclsilent(client, NULL,
-                                            client->view->v4_aaaa_acl,
-                                            ISC_TRUE) == ISC_R_SUCCESS &&
-                   (!WANTDNSSEC(client) ||
-                    sigrdataset == NULL ||
-                    !dns_rdataset_isassociated(sigrdataset) ||
-                    client->view->v4_aaaa == dns_v4_aaaa_break_dnssec)) {
+               if (client->filter_aaaa == dns_v4_aaaa_break_dnssec ||
+                   (client->filter_aaaa == dns_v4_aaaa_filter &&
+                    (!WANTDNSSEC(client) || sigrdataset == NULL ||
+                    !dns_rdataset_isassociated(sigrdataset))))
+               {
                        if (qtype == dns_rdatatype_aaaa) {
                                trdataset = query_newrdataset(client);
                                result = dns_db_findrdataset(db, node, version,
index d33b422cb70464345d5494b336b82bf540ba3d39..6f599bbbe0304c5d9a10a402c7cff5b4cb32020e 100644 (file)
@@ -18,6 +18,7 @@ $TTL  120
 @              SOA     ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 )
 @              NS      ns.utld
 ns.utld                A       10.53.0.1
+ns.utld                AAAA    fd92:7065:b8e:ffff::1
 ;
 signed         NS      ns.utld
 unsigned       NS      ns.utld
index 422ec2576ce2374a0c1ab98e9b0264fbbbb7ce6a..102f56ba54e966491cc150d4c63c53ae894a5c79 100644 (file)
 $TTL   120
 @              SOA     ns.utld.  hostmaster.ns.utld. ( 1 3600 1200 604800 60 )
 @              NS      ns.utld.
+@              MX      0 mx
 a-only         NS      1.0.0.1
 aaaa-only      AAAA    2001:db8::2
 dual           A       1.0.0.3
 dual           AAAA    2001:db8::3
+mx             A       1.0.0.3
+mx             AAAA    2001:db8::3
+
index 9626fc8f27f2a7b409d0ac4f96db96820bdde3d0..6caa60b593e7c0803c9fa6a9c3db2715c741460d 100644 (file)
 $TTL   120
 @              SOA     ns.utld.  hostmaster.ns.utld. ( 1 3600 1200 604800 60 )
 @              NS      ns.utld.
+@              MX      0 mx
 a-only         NS      1.0.0.4
 aaaa-only      AAAA    2001:db8::5
 dual           A       1.0.0.6
 dual           AAAA    2001:db8::6
+mx             A       1.0.0.3
+mx             AAAA    2001:db8::3
+
index d33b422cb70464345d5494b336b82bf540ba3d39..6f599bbbe0304c5d9a10a402c7cff5b4cb32020e 100644 (file)
@@ -18,6 +18,7 @@ $TTL  120
 @              SOA     ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 )
 @              NS      ns.utld
 ns.utld                A       10.53.0.1
+ns.utld                AAAA    fd92:7065:b8e:ffff::1
 ;
 signed         NS      ns.utld
 unsigned       NS      ns.utld
index 422ec2576ce2374a0c1ab98e9b0264fbbbb7ce6a..102f56ba54e966491cc150d4c63c53ae894a5c79 100644 (file)
 $TTL   120
 @              SOA     ns.utld.  hostmaster.ns.utld. ( 1 3600 1200 604800 60 )
 @              NS      ns.utld.
+@              MX      0 mx
 a-only         NS      1.0.0.1
 aaaa-only      AAAA    2001:db8::2
 dual           A       1.0.0.3
 dual           AAAA    2001:db8::3
+mx             A       1.0.0.3
+mx             AAAA    2001:db8::3
+
index 9626fc8f27f2a7b409d0ac4f96db96820bdde3d0..199f70ee66cb90ef68ebe0de150b990ad706909c 100644 (file)
@@ -21,3 +21,6 @@ a-only                NS      1.0.0.4
 aaaa-only      AAAA    2001:db8::5
 dual           A       1.0.0.6
 dual           AAAA    2001:db8::6
+mx             A       1.0.0.3
+mx             AAAA    2001:db8::3
+
index d9efd29815a5b8e70de6b08a941e8b2376d10cb7..bbd472982632b0407dd08beb12c231faba5a17e3 100644 (file)
@@ -174,6 +174,45 @@ else
 echo "I: skipped."
 fi
 
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=NS ($n)"
+ret=0
+$DIG $DIGOPTS +add ns unsigned -b 10.53.0.1 @10.53.0.1 > dig.out.ns1.test$n || ret=1
+grep AAAA dig.out.ns1.test$n > /dev/null 2>&1 && ret=1
+grep "ADDITIONAL: 2" dig.out.ns1.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)"
+ret=0
+$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.1 @10.53.0.1 > dig.out.ns1.test$n || ret=1
+grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n > /dev/null 2>&1 && ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is included in additional section, qtype=MX, signed ($n)"
+ret=0
+$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.1 @10.53.0.1 > dig.out.ns1.test$n || ret=1
+grep "^mx.signed.*AAAA" dig.out.ns1.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is included in additional section, qtype=MX, unsigned, over IPV6 ($n)"
+if $TESTSOCK6 fd92:7065:b8e:ffff::1
+then
+ret=0
+$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 > dig.out.ns1.test$n || ret=1
+grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+else
+echo "I: skipped."
+fi
+
+
 #
 # Authoritative tests against:
 #      filter-aaaa-on-v4 break-dnssec;
@@ -303,6 +342,45 @@ else
 echo "I: skipped."
 fi
 
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=NS, with break-dnssec ($n)"
+ret=0
+$DIG $DIGOPTS +add ns unsigned -b 10.53.0.4 @10.53.0.4 > dig.out.ns4.test$n || ret=1
+grep AAAA dig.out.ns4.test$n > /dev/null 2>&1 && ret=1
+grep "ADDITIONAL: 2" dig.out.ns4.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=MX, unsigned, with break-dnssec ($n)"
+ret=0
+$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.4 @10.53.0.4 > dig.out.ns4.test$n || ret=1
+grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n > /dev/null 2>&1 && ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=MX, signed, with break-dnssec ($n)"
+ret=0
+$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.4 @10.53.0.4 > dig.out.ns4.test$n || ret=1
+grep "^mx.signed.*AAAA" dig.out.ns4.test$n > /dev/null 2>&1 && ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is included in additional section, qtype=MX, unsigned, over IPV6, with break-dnssec ($n)"
+if $TESTSOCK6 fd92:7065:b8e:ffff::4
+then
+ret=0
+$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 > dig.out.ns4.test$n || ret=1
+grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+else
+echo "I: skipped."
+fi
+
+
 #
 # Recursive tests against:
 #      filter-aaaa-on-v4 yes;
@@ -431,6 +509,45 @@ else
 echo "I: skipped."
 fi
 
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=NS ($n)"
+ret=0
+$DIG $DIGOPTS +add ns unsigned -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1
+grep AAAA dig.out.ns2.test$n > /dev/null 2>&1 && ret=1
+grep "ADDITIONAL: 2" dig.out.ns2.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)"
+ret=0
+$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1
+grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n > /dev/null 2>&1 && ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is included in additional section, qtype=MX, signed ($n)"
+ret=0
+$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1
+grep "^mx.signed.*AAAA" dig.out.ns2.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is included in additional section, qtype=MX, unsigned, over IPV6 ($n)"
+if $TESTSOCK6 fd92:7065:b8e:ffff::2
+then
+ret=0
+$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1
+grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+else
+echo "I: skipped."
+fi
+
+
 #
 # Recursive tests against:
 #      filter-aaaa-on-v4 break-dnssec;
@@ -559,5 +676,43 @@ else
 echo "I: skipped."
 fi
 
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=NS, recursive with break-dnssec ($n)"
+ret=0
+$DIG $DIGOPTS +add ns unsigned -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1
+grep AAAA dig.out.ns3.test$n > /dev/null 2>&1 && ret=1
+grep "ADDITIONAL: 2" dig.out.ns3.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=MX, unsigned, recursive with break-dnssec ($n)"
+ret=0
+$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1
+grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n > /dev/null 2>&1 && ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is omitted from additional section, qtype=MX, signed, recursive with break-dnssec ($n)"
+ret=0
+$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1
+grep "^mx.signed.*AAAA" dig.out.ns3.test$n > /dev/null 2>&1 && ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that AAAA is included in additional section, qtype=MX, unsigned, over IPV6, recursive with break-dnssec ($n)"
+if $TESTSOCK6 fd92:7065:b8e:ffff::3
+then
+ret=0
+$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 > dig.out.ns3.test$n || ret=1
+grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+else
+echo "I: skipped."
+fi
+
 echo "I:exit status: $status"
 exit $status