+3731. [func] Added a "no-case-compress" ACL, which causes
+ named to use case-insensitive compression
+ (disabling change #3645) for specified
+ clients. (This is useful when dealing
+ with broken client implementations that
+ use case-sensitive name comparisons,
+ rejecting responses that fail to match the
+ capitalization of the query that was sent.)
+ [RT #35300]
+
3730. [cleanup] Added "never" as a synonym for "none" when
configuring key event dates in the dnssec tools.
[RT #35277]
static void ns_client_dumpmessage(ns_client_t *client, const char *reason);
static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
dns_dispatch_t *disp, isc_boolean_t tcp);
+static inline isc_boolean_t
+allowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl);
void
ns_client_recursing(ns_client_t *client) {
result = dns_compress_init(&cctx, -1, client->mctx);
if (result != ISC_R_SUCCESS)
goto done;
- dns_compress_setsensitive(&cctx, ISC_TRUE);
+ if (client->peeraddr_valid && client->view != NULL) {
+ isc_netaddr_t netaddr;
+ dns_name_t *name = NULL;
+
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+ if (client->message->tsigkey != NULL)
+ name = &client->message->tsigkey->name;
+ if (client->view->nocasecompress == NULL ||
+ !allowed(&netaddr, name, client->view->nocasecompress))
+ {
+ dns_compress_setsensitive(&cctx, ISC_TRUE);
+ }
+ }
cleanup_cctx = ISC_TRUE;
result = dns_message_renderbegin(client->message, &cctx, &buffer);
CHECK(dns_acl_none(mctx, &view->cacheacl));
}
+ /*
+ * Ignore case when compressing responses to the specified
+ * clients. This causes case not always to be presrerved,
+ * and is needed by some broken clients.
+ */
+ CHECK(configure_view_acl(vconfig, config, "no-case-compress", NULL,
+ actx, ns_g_mctx, &view->nocasecompress));
+
/*
* Filter setting on addresses in the answer section.
*/
--- /dev/null
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+controls { /* empty */ };
+
+options {
+ query-source address 10.53.0.2;
+ notify-source 10.53.0.2;
+ transfer-source 10.53.0.2;
+ port 5300;
+ pid-file "named.pid";
+ listen-on { 10.53.0.2; };
+ listen-on-v6 { none; };
+ recursion no;
+ notify yes;
+ ixfr-from-differences yes;
+ check-integrity no;
+ no-case-compress { 10.53.0.2; };
+};
+
+zone "example" {
+ type slave;
+ file "example.bk";
+ masters { 10.53.0.1; };
+};
n=0
n=`expr $n + 1`
-echo "I:testing case sensitive responses ($n)"
+echo "I:testing case preserving responses - no acl ($n)"
ret=0
-$DIG $DIGOPTS mx example. @10.53.0.1 -p 5300 > dig.n1.test$n
-grep "0.mail.eXaMpLe" dig.n1.test$n > /dev/null || ret=1
-grep "mAiL.example" dig.n1.test$n > /dev/null || ret=1
+$DIG $DIGOPTS mx example. @10.53.0.1 -p 5300 > dig.ns1.test$n
+grep "0.mail.eXaMpLe" dig.ns1.test$n > /dev/null || ret=1
+grep "mAiL.example" dig.ns1.test$n > /dev/null || ret=1
+test $ret -eq 0 || echo "I:failed"
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:testing no-case-compress acl '{ 10.53.0.2; }' ($n)"
+ret=0
+
+# check that we preserve zone case for non-matching query (10.53.0.1)
+$DIG $DIGOPTS mx example. -b 10.53.0.1 @10.53.0.1 -p 5300 > dig.ns1.test$n
+grep "0.mail.eXaMpLe" dig.ns1.test$n > /dev/null || ret=1
+grep "mAiL.example" dig.ns1.test$n > /dev/null || ret=1
+
+# check that we don't preserve zone case for match (10.53.0.2)
+$DIG $DIGOPTS mx example. -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.ns2.test$n
+grep "0.mail.example" dig.ns2.test$n > /dev/null || ret=1
+grep "mail.example" dig.ns2.test$n > /dev/null || ret=1
+
test $ret -eq 0 || echo "I:failed"
status=`expr $status + $ret`
<optional> try-tcp-refresh <replaceable>yes_or_no</replaceable>; </optional>
<optional> allow-v6-synthesis { <replaceable>address_match_list</replaceable> }; </optional>
<optional> blackhole { <replaceable>address_match_list</replaceable> }; </optional>
+ <optional> no-case-compress { <replaceable>address_match_list</replaceable> }; </optional>
<optional> use-v4-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> avoid-v4-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> use-v6-udp-ports { <replaceable>port_list</replaceable> }; </optional>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>no-case-compress</command></term> <listitem>
+ <para>
+ Specifies a list of addresses which require responses
+ to use case-insensitive compression. This ACL can be
+ used when <command>named</command> needs to work with
+ clients that do not comply with the requirement in RFC
+ 1034 to use case-insensitive name comparisons when
+ checking for matching domain names.
+ </para>
+ <para>
+ If left undefined, the ACL defaults to
+ <command>none</command>: case-insensitive compression
+ will be used for all clients. If the ACL is defined and
+ matches a client, then case will be ignored when
+ compressing domain names in DNS responses sent to that
+ client.
+ </para>
+ <para>
+ This can result in slightly smaller responses: if
+ a response contains the names "example.com" and
+ "example.COM", case-insensitive compression would treat
+ the second one as a duplicate. It also ensures
+ that the case of the query name exactly matches the
+ case of the owner names of returned records, rather
+ than matching the case of the records entered in
+ the zone file. This allows responses to exactly
+ match the query, which is required by some clients
+ due to incorrect use of case-sensitive comparisions.
+ </para>
+ <para>
+ Case-insensitive compression is <emphasis>always</emphasis>
+ used in AXFR and IXFR responses, regardless of whether
+ the client matches this ACL.
+ </para>
+ <para>
+ There are circusmstances in which <command>named</command>
+ will not preserve the case of owner names of records:
+ if a zone file defines records of different types with
+ the same name, but the capitalization of the name is
+ different (e.g., "www.example.com/A" and
+ "WWW.EXAMPLE.COM/AAAA"), then all resposnes for that
+ name will use the <emphasis>first</emphasis> version
+ of the name that was used in the zone file. This
+ limitation may be addressed in a future release. However,
+ domain names specified in the rdata of resource records
+ (i.e., records of type NS, MX, CNAME, etc) will always
+ have their case preserved unless the client matches this
+ ACL.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><command>resolver-query-timeout</command></term>
<listitem>
dns_acl_t * updateacl;
dns_acl_t * upfwdacl;
dns_acl_t * denyansweracl;
+ dns_acl_t * nocasecompress;
dns_rbt_t * answeracl_exclude;
dns_rbt_t * denyanswernames;
dns_rbt_t * answernames_exclude;
view->updateacl = NULL;
view->upfwdacl = NULL;
view->denyansweracl = NULL;
+ view->nocasecompress = NULL;
view->answeracl_exclude = NULL;
view->denyanswernames = NULL;
view->answernames_exclude = NULL;
dns_db_detach(&view->cachedb);
if (view->cache != NULL)
dns_cache_detach(&view->cache);
+ if (view->nocasecompress != NULL)
+ dns_acl_detach(&view->nocasecompress);
if (view->matchclients != NULL)
dns_acl_detach(&view->matchclients);
if (view->matchdestinations != NULL)
{ "minimal-responses", &cfg_type_boolean, 0 },
{ "prefetch", &cfg_type_prefetch, 0 },
{ "preferred-glue", &cfg_type_astring, 0 },
+ { "no-case-compress", &cfg_type_bracketed_aml, 0 },
{ "provide-ixfr", &cfg_type_boolean, 0 },
/*
* Note that the query-source option syntax is different