From 913b3afd3d3608784e3dffcfab5361c62cba62c2 Mon Sep 17 00:00:00 2001 From: Adam Tkac Date: Mar 17 2009 11:41:17 +0000 Subject: - fall back to insecure mode when no supported DNSSEC algorithm is found instead of SERVFAIL - don't fall back to non-EDNS0 queries when DO bit is set --- diff --git a/bind.spec b/bind.spec index 07c4616..8658bf2 100644 --- a/bind.spec +++ b/bind.spec @@ -20,7 +20,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: ISC Version: 9.6.0 -Release: 10.%{PATCHVER}%{?dist} +Release: 11.%{PATCHVER}%{?dist} Epoch: 32 Url: http://www.isc.org/products/BIND/ Buildroot:%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -54,6 +54,7 @@ Patch99: bind-96-libtool2.patch Patch101:bind-96-old-api.patch Patch102:bind-95-rh452060.patch Patch103:bind-96-realloc.patch +Patch106:bind9-fedora-0001.diff # SDB patches Patch11: bind-9.3.2b2-sdbsrc.patch @@ -220,6 +221,7 @@ mkdir m4 %patch102 -p1 -b .rh452060 %patch103 -p0 -b .realloc +%patch106 -p1 -b .nsec3 # Sparc and s390 arches need to use -fPIE %ifarch sparcv9 sparc64 s390 s390x @@ -569,6 +571,11 @@ rm -rf ${RPM_BUILD_ROOT} %ghost %{chroot_prefix}/etc/localtime %changelog +* Tue Mar 17 2009 Adam Tkac 32:9.6.0-11.P1 +- fall back to insecure mode when no supported DNSSEC algorithm is found + instead of SERVFAIL +- don't fall back to non-EDNS0 queries when DO bit is set + * Tue Mar 10 2009 Adam Tkac 32:9.6.0-10.P1 - enable DNSSEC only if it is enabled in sysconfig/dnssec diff --git a/bind9-fedora-0001.diff b/bind9-fedora-0001.diff new file mode 100644 index 0000000..8e92846 --- /dev/null +++ b/bind9-fedora-0001.diff @@ -0,0 +1,219 @@ +diff -ur bind-9.6.0-P1.pristine/lib/dns/resolver.c bind-9.6.0-P1/lib/dns/resolver.c +--- bind-9.6.0-P1.pristine/lib/dns/resolver.c 2008-11-06 18:52:34.000000000 -0600 ++++ bind-9.6.0-P1/lib/dns/resolver.c 2009-03-16 21:15:44.000000000 -0500 +@@ -222,6 +222,7 @@ + * is used for EDNS0 black hole detection. + */ + unsigned int timeouts; ++ + /*% + * Look aside state for DS lookups. + */ +@@ -245,6 +246,7 @@ + */ + isc_uint32_t rand_buf; + isc_uint32_t rand_bits; ++ isc_boolean_t timeout; + }; + + #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!') +@@ -1575,28 +1577,44 @@ + DNS_FETCHOPT_NOEDNS0); + } + +- /* Sync NOEDNS0 flag in addrinfo->flags and options now */ ++ /* Sync NOEDNS0 flag in addrinfo->flags and options now. */ + if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0) + query->options |= DNS_FETCHOPT_NOEDNS0; + + /* ++ * Handle timeouts by reducing the UDP response size to 512 bytes ++ * then if that doesn't work disabling EDNS (includes DO) and CD. ++ * ++ * These timeout can be due to: ++ * * broken nameservers that don't respond to EDNS queries. ++ * * broken/misconfigured firewalls and NAT implementations ++ * that don't handle IP fragmentation. ++ * * broken/misconfigured firewalls that don't handle responses ++ * greater than 512 bytes. ++ * * broken/misconfigured firewalls that don't handle EDNS, DO ++ * or CD. ++ * * packet loss / link outage. ++ */ ++ if (fctx->timeout) { ++ if ((triededns512(fctx, &query->addrinfo->sockaddr) || ++ fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) && ++ (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { ++ query->options |= DNS_FETCHOPT_NOEDNS0; ++ fctx->reason = "disabling EDNS"; ++ } else if ((triededns(fctx, &query->addrinfo->sockaddr) || ++ fctx->timeouts >= MAX_EDNS0_TIMEOUTS) && ++ (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { ++ query->options |= DNS_FETCHOPT_EDNS512; ++ fctx->reason = "reducing the advertised EDNS UDP " ++ "packet size to 512 octets"; ++ } ++ fctx->timeout = ISC_FALSE; ++ } ++ ++ /* + * Use EDNS0, unless the caller doesn't want it, or we know that + * the remote server doesn't like it. + */ +- +- if ((triededns512(fctx, &query->addrinfo->sockaddr) || +- fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) && +- (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { +- query->options |= DNS_FETCHOPT_NOEDNS0; +- fctx->reason = "disabling EDNS"; +- } else if ((triededns(fctx, &query->addrinfo->sockaddr) || +- fctx->timeouts >= MAX_EDNS0_TIMEOUTS) && +- (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { +- query->options |= DNS_FETCHOPT_EDNS512; +- fctx->reason = "reducing the advertised EDNS UDP packet " +- "size to 512 octets"; +- } +- + if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { + if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) { + unsigned int version = 0; /* Default version. */ +@@ -2909,6 +2927,7 @@ + isc_result_t result; + + fctx->timeouts++; ++ fctx->timeout = ISC_TRUE; + /* + * We could cancel the running queries here, or we could let + * them keep going. Since we normally use separate sockets for +@@ -3242,6 +3261,7 @@ + fctx->reason = NULL; + fctx->rand_buf = 0; + fctx->rand_bits = 0; ++ fctx->timeout = ISC_FALSE; + + dns_name_init(&fctx->nsname, NULL); + fctx->nsfetch = NULL; +@@ -4508,7 +4528,8 @@ + */ + ttl = fctx->res->view->maxncachettl; + if (fctx->type == dns_rdatatype_soa && +- covers == dns_rdatatype_any) ++ covers == dns_rdatatype_any && ++ fctx->res->zero_no_soa_ttl) + ttl = 0; + + result = ncache_adderesult(fctx->rmessage, fctx->cache, node, +@@ -5768,6 +5789,7 @@ + } + + fctx->timeouts = 0; ++ fctx->timeout = ISC_FALSE; + + /* + * XXXRTH We should really get the current time just once. We +diff -ur bind-9.6.0-P1.pristine/lib/dns/validator.c bind-9.6.0-P1/lib/dns/validator.c +--- bind-9.6.0-P1.pristine/lib/dns/validator.c 2008-11-14 17:47:33.000000000 -0600 ++++ bind-9.6.0-P1/lib/dns/validator.c 2009-03-16 21:13:56.000000000 -0500 +@@ -218,6 +218,37 @@ + return (ISC_TRUE); + } + ++/* ++ * Check that we have atleast one supported algorithm in the DLV RRset. ++ */ ++static inline isc_boolean_t ++dlv_algorithm_supported(dns_validator_t *val) { ++ dns_rdata_t rdata = DNS_RDATA_INIT; ++ dns_rdata_dlv_t dlv; ++ isc_result_t result; ++ ++ for (result = dns_rdataset_first(&val->dlv); ++ result == ISC_R_SUCCESS; ++ result = dns_rdataset_next(&val->dlv)) { ++ dns_rdata_reset(&rdata); ++ dns_rdataset_current(&val->dlv, &rdata); ++ result = dns_rdata_tostruct(&rdata, &dlv, NULL); ++ RUNTIME_CHECK(result == ISC_R_SUCCESS); ++ ++ if (!dns_resolver_algorithm_supported(val->view->resolver, ++ val->event->name, ++ dlv.algorithm)) ++ continue; ++ ++ if (dlv.digest_type != DNS_DSDIGEST_SHA256 && ++ dlv.digest_type != DNS_DSDIGEST_SHA1) ++ continue; ++ ++ return (ISC_TRUE); ++ } ++ return (ISC_FALSE); ++} ++ + /*% + * Look in the NSEC record returned from a DS query to see if there is + * a NS RRset at this name. If it is found we are at a delegation point. +@@ -2957,19 +2988,36 @@ + sizeof(namebuf)); + dns_rdataset_clone(&val->frdataset, &val->dlv); + val->havedlvsep = ISC_TRUE; +- validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); +- dlv_validator_start(val); ++ if (dlv_algorithm_supported(val)) { ++ validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", ++ namebuf); ++ dlv_validator_start(val); ++ } else { ++ validator_log(val, ISC_LOG_DEBUG(3), ++ "DLV %s found with no supported algorithms", ++ namebuf); ++ markanswer(val); ++ validator_done(val, ISC_R_SUCCESS); ++ } + } else if (eresult == DNS_R_NXRRSET || + eresult == DNS_R_NXDOMAIN || + eresult == DNS_R_NCACHENXRRSET || + eresult == DNS_R_NCACHENXDOMAIN) { +- result = finddlvsep(val, ISC_TRUE); ++ result = finddlvsep(val, ISC_TRUE); + if (result == ISC_R_SUCCESS) { +- dns_name_format(dns_fixedname_name(&val->dlvsep), +- namebuf, sizeof(namebuf)); +- validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", +- namebuf); +- dlv_validator_start(val); ++ if (dlv_algorithm_supported(val)) { ++ dns_name_format(dns_fixedname_name(&val->dlvsep), ++ namebuf, sizeof(namebuf)); ++ validator_log(val, ISC_LOG_DEBUG(3), ++ "DLV %s found", namebuf); ++ dlv_validator_start(val); ++ } else { ++ validator_log(val, ISC_LOG_DEBUG(3), ++ "DLV %s found with no supported " ++ "algorithms", namebuf); ++ markanswer(val); ++ validator_done(val, ISC_R_SUCCESS); ++ } + } else if (result == ISC_R_NOTFOUND) { + validator_log(val, ISC_LOG_DEBUG(3), "DLV not found"); + markanswer(val); +@@ -3032,9 +3080,16 @@ + } + dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf, + sizeof(namebuf)); +- validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); +- dlv_validator_start(val); +- return (DNS_R_WAIT); ++ if (dlv_algorithm_supported(val)) { ++ validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); ++ dlv_validator_start(val); ++ return (DNS_R_WAIT); ++ } ++ validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported " ++ "algorithms", namebuf); ++ markanswer(val); ++ validator_done(val, ISC_R_SUCCESS); ++ return (ISC_R_SUCCESS); + } + + /*%