]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Merge pull request #4215 from rgacogne/rec-rpz-override-local
authorPieter Lexis <pieterlexis@users.noreply.github.com>
Wed, 27 Jul 2016 12:34:27 +0000 (14:34 +0200)
committerGitHub <noreply@github.com>
Wed, 27 Jul 2016 12:34:27 +0000 (14:34 +0200)
rec: RPZ default policy should also override local data RRs

45 files changed:
build-scripts/build-auth-rpm
configure.ac
docs/markdown/appendix/compiling-powerdns.md
docs/markdown/authoritative/settings.md
docs/markdown/changelog.raw.md
docs/markdown/recursor/settings.md
docs/secpoll.zone
m4/pdns_enable_remotebackend_zeromq.m4
modules/luabackend/lua_functions.cc
modules/pipebackend/pipebackend.cc
modules/remotebackend/remotebackend.cc
pdns/README-dnsdist.md
pdns/common_startup.cc
pdns/dnsdist-console.cc
pdns/dnsdist-lua.cc
pdns/dnsdist.cc
pdns/dnspacket.cc
pdns/dnspacket.hh
pdns/dnsreplay.cc
pdns/dnsrulactions.hh
pdns/iputils.cc
pdns/ixfr.cc
pdns/ixfr.hh
pdns/logger.cc
pdns/logger.hh
pdns/lua-auth.cc
pdns/lua-recursor4.cc
pdns/packethandler.cc
pdns/pdns_recursor.cc
pdns/rec-lua-conf.cc
pdns/recursordist/Makefile.am
pdns/reczones.cc
pdns/resolver.cc
pdns/resolver.hh
pdns/rfc2136handler.cc
pdns/rpzloader.cc
pdns/rpzloader.hh
pdns/slavecommunicator.cc
pdns/syncres.cc
pdns/tcpreceiver.cc
pdns/validate-recursor.cc
pdns/validate.cc
regression-tests.dnsdist/test_Advanced.py
regression-tests.recursor-dnssec/recursortests.py
regression-tests.recursor-dnssec/test_Simple.py

index e3da467f49aa8a8646ef8396a8ff29bf8dcbaf9c..e6dc2785fa996171670b7e19c18f531c42c1aa48 100755 (executable)
@@ -639,6 +639,16 @@ BuildRequires: sqlite-devel
 %description backend-sqlite
 This package contains the SQLite backend for %{name}
 
+%package backend-tinydns
+Summary: TinyDNS backend for %{name}
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: tinycdb-devel
+%global backends %{backends} tinydns
+
+%description backend-tinydns
+This package contains the TinyDNS backend for %{name}
+
 %prep
 %setup -q -n %{name}-${TARBALLVERSION}
 
@@ -791,6 +801,9 @@ exit 0
 %doc modules/gsqlite3backend/dnssec-3.x_to_3.4.0_schema.sqlite3.sql
 %doc modules/gsqlite3backend/nodnssec-3.x_to_3.4.0_schema.sqlite3.sql
 %{_libdir}/%{name}/libgsqlite3backend.so
+
+%files backend-tinydns
+%{_libdir}/%{name}/libtinydnsbackend.so
 EOF
       ;;
   SLES\ 12*)
index 9f7039e9ef36d0a61637d1450197d616910575fe..7cc72107f56e72f10417ea4edbe6872c68352adb 100644 (file)
@@ -349,7 +349,7 @@ AC_MSG_NOTICE([----------------])
 AC_MSG_NOTICE([Built-in modules: $modules])
 AC_MSG_NOTICE([Dynamic modules: $dynmodules])
 AC_MSG_NOTICE([])
-AS_IF([test "x$openssl_ecdsa" == "xyes"],
+AS_IF([test "x$openssl_ecdsa" = "xyes"],
   [AC_MSG_NOTICE([OpenSSL ecdsa: yes])],
   [AC_MSG_NOTICE([OpenSSL ecdsa: no])]
 )
@@ -363,7 +363,7 @@ AS_IF([test "x$LUAPC" != "x"],
     [AC_MSG_NOTICE([LuaJit: $LUAJITPC])],
     [AC_MSG_NOTICE([Lua/LuaJit: no])])
 ])
-AS_IF([test "x$enable_experimental_gss_tsig" == "xyes"],
+AS_IF([test "x$enable_experimental_gss_tsig" = "xyes"],
   [AC_MSG_NOTICE([GSS-TSIG: yes])]
 )
 AS_IF([test "x$systemd" != "xn"],
index 2bdb0f6a212a22fa00581a278b0140f1e4814cee..44c9d646c2a06a797da82263129c76fe5d691c3b 100644 (file)
@@ -29,9 +29,10 @@ You can also download snapshot tarballs generated by Jenkins and can be found
 
 You can also download releases on the [website](https://downloads.powerdns.com/releases/).
 These releases are PGP-signed with key-id [FBAE 0323 821C 7706 A5CA 151B DCF5
-13FA 7EED 19F3](https://pgp.mit.edu/pks/lookup?op=get&search=0xDCF513FA7EED19F3)
-or [1628 90D0 689D D12D D33E 4696 1C5E
-E990 D2E7 1575](https://pgp.mit.edu/pks/lookup?op=get&search=0x1C5EE990D2E71575).
+13FA 7EED 19F3](https://pgp.mit.edu/pks/lookup?op=get&search=0xDCF513FA7EED19F3),
+[1628 90D0 689D D12D D33E 4696 1C5E
+E990 D2E7 1575](https://pgp.mit.edu/pks/lookup?op=get&search=0x1C5EE990D2E71575)
+or [B76C D467 1C09 68BA A87D  E61C 5E50 715B F2FF E1A7](https://pgp.mit.edu/pks/lookup?op=get&search=0x5E50715BF2FFE1A7).
 
 ## OS specific gotcha's
 ### AIX
index 7654e444917604d63384a8b3b27838b72a2799ea..6d9ccbeec37ee14785091730ffc488d6a8b0b98b 100644 (file)
@@ -844,3 +844,10 @@ If the webserver should print arguments. See ["Performance Monitoring"](../commo
 * Default: yes
 
 If a PID file should be written. Available since 4.0.
+
+## `xfr-max-received-mbytes`
+* Integer
+* Default: 100
+
+Specifies the maximum number of received megabytes allowed on an incoming AXFR/IXFR update, to prevent
+resource exhaustion. A value of 0 means no restriction.
index 5cce9306e5a7b3558976e753b70e3841090c318d..53d7d8f3d1a898e3e1945c012acc89e4c6b4948b 100644 (file)
@@ -8,6 +8,10 @@ This release improves interoperability with DNSSEC clients that expect an AD-bit
 ## Bug fixes
 
  - [#4162](https://github.com/PowerDNS/pdns/pull/4162) Don't validate zones from the local auth store, go one level down while validating when there is a CNAME
+ - [#4187](https://github.com/PowerDNS/pdns/pull/4187):
+   * Don't go bogus on islands of security
+   * Check all possible chains for Insecures
+   * Don't go Bogus on a CNAME at the apex
 
 ## Improvements
 
index 7778428903eda55c92b4b56b6e53fc4645075098..792c376d5bf18c2fbf73c9b1d71e6c1e63d86261 100644 (file)
@@ -479,6 +479,8 @@ In addition to those, `rpzMaster` accepts:
 * tsigalgo = the name of the TSIG algorithm (like 'hmac-md5') used
 * tsigsecret = base64 encoded TSIG secret
 * refresh = an integer describing the interval between checks for updates. By default, the RPZ zone's default is used
+* maxReceivedMBytes = the maximum size in megabytes of an AXFR/IXFR update, to prevent resource exhaustion.
+The default value of 0 means no restriction.
 
 If no settings are included, the RPZ is taken literally with no overrides applied.
 
@@ -663,8 +665,7 @@ Don't log queries.
 
 ## `root-nx-trust`
 * Boolean
-* Default: no
-* Available since: 3.7.0
+* Default: no (<= 4.0.0), yes
 
 If set, an NXDOMAIN from the root-servers will serve as a blanket NXDOMAIN for the entire TLD
 the query belonged to. The effect of this is far fewer queries to the root-servers.
index 9926e93c32441ec45d6d518eeb47901d6b14749f..80eb8ae58844cbad18bb3513c9ba9fca18e26051 100644 (file)
@@ -1,4 +1,4 @@
-@       86400   IN  SOA pdns-public-ns1.powerdns.com. pieter\.lexis.powerdns.com. 2016071102 10800 3600 604800 10800
+@       86400   IN  SOA pdns-public-ns1.powerdns.com. pieter\.lexis.powerdns.com. 2016072001 10800 3600 604800 10800
 @       3600    IN  NS  pdns-public-ns1.powerdns.com.
 @       3600    IN  NS  pdns-public-ns2.powerdns.com.
 ; Auth
@@ -16,12 +16,12 @@ auth-3.4.7.security-status                              60 IN TXT "1 OK"
 auth-3.4.8.security-status                              60 IN TXT "1 OK"
 auth-3.4.9.security-status                              60 IN TXT "1 OK"
 
-auth-4.0.0-alpha1.security-status                       60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-alpha2.security-status                       60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-alpha3.security-status                       60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-beta1.security-status                        60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-rc1.security-status                          60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0-rc2.security-status                          60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0-alpha1.security-status                       60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-alpha2.security-status                       60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-alpha3.security-status                       60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-beta1.security-status                        60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-rc1.security-status                          60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0-rc2.security-status                          60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
 auth-4.0.0.security-status                              60 IN TXT "1 OK"
 
 ; Auth Debian
@@ -52,15 +52,15 @@ auth-3.4.5-1_bpo8_1.debian.security-status              60 IN TXT "3 Upgrade now
 auth-3.4.6-1_bpo8_1.debian.security-status              60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-03/"
 auth-3.4.7-1_bpo8_1.debian.security-status              60 IN TXT "1 OK"
 
-auth-4.0.0_alpha1-1.debian.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha1-2.debian.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-1.debian.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-2.debian.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-3.debian.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-4.debian.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1.debian.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1.debian.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_beta1-1.debian.security-status               60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha1-1.debian.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha1-2.debian.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-1.debian.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-2.debian.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-3.debian.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-4.debian.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1.debian.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1.debian.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_beta1-1.debian.security-status               60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
 
 ; Auth Ubuntu
 auth-3.4.1-3.ubuntu.security-status                     60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/md/security/powerdns-advisory-2015-02/"
@@ -69,9 +69,9 @@ auth-3.4.5-1.ubuntu.security-status                     60 IN TXT "3 Upgrade now
 auth-3.4.6-1.ubuntu.security-status                     60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-03/"
 auth-3.4.7-1.ubuntu.security-status                     60 IN TXT "1 OK"
 
-auth-4.0.0_alpha1-1.ubuntu.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-1.ubuntu.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-3build1.ubuntu.security-status        60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha1-1.ubuntu.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-1.ubuntu.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-3build1.ubuntu.security-status        60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
 
 ; Auth Raspbian
 auth-3.4.1-3.raspbian.security-status                   60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/md/security/powerdns-advisory-2015-02/"
@@ -98,11 +98,11 @@ recursor-3.7.1.security-status                          60 IN TXT "3 Upgrade now
 recursor-3.7.2.security-status                          60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
 recursor-3.7.3.security-status                          60 IN TXT "1 OK"
 
-recursor-4.0.0-alpha1.security-status                   60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0-alpha2.security-status                   60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0-alpha3.security-status                   60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0-beta1.security-status                    60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0-rc1.security-status                      60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0-alpha1.security-status                   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0-alpha2.security-status                   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0-alpha3.security-status                   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0-beta1.security-status                    60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0-rc1.security-status                      60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
 recursor-4.0.0.security-status                          60 IN TXT "1 OK"
 
 ; Recursor Debian
@@ -121,13 +121,13 @@ recursor-3.7.3-1.debian.security-status                 60 IN TXT "1 OK"
 recursor-3.7.3-1_bpo8_1.debian.security-status          60 IN TXT "1 OK"
 recursor-3.7.3-1_bpo7_1.debian.security-status          60 IN TXT "1 OK"
 
-recursor-4.0.0_alpha1-1.debian.security-status          60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha1-3.debian.security-status          60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha2-1.debian.security-status          60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha2-2.debian.security-status          60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1.debian.security-status          60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1.debian.security-status           60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-2.debian.security-status           60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha1-1.debian.security-status          60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha1-3.debian.security-status          60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha2-1.debian.security-status          60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha2-2.debian.security-status          60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1.debian.security-status          60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1.debian.security-status           60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-2.debian.security-status           60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
 
 ; Recursor Raspbian
 recursor-3.6.2-2.raspbian.security-status               60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
@@ -138,8 +138,8 @@ recursor-3.6.2-2.ubuntu.security-status                 60 IN TXT "3 Upgrade now
 recursor-3.7.2-1.ubuntu.security-status                 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
 recursor-3.7.3-1.ubuntu.security-status                 60 IN TXT "1 OK"
 
-auth-4.0.0_alpha1-1.ubuntu.security-status              60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-2.ubuntu.security-status              60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha1-1.ubuntu.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-2.ubuntu.security-status              60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
 
 ; Recursor Fedora, EL
 recursor-3.6.2-1.fc19.fedora.security-status            60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
@@ -154,43 +154,43 @@ recursor-3.6.2-1.el7.fedora.security-status             60 IN TXT "3 Upgrade now
 ;; Builder Generated packages (auth)
 
 ; Debian
-auth-4.0.0_alpha1-1pdns.jessie.debian.security-status   60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-1pdns.jessie.debian.security-status   60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1pdns.jessie.debian.security-status   60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_beta1-1pdns.jessie.debian.security-status    60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha1-1pdns.jessie.debian.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-1pdns.jessie.debian.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1pdns.jessie.debian.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_beta1-1pdns.jessie.debian.security-status    60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
 
 ; Ubuntu
-auth-4.0.0_alpha2-1pdns.wily.ubuntu.security-status     60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha2-1pdns.trusty.ubuntu.security-status   60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1pdns.trusty.ubuntu.security-status   60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_beta1-1pdns.trusty.ubuntu.security-status   60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha2-1pdns.wily.ubuntu.security-status     60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha2-1pdns.trusty.ubuntu.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1pdns.trusty.ubuntu.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_beta1-1pdns.trusty.ubuntu.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
 
 ; Raspbian
-auth-4.0.0_alpha2-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_alpha3-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
-auth-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
+auth-4.0.0_alpha2-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_alpha3-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
+auth-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-authoritative-server-4-0-0-released/"
 
 ;; Builder Generated packages (recursor)
 
 ; Debian
-recursor-4.0.0_alpha1-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha2-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.jessie.debian.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha1-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha2-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.jessie.debian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
 
 ; Ubuntu
-recursor-4.0.0_alpha2-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.trusty.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha2-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.trusty.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
 
-recursor-4.0.0_alpha2-1pdns.wily.ubuntu.security-status   60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1pdns.wily.ubuntu.security-status   60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.wily.ubuntu.security-status   60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha2-1pdns.wily.ubuntu.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1pdns.wily.ubuntu.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.wily.ubuntu.security-status   60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
 
-recursor-4.0.0_alpha3-1pdns.xenial.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.xenial.ubuntu.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha3-1pdns.xenial.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.xenial.ubuntu.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
 
 ; Raspbian
-recursor-4.0.0_alpha2-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_alpha3-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
-recursor-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "0 Unknown, prerelease"
+recursor-4.0.0_alpha2-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_alpha3-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
+recursor-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities). Please upgrade to final, see https://blog.powerdns.com/2016/07/11/powerdns-recursor-4-0-0-released/"
index ef9f19c59d52ac594a0aa5016f943aaaed3110d3..b20d1b26801b80c4c54b7aa8a6749f768bebcc0d 100644 (file)
@@ -15,7 +15,7 @@ AC_DEFUN([PDNS_ENABLE_REMOTEBACKEND_ZEROMQ],[
 
   AS_IF([test "x$enable_remotebackend_zeromq" != "xno"],
     [
-      AS_IF([test "x$have_remotebackend" == "xyes"],
+      AS_IF([test "x$have_remotebackend" = "xyes"],
         [
           PKG_CHECK_MODULES([LIBZMQ], [libzmq],
             [
index bb0b19a520da4391bd4666979caa25d98f699884..daea36937c2ad848e9dd25903fc6faf6ca1cd253 100644 (file)
@@ -124,9 +124,9 @@ int l_dnspacket (lua_State *lua) {
        return 1;
     }
 
-    lua_pushstring(lua, lb->dnspacket->getRemote().c_str());
+    lua_pushstring(lua, lb->dnspacket->getRemote().toString().c_str());
     lua_pushinteger(lua, lb->dnspacket->getRemotePort());
-    lua_pushstring(lua, lb->dnspacket->getLocal().c_str());
+    lua_pushstring(lua, lb->dnspacket->getLocal().toString().c_str());
     lua_pushstring(lua, lb->dnspacket->getRealRemote().toString().c_str());
 
     return 4;
index fbbf5bccd6df9259e02d081e20996949202c4c2e..1154bba77a13e7e8f07b2bf0e3dc9e0714d3328d 100644 (file)
@@ -155,9 +155,9 @@ void PipeBackend::lookup(const QType& qtype,const DNSName& qname, DNSPacket *pkt
       string remoteIP="0.0.0.0";
       Netmask realRemote("0.0.0.0/0");
       if (pkt_p) {
-        localIP=pkt_p->getLocal();
+        localIP=pkt_p->getLocal().toString();
         realRemote = pkt_p->getRealRemote();
-        remoteIP = pkt_p->getRemote();
+        remoteIP = pkt_p->getRemote().toString();
       }
       // abi-version = 1
       // type    qname           qclass  qtype   id      remote-ip-address
index 5261120db12c5bf8ace3d1429486b1d3e30bab43..95c40df79ac274c2d596f26b0f832b1493d83324 100644 (file)
@@ -157,9 +157,9 @@ void RemoteBackend::lookup(const QType &qtype, const DNSName& qdomain, DNSPacket
    string realRemote="0.0.0.0/0";
 
    if (pkt_p) {
-     localIP=pkt_p->getLocal();
+     localIP=pkt_p->getLocal().toString();
      realRemote = pkt_p->getRealRemote().toString();
-     remoteIP = pkt_p->getRemote();
+     remoteIP = pkt_p->getRemote().toString();
    }
 
    Json query = Json::object{
index b4076558c4942f40e3731e2a25df2df97b7867b8..70173b9752f133012f87e459deac34d6a393a09a 100644 (file)
@@ -338,6 +338,8 @@ Rules have selectors and actions. Current selectors are:
  * Number of entries in a given section (RecordsCountRule)
  * Number of entries of a specific type in a given section (RecordsTypeCountRule)
  * Presence of trailing data (TrailingDataRule)
+ * Number of labels in the qname (QNameLabelsCountRule)
+ * Wire length of the qname (QNameWireLengthRule)
 
 Special rules are:
 
@@ -392,6 +394,8 @@ A DNS rule can be:
  * an OpcodeRule
  * an OrRule
  * a QClassRule
+ * a QNameLabelsCountRule
+ * a QNameWireLengthRule
  * a QTypeRule
  * a RegexRule
  * a RE2Rule
@@ -1220,6 +1224,8 @@ instantiate a server with additional parameters
     * `OrRule()`: matches if at least one of the sub-rules matches
     * `OpcodeRule()`: matches queries with the specified opcode
     * `QClassRule(qclass)`: matches queries with the specified qclass (numeric)
+    * `QNameLabelsCountRule(min, max)`: matches if the qname has less than `min` or more than `max` labels
+    * `QNameWireLengthRule(min, max)`: matches if the qname's length on the wire is less than `min` or more than `max` bytes
     * `QTypeRule(qtype)`: matches queries with the specified qtype
     * `RegexRule(regex)`: matches the query name against the supplied regex
     * `RecordsCountRule(section, minCount, maxCount)`: matches if there is at least `minCount` and at most `maxCount` records in the `section` section
@@ -1340,9 +1346,11 @@ instantiate a server with additional parameters
         * `toStringWithPort()`: alias for `tostringWithPort()`
     * DNSName related:
         * `newDNSName(name)`: make a DNSName based on this .-terminated name
+        * member `countLabels()`: return the number of labels
         * member `isPartOf(dnsname)`: is this dnsname part of that dnsname
         * member `tostring()`: return as a human friendly . terminated string
         * member `toString()`: alias for `tostring()`
+        * member `wirelength()`: return the length on the wire
     * DNSQuestion related:
         * member `dh`: DNSHeader
         * member `len`: the question length
index c783d9a7479f3b1c927608ed53303dd8cb1e7a7c..e6377a5d68cf0cca56c75067be943e70da54115a 100644 (file)
@@ -187,6 +187,8 @@ void declareArguments()
 
   ::arg().setSwitch("outgoing-axfr-expand-alias", "Expand ALIAS records during outgoing AXFR")="no";
   ::arg().setSwitch("8bit-dns", "Allow 8bit dns queries")="no";
+
+  ::arg().set("xfr-max-received-mbytes", "Maximum number of megabytes received from an incoming XFR")="100";
 }
 
 static time_t s_start=time(0);
@@ -389,9 +391,9 @@ void *qthread(void *number)
     if(logDNSQueries) {
       string remote;
       if(P->hasEDNSSubnet()) 
-        remote = P->getRemote() + "<-" + P->getRealRemote().toString();
+        remote = P->getRemote().toString() + "<-" + P->getRealRemote().toString();
       else
-        remote = P->getRemote();
+        remote = P->getRemote().toString();
       L << Logger::Notice<<"Remote "<< remote <<" wants '" << P->qdomain<<"|"<<P->qtype.getName() << 
             "', do = " <<P->d_dnssecOk <<", bufsize = "<< P->getMaxReplyLen()<<": ";
     }
index c909efc09af84f24c35846c5a0462e2693f195be..1b37daac165ea372ae706177f3aad6b4a1640f5d 100644 (file)
@@ -248,7 +248,7 @@ char* my_generator(const char* text, int state)
       "PoolAction(", "printDNSCryptProviderFingerprint(",
       "RegexRule(", "RemoteLogAction(", "RemoteLogResponseAction(", "rmResponseRule(",
       "rmRule(", "rmServer(", "roundrobin",
-      "QTypeRule(",
+      "QNameLabelsCountRule(", "QNameWireLengthRule(", "QTypeRule(",
       "setACL(", "setDNSSECPool(", "setECSOverride(",
       "setECSSourcePrefixV4(", "setECSSourcePrefixV6(", "setKey(", "setLocal(",
       "setMaxTCPClientThreads(", "setMaxTCPQueuedConnections(", "setMaxUDPOutstanding(", "setRules(",
index ebd6e41889d6afbadc2d94e9aa07e9041b82d65c..ebd4a1fbe07b4ac56f1e45d746a3da620f2fe5ac 100644 (file)
@@ -194,14 +194,20 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
                        }
                        ComboAddress sourceAddr;
                        unsigned int sourceItf = 0;
-                       if(auto address = boost::get<string>(&pvars)) {
+                       if(auto addressStr = boost::get<string>(&pvars)) {
+                         ComboAddress address(*addressStr, 53);
                          std::shared_ptr<DownstreamState> ret;
+                         if(IsAnyAddress(address)) {
+                           g_outputBuffer="Error creating new server: invalid address for a downstream server.";
+                           errlog("Error creating new server: %s is not a valid address for a downstream server", *addressStr);
+                           return ret;
+                         }
                          try {
-                           ret=std::make_shared<DownstreamState>(ComboAddress(*address, 53));
+                           ret=std::make_shared<DownstreamState>(address);
                          }
                          catch(std::exception& e) {
                            g_outputBuffer="Error creating new server: "+string(e.what());
-                           errlog("Error creating new server with address %s: %s", *address, e.what());
+                           errlog("Error creating new server with address %s: %s", addressStr, e.what());
                            return ret;
                          }
 
@@ -280,8 +286,14 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
                        }
 
                        std::shared_ptr<DownstreamState> ret;
+                       ComboAddress address(boost::get<string>(vars["address"]), 53);
+                       if(IsAnyAddress(address)) {
+                         g_outputBuffer="Error creating new server: invalid address for a downstream server.";
+                         errlog("Error creating new server: %s is not a valid address for a downstream server", boost::get<string>(vars["address"]));
+                         return ret;
+                       }
                        try {
-                         ret=std::make_shared<DownstreamState>(ComboAddress(boost::get<string>(vars["address"]), 53), sourceAddr, sourceItf);
+                         ret=std::make_shared<DownstreamState>(address, sourceAddr, sourceItf);
                        }
                        catch(std::exception& e) {
                          g_outputBuffer="Error creating new server: "+string(e.what());
@@ -879,6 +891,14 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       return std::shared_ptr<DNSRule>(new TrailingDataRule());
     });
 
+  g_lua.writeFunction("QNameLabelsCountRule", [](unsigned int minLabelsCount, unsigned int maxLabelsCount) {
+      return std::shared_ptr<DNSRule>(new QNameLabelsCountRule(minLabelsCount, maxLabelsCount));
+    });
+
+  g_lua.writeFunction("QNameWireLengthRule", [](size_t min, size_t max) {
+      return std::shared_ptr<DNSRule>(new QNameWireLengthRule(min, max));
+    });
+
   g_lua.writeFunction("addAction", [](luadnsrule_t var, std::shared_ptr<DNSAction> ea)
                      {
                         setLuaSideEffect();
@@ -1066,6 +1086,8 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
   g_lua.registerFunction("toStringWithPort", &ComboAddress::toStringWithPort);
   g_lua.registerFunction<uint16_t(ComboAddress::*)()>("getPort", [](const ComboAddress& ca) { return ntohs(ca.sin4.sin_port); } );
   g_lua.registerFunction("isPartOf", &DNSName::isPartOf);
+  g_lua.registerFunction("countLabels", &DNSName::countLabels);
+  g_lua.registerFunction("wirelength", &DNSName::wirelength);
   g_lua.registerFunction<string(DNSName::*)()>("tostring", [](const DNSName&dn ) { return dn.toString(); });
   g_lua.registerFunction<string(DNSName::*)()>("toString", [](const DNSName&dn ) { return dn.toString(); });
   g_lua.writeFunction("newDNSName", [](const std::string& name) { return DNSName(name); });
index a0a550dca19cd52c4818f7c46ebdae2969d7a7cd..6645955fded338b7e033a4738de4e97cfdc52470 100644 (file)
@@ -1092,7 +1092,7 @@ try
       vinfolog("Got query from %s, relayed to %s", remote.toStringWithPort(), ss->getName());
     }
     catch(std::exception& e){
-      errlog("Got an error in UDP question thread while parsing a query from %s, id %d: %s", remote.toStringWithPort(), queryId, e.what());
+      vinfolog("Got an error in UDP question thread while parsing a query from %s, id %d: %s", remote.toStringWithPort(), queryId, e.what());
     }
   }
   return 0;
index df8d34070beb2e2faac62ee4e12d6e16d480fabb..b6f0b818af20b9417be66b69dfa2b4380133a4a4 100644 (file)
@@ -81,9 +81,9 @@ const string& DNSPacket::getString()
   return d_rawpacket;
 }
 
-string DNSPacket::getRemote() const
+ComboAddress DNSPacket::getRemote() const
 {
-  return d_remote.toString();
+  return d_remote;
 }
 
 uint16_t DNSPacket::getRemotePort() const
index 4f9a51a1a2c3ccb32ec68220432d06da8c7f8aec..bf5e785782f9db9e027c1004b3c335db5680347f 100644 (file)
@@ -73,14 +73,14 @@ public:
 
   // address & socket manipulation
   void setRemote(const ComboAddress*);
-  string getRemote() const;
+  ComboAddress getRemote() const;
   Netmask getRealRemote() const;
-  string getLocal() const
+  ComboAddress getLocal() const
   {
     ComboAddress ca;
     socklen_t len=sizeof(ca);
     getsockname(d_socket, (sockaddr*)&ca, &len);
-    return ca.toString();
+    return ca;
   }
   uint16_t getRemotePort() const;
 
index aead489a33c032013cff15e38b9feb6c33eee196..4e0d16f3776abda42e0d9345364513c06ce2b338 100644 (file)
@@ -601,7 +601,7 @@ bool sendPacketFromPR(PcapPacketReader& pr, const ComboAddress& remote, int stam
       //      dh->rd=1; // useful to replay traffic to auths to a recursor
       uint16_t dlen = pr.d_len;
 
-      addECSOption((char*)pr.d_payload, 1500, &dlen, pr.getSource(), stamp);
+      if (stamp >= 0) addECSOption((char*)pr.d_payload, 1500, &dlen, pr.getSource(), stamp);
       pr.d_len=dlen;
       s_socket->sendTo((const char*)pr.d_payload, dlen, remote);
       sent=true;
index 2d6f9d2abb32a090db425d58f1ec040536578196..9441bce9b17b003b02f5955ce69d42c45e0314b5 100644 (file)
@@ -488,6 +488,46 @@ public:
   }
 };
 
+class QNameLabelsCountRule : public DNSRule
+{
+public:
+  QNameLabelsCountRule(unsigned int minLabelsCount, unsigned int maxLabelsCount): d_min(minLabelsCount), d_max(maxLabelsCount)
+  {
+  }
+  bool matches(const DNSQuestion* dq) const override
+  {
+    unsigned int count = dq->qname->countLabels();
+    return count < d_min || count > d_max;
+  }
+  string toString() const override
+  {
+    return "labels count < " + std::to_string(d_min) + " || labels count > " + std::to_string(d_max);
+  }
+private:
+  unsigned int d_min;
+  unsigned int d_max;
+};
+
+class QNameWireLengthRule : public DNSRule
+{
+public:
+  QNameWireLengthRule(size_t min, size_t max): d_min(min), d_max(max)
+  {
+  }
+  bool matches(const DNSQuestion* dq) const override
+  {
+    size_t const wirelength = dq->qname->wirelength();
+    return wirelength < d_min || wirelength > d_max;
+  }
+  string toString() const override
+  {
+    return "wire length < " + std::to_string(d_min) + " || wire length > " + std::to_string(d_max);
+  }
+private:
+  size_t d_min;
+  size_t d_max;
+};
+
 class DropAction : public DNSAction
 {
 public:
index bc66780d3d3d799e6fcf9526cea38e5620cc9a92..1fe0872449a30fea41a54b8cce1d031895e82afe 100644 (file)
@@ -23,16 +23,20 @@ int SSocket(int family, int type, int flags)
 int SConnect(int sockfd, const ComboAddress& remote)
 {
   int ret = connect(sockfd, (struct sockaddr*)&remote, remote.getSocklen());
-  if(ret < 0)
-    RuntimeError(boost::format("connecting socket to %s: %s") % remote.toStringWithPort() % strerror(errno));
+  if(ret < 0) {
+    int savederrno = errno;
+    RuntimeError(boost::format("connecting socket to %s: %s") % remote.toStringWithPort() % strerror(savederrno));
+  }
   return ret;
 }
 
 int SBind(int sockfd, const ComboAddress& local)
 {
   int ret = bind(sockfd, (struct sockaddr*)&local, local.getSocklen());
-  if(ret < 0)
-    RuntimeError(boost::format("binding socket to %s: %s") % local.toStringWithPort() % strerror(errno));
+  if(ret < 0) {
+    int savederrno = errno;
+    RuntimeError(boost::format("binding socket to %s: %s") % local.toStringWithPort() % strerror(savederrno));
+  }
   return ret;
 }
 
index 06d9fe5a9f6129ccd177c57d9b333a3fb3739187..dc87f74fbee3ba0e9c97966dfd6637721b59b559 100644 (file)
@@ -7,7 +7,7 @@
 
 // Returns pairs of "remove & add" vectors. If you get an empty remove, it means you got an AXFR!
 vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& oursr, 
-                                                                   const TSIGTriplet& tt, const ComboAddress* laddr)
+                                                                   const TSIGTriplet& tt, const ComboAddress* laddr, size_t maxReceivedBytes)
 {
   vector<pair<vector<DNSRecord>, vector<DNSRecord> > >  ret;
   vector<uint8_t> packet;
@@ -55,6 +55,7 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAd
   // CURRENT MASTER SOA 
   shared_ptr<SOARecordContent> masterSOA;
   vector<DNSRecord> records;
+  size_t receivedBytes = 0;
   for(;;) {
     if(s.read((char*)&len, 2)!=2)
       break;
@@ -62,8 +63,13 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAd
     //    cout<<"Got chunk of "<<len<<" bytes"<<endl;
     if(!len)
       break;
+
+    if (maxReceivedBytes > 0 && (maxReceivedBytes - receivedBytes) < (size_t) len)
+      throw std::runtime_error("Reached the maximum number of received bytes in an IXFR delta for zone '"+zone.toString()+"' from master '"+master.toStringWithPort());
+
     char reply[len]; 
     readn2(s.getHandle(), reply, len);
+    receivedBytes += len;
     MOADNSParser mdp(string(reply, len));
     if(mdp.d_header.rcode) 
       throw std::runtime_error("Got an error trying to IXFR zone '"+zone.toString()+"' from master '"+master.toStringWithPort()+"': "+RCode::to_s(mdp.d_header.rcode));
index 543f4454a2b91273c13f7904f46d1e2a81667dff..eef2252247f0ac5464171bef2bb5d5cc197aafa4 100644 (file)
@@ -4,4 +4,4 @@
 
 vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const ComboAddress& master, const DNSName& zone, 
                                                                      const DNSRecord& sr, const TSIGTriplet& tt=TSIGTriplet(),
-                                                                     const ComboAddress* laddr=0);
+                                                                     const ComboAddress* laddr=0, size_t maxReceivedBytes=0);
index ae4585f10c3ab0206f6ca5e014188d9d60cb3501..9c10eb5bac491d24b90d966dfee28b1bdde99e77 100644 (file)
@@ -235,3 +235,10 @@ Logger& Logger::operator<<(const DNSName &d)
 
   return *this;
 }
+
+Logger& Logger::operator<<(const ComboAddress &ca)
+{
+  *this<<ca.toString();
+  return *this;
+}
+
index 9d1d85d2cf6a823842fb9752c5427fde22e3a74b..0840a7bfe7e61a1c57817758a99cb344f70f48bf 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "namespaces.hh"
 #include "dnsname.hh"
+#include "iputils.hh"
 
 //! The Logger class can be used to log messages in various ways.
 class Logger
@@ -80,7 +81,7 @@ public:
   Logger& operator<<(unsigned long);   //!< log an unsigned int
   Logger& operator<<(unsigned long long);   //!< log an unsigned 64 bit int
   Logger& operator<<(const DNSName&); 
-
+  Logger& operator<<(const ComboAddress&); //!< log an address
   Logger& operator<<(Urgency);    //!< set the urgency, << style
 
   Logger& operator<<(std::ostream & (&)(std::ostream &)); //!< this is to recognise the endl, and to commit the log
index 58be56b1589a2c28ad8589503607b2f698df362f..193b742a007f048a259207b1a006d6d675679301 100644 (file)
@@ -193,13 +193,13 @@ static int ldp_addRecords(lua_State *L) {
 
 static int ldp_getRemote(lua_State *L) {
   DNSPacket *p=ldp_checkDNSPacket(L);
-  lua_pushstring(L, p->getRemote().c_str());
+  lua_pushstring(L, p->getRemote().toString().c_str());
   return 1;
 }
 
 static int ldp_getRemoteRaw(lua_State *L) {
   DNSPacket *p=ldp_checkDNSPacket(L);
-  const ComboAddress& ca=p->d_remote;
+  const ComboAddress& ca=p->getRemote();
   if(ca.sin4.sin_family == AF_INET) {
     lua_pushlstring(L, (const char*)&ca.sin4.sin_addr.s_addr, 4);
   }
index f3b9ace731901b6317bf50b54864dfe7cb519638..f2d199671eb1eed14df9db70f568b1b8ede58797 100644 (file)
@@ -437,8 +437,7 @@ RecursorLua4::RecursorLua4(const std::string& fname)
   
   ifstream ifs(fname);
   if(!ifs) {
-    theL()<<Logger::Error<<"Unable to read configuration file from '"<<fname<<"': "<<strerror(errno)<<endl;
-    return;
+    throw std::runtime_error("Unable to read configuration file from '"+fname+"': "+strerror(errno));
   }    
   d_lw->executeCode(ifs);
 
index adff6f62f8e6671b8e1e8f4c5e3bcbe978aa872d..e85421fb3b7ded1e7d6e17c64d2ea00d81e680e5 100644 (file)
@@ -763,8 +763,8 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigke
   try {
     Resolver resolver;
     uint32_t theirserial;
-    resolver.getSoaSerial(p->getRemote(),p->qdomain, &theirserial);    
-    resolver.resolve(p->getRemote(), p->qdomain, QType::NS, &nsset);
+    resolver.getSoaSerial(p->getRemote().toString(),p->qdomain, &theirserial);
+    resolver.resolve(p->getRemote().toString(), p->qdomain, QType::NS, &nsset);
   }
   catch(ResolverException &re) {
     L<<Logger::Error<<"Error resolving SOA or NS for "<<p->qdomain<<" at: "<< p->getRemote() <<": "<<re.reason<<endl;
@@ -791,7 +791,7 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigke
     return RCode::Refused;
   }
 
-  if(!B.superMasterBackend(p->getRemote(), p->qdomain, nsset, &nameserver, &account, &db)) {
+  if(!B.superMasterBackend(p->getRemote().toString(), p->qdomain, nsset, &nameserver, &account, &db)) {
     L<<Logger::Error<<"Unable to find backend willing to host "<<p->qdomain<<" for potential supermaster "<<p->getRemote()<<". Remote nameservers: "<<endl;
     for(const auto& rr: nsset) {
       if(rr.qtype.getCode()==QType::NS)
@@ -800,7 +800,7 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigke
     return RCode::Refused;
   }
   try {
-    db->createSlaveDomain(p->getRemote(), p->qdomain, nameserver, account);
+    db->createSlaveDomain(p->getRemote().toString(), p->qdomain, nameserver, account);
     if (tsigkeyname.empty() == false) {
       vector<string> meta;
       meta.push_back(tsigkeyname.toStringNoDot());
@@ -863,7 +863,7 @@ int PacketHandler::processNotify(DNSPacket *p)
     }
   }
 
-  if(::arg().contains("trusted-notification-proxy", p->getRemote())) {
+  if(::arg().contains("trusted-notification-proxy", p->getRemote().toString())) {
     L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from trusted-notification-proxy "<< p->getRemote()<<endl;
     if(di.masters.empty()) {
       L<<Logger::Error<<"However, "<<p->qdomain<<" does not have any masters defined"<<endl;
@@ -874,7 +874,7 @@ int PacketHandler::processNotify(DNSPacket *p)
     L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" but we are master, rejecting"<<endl;
     return RCode::Refused;
   }
-  else if(!db->isMaster(p->qdomain, p->getRemote())) {
+  else if(!db->isMaster(p->qdomain, p->getRemote().toString())) {
     L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" which is not a master"<<endl;
     return RCode::Refused;
   }
index 4b2672bbd7b0ec2a79b703d1ea91e26c1c573c24..6717e0571dce678c1b46015622caee340cf17306 100644 (file)
@@ -953,8 +953,20 @@ void startDoResolve(void *p)
 
       bool needCommit = false;
       for(auto i=ret.cbegin(); i!=ret.cend(); ++i) {
-        if(!DNSSECOK && (i->d_type == QType::RRSIG || i->d_type==QType::NSEC || i->d_type==QType::NSEC3))
+        if( ! DNSSECOK &&
+            ( i->d_type == QType::NSEC3 ||
+              (
+                ( i->d_type == QType::RRSIG || i->d_type==QType::NSEC ) &&
+                (
+                  ( dc->d_mdp.d_qtype != i->d_type &&  dc->d_mdp.d_qtype != QType::ANY ) ||
+                  i->d_place != DNSResourceRecord::ANSWER
+                )
+              )
+            )
+          ) {
           continue;
+        }
+
        pw.startRecord(i->d_name, i->d_type, i->d_ttl, i->d_class, i->d_place);
        if(i->d_type != QType::OPT) // their TTL ain't real
          minTTL = min(minTTL, i->d_ttl);
@@ -2864,7 +2876,7 @@ int main(int argc, char **argv)
     ::arg().setSwitch("write-pid","Write a PID file")="yes";
     ::arg().set("loglevel","Amount of logging. Higher is more. Do not set below 3")="4";
     ::arg().set("disable-syslog","Disable logging to syslog, useful when running inside a supervisor that logs stdout")="no";
-    ::arg().set("log-common-errors","If we should log rather common errors")="yes";
+    ::arg().set("log-common-errors","If we should log rather common errors")="no";
     ::arg().set("chroot","switch to chroot jail")="";
     ::arg().set("setgid","If set, change group id to this gid for more security")="";
     ::arg().set("setuid","If set, change user id to this uid for more security")="";
@@ -2932,7 +2944,7 @@ int main(int argc, char **argv)
     ::arg().setSwitch( "disable-packetcache", "Disable packetcache" )= "no";
     ::arg().set("edns-subnet-whitelist", "List of netmasks and domains that we should enable EDNS subnet for")="";
     ::arg().setSwitch( "pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads")="";
-    ::arg().setSwitch( "root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist")="no";
+    ::arg().setSwitch( "root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist")="yes";
     ::arg().setSwitch( "any-to-tcp","Answer ANY queries with tc=1, shunting to TCP" )="no";
     ::arg().setSwitch( "lowercase-outgoing","Force outgoing questions to lowercase")="no";
     ::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate")="1680";
index 0c1474ed588c81da2b82a3387f7a06604f551c33..e6c07b0e311919451b629c65cc408eae9d3eaf41 100644 (file)
@@ -130,6 +130,7 @@ void loadRecursorLuaConfig(const std::string& fname)
         TSIGTriplet tt;
         int refresh=0;
        std::string polName;
+       size_t maxReceivedXFRMBytes = 0;
        if(options) {
          auto& have = *options;
          if(have.count("policyName")) {
@@ -163,14 +164,17 @@ void loadRecursorLuaConfig(const std::string& fname)
           if(have.count("refresh")) {
             refresh = boost::get<int>(constGet(have,"refresh"));
           }
+          if(have.count("maxReceivedMBytes")) {
+            maxReceivedXFRMBytes = static_cast<size_t>(boost::get<int>(constGet(have,"maxReceivedMBytes")));
+          }
        }
        ComboAddress master(master_, 53);
        DNSName zone(zone_);
 
-       auto sr=loadRPZFromServer(master, zone, lci.dfe, polName, defpol, 0, tt);
+       auto sr=loadRPZFromServer(master, zone, lci.dfe, polName, defpol, 0, tt, maxReceivedXFRMBytes * 1024 * 1024);
         if(refresh)
           sr->d_st.refresh=refresh;
-       std::thread t(RPZIXFRTracker, master, zone, polName, tt, sr);
+       std::thread t(RPZIXFRTracker, master, zone, polName, tt, sr, maxReceivedXFRMBytes * 1024 * 1024);
        t.detach();
       }
       catch(std::exception& e) {
index 8ff56231465eb134177e0be1d03c4ec864d06ef7..ab5809c29c867e3d730993bd2d71296b8292eba0 100644 (file)
@@ -229,20 +229,21 @@ recursor.conf-dist: pdns_recursor
 MANPAGES=pdns_recursor.1 \
         rec_control.1
 
-dist_man_MANS=$(MANPAGES)
+if HAVE_PANDOC
+  dist_man_MANS=$(MANPAGES)
+endif
+if HAVE_MANPAGES
+  dist_man_MANS=$(MANPAGES)
+endif
 
 if HAVE_PANDOC
 $(MANPAGES): %: %.md
        $(AM_V_GEN)$(PANDOC) -s -t man $< -o $@
 else
-if HAVE_MANPAGES
-#nothing
-else
 $(MANPAGES):
        echo "You need pandoc to generate the manpages"
        exit 1
 endif
-endif
 
 if HAVE_SYSTEMD
 pdns-recursor.service: pdns-recursor.service.in
index 74df7ec8e161ceee296eb5597cd5cbafd7263599..3cd3c9e5b8250bd64c2a07894ad8ced126691123 100644 (file)
@@ -311,7 +311,7 @@ string reloadAuthAndForwards()
 }
 
 
-void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& polName, const TSIGTriplet& tt, shared_ptr<SOARecordContent> oursr)
+void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& polName, const TSIGTriplet& tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes)
 {
   int refresh = oursr->d_st.refresh;
   for(;;) {
@@ -323,7 +323,7 @@ void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::
     L<<Logger::Info<<"Getting IXFR deltas for "<<zone<<" from "<<master.toStringWithPort()<<", our serial: "<<getRR<SOARecordContent>(dr)->d_st.serial<<endl;
     vector<pair<vector<DNSRecord>, vector<DNSRecord> > > deltas;
     try {
-      deltas = getIXFRDeltas(master, zone, dr, tt);
+      deltas = getIXFRDeltas(master, zone, dr, tt, nullptr, maxReceivedBytes);
     } catch(std::runtime_error& e ){
       L<<Logger::Warning<<e.what()<<endl;
       continue;
index 0220e157366f2976ed3ba36276027fdaa53e3351..b50dc91a6fa03a544f6602fadd34033f56fdd468 100644 (file)
@@ -360,8 +360,9 @@ void Resolver::getSoaSerial(const string &ipport, const DNSName &domain, uint32_
 AXFRRetriever::AXFRRetriever(const ComboAddress& remote,
                              const DNSName& domain,
                              const TSIGTriplet& tt, 
-                             const ComboAddress* laddr)
-  : d_tt(tt), d_tsigPos(0), d_nonSignedMessages(0)
+                             const ComboAddress* laddr,
+                             size_t maxReceivedBytes)
+  : d_tt(tt), d_receivedBytes(0), d_maxReceivedBytes(maxReceivedBytes), d_tsigPos(0), d_nonSignedMessages(0)
 {
   ComboAddress local;
   if (laddr != NULL) {
@@ -445,8 +446,14 @@ int AXFRRetriever::getChunk(Resolver::res_t &res, vector<DNSRecord>* records) //
   int len=getLength();
   if(len<0)
     throw ResolverException("EOF trying to read axfr chunk from remote TCP client");
-  
-  timeoutReadn(len); 
+
+  if (d_maxReceivedBytes > 0 && (d_maxReceivedBytes - d_receivedBytes) < (size_t) len)
+    throw ResolverException("Reached the maximum number of received bytes during AXFR");
+
+  timeoutReadn(len);
+
+  d_receivedBytes += (uint16_t) len;
+
   MOADNSParser mdp(d_buf.get(), len);
 
   int err;
index 24e45454db998870ee1d79b21d9c49166f7e1155..03fb4fdcb8a41ffbbc2523a004a7ba7c5520437a 100644 (file)
@@ -86,8 +86,9 @@ class AXFRRetriever : public boost::noncopyable
     AXFRRetriever(const ComboAddress& remote,
                   const DNSName& zone,
                   const TSIGTriplet& tt = TSIGTriplet(),
-                  const ComboAddress* laddr = NULL);
-       ~AXFRRetriever();
+                  const ComboAddress* laddr = NULL,
+                  size_t maxReceivedBytes=0);
+    ~AXFRRetriever();
     int getChunk(Resolver::res_t &res, vector<DNSRecord>* records=0);  
   
   private:
@@ -104,6 +105,8 @@ class AXFRRetriever : public boost::noncopyable
     TSIGTriplet d_tt;
     string d_prevMac; // RFC2845 4.4
     string d_signData;
+    size_t d_receivedBytes;
+    size_t d_maxReceivedBytes;
     uint32_t d_tsigPos;
     uint d_nonSignedMessages; // RFC2845 4.4
     TSIGRecordContent d_trc;
index aca057da71d031fcd3fad5e4e86fece75a0511ea..e37357d353faaceaa0124c3680dd0d43c45424de 100644 (file)
@@ -670,7 +670,7 @@ int PacketHandler::processUpdate(DNSPacket *p) {
   if (! ::arg().mustDo("dnsupdate"))
     return RCode::Refused;
 
-  string msgPrefix="UPDATE (" + itoa(p->d.id) + ") from " + p->getRemote() + " for " + p->qdomain.toLogString() + ": ";
+  string msgPrefix="UPDATE (" + itoa(p->d.id) + ") from " + p->getRemote().toString() + " for " + p->qdomain.toLogString() + ": ";
   L<<Logger::Info<<msgPrefix<<"Processing started."<<endl;
 
   // Check permissions - IP based
index 46bd4c168b31239c0932e76023aa8738e9f8cf81..9a1d0991652426b01730685a3206c8aa55848f1d 100644 (file)
@@ -110,14 +110,14 @@ void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, const std::
   }
 }
 
-shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& polName, boost::optional<DNSFilterEngine::Policy> defpol, int place,  const TSIGTriplet& tt)
+shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& polName, boost::optional<DNSFilterEngine::Policy> defpol, int place,  const TSIGTriplet& tt, size_t maxReceivedBytes)
 {
   L<<Logger::Warning<<"Loading RPZ zone '"<<zone<<"' from "<<master.toStringWithPort()<<endl;
   if(!tt.name.empty())
     L<<Logger::Warning<<"With TSIG key '"<<tt.name<<"' of algorithm '"<<tt.algo<<"'"<<endl;
 
   ComboAddress local= master.sin4.sin_family == AF_INET ? ComboAddress("0.0.0.0") : ComboAddress("::"); // should be configurable
-  AXFRRetriever axfr(master, zone, tt, &local);
+  AXFRRetriever axfr(master, zone, tt, &local, maxReceivedBytes);
   unsigned int nrecords=0;
   Resolver::res_t nop;
   vector<DNSRecord> chunk;
index c61993ae4f842d79aab2e6a4fca8e5fa0daeb028..031e82795f8bbdbe1020c750137c5e6f7ff7dbed 100644 (file)
@@ -4,6 +4,6 @@
 #include "dnsrecords.hh"
 
 int loadRPZFromFile(const std::string& fname, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place);
-std::shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt);
+std::shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt, size_t maxReceivedBytes);
 void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, const std::string& policyName, bool addOrRemove, boost::optional<DNSFilterEngine::Policy> defpol, int place);
-void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& policyName, const TSIGTriplet &tt, shared_ptr<SOARecordContent> oursr);
+void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& policyName, const TSIGTriplet &tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes);
index 9562c21d48cb4c46e57163b2be80c245fddb5f8b..2828a7289ac2d397368499db3879e0682bafb169 100644 (file)
@@ -103,7 +103,7 @@ void CommunicatorClass::ixfrSuck(const DNSName &domain, const TSIGTriplet& tt, c
 
     DNSRecord dr;
     dr.d_content = std::make_shared<SOARecordContent>(DNSName("."), DNSName("."), st);
-    auto deltas = getIXFRDeltas(remote, domain, dr, tt, laddr.sin4.sin_family ? &laddr : 0);
+    auto deltas = getIXFRDeltas(remote, domain, dr, tt, laddr.sin4.sin_family ? &laddr : 0, ((size_t) ::arg().asNum("xfr-max-received-mbytes")) * 1024 * 1024);
     zs.numDeltas=deltas.size();
     //    cout<<"Got "<<deltas.size()<<" deltas from serial "<<di.serial<<", applying.."<<endl;
     
@@ -235,7 +235,7 @@ static bool processRecordForZS(const DNSName& domain, bool& firstNSEC3, DNSResou
 vector<DNSResourceRecord> doAxfr(const ComboAddress& raddr, const DNSName& domain, const TSIGTriplet& tt, const ComboAddress& laddr,  scoped_ptr<AuthLua>& pdl, ZoneStatus& zs)
 {
   vector<DNSResourceRecord> rrs;
-  AXFRRetriever retriever(raddr, domain, tt, (laddr.sin4.sin_family == 0) ? NULL : &laddr);
+  AXFRRetriever retriever(raddr, domain, tt, (laddr.sin4.sin_family == 0) ? NULL : &laddr, ((size_t) ::arg().asNum("xfr-max-received-mbytes")) * 1024 * 1024);
   Resolver::res_t recs;
   bool first=true;
   bool firstNSEC3{true};
index 8c44f8102454e5ce7212b7b2b7a1e09192ef43b1..aa6e64c8ab965d7ab1bd51962a3fe6be33c124c1 100644 (file)
@@ -443,7 +443,7 @@ int SyncRes::doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecor
       }
     }
 
-    if(doCNAMECacheCheck(qname,qtype,ret,depth,res)) // will reroute us if needed
+    if(qtype != QType::DS && doCNAMECacheCheck(qname,qtype,ret,depth,res)) // will reroute us if needed
       return res;
 
     if(doCacheCheck(qname,qtype,ret,depth,res)) // we done
index ff2d75405fa2d7566642e8a4f9da1e44c009e679..eb9913fd84b94ebbdfd18327a315c1b200477026 100644 (file)
@@ -321,9 +321,9 @@ void *TCPNameserver::doConnection(void *data)
       if(logDNSQueries)  {
         string remote;
         if(packet->hasEDNSSubnet()) 
-          remote = packet->getRemote() + "<-" + packet->getRealRemote().toString();
+          remote = packet->getRemote().toString() + "<-" + packet->getRealRemote().toString();
         else
-          remote = packet->getRemote();
+          remote = packet->getRemote().toString();
         L << Logger::Notice<<"TCP Remote "<< remote <<" wants '" << packet->qdomain<<"|"<<packet->qtype.getName() << 
         "', do = " <<packet->d_dnssecOk <<", bufsize = "<< packet->getMaxReplyLen()<<": ";
       }
@@ -469,7 +469,7 @@ bool TCPNameserver::canDoAXFR(shared_ptr<DNSPacket> q)
           vector<string> nsips=fns.lookup(j, B);
           for(vector<string>::const_iterator k=nsips.begin();k!=nsips.end();++k) {
             // cerr<<"got "<<*k<<" from AUTO-NS"<<endl;
-            if(*k == q->getRemote())
+            if(*k == q->getRemote().toString())
             {
               // cerr<<"got AUTO-NS hit"<<endl;
               L<<Logger::Warning<<"AXFR of domain '"<<q->qdomain<<"' allowed: client IP "<<q->getRemote()<<" is in NSset"<<endl;
@@ -493,7 +493,7 @@ bool TCPNameserver::canDoAXFR(shared_ptr<DNSPacket> q)
 
   extern CommunicatorClass Communicator;
 
-  if(Communicator.justNotified(q->qdomain, q->getRemote())) { // we just notified this ip 
+  if(Communicator.justNotified(q->qdomain, q->getRemote().toString())) { // we just notified this ip
     L<<Logger::Warning<<"Approved AXFR of '"<<q->qdomain<<"' from recently notified slave "<<q->getRemote()<<endl;
     return true;
   }
index add348c288c886a408c32d07f59dde8a0a365061..5819cfe7a91b16aa25795b721312d0b11d1ae386 100644 (file)
@@ -32,6 +32,25 @@ inline vState increaseDNSSECStateCounter(const vState& state)
   return state;
 }
 
+/*
+ * This inline possibly sets currentState based on the new state. It will only
+ * set it to Secure iff the newState is Secure and mayUpgradeToSecure == true.
+ * This should be set by the calling function when checking more than one record
+ * and this is not the first record, this way, we can never go *back* to Secure
+ * from an Insecure vState
+ */
+inline void processNewState(vState& currentState, const vState& newState, bool& hadNTA, const bool& mayUpgradeToSecure)
+{
+  if (mayUpgradeToSecure && newState == Secure)
+    currentState = Secure;
+
+  if (newState == Insecure || newState == NTA) // We can never go back to Secure
+    currentState = Insecure;
+
+  if (newState == NTA)
+    hadNTA = true;
+}
+
 vState validateRecords(const vector<DNSRecord>& recs)
 {
   if(recs.empty())
@@ -53,41 +72,57 @@ vState validateRecords(const vector<DNSRecord>& recs)
   SRRecordOracle sro;
 
   vState state=Insecure;
+  bool hadNTA = false;
   if(numsigs) {
+    bool first = true;
     for(const auto& csp : cspmap) {
       for(const auto& sig : csp.second.signatures) {
-        state = getKeysFor(sro, sig->d_signer, keys); // XXX check validity here
-        if(state == NTA) {
-          increaseDNSSECStateCounter(state);
-          return Insecure;
-        }
+        vState newState = getKeysFor(sro, sig->d_signer, keys); // XXX check validity here
+
+        if (newState == Bogus) // No hope
+          return increaseDNSSECStateCounter(Bogus);
+
+        processNewState(state, newState, hadNTA, first);
+
+        first = false;
+
         LOG("! state = "<<vStates[state]<<", now have "<<keys.size()<<" keys"<<endl);
         for(const auto& k : keys) {
           LOG("Key: "<<k.getZoneRepresentation()<< " {tag="<<k.getTag()<<"}"<<endl);
         }
-        // this sort of charges on and 'state' ends up as the last thing to have been checked
-        // maybe not the right idea
       }
     }
-    if(state == Bogus)
-      return increaseDNSSECStateCounter(state);
     validateWithKeySet(cspmap, validrrsets, keys);
   }
   else {
     LOG("! no sigs, hoping for Insecure status of "<<recs.begin()->d_name<<endl);
-    state = getKeysFor(sro, recs.begin()->d_name, keys); // um WHAT DOES THIS MEAN - try first qname??
-   
-    LOG("! state = "<<vStates[state]<<", now have "<<keys.size()<<" keys "<<endl);
-    
+
+    bool first = true;
+    for(const auto& rec : recs) {
+      vState newState = getKeysFor(sro, rec.d_name, keys);
+
+      if (newState == Bogus) // We're done
+        return increaseDNSSECStateCounter(Bogus);
+
+      processNewState(state, newState, hadNTA, first);
+      first = false;
+
+      LOG("! state = "<<vStates[state]<<", now have "<<keys.size()<<" keys "<<endl);
+    }
     return increaseDNSSECStateCounter(state);
   }
-  
+
   LOG("Took "<<sro.d_queries<<" queries"<<endl);
   if(validrrsets.size() == cspmap.size())// shortcut - everything was ok
     return increaseDNSSECStateCounter(Secure);
 
-  if(keys.empty())
+  if(state == Insecure || keys.empty()) {
+    if (hadNTA) {
+      increaseDNSSECStateCounter(NTA);
+      return Insecure;
+    }
     return increaseDNSSECStateCounter(Insecure);
+  }
 
 #if 0
   cerr<<"! validated "<<validrrsets.size()<<" RRsets out of "<<cspmap.size()<<endl;
@@ -108,6 +143,5 @@ vState validateRecords(const vector<DNSRecord>& recs)
       return increaseDNSSECStateCounter(Bogus);
     }
   }
-  
   return increaseDNSSECStateCounter(Insecure);
 }
index bb90f41dd193c4beeb07edecf79afa22342224f5..f3a94dc78781919d83815a51808fbb16e8f50e6f 100644 (file)
@@ -203,16 +203,13 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset)
   }
 
   vector<string> labels = zone.getRawLabels();
-  vState state;
-
-  state = Indeterminate;
 
   typedef std::multimap<uint16_t, DSRecordContent> dsmap_t;
   dsmap_t dsmap;
   keyset_t validkeys;
 
   DNSName qname = lowestTA;
-  state = Secure; // the lowest Trust Anchor is secure
+  vState state = Secure; // the lowest Trust Anchor is secure
 
   while(zone.isPartOf(qname))
   {
@@ -390,8 +387,10 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset)
               LOG("\t"<<r->getZoneRepresentation()<<endl);
               auto nsec = std::dynamic_pointer_cast<NSECRecordContent>(r);
               if(nsec) {
-                if(v.first.first == qname && !nsec->d_set.count(QType::DS))
+                if(v.first.first == qname && !nsec->d_set.count(QType::DS)) {
+                  LOG("Denies existence of DS!"<<endl);
                   return Insecure;
+                }
                 else if(v.first.first.canonCompare(qname) && qname.canonCompare(nsec->d_next) ) {
                   LOG("Did not find DS for this level, trying one lower"<<endl);
                   goto skipLevel;
index e2542b3bfa5f0a7ac409dcd75d035da6bd7f4013..d98392fd73e202bd6246bc6f45a5a44bd11cd8b5 100644 (file)
@@ -1018,3 +1018,121 @@ class TestAdvancedNMGRule(DNSDistTest):
         (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
         self.assertEquals(receivedResponse, expectedResponse)
 
+class TestAdvancedLabelsCountRule(DNSDistTest):
+
+    _config_template = """
+    addAction(QNameLabelsCountRule(5,6), RCodeAction(dnsdist.REFUSED))
+    newServer{address="127.0.0.1:%s"}
+    """
+
+    def testAdvancedLabelsCountRule(self):
+        """
+        Advanced: QNameLabelsCountRule(5,6)
+        """
+        # 6 labels, we should be fine
+        name = 'ok.labelscount.advanced.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        response = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    3600,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '192.0.2.1')
+        response.answer.append(rrset)
+
+        (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = query.id
+        self.assertEquals(query, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+
+        (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = query.id
+        self.assertEquals(query, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+
+        # more than 6 labels, the query should be refused
+        name = 'not.ok.labelscount.advanced.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        expectedResponse = dns.message.make_response(query)
+        expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, expectedResponse)
+
+        (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, expectedResponse)
+
+        # less than 5 labels, the query should be refused
+        name = 'labelscountadvanced.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        expectedResponse = dns.message.make_response(query)
+        expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, expectedResponse)
+
+        (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, expectedResponse)
+
+class TestAdvancedWireLengthRule(DNSDistTest):
+
+    _config_template = """
+    addAction(QNameWireLengthRule(54,56), RCodeAction(dnsdist.REFUSED))
+    newServer{address="127.0.0.1:%s"}
+    """
+
+    def testAdvancedWireLengthRule(self):
+        """
+        Advanced: QNameWireLengthRule(54,56)
+        """
+        name = 'longenough.qnamewirelength.advanced.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        response = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    3600,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '192.0.2.1')
+        response.answer.append(rrset)
+
+        (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = query.id
+        self.assertEquals(query, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+
+        (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = query.id
+        self.assertEquals(query, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+
+        # too short, the query should be refused
+        name = 'short.qnamewirelength.advanced.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        expectedResponse = dns.message.make_response(query)
+        expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, expectedResponse)
+
+        (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, expectedResponse)
+
+        # too long, the query should be refused
+        name = 'toolongtobevalid.qnamewirelength.advanced.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        expectedResponse = dns.message.make_response(query)
+        expectedResponse.set_rcode(dns.rcode.REFUSED)
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, expectedResponse)
+
+        (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+        self.assertEquals(receivedResponse, expectedResponse)
index 31a3b547de8e2c1347e8eea3d092949f96793f4f..b1b86f7106ef00bb81dce47922a179aee2ae55ab 100644 (file)
@@ -92,6 +92,9 @@ ns1.optout.example.      3600 IN A    {prefix}.14
 
 insecure-formerr.example. 3600 IN NS   ns1.insecure-formerr.example.
 ns1.insecure-formerr.example. 3600 IN A    {prefix}.2
+
+islandofsecurity.example.          3600 IN NS   ns1.islandofsecurity.example.
+ns1.islandofsecurity.example.      3600 IN A    {prefix}.9
         """,
         'secure.example': """
 secure.example.          3600 IN SOA  {soa}
@@ -102,6 +105,7 @@ host1.secure.example.    3600 IN A    192.0.2.2
 cname.secure.example.    3600 IN CNAME host1.secure.example.
 cname-to-insecure.secure.example. 3600 IN CNAME node1.insecure.example.
 cname-to-bogus.secure.example.    3600 IN CNAME ted.bogus.example.
+cname-to-islandofsecurity.secure.example. 3600 IN CNAME node1.islandofsecurity.example.
 
 host1.sub.secure.example. 3600 IN A    192.0.2.11
 
@@ -164,6 +168,13 @@ secure.optout.example.          3600 IN NS   ns1.secure.optout.example.
 ns1.secure.optout.example.      3600 IN A    {prefix}.15
 
 node1.secure.optout.example.    3600 IN A    192.0.2.8
+        """,
+        'islandofsecurity.example': """
+islandofsecurity.example.          3600 IN SOA  {soa}
+islandofsecurity.example.          3600 IN NS   ns1.islandofsecurity.example.
+ns1.islandofsecurity.example.      3600 IN A    {prefix}.9
+
+node1.islandofsecurity.example.    3600 IN A    192.0.2.20
         """
     }
 
@@ -204,6 +215,12 @@ PrivateKey: efmq9G+J4Y2iPnIBRwJiy6Z/nIHSzpsCy/7XHhlS19A=
 Private-key-format: v1.2
 Algorithm: 13 (ECDSAP256SHA256)
 PrivateKey: xcNUxt1Knj14A00lKQFDboluiJyM2f7FxpgsQaQ3AQ4=
+        """,
+
+        'islandofsecurity.example': """
+Private-key-format: v1.2
+Algorithm: 13 (ECDSAP256SHA256)
+PrivateKey: o9F5iix8V68tnMcuOaM2Lt8XXhIIY//SgHIHEePk6cM=
         """
     }
 
@@ -212,7 +229,7 @@ PrivateKey: xcNUxt1Knj14A00lKQFDboluiJyM2f7FxpgsQaQ3AQ4=
     # go into the _zones's zonecontent
     _auth_zones = {
         '8': ['ROOT'],
-        '9': ['secure.example'],
+        '9': ['secure.example', 'islandofsecurity.example'],
         '10': ['example'],
         '11': ['example'],
         '12': ['bogus.example'],
index 178177762e79a4fe5fab2f80fd63120bde517c72..300710dbd3bcd78b7254f14436d7e4252394277f 100644 (file)
@@ -84,3 +84,15 @@ auth-zones=authzone.example=configs/%s/authzone.zone""" % _confdir
 
         self.assertRcodeEqual(resPTR, dns.rcode.NOERROR)
         self.assertRRsetInAnswer(resPTR, expectedPTR)
+
+    def testIslandOfSecurity(self):
+        query = dns.message.make_query('cname-to-islandofsecurity.secure.example.', 'A', want_dnssec=True)
+
+        expectedCNAME = dns.rrset.from_text('cname-to-islandofsecurity.secure.example.', 0, 'IN', 'CNAME', 'node1.islandofsecurity.example.')
+        expectedA = dns.rrset.from_text('node1.islandofsecurity.example.', 0, 'IN', 'A', '192.0.2.20')
+
+        res = self.sendUDPQuery(query)
+
+        self.assertRcodeEqual(res, dns.rcode.NOERROR)
+        self.assertRRsetInAnswer(res, expectedA)
+