]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Merge pull request #4246 from rgacogne/dnsdist-api-array-pools
authorRemi Gacogne <rgacogne@users.noreply.github.com>
Mon, 1 Aug 2016 07:15:51 +0000 (09:15 +0200)
committerGitHub <noreply@github.com>
Mon, 1 Aug 2016 07:15:51 +0000 (09:15 +0200)
dnsdist: API now sends pools as a JSON array instead of a string

42 files changed:
configure.ac
docs/manpages/rec_control.1.md
docs/markdown/authoritative/performance.md
docs/markdown/changelog.raw.md
docs/markdown/recursor/scripting.md
docs/markdown/recursor/upgrading.md [new file with mode: 0644]
docs/mkdocs.yml
docs/secpoll.zone
m4/pdns_check_libcrypto.m4 [moved from m4/ax_check_openssl.m4 with 51% similarity]
m4/pdns_check_libcrypto_ecdsa.m4 [new file with mode: 0644]
m4/pdns_enable_unit_tests.m4
modules/remotebackend/Makefile.am
pdns/Makefile.am
pdns/bindlexer.l
pdns/common_startup.cc
pdns/distributor.hh
pdns/dns_random.cc
pdns/dnsdistdist/configure.ac
pdns/dnssecinfra.cc
pdns/opensslsigners.cc
pdns/packethandler.cc
pdns/protobuf.cc
pdns/rec-lua-conf.cc
pdns/rec-lua-conf.hh
pdns/rec_channel_rec.cc
pdns/recursordist/Makefile.am
pdns/recursordist/configure.ac
pdns/recursordist/m4/ax_check_openssl.m4 [deleted symlink]
pdns/recursordist/m4/pdns_check_libcrypto.m4 [new symlink]
pdns/recursordist/m4/pdns_check_libcrypto_ecdsa.m4 [new symlink]
pdns/responsestats-auth.cc
pdns/secpoll-recursor.cc
pdns/toysdig.cc
pdns/validate.cc
pdns/validate.hh
pdns/zoneparser-tng.cc
regression-tests/tests/direct-nsec-nxdomain/command [new file with mode: 0755]
regression-tests/tests/direct-nsec-nxdomain/description [new file with mode: 0644]
regression-tests/tests/direct-nsec-nxdomain/expected_result [new file with mode: 0644]
regression-tests/tests/direct-nsec-nxdomain/expected_result.dnssec [new file with mode: 0644]
regression-tests/tests/direct-nsec-nxdomain/expected_result.narrow [new file with mode: 0644]
regression-tests/tests/direct-nsec-nxdomain/expected_result.nsec3 [new file with mode: 0644]

index 7cc72107f56e72f10417ea4edbe6872c68352adb..050613cd6b0c8d0c1e9dac2169919abab0b64642 100644 (file)
@@ -93,11 +93,12 @@ AC_CHECK_HEADERS(
 
 PDNS_ENABLE_BOTAN
 PDNS_CHECK_LIBSODIUM
-AX_CHECK_OPENSSL([
+PDNS_CHECK_LIBCRYPTO([
 ],[
-   AC_MSG_ERROR([OpenSSL not found])
+   AC_MSG_ERROR([OpenSSL/libcrypto not found])
   ]
 )
+PDNS_CHECK_LIBCRYPTO_ECDSA
 
 PDNS_CHECK_RAGEL
 PDNS_CHECK_CLOCK_GETTIME
@@ -108,6 +109,9 @@ BOOST_REQUIRE([1.35])
 AM_CONDITIONAL([HAVE_BOOST_GE_148], [test "$boost_major_version" -ge 148])
 
 BOOST_PROGRAM_OPTIONS([mt])
+AS_IF([test "$boost_cv_lib_program_options" = "no"], [
+  AC_MSG_ERROR([Boost Program Options library not found])
+])
 PDNS_ENABLE_UNIT_TESTS
 PDNS_ENABLE_REPRODUCIBLE
 
@@ -349,7 +353,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$libcrypto_ecdsa" == "xyes"],
   [AC_MSG_NOTICE([OpenSSL ecdsa: yes])],
   [AC_MSG_NOTICE([OpenSSL ecdsa: no])]
 )
index 2fe834bef9a75ddfee5dee60271d265a4b297c8a..788c9a6236dc5696ddb722cce0016c5227bc4429 100644 (file)
@@ -47,7 +47,8 @@ add-nta *DOMAIN* [*REASON*]
 :    Add a Negative Trust Anchor for *DOMAIN*, suffixed optionally with *REASON*.
 
 add-ta *DOMAIN* *DSRECORD*
-:    Add a Trust Anchor for *DOMAIN* with DS record data *DSRECORD*.
+:    Add a Trust Anchor for *DOMAIN* with DS record data *DSRECORD*. This adds the
+     new Trust Anchor to the existing set of Trust Anchors for *DOMAIN*.
 
 current-queries
 :    Shows the currently active queries.
index ddcc75acb031493f3055ac8e31d90a1437cc4b62..43645c7a5d6c437ef7ce1432aa46adacd53ca911 100644 (file)
@@ -81,7 +81,7 @@ daemon.
 * `tcp6-answers-bytes`: Total number of answer bytes sent over TCPv6 (since 4.0.0)
 * `tcp6-answers`: Number of answers sent out over TCPv6
 * `tcp6-queries`: Number of questions received over TCPv6
-* `timedout-questions`: Amount of packets that were dropped because they had to wait too long internally
+* `timedout-packets`: Amount of packets that were dropped because they had to wait too long internally
 * `udp-answers-bytes`: Total number of answer bytes sent over UDP
 * `udp-answers`: Number of answers sent out over UDP
 * `udp-do-queries`: Number of queries received with the DO (DNSSEC OK) bit set
index 53d7d8f3d1a898e3e1945c012acc89e4c6b4948b..cacb30fe8d84d9f1083cbb3fc912830ccb912219 100644 (file)
@@ -1,21 +1,60 @@
 **Note**: Beyond PowerDNS 2.9.20, the Authoritative Server and Recursor are released separately.
 
 # PowerDNS Recursor 4.0.1
-UNRELEASED
+Released July 29th 2016
 
-This release improves interoperability with DNSSEC clients that expect an AD-bit on validated data when they query with only the DO-bit set.
+This release has several improvements with regards to DNSSEC validation and it improves interoperability with DNSSEC clients that expect an AD-bit on validated data when they query with only the DO-bit set.
 
 ## Bug fixes
 
+ - [#4119](https://github.com/PowerDNS/pdns/pull/4119) Improve DNSSEC record skipping for non dnssec queries (Kees Monshouwer)
  - [#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
+ - [#4215](https://github.com/PowerDNS/pdns/pull/4215) RPZ: default policy should also override local data RRs
+ - [#4243](https://github.com/PowerDNS/pdns/pull/4243) Fix a crash when the next name in a chained query is empty and `rec_control current-queries` is invoked
 
 ## Improvements
 
+ - [#4056](https://github.com/PowerDNS/pdns/pull/4056) OpenSSL 1.1.0 support (Christian Hofstaedtler)
+ - [#4133](https://github.com/PowerDNS/pdns/pull/4133) Add limits to the size of received {A,I}XFR (CVE-2016-6172)
+ - [#4140](https://github.com/PowerDNS/pdns/pull/4140) Fix warnings with gcc on musl-libc (James Taylor)
  - [#4160](https://github.com/PowerDNS/pdns/pull/4160) Also validate on +DO
+ - [#4164](https://github.com/PowerDNS/pdns/pull/4164) Fail to start when the lua-dns-script does not exist
+ - [#4168](https://github.com/PowerDNS/pdns/pull/4168) Add more Netmask methods for Lua (Aki Tuomi)
+ - [#4210](https://github.com/PowerDNS/pdns/pull/4210) Validate DNSSEC for security polling
+ - [#4217](https://github.com/PowerDNS/pdns/pull/4217) Turn on root-nx-trust by default and log-common-errors=off
+ - [#4207](https://github.com/PowerDNS/pdns/pull/4207) Allow for multiple trust anchors per zone
+ - [#4242](https://github.com/PowerDNS/pdns/pull/4242) Fix compilation warning when building without Protobuf
+
+# PowerDNS Authoritative Server 4.0.1
+Released July 29th 2016
+
+This release fixes two small issues and adds a setting to limit AXFR and IXFR sizes, in response to [CVE-2016-6172](http://www.openwall.com/lists/oss-security/2016/07/06/4).
+
+## Bug fixes
+
+ - [#4126](https://github.com/PowerDNS/pdns/pull/4126) Wait for the connection to the carbon server to be established
+ - [#4206](https://github.com/PowerDNS/pdns/pull/4206) Don't try to deallocate empty PG statements
+ - [#4245](https://github.com/PowerDNS/pdns/pull/4245) Send the correct response when queried for an NSEC directly (Kees Monshouwer)
+ - [#4252](https://github.com/PowerDNS/pdns/pull/4252) Don't include bind files if length <= 2 or > sizeof(filename)
+ - [#4255](https://github.com/PowerDNS/pdns/pull/4255) Catch runtime_error when parsing a broken MNAME
+
+## Improvements
+
+ - [#4044](https://github.com/PowerDNS/pdns/pull/4044) Make DNSPacket return a ComboAddress for local and remote (Aki Tuomi)
+ - [#4056](https://github.com/PowerDNS/pdns/pull/4056) OpenSSL 1.1.0 support (Christian Hofstaedtler)
+ - [#4169](https://github.com/PowerDNS/pdns/pull/4169) Fix typos in a logmessage and exception (Christian Hofsteadtler)
+ - [#4183](https://github.com/PowerDNS/pdns/pull/4183) pdnsutil: Remove checking of ctime and always diff the changes (Hannu Ylitalo)
+ - [#4192](https://github.com/PowerDNS/pdns/pull/4192) dnsreplay: Only add Client Subnet stamp when asked
+ - [#4250](https://github.com/PowerDNS/pdns/pull/4250) Use toLogString() for ringAccount (Kees Monshouwer)
+
+## Additions
+
+ - [#4133](https://github.com/PowerDNS/pdns/pull/4133) Add limits to the size of received {A,I}XFR (CVE-2016-6172)
+ - [#4142](https://github.com/PowerDNS/pdns/pull/4142) Add used filedescriptor statistic (Kees Monshouwer)
 
 # PowerDNS Recursor 4.0.0
 Released July 11th 2016
index 9625b4ea85b86e14e38bde18639b447c70dd9d30..ac3291ad85414f8e9f548418acc30d2812e79d59 100644 (file)
@@ -240,6 +240,11 @@ To compare the address (so not the port) of two ComboAddresses, use `:equal`.
 To convert an address to human-friendly representation, use `:toString()` or
 `:toStringWithPort()`. To get only the port number, use `:getPort()`.
 
+Other functions that can be called on a ComboAddress are:
+ * `isIpv4` - true if the address is an IPv4 address
+ * `isIpv6` - true if the address is an IPv6 address
+ * `getBits` - the number of bits in the address
+
 ### DNSName
 DNSNames are passed to various functions, and they sport the following methods:
 
diff --git a/docs/markdown/recursor/upgrading.md b/docs/markdown/recursor/upgrading.md
new file mode 100644 (file)
index 0000000..813eb6f
--- /dev/null
@@ -0,0 +1,8 @@
+Before upgrading, it is advised to read the [changelog](../changelog.md).
+When upgrading several versions, please read **all** notes applying to the upgrade.
+
+# 4.0.0 to 4.0.1
+Two settings have changed defaults, these new defaults decrease CPU usage:
+
+ - [`root-nx-trust`](settings.md#root-nx-trust) changed from `no` to `yes`
+ - [`log-common-errors`](settings.md#log-common-errors) changed from `yes` to `no`
index a91ca1c49ce65aafc87e5c2b3c258a8e69dee3bb..0bd37f0644894890b9e9f48a4f9c8faa790c895b 100644 (file)
@@ -58,6 +58,7 @@ pages:
     - Deprecated Backends: authoritative/backend-deprecated.md
   - Recursor:
     - Introduction: recursor/index.md
+    - Upgrade Notes: recursor/upgrading.md
     - Security of the Recursor: recursor/security.md
     - DNSSEC in the Recursor: recursor/dnssec.md
     - Recursor Statistics: recursor/stats.md
index 80eb8ae58844cbad18bb3513c9ba9fca18e26051..4eef8b24a89e7ca078a7e11aa0e53245f506ea0b 100644 (file)
@@ -1,4 +1,4 @@
-@       86400   IN  SOA pdns-public-ns1.powerdns.com. pieter\.lexis.powerdns.com. 2016072001 10800 3600 604800 10800
+@       86400   IN  SOA pdns-public-ns1.powerdns.com. pieter\.lexis.powerdns.com. 2016072801 10800 3600 604800 10800
 @       3600    IN  NS  pdns-public-ns1.powerdns.com.
 @       3600    IN  NS  pdns-public-ns2.powerdns.com.
 ; Auth
@@ -23,6 +23,7 @@ auth-4.0.0-beta1.security-status                        60 IN TXT "2 Unsupported
 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-4.0.1.security-status                              60 IN TXT "1 OK"
 
 ; Auth Debian
 auth-3.4.1-2.debian.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/"
@@ -104,6 +105,7 @@ recursor-4.0.0-alpha3.security-status                   60 IN TXT "2 Unsupported
 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-4.0.1.security-status                          60 IN TXT "1 OK"
 
 ; Recursor Debian
 recursor-3.6.2-2.debian.security-status                 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/md/security/powerdns-advisory-2015-01/"
similarity index 51%
rename from m4/ax_check_openssl.m4
rename to m4/pdns_check_libcrypto.m4
index 587b29d348ca3192a96f8b49d02f989bbe71032c..9f495b42ed91e5549d25bdf2edd45135ad52203f 100644 (file)
@@ -1,29 +1,26 @@
-# ===========================================================================
-#     http://www.gnu.org/software/autoconf-archive/ax_check_openssl.html
-# ===========================================================================
-#
 # SYNOPSIS
 #
-#   AX_CHECK_OPENSSL([action-if-found[, action-if-not-found]])
+#   PDNS_CHECK_LIBCRYPTO([action-if-found[, action-if-not-found]])
 #
 # DESCRIPTION
 #
-#   Look for OpenSSL in a number of default spots, or in a user-selected
-#   spot (via --with-openssl).  Sets
+#   Look for OpenSSL's libcrypto in a number of default spots, or in a
+#   user-selected spot (via --with-libcrypto).  Sets
 #
-#     OPENSSL_INCLUDES to the include directives required
-#     OPENSSL_LIBS to the -l directives required
-#     OPENSSL_LDFLAGS to the -L or -R flags required
+#     LIBCRYPTO_INCLUDES to the include directives required
+#     LIBCRYPTO_LIBS to the -l directives required
+#     LIBCRYPTO_LDFLAGS to the -L or -R flags required
 #
 #   and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately
 #
-#   This macro sets OPENSSL_INCLUDES such that source files should use the
+#   This macro sets LIBCRYPTO_INCLUDES such that source files should use the
 #   openssl/ directory in include directives:
 #
 #     #include <openssl/hmac.h>
 #
 # LICENSE
 #
+# Taken and modified from AX_CHECK_OPENSSL by:
 #   Copyright (c) 2009,2010 Zmanda Inc. <http://www.zmanda.com/>
 #   Copyright (c) 2009,2010 Dustin J. Mitchell <dustin@zmanda.com>
 #
 #   and this notice are preserved. This file is offered as-is, without any
 #   warranty.
 
-#serial 8 (PowerDNS modified)
+#serial 1
 
-AU_ALIAS([CHECK_SSL], [AX_CHECK_OPENSSL])
-AC_DEFUN([AX_CHECK_OPENSSL], [
+AU_ALIAS([CHECK_LIBCRYPTO], [PDNS_CHECK_LIBCRYPTO])
+AC_DEFUN([PDNS_CHECK_LIBCRYPTO], [
     found=false
-    AC_ARG_WITH([openssl],
-        [AS_HELP_STRING([--with-openssl=DIR],
+    AC_ARG_WITH([libcrypto],
+        [AS_HELP_STRING([--with-libcrypto=DIR],
             [root of the OpenSSL directory])],
         [
             case "$withval" in
             "" | y | ye | yes | n | no)
-            AC_MSG_ERROR([Invalid --with-openssl value])
+            AC_MSG_ERROR([Invalid --with-libcrypto value])
               ;;
             *) ssldirs="$withval"
               ;;
@@ -51,12 +48,12 @@ AC_DEFUN([AX_CHECK_OPENSSL], [
         ], [
             # if pkg-config is installed and openssl has installed a .pc file,
             # then use that information and don't search ssldirs
-            AC_PATH_PROG([PKG_CONFIG], [pkg-config])
+            AC_CHECK_TOOL([PKG_CONFIG], [pkg-config])
             if test x"$PKG_CONFIG" != x""; then
-                OPENSSL_LDFLAGS=`$PKG_CONFIG libcrypto --libs-only-L 2>/dev/null`
+                LIBCRYPTO_LDFLAGS=`$PKG_CONFIG libcrypto --libs-only-L 2>/dev/null`
                 if test $? = 0; then
-                    OPENSSL_LIBS=`$PKG_CONFIG libcrypto --libs-only-l 2>/dev/null`
-                    OPENSSL_INCLUDES=`$PKG_CONFIG libcrypto --cflags-only-I 2>/dev/null`
+                    LIBCRYPTO_LIBS=`$PKG_CONFIG libcrypto --libs-only-l 2>/dev/null`
+                    LIBCRYPTO_INCLUDES=`$PKG_CONFIG libcrypto --cflags-only-I 2>/dev/null`
                     found=true
                 fi
             fi
@@ -73,13 +70,13 @@ AC_DEFUN([AX_CHECK_OPENSSL], [
     # an 'openssl' subdirectory
 
     if ! $found; then
-        OPENSSL_INCLUDES=
+        LIBCRYPTO_INCLUDES=
         for ssldir in $ssldirs; do
             AC_MSG_CHECKING([for openssl/crypto.h in $ssldir])
             if test -f "$ssldir/include/openssl/crypto.h"; then
-                OPENSSL_INCLUDES="-I$ssldir/include"
-                OPENSSL_LDFLAGS="-L$ssldir/lib"
-                OPENSSL_LIBS="-lcrypto"
+                LIBCRYPTO_INCLUDES="-I$ssldir/include"
+                LIBCRYPTO_LDFLAGS="-L$ssldir/lib"
+                LIBCRYPTO_LIBS="-lcrypto"
                 found=true
                 AC_MSG_RESULT([yes])
                 break
@@ -95,32 +92,20 @@ AC_DEFUN([AX_CHECK_OPENSSL], [
     # try the preprocessor and linker with our new flags,
     # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
 
-    AC_MSG_CHECKING([whether compiling and linking against OpenSSL works])
-    echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \
-        "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&AS_MESSAGE_LOG_FD
+    AC_MSG_CHECKING([whether compiling and linking against OpenSSL's libcrypto works])
+    echo "Trying link with LIBCRYPTO_LDFLAGS=$LIBCRYPTO_LDFLAGS;" \
+        "LIBCRYPTO_LIBS=$LIBCRYPTO_LIBS; LIBCRYPTO_INCLUDES=$LIBCRYPTO_INCLUDES" >&AS_MESSAGE_LOG_FD
 
     save_LIBS="$LIBS"
     save_LDFLAGS="$LDFLAGS"
     save_CPPFLAGS="$CPPFLAGS"
-    LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
-    LIBS="$OPENSSL_LIBS $LIBS"
-    CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS"
+    LDFLAGS="$LDFLAGS $LIBCRYPTO_LDFLAGS"
+    LIBS="$LIBCRYPTO_LIBS $LIBS"
+    CPPFLAGS="$LIBCRYPTO_INCLUDES $CPPFLAGS"
     AC_LINK_IFELSE(
-        [AC_LANG_PROGRAM([#include <openssl/crypto.h>], [CRYPTO_free(NULL)])],
+        [AC_LANG_PROGRAM([#include <openssl/crypto.h>], [ERR_load_CRYPTO_strings()])],
         [
             AC_MSG_RESULT([yes])
-            openssl_ecdsa=yes
-            AC_CHECK_FUNC(ECDSA_do_sign,
-            [
-                AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [ : ], [ openssl_ecdsa=no ], [AC_INCLUDES_DEFAULT
-#include <openssl/evp.h>
-                ])
-            ], [
-                openssl_ecdsa=no
-            ])
-            AS_IF([test "x$openssl_ecdsa" = "xyes"], [
-                AC_DEFINE([HAVE_OPENSSL_ECDSA], [1], [define to 1 if OpenSSL ecdsa support is avalable.])
-            ])
             $1
         ], [
             AC_MSG_RESULT([no])
@@ -130,7 +115,7 @@ AC_DEFUN([AX_CHECK_OPENSSL], [
     LDFLAGS="$save_LDFLAGS"
     LIBS="$save_LIBS"
 
-    AC_SUBST([OPENSSL_INCLUDES])
-    AC_SUBST([OPENSSL_LIBS])
-    AC_SUBST([OPENSSL_LDFLAGS])
+    AC_SUBST([LIBCRYPTO_INCLUDES])
+    AC_SUBST([LIBCRYPTO_LIBS])
+    AC_SUBST([LIBCRYPTO_LDFLAGS])
 ])
diff --git a/m4/pdns_check_libcrypto_ecdsa.m4 b/m4/pdns_check_libcrypto_ecdsa.m4
new file mode 100644 (file)
index 0000000..88aa353
--- /dev/null
@@ -0,0 +1,17 @@
+AC_DEFUN([PDNS_CHECK_LIBCRYPTO_ECDSA], [
+  AC_REQUIRE([PDNS_CHECK_LIBCRYPTO])
+  libcrypto_ecdsa=yes
+  AC_CHECK_HEADER([openssl/ecdsa.h], [
+    AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [ : ], [
+      libcrypto_ecdsa=no
+    ], [AC_INCLUDES_DEFAULT
+#include <openssl/evp.h>
+    ])
+  ], [
+    libcrypto_ecdsa=no
+  ])
+
+  AS_IF([test "x$libcrypto_ecdsa" = "xyes"], [
+    AC_DEFINE([HAVE_LIBCRYPTO_ECDSA], [1], [define to 1 if OpenSSL ecdsa support is avalable.])
+  ])
+])
index d72644de817dcb633d12ebd8a736e2c6379de9f3..abc4ec00b249e86959805e9f54c5857173385f88 100644 (file)
@@ -21,5 +21,8 @@ AC_DEFUN([PDNS_ENABLE_UNIT_TESTS], [
 
   AS_IF([test "x$enable_unit_tests" != "xno" || test "x$enable_backend_unit_tests" != "xno"], [
      BOOST_TEST([mt])
+     AS_IF([test "$boost_cv_lib_unit_test_framework" = "no"], [
+       AC_MSG_ERROR([Boost Unit Test library not found])
+     ])
    ])
 ])
index cc4afbbc46d5f26d9cbd0bf9df2fbc4c2d2994e1..ffe8a353ae1e88a3b8e3d14edb8b2916a53f85c1 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS += \
        -I$(top_srcdir)/ext/json11 \
        $(YAHTTP_CFLAGS) \
-       $(OPENSSL_CFLAGS) \
+       $(LIBCRYPTO_CFLAGS) \
        $(LIBZMQ_CFLAGS)
 
 AM_LDFLAGS = $(THREADFLAGS)
@@ -131,7 +131,7 @@ libtestremotebackend_la_CPPFLAGS = $(AM_CPPFLAGS)
 
 libtestremotebackend_la_LIBADD = \
        $(YAHTTP_LIBS) \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS) \
        $(LIBDL) $(JSON11_LIBS)
index 082c6cd95981ef6592014f7b4bf489c5b244e099..eee30caf3595a5865c3789c6092fb215850f871c 100644 (file)
@@ -4,7 +4,7 @@ AM_CPPFLAGS += \
        -I$(top_srcdir)/ext/json11 \
        $(YAHTTP_CFLAGS) \
        $(LIBEDIT_CFLAGS) \
-       $(OPENSSL_INCLUDES) \
+       $(LIBCRYPTO_INCLUDES) \
        $(SYSTEMD_CFLAGS)
 
 AM_CXXFLAGS = \
@@ -211,7 +211,7 @@ pdns_server_SOURCES = \
 pdns_server_LDFLAGS = \
        $(AM_LDFLAGS) \
        $(DYNLINKFLAGS) \
-       $(OPENSSL_LDFLAGS)
+       $(LIBCRYPTO_LDFLAGS)
 
 pdns_server_LDADD = \
        @moduleobjects@ \
@@ -219,7 +219,7 @@ pdns_server_LDADD = \
        $(LIBDL) \
        $(YAHTTP_LIBS) \
        $(JSON11_LIBS) \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(SYSTEMD_LIBS)
 
 if BOTAN110
@@ -302,7 +302,7 @@ pdnsutil_LDFLAGS = \
        $(AM_LDFLAGS) \
        $(DYNLINKFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS) \
-       $(OPENSSL_LDFLAGS)
+       $(LIBCRYPTO_LDFLAGS)
 
 pdnsutil_LDADD = \
        @moduleobjects@ \
@@ -311,7 +311,7 @@ pdnsutil_LDADD = \
        $(JSON11_LIBS) \
        $(LIBDL) \
        $(BOOST_PROGRAM_OPTIONS_LIBS) \
-       $(OPENSSL_LIBS)
+       $(LIBCRYPTO_LIBS)
 
 if BOTAN110
 pdnsutil_SOURCES += botan110signers.cc
@@ -368,8 +368,8 @@ zone2sql_SOURCES = \
        zone2sql.cc \
        zoneparser-tng.cc
 
-zone2sql_LDADD = $(OPENSSL_LIBS) $(JSON11_LIBS)
-zone2sql_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+zone2sql_LDADD = $(LIBCRYPTO_LIBS) $(JSON11_LIBS)
+zone2sql_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 zone2json_SOURCES = \
        arguments.cc \
@@ -395,8 +395,8 @@ zone2json_SOURCES = \
        zone2json.cc \
        zoneparser-tng.cc
 
-zone2json_LDADD = $(OPENSSL_LIBS) $(JSON11_LIBS)
-zone2json_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+zone2json_LDADD = $(LIBCRYPTO_LIBS) $(JSON11_LIBS)
+zone2json_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 # pkglib_LTLIBRARIES = iputils.la
 # iputils_la_SOURCES = lua-iputils.cc
@@ -431,8 +431,8 @@ zone2ldap_SOURCES = \
        zone2ldap.cc \
        zoneparser-tng.cc
 
-zone2ldap_LDADD = $(OPENSSL_LIBS)
-zone2ldap_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+zone2ldap_LDADD = $(LIBCRYPTO_LIBS)
+zone2ldap_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 sdig_SOURCES = \
        base32.cc \
@@ -455,8 +455,8 @@ sdig_SOURCES = \
        statbag.cc \
        unix_utility.cc
 
-sdig_LDADD = $(OPENSSL_LIBS)
-sdig_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+sdig_LDADD = $(LIBCRYPTO_LIBS)
+sdig_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 calidns_SOURCES = \
        base32.cc \
@@ -478,8 +478,8 @@ calidns_SOURCES = \
        statbag.cc \
        unix_utility.cc
 
-calidns_LDADD = $(OPENSSL_LIBS)
-calidns_LDFLAGS = $(AM_LDFLAGS) $(THREADFLAGS) $(OPENSSL_LDFLAGS)
+calidns_LDADD = $(LIBCRYPTO_LIBS)
+calidns_LDFLAGS = $(AM_LDFLAGS) $(THREADFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 dumresp_SOURCES = \
        dnslabeltext.cc \
@@ -521,8 +521,8 @@ stubquery_SOURCES = \
        stubquery.cc \
        unix_utility.cc
 
-stubquery_LDADD = $(OPENSSL_LIBS)
-stubquery_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+stubquery_LDADD = $(LIBCRYPTO_LIBS)
+stubquery_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 saxfr_SOURCES = \
        base32.cc \
@@ -546,8 +546,8 @@ saxfr_SOURCES = \
        statbag.cc \
        unix_utility.cc
 
-saxfr_LDADD = $(OPENSSL_LIBS)
-saxfr_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+saxfr_LDADD = $(LIBCRYPTO_LIBS)
+saxfr_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 if PKCS11
 saxfr_SOURCES += pkcs11signers.cc pkcs11signers.hh
@@ -585,8 +585,8 @@ ixplore_SOURCES = \
        statbag.cc \
        unix_utility.cc zoneparser-tng.cc
 
-ixplore_LDADD = $(OPENSSL_LIBS)
-ixplore_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+ixplore_LDADD = $(LIBCRYPTO_LIBS)
+ixplore_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 if PKCS11
 ixplore_SOURCES += pkcs11signers.cc pkcs11signers.hh
@@ -619,11 +619,11 @@ dnstcpbench_SOURCES = \
 
 dnstcpbench_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
 
 dnstcpbench_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS)
 
 nsec3dig_SOURCES = \
@@ -647,8 +647,8 @@ nsec3dig_SOURCES = \
        statbag.cc \
        unix_utility.cc
 
-nsec3dig_LDADD = $(OPENSSL_LIBS)
-nsec3dig_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+nsec3dig_LDADD = $(LIBCRYPTO_LIBS)
+nsec3dig_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 if PKCS11
 nsec3dig_SOURCES += pkcs11signers.cc pkcs11signers.hh
@@ -692,8 +692,8 @@ toysdig_SOURCES = \
 
 
 toysdig_LDFLAGS = $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS)
-toysdig_LDADD = $(OPENSSL_LIBS)
+       $(LIBCRYPTO_LDFLAGS)
+toysdig_LDADD = $(LIBCRYPTO_LIBS)
 
 if GSS_TSIG
 toysdig_LDADD += $(GSS_LIBS)
@@ -735,8 +735,8 @@ tsig_tests_SOURCES = \
        tsig-tests.cc \
        unix_utility.cc
 
-tsig_tests_LDADD = $(OPENSSL_LIBS)
-tsig_tests_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
+tsig_tests_LDADD = $(LIBCRYPTO_LIBS)
+tsig_tests_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
 
 if PKCS11
 tsig_tests_SOURCES += pkcs11signers.cc pkcs11signers.hh
@@ -765,8 +765,8 @@ speedtest_SOURCES = \
        statbag.cc \
        unix_utility.cc
 
-speedtest_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS)
-speedtest_LDADD = $(OPENSSL_LIBS) \
+speedtest_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS)
+speedtest_LDADD = $(LIBCRYPTO_LIBS) \
        $(RT_LIBS)
 
 dnswasher_SOURCES = \
@@ -803,11 +803,11 @@ dnsbulktest_SOURCES = \
 
 dnsbulktest_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
 
 dnsbulktest_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS)
 
 comfun_SOURCES = \
@@ -832,11 +832,11 @@ comfun_SOURCES = \
 
 comfun_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
 
 comfun_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS)
 
 
@@ -863,9 +863,9 @@ dnsscan_SOURCES = \
 
 dnsscan_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS)
+       $(LIBCRYPTO_LDFLAGS)
 
-dnsscan_LDADD = $(OPENSSL_LIBS)
+dnsscan_LDADD = $(LIBCRYPTO_LIBS)
 
 dnsreplay_SOURCES = \
        anadns.hh \
@@ -892,11 +892,11 @@ dnsreplay_SOURCES = \
 
 dnsreplay_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
 
 dnsreplay_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS)
 
 nproxy_SOURCES = \
@@ -921,11 +921,11 @@ nproxy_SOURCES = \
 
 nproxy_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
 
 nproxy_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS)
 
 pdns_notify_SOURCES = \
@@ -951,11 +951,11 @@ pdns_notify_SOURCES = \
 
 pdns_notify_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
 
 pdns_notify_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS)
 
 dnsscope_SOURCES = \
@@ -983,11 +983,11 @@ dnsscope_SOURCES = \
 
 dnsscope_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
 
 dnsscope_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS)
 
 dnsgram_SOURCES = \
@@ -1012,10 +1012,10 @@ dnsgram_SOURCES = \
 
 dnsgram_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS)
+       $(LIBCRYPTO_LDFLAGS)
 
 dnsgram_LDADD = \
-       $(OPENSSL_LIBS)
+       $(LIBCRYPTO_LIBS)
 
 dnsdemog_SOURCES = \
        base32.cc \
@@ -1039,10 +1039,10 @@ dnsdemog_SOURCES = \
 
 dnsdemog_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS)
+       $(LIBCRYPTO_LDFLAGS)
 
 dnsdemog_LDADD = \
-       $(OPENSSL_LIBS)
+       $(LIBCRYPTO_LIBS)
 
 if HAVE_PROTOBUF
 if HAVE_PROTOC
@@ -1080,11 +1080,11 @@ nodist_dnspcap2protobuf_SOURCES=dnsmessage.pb.cc dnsmessage.pb.h
 
 dnspcap2protobuf_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
 
 dnspcap2protobuf_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(PROTOBUF_LIBS) \
        $(BOOST_PROGRAM_OPTIONS_LIBS)
 endif
@@ -1156,11 +1156,11 @@ testrunner_SOURCES = \
 
 testrunner_LDFLAGS = \
        $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
        $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) 
 
 testrunner_LDADD = \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) \
        $(RT_LIBS) \
        $(LIBDL)
index 4a47e7a2d2005e56844dc69eeccbc82336255e9f..8003a2740e456045cc9060b84949ae65e3f2b8bf 100644 (file)
@@ -44,25 +44,43 @@ include                 BEGIN(incl);
        char filename[1024];
         if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
             {
-            fprintf( stderr, "Includes nested too deeply" );
+            fprintf( stderr, "Includes nested too deeply\n" );
             exit( 1 );
             }
 
+        if (strlen(yytext) <= 2) {
+            fprintf( stderr, "Empty include directive\n" );
+            exit( 1 );
+        }
+
         yytext[strlen(yytext)-2]=0;
 
         include_stack[include_stack_ptr]=YY_CURRENT_BUFFER;
         include_stack_name[include_stack_ptr]=current_filename=strdup(yytext+1);
         include_stack_ln[include_stack_ptr++]=linenumber;
         linenumber=1;
-       if(*(yytext+1)=='/')
+
+       if(*(yytext+1)=='/') {
+                if (strlen(yytext+1) >= sizeof(filename)) {
+                 fprintf( stderr, "Filename '%s' is too long\n",yytext+1);
+                 exit( 1 );
+               }
                strcpy(filename,yytext+1);
+       }
        else {
+               size_t bind_directory_len = strlen(bind_directory);
+               if (bind_directory_len >= sizeof(filename) ||
+                   strlen(yytext+1) + 2 >= sizeof(filename) - bind_directory_len) {
+                 fprintf( stderr, "Filename '%s' is too long\n",yytext+1);
+                 exit( 1 );
+               }
                strcpy(filename,bind_directory);
                strcat(filename,"/");
                strcat(filename,yytext+1);
        }
+       filename[sizeof(filename)-1]='\0';
 
-        if (*yytext &&!(yyin=fopen(filename,"r"))) {
+       if (!(yyin=fopen(filename,"r"))) {
          fprintf( stderr, "Unable to open '%s': %s\n",filename,strerror(errno));
          exit( 1 );
        }
index 4d7d8daf2adda788f37ffb9fbbdec7caaa404120..46f3d50159f2c48a57329aefda59e25fb0721a6b 100644 (file)
@@ -387,7 +387,7 @@ void *qthread(void *number)
      if(P->d.qr)
        continue;
 
-    S.ringAccount("queries", P->qdomain.toString()+"/"+P->qtype.getName());
+    S.ringAccount("queries", P->qdomain.toLogString()+"/"+P->qtype.getName());
     S.ringAccount("remotes",P->d_remote);
     if(logDNSQueries) {
       string remote;
index d1940ec69182e31c508000350cee1c67add6decf..b5be8503a6bcfc9236e37219d5703ea6af5ecfeb 100644 (file)
@@ -217,7 +217,7 @@ retry:
 
           a->setRcode(RCode::ServFail);
           S.inc("servfail-packets");
-          S.ringAccount("servfail-queries",QD->Q->qdomain.toString());
+          S.ringAccount("servfail-queries",QD->Q->qdomain.toLogString());
 
           delete QD->Q;
         } else {
@@ -234,7 +234,7 @@ retry:
 
           a->setRcode(RCode::ServFail);
           S.inc("servfail-packets");
-          S.ringAccount("servfail-queries",QD->Q->qdomain.toString());
+          S.ringAccount("servfail-queries",QD->Q->qdomain.toLogString());
 
           delete QD->Q;
         } else {
@@ -281,7 +281,7 @@ retry:
 
       a->setRcode(RCode::ServFail);
       S.inc("servfail-packets");
-      S.ringAccount("servfail-queries",q->qdomain.toString());
+      S.ringAccount("servfail-queries",q->qdomain.toLogString());
     } else {
       L<<Logger::Error<<"Backend error (retry once): "<<e.reason<<endl;
       goto retry;
@@ -296,7 +296,7 @@ retry:
 
       a->setRcode(RCode::ServFail);
       S.inc("servfail-packets");
-      S.ringAccount("servfail-queries",q->qdomain.toString());
+      S.ringAccount("servfail-queries",q->qdomain.toLogString());
     } else {
       L<<Logger::Error<<"Caught unknown exception in Distributor thread "<<(unsigned long)pthread_self()<<" (retry once)"<<endl;
       goto retry;
index 415542b3b0453cd8474c65bac74fa94e6dc19481..623e3aa54dd4df3de3647d204e6b369542eca537 100644 (file)
@@ -2,6 +2,12 @@
 #include "config.h"
 #endif
 #include <openssl/aes.h>
+#if OPENSSL_VERSION_NUMBER > 0x1000100fL
+// Older OpenSSL does not have CRYPTO_ctr128_encrypt. Before 1.1.0 the header
+// file did not have the necessary extern "C" wrapper. In 1.1.0, AES_ctr128_encrypt
+// was removed.
+#include <openssl/modes.h>
+#endif
 #include <iostream>
 #include <cstdlib>
 #include <cstring>
@@ -47,7 +53,11 @@ unsigned int dns_random(unsigned int n)
   if(!g_initialized)
     abort();
   uint32_t out;
+#if OPENSSL_VERSION_NUMBER > 0x1000100fL
+  CRYPTO_ctr128_encrypt((const unsigned char*)&g_in, (unsigned char*) &out, sizeof(g_in), &aes_key, g_counter, g_stream, &g_offset, (block128_f) AES_encrypt);
+#else
   AES_ctr128_encrypt((const unsigned char*)&g_in, (unsigned char*) &out, sizeof(g_in), &aes_key, g_counter, g_stream, &g_offset);
+#endif
   return out % n;
 }
 
index 3df8be0be838183af9f60396d037e71c7f610eb2..53d9a9aa300ca36ffcbd943597a26fee87cd7b6f 100644 (file)
@@ -30,7 +30,6 @@ AS_IF([test "x$PROTOBUF_LIBS" != "x" -a x"$PROTOC" != "x"],
 )
 
 BOOST_REQUIRE([$boost_required_version])
-BOOST_FOREACH
 
 PDNS_ENABLE_UNIT_TESTS
 PDNS_CHECK_RE2
index 6695a890b9529438f7835891a75978f10e3b1eee..addcab456734ec62f7c66f86b6a7efebeb0974d0 100644 (file)
@@ -273,7 +273,9 @@ pair<unsigned int, unsigned int> DNSCryptoKeyEngine::testMakers(unsigned int alg
   unsigned int udiffSign= dt.udiff()/100, udiffVerify;
   
   dckeVerify->fromPublicKeyString(dckeSign->getPublicKeyString());
-  
+  if (dckeVerify->getPublicKeyString().compare(dckeSign->getPublicKeyString())) {
+    throw runtime_error("Comparison of public key loaded into verifier produced by signer failed");
+  }
   dt.set();
   if(dckeVerify->verify(message, signature)) {
     udiffVerify = dt.udiff();
index 48bbed6a08f214e2ba6f45d7784d6ed592835d8c..3496992574c157c3de7f71600d90b70af7756088 100644 (file)
@@ -2,18 +2,18 @@
 #include "config.h"
 #endif
 #include <openssl/obj_mac.h>
-#ifdef HAVE_OPENSSL_ECDSA
+#ifdef HAVE_LIBCRYPTO_ECDSA
 #include <openssl/ecdsa.h>
 #endif
 #include <openssl/sha.h>
 #include <openssl/rand.h>
 #include <openssl/rsa.h>
+#include <openssl/opensslv.h>
 #include "opensslsigners.hh"
 #include "dnssecinfra.hh"
 
-
-/* pthread locking */
-
+#if OPENSSL_VERSION_NUMBER < 0x1010000fL
+/* OpenSSL < 1.1.0 needs support for threading/locking in the calling application. */
 static pthread_mutex_t *openssllocks;
 
 extern "C" {
@@ -55,6 +55,75 @@ void openssl_thread_cleanup()
   OPENSSL_free(openssllocks);
 }
 
+/* compat helpers. These DO NOT do any of the checking that the libssl 1.1 functions do. */
+static inline void RSA_get0_key(const RSA* rsakey, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d) {
+  *n = rsakey->n;
+  *e = rsakey->e;
+  *d = rsakey->d;
+}
+
+static inline int RSA_set0_key(RSA* rsakey, BIGNUM* n, BIGNUM* e, BIGNUM* d) {
+  if (n) {
+    BN_clear_free(rsakey->n);
+    rsakey->n = n;
+  }
+  if (e) {
+    BN_clear_free(rsakey->e);
+    rsakey->e = e;
+  }
+  if (d) {
+    BN_clear_free(rsakey->d);
+    rsakey->d = d;
+  }
+  return 1;
+}
+
+static inline void RSA_get0_factors(const RSA* rsakey, const BIGNUM** p, const BIGNUM** q) {
+  *p = rsakey->p;
+  *q = rsakey->q;
+}
+
+static inline int RSA_set0_factors(RSA* rsakey, BIGNUM* p, BIGNUM* q) {
+  BN_clear_free(rsakey->p);
+  rsakey->p = p;
+  BN_clear_free(rsakey->q);
+  rsakey->q = q;
+  return 1;
+}
+
+static inline void RSA_get0_crt_params(const RSA* rsakey, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp) {
+  *dmp1 = rsakey->dmp1;
+  *dmq1 = rsakey->dmq1;
+  *iqmp = rsakey->iqmp;
+}
+
+static inline int RSA_set0_crt_params(RSA* rsakey, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp) {
+  BN_clear_free(rsakey->dmp1);
+  rsakey->dmp1 = dmp1;
+  BN_clear_free(rsakey->dmq1);
+  rsakey->dmq1 = dmq1;
+  BN_clear_free(rsakey->iqmp);
+  rsakey->iqmp = iqmp;
+  return 1;
+}
+
+static inline void ECDSA_SIG_get0(const ECDSA_SIG* signature, const BIGNUM** pr, const BIGNUM** ps) {
+  *pr = signature->r;
+  *ps = signature->s;
+}
+
+static inline int ECDSA_SIG_set0(ECDSA_SIG* signature, BIGNUM* pr, BIGNUM* ps) {
+  BN_clear_free(signature->r);
+  BN_clear_free(signature->s);
+  signature->r = pr;
+  signature->s = ps;
+  return 1;
+}
+#else
+void openssl_thread_setup() {}
+void openssl_thread_cleanup() {}
+#endif
+
 
 /* seeding PRNG */
 
@@ -90,18 +159,18 @@ public:
       RSA_free(d_key);
   }
 
-  string getName() const { return "OpenSSL RSA"; }
-  int getBits() const { return RSA_size(d_key) << 3; }
+  string getName() const override { return "OpenSSL RSA"; }
+  int getBits() const override { return RSA_size(d_key) << 3; }
 
-  void create(unsigned int bits);
-  storvector_t convertToISCVector() const;
-  std::string hash(const std::string& hash) const;
-  std::string sign(const std::string& hash) const;
-  bool verify(const std::string& hash, const std::string& signature) const;
-  std::string getPubKeyHash() const;
-  std::string getPublicKeyString() const;
-  void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap);
-  void fromPublicKeyString(const std::string& content);
+  void create(unsigned int bits) override;
+  storvector_t convertToISCVector() const override;
+  std::string hash(const std::string& hash) const override;
+  std::string sign(const std::string& hash) const override;
+  bool verify(const std::string& hash, const std::string& signature) const override;
+  std::string getPubKeyHash() const override;
+  std::string getPublicKeyString() const override;
+  void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap) override;
+  void fromPublicKeyString(const std::string& content) override;
   bool checkKey() const override;
 
   static DNSCryptoKeyEngine* maker(unsigned int algorithm)
@@ -156,14 +225,18 @@ DNSCryptoKeyEngine::storvector_t OpenSSLRSADNSCryptoKeyEngine::convertToISCVecto
   storvector_t storvect;
   typedef vector<pair<string, const BIGNUM*> > outputs_t;
   outputs_t outputs;
-  outputs.push_back(make_pair("Modulus", d_key->n));
-  outputs.push_back(make_pair("PublicExponent",d_key->e));
-  outputs.push_back(make_pair("PrivateExponent",d_key->d));
-  outputs.push_back(make_pair("Prime1",d_key->p));
-  outputs.push_back(make_pair("Prime2",d_key->q));
-  outputs.push_back(make_pair("Exponent1",d_key->dmp1));
-  outputs.push_back(make_pair("Exponent2",d_key->dmq1));
-  outputs.push_back(make_pair("Coefficient",d_key->iqmp));
+  const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
+  RSA_get0_key(d_key, &n, &e, &d);
+  RSA_get0_factors(d_key, &p, &q);
+  RSA_get0_crt_params(d_key, &dmp1, &dmq1, &iqmp);
+  outputs.push_back(make_pair("Modulus", n));
+  outputs.push_back(make_pair("PublicExponent", e));
+  outputs.push_back(make_pair("PrivateExponent", d));
+  outputs.push_back(make_pair("Prime1", p));
+  outputs.push_back(make_pair("Prime2", q));
+  outputs.push_back(make_pair("Exponent1", dmp1));
+  outputs.push_back(make_pair("Exponent2", dmq1));
+  outputs.push_back(make_pair("Coefficient", iqmp));
 
   string algorithm=std::to_string(d_algorithm);
   switch(d_algorithm) {
@@ -261,7 +334,9 @@ bool OpenSSLRSADNSCryptoKeyEngine::verify(const std::string& msg, const std::str
 
 std::string OpenSSLRSADNSCryptoKeyEngine::getPubKeyHash() const
 {
-  unsigned char tmp[std::max(BN_num_bytes(d_key->e), BN_num_bytes(d_key->n))];
+  const BIGNUM *n, *e, *d;
+  RSA_get0_key(d_key, &n, &e, &d);
+  unsigned char tmp[std::max(BN_num_bytes(e), BN_num_bytes(n))];
   unsigned char hash[SHA_DIGEST_LENGTH];
   SHA_CTX ctx;
 
@@ -271,13 +346,13 @@ std::string OpenSSLRSADNSCryptoKeyEngine::getPubKeyHash() const
     throw runtime_error(getName()+" failed to init hash context for generating the public key hash");
   }
 
-  int len = BN_bn2bin(d_key->e, tmp);
+  int len = BN_bn2bin(e, tmp);
   res = SHA1_Update(&ctx, tmp, len);
   if (res != 1) {
     throw runtime_error(getName()+" failed to update hash context for generating the public key hash");
   }
 
-  len = BN_bn2bin(d_key->n, tmp);
+  len = BN_bn2bin(n, tmp);
   res = SHA1_Update(&ctx, tmp, len);
   if (res != 1) {
     throw runtime_error(getName()+" failed to update hash context for generating the public key hash");
@@ -294,10 +369,12 @@ std::string OpenSSLRSADNSCryptoKeyEngine::getPubKeyHash() const
 
 std::string OpenSSLRSADNSCryptoKeyEngine::getPublicKeyString() const
 {
+  const BIGNUM *n, *e, *d;
+  RSA_get0_key(d_key, &n, &e, &d);
   string keystring;
-  unsigned char tmp[std::max(BN_num_bytes(d_key->e), BN_num_bytes(d_key->n))];
+  unsigned char tmp[std::max(BN_num_bytes(e), BN_num_bytes(n))];
 
-  int len = BN_bn2bin(d_key->e, tmp);
+  int len = BN_bn2bin(e, tmp);
   if (len < 255) {
     keystring.assign(1, (char) (unsigned int) len);
   } else {
@@ -308,7 +385,7 @@ std::string OpenSSLRSADNSCryptoKeyEngine::getPublicKeyString() const
   }
   keystring.append((char *) tmp, len);
 
-  len = BN_bn2bin(d_key->n, tmp);
+  len = BN_bn2bin(n, tmp);
   keystring.append((char *) tmp, len);
 
   return keystring;
@@ -324,14 +401,68 @@ void OpenSSLRSADNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map
     throw runtime_error(getName()+" allocation of key structure failed");
   }
 
-  places["Modulus"]=&key->n;
-  places["PublicExponent"]=&key->e;
-  places["PrivateExponent"]=&key->d;
-  places["Prime1"]=&key->p;
-  places["Prime2"]=&key->q;
-  places["Exponent1"]=&key->dmp1;
-  places["Exponent2"]=&key->dmq1;
-  places["Coefficient"]=&key->iqmp;
+  BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
+  n = BN_new();
+  if (n == NULL) {
+    RSA_free(key);
+    throw runtime_error(getName()+" allocation of BIGNUM n failed");
+  }
+  e = BN_new();
+  if (e == NULL) {
+    RSA_free(key);
+    BN_clear_free(n);
+    throw runtime_error(getName()+" allocation of BIGNUM e failed");
+  }
+  d = BN_new();
+  if (d == NULL) {
+    RSA_free(key);
+    BN_clear_free(n);
+    BN_clear_free(e);
+    throw runtime_error(getName()+" allocation of BIGNUM d failed");
+  }
+  RSA_set0_key(key, n, e, d);
+
+  p = BN_new();
+  if (p == NULL) {
+    RSA_free(key);
+    throw runtime_error(getName()+" allocation of BIGNUM p failed");
+  }
+  q = BN_new();
+  if (q == NULL) {
+    RSA_free(key);
+    BN_clear_free(p);
+    throw runtime_error(getName()+" allocation of BIGNUM q failed");
+  }
+  RSA_set0_factors(key, p, q);
+
+  dmp1 = BN_new();
+  if (dmp1 == NULL) {
+    RSA_free(key);
+    throw runtime_error(getName()+" allocation of BIGNUM dmp1 failed");
+  }
+  dmq1 = BN_new();
+  if (dmq1 == NULL) {
+    RSA_free(key);
+    BN_clear_free(dmp1);
+    throw runtime_error(getName()+" allocation of BIGNUM dmq1 failed");
+  }
+  iqmp = BN_new();
+  if (iqmp == NULL) {
+    RSA_free(key);
+    BN_clear_free(dmq1);
+    BN_clear_free(iqmp);
+    throw runtime_error(getName()+" allocation of BIGNUM iqmp failed");
+  }
+  RSA_set0_crt_params(key, dmp1, dmq1, iqmp);
+
+  places["Modulus"]=&n;
+  places["PublicExponent"]=&e;
+  places["PrivateExponent"]=&d;
+  places["Prime1"]=&p;
+  places["Prime2"]=&q;
+  places["Exponent1"]=&dmp1;
+  places["Exponent2"]=&dmq1;
+  places["Coefficient"]=&iqmp;
 
   drc.d_algorithm = pdns_stou(stormap["algorithm"]);
 
@@ -342,10 +473,7 @@ void OpenSSLRSADNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map
     if (!val.second)
       continue;
 
-    if (*val.second)
-      BN_clear_free(*val.second);
-
-    *val.second = BN_bin2bn((unsigned char*) raw.c_str(), raw.length(), NULL);
+    *val.second = BN_bin2bn((unsigned char*) raw.c_str(), raw.length(), *val.second);
     if (!*val.second) {
       RSA_free(key);
       throw runtime_error(getName()+" error loading " + val.first);
@@ -402,13 +530,13 @@ void OpenSSLRSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& input)
     throw runtime_error(getName()+" allocation of key structure failed");
   }
 
-  key->e = BN_bin2bn((unsigned char*)exponent.c_str(), exponent.length(), NULL);
-  if (!key->e) {
+  BIGNUM *e = BN_bin2bn((unsigned char*)exponent.c_str(), exponent.length(), NULL);
+  if (!e) {
     RSA_free(key);
     throw runtime_error(getName()+" error loading e value of public key");
   }
-  key->n = BN_bin2bn((unsigned char*)modulus.c_str(), modulus.length(), NULL);
-  if (!key->n) {
+  BIGNUM *n = BN_bin2bn((unsigned char*)modulus.c_str(), modulus.length(), NULL);
+  if (!n) {
     RSA_free(key);
     throw runtime_error(getName()+" error loading n value of public key");
   }
@@ -416,10 +544,11 @@ void OpenSSLRSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& input)
   if (d_key)
     RSA_free(d_key);
 
+  RSA_set0_key(key, n, e, NULL);
   d_key = key;
 }
 
-#ifdef HAVE_OPENSSL_ECDSA
+#ifdef HAVE_LIBCRYPTO_ECDSA
 class OpenSSLECDSADNSCryptoKeyEngine : public DNSCryptoKeyEngine
 {
 public:
@@ -463,18 +592,18 @@ public:
     BN_CTX_free(d_ctx);
   }
 
-  string getName() const { return "OpenSSL ECDSA"; }
-  int getBits() const { return d_len << 3; }
+  string getName() const override { return "OpenSSL ECDSA"; }
+  int getBits() const override { return d_len << 3; }
 
-  void create(unsigned int bits);
-  storvector_t convertToISCVector() const;
-  std::string hash(const std::string& hash) const;
-  std::string sign(const std::string& hash) const;
-  bool verify(const std::string& hash, const std::string& signature) const;
-  std::string getPubKeyHash() const;
-  std::string getPublicKeyString() const;
-  void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap);
-  void fromPublicKeyString(const std::string& content);
+  void create(unsigned int bits) override;
+  storvector_t convertToISCVector() const override;
+  std::string hash(const std::string& hash) const override;
+  std::string sign(const std::string& hash) const override;
+  bool verify(const std::string& hash, const std::string& signature) const override;
+  std::string getPubKeyHash() const override;
+  std::string getPublicKeyString() const override;
+  void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap) override;
+  void fromPublicKeyString(const std::string& content) override;
   bool checkKey() const override;
 
   static DNSCryptoKeyEngine* maker(unsigned int algorithm)
@@ -565,12 +694,14 @@ std::string OpenSSLECDSADNSCryptoKeyEngine::sign(const std::string& msg) const
   string ret;
   unsigned char tmp[d_len];
 
-  int len = BN_bn2bin(signature->r, tmp);
+  const BIGNUM *pr, *ps;
+  ECDSA_SIG_get0(signature, &pr, &ps);
+  int len = BN_bn2bin(pr, tmp);
   if (d_len - len)
     ret.append(d_len - len, 0x00);
   ret.append(string((char*) tmp, len));
 
-  len = BN_bn2bin(signature->s, tmp);
+  len = BN_bn2bin(ps, tmp);
   if (d_len - len)
     ret.append(d_len - len, 0x00);
   ret.append(string((char*) tmp, len));
@@ -595,13 +726,21 @@ bool OpenSSLECDSADNSCryptoKeyEngine::verify(const std::string& msg, const std::s
     throw runtime_error(getName()+" allocation of signature structure failed");
   }
 
-  sig->r = BN_bin2bn((unsigned char*) signature.c_str(), d_len, sig->r);
-  sig->s = BN_bin2bn((unsigned char*) signature.c_str() + d_len, d_len, sig->s);
-  if (!sig->r || !sig->s) {
+  BIGNUM *r, *s;
+  r = BN_bin2bn((unsigned char*) signature.c_str(), d_len, NULL);
+  s = BN_bin2bn((unsigned char*) signature.c_str() + d_len, d_len, NULL);
+  if (!r || !s) {
+    if (r) {
+      BN_clear_free(r);
+    }
+    if (s) {
+      BN_clear_free(s);
+    }
     ECDSA_SIG_free(sig);
     throw runtime_error(getName()+" invalid signature");
   }
 
+  ECDSA_SIG_set0(sig, r, s);
   int ret = ECDSA_do_verify((unsigned char*) hash.c_str(), hash.length(), sig, d_eckey);
 
   ECDSA_SIG_free(sig);
@@ -732,7 +871,7 @@ namespace {
       DNSCryptoKeyEngine::report(7, &OpenSSLRSADNSCryptoKeyEngine::maker);
       DNSCryptoKeyEngine::report(8, &OpenSSLRSADNSCryptoKeyEngine::maker);
       DNSCryptoKeyEngine::report(10, &OpenSSLRSADNSCryptoKeyEngine::maker);
-#ifdef HAVE_OPENSSL_ECDSA
+#ifdef HAVE_LIBCRYPTO_ECDSA
       DNSCryptoKeyEngine::report(13, &OpenSSLECDSADNSCryptoKeyEngine::maker);
       DNSCryptoKeyEngine::report(14, &OpenSSLECDSADNSCryptoKeyEngine::maker);
 #endif
index e85421fb3b7ded1e7d6e17c64d2ea00d81e680e5..b8c4a023762ee7bc449ecb1312d7fc84f46f4b24 100644 (file)
@@ -700,7 +700,8 @@ void PacketHandler::addNSEC(DNSPacket *p, DNSPacket *r, const DNSName& target, c
 
   DNSName before,after;
   sd.db->getBeforeAndAfterNames(sd.domain_id, auth, target, before, after);
-  emitNSEC(r, sd, before, after, mode);
+  if (mode != 5 || before == target)
+    emitNSEC(r, sd, before, after, mode);
 
   if (mode == 2 || mode == 4) {
     // wildcard NO-DATA or wildcard denial
@@ -759,15 +760,20 @@ int PacketHandler::trySuperMaster(DNSPacket *p, const DNSName& tsigkeyname)
 
 int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigkeyname)
 {
+  string remote = p->getRemote().toString();
+  if(p->hasEDNSSubnet() && ::arg().contains("trusted-notification-proxy", remote)) {
+    remote = p->getRealRemote().toStringNoMask();
+  }
+
   Resolver::res_t nsset;
   try {
     Resolver resolver;
     uint32_t theirserial;
-    resolver.getSoaSerial(p->getRemote().toString(),p->qdomain, &theirserial);
-    resolver.resolve(p->getRemote().toString(), p->qdomain, QType::NS, &nsset);
+    resolver.getSoaSerial(remote,p->qdomain, &theirserial);
+    resolver.resolve(remote, 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;
+    L<<Logger::Error<<"Error resolving SOA or NS for "<<p->qdomain<<" at: "<< remote <<": "<<re.reason<<endl;
     return RCode::ServFail;
   }
 
@@ -779,7 +785,7 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigke
   }
 
   if(!haveNS) {
-    L<<Logger::Error<<"While checking for supermaster, did not find NS for "<<p->qdomain<<" at: "<< p->getRemote()<<endl;
+    L<<Logger::Error<<"While checking for supermaster, did not find NS for "<<p->qdomain<<" at: "<< remote <<endl;
     return RCode::ServFail;
   }
 
@@ -787,12 +793,12 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigke
   DNSBackend *db;
 
   if (!::arg().mustDo("allow-unsigned-supermaster") && tsigkeyname.empty()) {
-    L<<Logger::Error<<"Received unsigned NOTIFY for "<<p->qdomain<<" from potential supermaster "<<p->getRemote()<<". Refusing."<<endl;
+    L<<Logger::Error<<"Received unsigned NOTIFY for "<<p->qdomain<<" from potential supermaster "<<remote<<". Refusing."<<endl;
     return RCode::Refused;
   }
 
-  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;
+  if(!B.superMasterBackend(remote, p->qdomain, nsset, &nameserver, &account, &db)) {
+    L<<Logger::Error<<"Unable to find backend willing to host "<<p->qdomain<<" for potential supermaster "<<remote<<". Remote nameservers: "<<endl;
     for(const auto& rr: nsset) {
       if(rr.qtype.getCode()==QType::NS)
         L<<Logger::Error<<rr.content<<endl;
@@ -808,10 +814,10 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigke
     }
   }
   catch(PDNSException& ae) {
-    L<<Logger::Error<<"Database error trying to create "<<p->qdomain<<" for potential supermaster "<<p->getRemote()<<": "<<ae.reason<<endl;
+    L<<Logger::Error<<"Database error trying to create "<<p->qdomain<<" for potential supermaster "<<remote<<": "<<ae.reason<<endl;
     return RCode::ServFail;
   }
-  L<<Logger::Warning<<"Created new slave zone '"<<p->qdomain<<"' from supermaster "<<p->getRemote()<<endl;
+  L<<Logger::Warning<<"Created new slave zone '"<<p->qdomain<<"' from supermaster "<<remote<<endl;
   return RCode::NoError;
 }
 
@@ -996,7 +1002,7 @@ void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const DNSName& targe
   if(d_dk.isSecuredZone(sd.qname))
     addNSECX(p, r, target, wildcard, sd.qname, mode);
 
-  S.ringAccount("noerror-queries",p->qdomain.toString()+"/"+p->qtype.getName());
+  S.ringAccount("noerror-queries",p->qdomain.toLogString()+"/"+p->qtype.getName());
 }
 
 
@@ -1325,7 +1331,8 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
     // this TRUMPS a cname!
     if(p->qtype.getCode() == QType::NSEC && d_dk.isSecuredZone(sd.qname) && !d_dk.getNSEC3PARAM(sd.qname, 0)) {
       addNSEC(p, r, target, DNSName(), sd.qname, 5);
-      goto sendit;
+      if (!r->isEmpty())
+        goto sendit;
     }
 
     // this TRUMPS a cname!
@@ -1511,7 +1518,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
     r=p->replyPacket(); // generate an empty reply packet
     r->setRcode(RCode::ServFail);
     S.inc("servfail-packets");
-    S.ringAccount("servfail-queries",p->qdomain.toString());
+    S.ringAccount("servfail-queries",p->qdomain.toLogString());
   }
   catch(PDNSException &e) {
     L<<Logger::Error<<"Backend reported permanent error which prevented lookup ("+e.reason+"), aborting"<<endl;
@@ -1523,7 +1530,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
     r=p->replyPacket(); // generate an empty reply packet
     r->setRcode(RCode::ServFail);
     S.inc("servfail-packets");
-    S.ringAccount("servfail-queries",p->qdomain.toString());
+    S.ringAccount("servfail-queries",p->qdomain.toLogString());
   }
   return r; 
 
index 248fd608defc8ac443bd9c782d675e89bc9fed8d..d04fa2540b1a702a88d2fbd577e822034080d540 100644 (file)
@@ -151,6 +151,8 @@ std::string DNSProtoBufMessage::toDebugString() const
 {
 #ifdef HAVE_PROTOBUF
   return d_message.DebugString();
+#else
+  return std::string();
 #endif /* HAVE_PROTOBUF */
 }
 
index e6c07b0e311919451b629c65cc408eae9d3eaf41..73822342e17c9f267d5b5c29cfececda2a64dbd0 100644 (file)
@@ -14,6 +14,7 @@
 #include "rpzloader.hh"
 #include "base64.hh"
 #include "remote_logger.hh"
+#include "validate.hh"
 
 GlobalStateHolder<LuaConfigItems> g_luaconfs; 
 
@@ -32,9 +33,8 @@ GlobalStateHolder<LuaConfigItems> g_luaconfs;
 
 LuaConfigItems::LuaConfigItems()
 {
-  auto ds=std::unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make("19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5")));
-  // this hurts physically
-  dsAnchors[DNSName(".")] = *ds;
+  auto ds=unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make("19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5")));
+  dsAnchors[DNSName(".")].insert(*ds);
 }
 
 /* DID YOU READ THE STORY ABOVE? */
@@ -219,8 +219,10 @@ void loadRecursorLuaConfig(const std::string& fname)
                    });
 
   Lua.writeFunction("addDS", [&lci](const std::string& who, const std::string& what) {
-      lci.dsAnchors[DNSName(who)]= *std::unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(what)));
-    });
+      DNSName zone(who);
+      auto ds = unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(what)));
+      lci.dsAnchors[zone].insert(*ds);
+  });
 
   Lua.writeFunction("clearDS", [&lci](boost::optional<string> who) {
       if(who)
index a4207cbaeb9ce81b2530c143f0efe2813f876ec6..3b3a083903958ed5b9aea00630cca47d1b95fd9f 100644 (file)
@@ -3,6 +3,7 @@
 #include "sortlist.hh"
 #include "filterpo.hh"
 #include "remote_logger.hh"
+#include "validate.hh"
 
 class LuaConfigItems 
 {
@@ -10,7 +11,7 @@ public:
   LuaConfigItems();
   SortList sortlist;
   DNSFilterEngine dfe;
-  map<DNSName,DSRecordContent> dsAnchors;
+  map<DNSName,dsmap_t> dsAnchors;
   map<DNSName,std::string> negAnchors;
   std::shared_ptr<RemoteLogger> protobufServer{nullptr};
   uint8_t protobufMaskV4{32};
index a209e822a67aa4d99a8b23496ccf76c7f4726d2a..1e8e77a50798c1a1c10e6960d9015a132ec911c1 100644 (file)
@@ -489,7 +489,8 @@ string doAddTA(T begin, T end)
   try {
     L<<Logger::Warning<<"Adding Trust Anchor for "<<who<<" with data '"<<what<<"', requested via control channel";
     g_luaconfs.modify([who, what](LuaConfigItems& lci) {
-      lci.dsAnchors[who] = *std::unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(what)));
+      auto ds = unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(what)));
+      lci.dsAnchors[who].insert(*ds);
       });
     broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true));
     L<<Logger::Warning<<endl;
@@ -546,8 +547,13 @@ static string getTAs()
 {
   string ret("Configured Trust Anchors:\n");
   auto luaconf = g_luaconfs.getLocal();
-  for (auto anchor : luaconf->dsAnchors)
-    ret += anchor.first.toLogString() + "\t" + anchor.second.getZoneRepresentation() + "\n";
+  for (auto anchor : luaconf->dsAnchors) {
+    ret += anchor.first.toLogString() + "\n";
+    for (auto e : anchor.second) {
+      ret+="\t\t"+e.getZoneRepresentation() + "\n";
+    }
+  }
+
   return ret;
 }
 
@@ -593,7 +599,7 @@ static string* pleaseGetCurrentQueries()
   for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end() && n < 100; ++mthread, ++n) {
     const PacketID& pident = mthread->key;
     ostr << (fmt 
-             % pident.domain.toString() /* ?? */ % DNSRecordContent::NumberToType(pident.type) 
+             % pident.domain.toLogString() /* ?? */ % DNSRecordContent::NumberToType(pident.type) 
              % pident.remote.toString() % (pident.sock ? 'Y' : 'n')
              % (pident.fd == -1 ? 'Y' : 'n')
              );
index ab5809c29c867e3d730993bd2d71296b8292eba0..dbed2fad116cf8feb79a0e3c5815b09f8cbc8f97 100644 (file)
@@ -6,7 +6,7 @@ AM_CPPFLAGS += \
        -I$(top_srcdir)/ext/json11 \
        -I$(top_srcdir)/ext/rapidjson/include \
        $(YAHTTP_CFLAGS) \
-       $(OPENSSL_INCLUDES)
+       $(LIBCRYPTO_INCLUDES)
 
 AM_CXXFLAGS = \
        -DSYSCONFDIR=\"$(sysconfdir)\" \
@@ -145,13 +145,13 @@ endif
 pdns_recursor_LDADD = \
        $(YAHTTP_LIBS) \
        $(JSON11_LIBS) \
-       $(OPENSSL_LIBS) \
+       $(LIBCRYPTO_LIBS) \
        $(BOOST_CONTEXT_LIBS) \
        $(SYSTEMD_LIBS) \
        $(RT_LIBS)
 
 pdns_recursor_LDFLAGS = $(AM_LDFLAGS) \
-       $(OPENSSL_LDFLAGS)
+       $(LIBCRYPTO_LDFLAGS)
 
 if BOTAN110
 pdns_recursor_SOURCES += \
index 0ee0c5a17e607c1737840ca9c1c0564021196549..2b563934bc70ebc9031ce3543b217886a37fc32d 100644 (file)
@@ -98,10 +98,12 @@ PDNS_ENABLE_VERBOSE_LOGGING
 
 # Crypto libraries
 PDNS_ENABLE_BOTAN
-AX_CHECK_OPENSSL([
+PDNS_CHECK_LIBCRYPTO([
 ],[
-  AC_MSG_ERROR([OpenSSL not found])
-])
+   AC_MSG_ERROR([OpenSSL/libcrypto not found])
+  ]
+)
+PDNS_CHECK_LIBCRYPTO_ECDSA
 
 # check for tools we might need
 PDNS_CHECK_RAGEL
@@ -187,6 +189,7 @@ AS_IF([test "x$LUAPC" != "x"],
     [AC_MSG_NOTICE([LuaJit: $LUAJITPC])],
     [AC_MSG_NOTICE([Lua/LuaJit: no])])
 ])
+AC_MSG_NOTICE([OpenSSL ECDSA: $libcrypto_ecdsa])
 AS_IF([test "x$PROTOBUF_LIBS" != "x" -a x"$PROTOC" != "x"],
   [AC_MSG_NOTICE([Protobuf: yes])],
   [AC_MSG_NOTICE([Protobuf: no])]
diff --git a/pdns/recursordist/m4/ax_check_openssl.m4 b/pdns/recursordist/m4/ax_check_openssl.m4
deleted file mode 120000 (symlink)
index f33eaf4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../m4/ax_check_openssl.m4
\ No newline at end of file
diff --git a/pdns/recursordist/m4/pdns_check_libcrypto.m4 b/pdns/recursordist/m4/pdns_check_libcrypto.m4
new file mode 120000 (symlink)
index 0000000..b56d43a
--- /dev/null
@@ -0,0 +1 @@
+../../../m4/pdns_check_libcrypto.m4
\ No newline at end of file
diff --git a/pdns/recursordist/m4/pdns_check_libcrypto_ecdsa.m4 b/pdns/recursordist/m4/pdns_check_libcrypto_ecdsa.m4
new file mode 120000 (symlink)
index 0000000..5715217
--- /dev/null
@@ -0,0 +1 @@
+../../../m4/pdns_check_libcrypto_ecdsa.m4
\ No newline at end of file
index 8af59d0398a51a643c8af1ea7bae3f4dcff5c0a3..2112dce2a6cc58a996f7c6cc2aaf98a483de18df 100644 (file)
@@ -24,9 +24,9 @@ void ResponseStats::submitResponse(DNSPacket &p, bool udpOrTCP) {
 
   if(p.d.aa) {
     if (p.d.rcode==RCode::NXDomain)
-      S.ringAccount("nxdomain-queries",p.qdomain.toString()+"/"+p.qtype.getName());
+      S.ringAccount("nxdomain-queries",p.qdomain.toLogString()+"/"+p.qtype.getName());
   } else if (p.isEmpty()) {
-    S.ringAccount("unauth-queries",p.qdomain.toString()+"/"+p.qtype.getName());
+    S.ringAccount("unauth-queries",p.qdomain.toLogString()+"/"+p.qtype.getName());
     S.ringAccount("remotes-unauth",p.d_remote);
   }
 
index bccfd4a8f2748f660b4a55f23ea3b54f167bb5d7..4266445644033f7553c481f3dd90c5d48c65bbf3 100644 (file)
@@ -6,6 +6,7 @@
 #include "logger.hh"
 #include "arguments.hh"
 #include "version.hh"
+#include "validate-recursor.hh"
 
 #include <stdint.h>
 #ifndef PACKAGEVERSION 
@@ -20,13 +21,15 @@ void doSecPoll(time_t* last_secpoll)
   if(::arg()["security-poll-suffix"].empty())
     return;
 
+  string pkgv(PACKAGEVERSION);
   struct timeval now;
   gettimeofday(&now, 0);
   SyncRes sr(now);
-  sr.d_doDNSSEC=true;
+  if (g_dnssecmode != DNSSECMode::Off)
+    sr.d_doDNSSEC=true;
   vector<DNSRecord> ret;
 
-  string version = "recursor-" +string(PACKAGEVERSION);
+  string version = "recursor-" +pkgv;
   string qstring(version.substr(0, 63)+ ".security-status."+::arg()["security-poll-suffix"]);
 
   if(*qstring.rbegin()!='.')
@@ -35,8 +38,20 @@ void doSecPoll(time_t* last_secpoll)
   boost::replace_all(qstring, "+", "_");
   boost::replace_all(qstring, "~", "_");
 
+  vState state = Indeterminate;
   DNSName query(qstring);
   int res=sr.beginResolve(query, QType(QType::TXT), 1, ret);
+
+  if (g_dnssecmode != DNSSECMode::Off && res)
+    state = validateRecords(ret);
+
+  if(state == Bogus) {
+    L<<Logger::Error<<"Could not retrieve security status update for '" +pkgv+ "' on '"<<query<<"', DNSSEC validation result was Bogus!"<<endl;
+    if(g_security_status == 1) // If we were OK, go to unknown
+      g_security_status = 0;
+    return;
+  }
+
   if(!res && !ret.empty()) {
     string content=ret.begin()->d_content->getZoneRepresentation();
     if(!content.empty() && content[0]=='"' && content[content.size()-1]=='"') {
@@ -51,15 +66,14 @@ void doSecPoll(time_t* last_secpoll)
     *last_secpoll=now.tv_sec;
   }
   else {
-    string pkgv(PACKAGEVERSION);
     if(pkgv.find("0.0."))
       L<<Logger::Warning<<"Could not retrieve security status update for '" +pkgv+ "' on '"<<query<<"', RCODE = "<< RCode::to_s(res)<<endl;
     else
-      L<<Logger::Warning<<"Not validating response for security status update, this a non-release version."<<endl;
+      L<<Logger::Warning<<"Ignoring response for security status update, this a non-release version."<<endl;
 
-    if(g_security_status == 1) // it was ok, not it is unknown
+    if(g_security_status == 1) // it was ok, now it is unknown
       g_security_status = 0;
-    if(res == RCode::NXDomain) // if we had servfail, keep on trying more more frequently
+    if(res == RCode::NXDomain) // if we had NXDOMAIN, keep on trying more more frequently
       *last_secpoll=now.tv_sec; 
   }
 
index 42f9002f29614d64d27f67ccc496f8e637cb279a..fefe41460954c9a93305be29b10d22bc0c2ff317 100644 (file)
@@ -101,8 +101,7 @@ GlobalStateHolder<LuaConfigItems> g_luaconfs;
 LuaConfigItems::LuaConfigItems()
 {
   auto ds=std::unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make("19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5")));
-  // this hurts physically
-  dsAnchors[DNSName(".")] = *ds;
+  dsAnchors[DNSName(".")].insert(*ds);
 }
 
 DNSFilterEngine::DNSFilterEngine() {}
index f3a94dc78781919d83815a51808fbb16e8f50e6f..e1bf751bb21eb67e34dbaa36a8f2431d7bb57363 100644 (file)
@@ -204,7 +204,6 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset)
 
   vector<string> labels = zone.getRawLabels();
 
-  typedef std::multimap<uint16_t, DSRecordContent> dsmap_t;
   dsmap_t dsmap;
   keyset_t validkeys;
 
@@ -213,18 +212,17 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset)
 
   while(zone.isPartOf(qname))
   {
-    if(auto ds = rplookup(luaLocal->dsAnchors, qname))
-    {
-      dsmap.insert(make_pair(ds->d_tag, *ds));
-    }
-  
+    dsmap_t* tmp = (dsmap_t*) rplookup(luaLocal->dsAnchors, qname);
+    if (tmp)
+      dsmap = *tmp;
+
     vector<RRSIGRecordContent> sigs;
     vector<shared_ptr<DNSRecordContent> > toSign;
     vector<uint16_t> toSignTags;
 
     keyset_t tkeys; // tentative keys
     validkeys.clear();
-    
+
     // start of this iteration
     // we can trust that dsmap has valid DS records for qname
 
@@ -258,13 +256,12 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset)
     }
     LOG("got "<<tkeys.size()<<" keys and "<<sigs.size()<<" sigs from server"<<endl);
 
-    for(dsmap_t::const_iterator i=dsmap.begin(); i!=dsmap.end(); i++)
+    for(auto const& dsrc : dsmap)
     {
-      DSRecordContent dsrc=i->second;
-      auto r = getByTag(tkeys, i->first);
+      auto r = getByTag(tkeys, dsrc.d_tag);
       //      cerr<<"looking at DS with tag "<<dsrc.d_tag<<"/"<<i->first<<", got "<<r.size()<<" DNSKEYs for tag"<<endl;
 
-      for(const auto& drc : r) 
+      for(const auto& drc : r)
       {
        bool isValid = false;
        DSRecordContent dsrc2;
@@ -277,7 +274,7 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset)
        }
 
         if(isValid) {
-         LOG("got valid DNSKEY (it matches the DS) with tag "<<dsrc.d_tag<<"/"<<i->first<<" for "<<qname<<endl);
+         LOG("got valid DNSKEY (it matches the DS) with tag "<<dsrc.d_tag<<" for "<<qname<<endl);
          
           validkeys.insert(drc);
          dotNode("DS", qname, "" /*std::to_string(dsrc.d_tag)*/, (boost::format("tag=%d, digest algo=%d, algo=%d") % dsrc.d_tag % static_cast<int>(dsrc.d_digesttype) % static_cast<int>(dsrc.d_algorithm)).str());
@@ -436,7 +433,7 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset)
         {
           const auto dsrc=std::dynamic_pointer_cast<DSRecordContent>(*j);
           if(dsrc) {
-            dsmap.insert(make_pair(dsrc->d_tag, *dsrc));
+            dsmap.insert(*dsrc);
             // dotEdge(keyqname,
             //         "DNSKEY", keyqname, ,
             //         "DS", qname, std::to_string(dsrc.d_tag));
index a0a7f3578247611d394109000eb40f04e596fa10..00c555dda0f506386df75711a7cba5541e4ba745 100644 (file)
@@ -31,6 +31,7 @@ struct ContentSigPair
   // ponder adding a validate method that accepts a key
 };
 typedef map<pair<DNSName,uint16_t>, ContentSigPair> cspmap_t;
+typedef std::set<DSRecordContent> dsmap_t;
 void validateWithKeySet(const cspmap_t& rrsets, cspmap_t& validated, const std::set<DNSKEYRecordContent>& keys);
 cspmap_t harvestCSPFromRecs(const vector<DNSRecord>& recs);
 vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, std::set<DNSKEYRecordContent> &keyset);
index d1f8bacf794bc954e5ea15a0dc3ae0a06533b37b..c4f4becba4f7c13a79f38541e69853f315db608b 100644 (file)
@@ -452,8 +452,12 @@ bool ZoneParserTNG::get(DNSResourceRecord& rr, std::string* comment)
     if(recparts.size() > 7)
       throw PDNSException("SOA record contents for "+rr.qname.toString()+" contains too many parts");
     if(recparts.size() > 1) {
-      recparts[0]=toCanonic(d_zonename, recparts[0]).toStringRootDot();
-      recparts[1]=toCanonic(d_zonename, recparts[1]).toStringRootDot();
+      try {
+        recparts[0]=toCanonic(d_zonename, recparts[0]).toStringRootDot();
+        recparts[1]=toCanonic(d_zonename, recparts[1]).toStringRootDot();
+      } catch (runtime_error &re) {
+        throw PDNSException(re.what());
+      }
     }
     rr.content.clear();
     for(string::size_type n = 0; n < recparts.size(); ++n) {
diff --git a/regression-tests/tests/direct-nsec-nxdomain/command b/regression-tests/tests/direct-nsec-nxdomain/command
new file mode 100755 (executable)
index 0000000..79f0b35
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+cleandig host-1234x.example.com NSEC dnssec
diff --git a/regression-tests/tests/direct-nsec-nxdomain/description b/regression-tests/tests/direct-nsec-nxdomain/description
new file mode 100644 (file)
index 0000000..ed16d8a
--- /dev/null
@@ -0,0 +1 @@
+Make sure we send a proper denial for nonexistent NSEC records
diff --git a/regression-tests/tests/direct-nsec-nxdomain/expected_result b/regression-tests/tests/direct-nsec-nxdomain/expected_result
new file mode 100644 (file)
index 0000000..eb7ac3e
--- /dev/null
@@ -0,0 +1,4 @@
+1      example.com.    IN      SOA     86400   ns1.example.com. ahu.example.com. 2847484148 28800 7200 604800 86400
+2      .       IN      OPT     32768   
+Rcode: 3 (Non-Existent domain), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='host-1234x.example.com.', qtype=NSEC
diff --git a/regression-tests/tests/direct-nsec-nxdomain/expected_result.dnssec b/regression-tests/tests/direct-nsec-nxdomain/expected_result.dnssec
new file mode 100644 (file)
index 0000000..15ec6c7
--- /dev/null
@@ -0,0 +1,9 @@
+1      example.com.    IN      NSEC    86400   double.example.com. NS SOA MX RRSIG NSEC DNSKEY
+1      example.com.    IN      RRSIG   86400   NSEC 13 2 86400 [expiry] [inception] [keytag] example.com. ...
+1      example.com.    IN      RRSIG   86400   SOA 13 2 100000 [expiry] [inception] [keytag] example.com. ...
+1      example.com.    IN      SOA     86400   ns1.example.com. ahu.example.com. 2847484148 28800 7200 604800 86400
+1      host-12349.example.com. IN      NSEC    86400   host-1235.example.com. A RRSIG NSEC
+1      host-12349.example.com. IN      RRSIG   86400   NSEC 13 3 86400 [expiry] [inception] [keytag] example.com. ...
+2      .       IN      OPT     32768   
+Rcode: 3 (Non-Existent domain), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='host-1234x.example.com.', qtype=NSEC
diff --git a/regression-tests/tests/direct-nsec-nxdomain/expected_result.narrow b/regression-tests/tests/direct-nsec-nxdomain/expected_result.narrow
new file mode 100644 (file)
index 0000000..7e49a11
--- /dev/null
@@ -0,0 +1,11 @@
+1      4jiv8rrf3verm9rp51f55587fbfms5g9.example.com.   IN      NSEC3   86400   1 [flags] 1 abcd 4JIV8RRF3VERM9RP51F55587FBFMS5GB
+1      4jiv8rrf3verm9rp51f55587fbfms5g9.example.com.   IN      RRSIG   86400   NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ...
+1      9fag9508oqu3m22qac0u5eqgg45v8cf0.example.com.   IN      NSEC3   86400   1 [flags] 1 abcd 9FAG9508OQU3M22QAC0U5EQGG45V8CF2
+1      9fag9508oqu3m22qac0u5eqgg45v8cf0.example.com.   IN      RRSIG   86400   NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ...
+1      example.com.    IN      RRSIG   86400   SOA 13 2 100000 [expiry] [inception] [keytag] example.com. ...
+1      example.com.    IN      SOA     86400   ns1.example.com. ahu.example.com. 2847484148 28800 7200 604800 86400
+1      vtnq6ocn2vkuiv3nju14oqtaen2mt5sk.example.com.   IN      NSEC3   86400   1 [flags] 1 abcd VTNQ6OCN2VKUIV3NJU14OQTAEN2MT5SL NS SOA MX RRSIG DNSKEY NSEC3PARAM
+1      vtnq6ocn2vkuiv3nju14oqtaen2mt5sk.example.com.   IN      RRSIG   86400   NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ...
+2      .       IN      OPT     32768   
+Rcode: 3 (Non-Existent domain), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='host-1234x.example.com.', qtype=NSEC
diff --git a/regression-tests/tests/direct-nsec-nxdomain/expected_result.nsec3 b/regression-tests/tests/direct-nsec-nxdomain/expected_result.nsec3
new file mode 100644 (file)
index 0000000..5f40ba9
--- /dev/null
@@ -0,0 +1,11 @@
+1      4j9ti2b4c7iibemvegh99nmoe5m72rb6.example.com.   IN      NSEC3   86400   1 [flags] 1 abcd 4JKT13JQPK715SGVL9KSRFVACKO95SV4 A RRSIG
+1      4j9ti2b4c7iibemvegh99nmoe5m72rb6.example.com.   IN      RRSIG   86400   NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ...
+1      9f8hti7cc7oqnqjv84klnp89glqrss3r.example.com.   IN      NSEC3   86400   1 [flags] 1 abcd 9FDAOFPLLN0FQFU9DP274GOU59QFHSLD A RRSIG
+1      9f8hti7cc7oqnqjv84klnp89glqrss3r.example.com.   IN      RRSIG   86400   NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ...
+1      example.com.    IN      RRSIG   86400   SOA 13 2 100000 [expiry] [inception] [keytag] example.com. ...
+1      example.com.    IN      SOA     86400   ns1.example.com. ahu.example.com. 2847484148 28800 7200 604800 86400
+1      vtnq6ocn2vkuiv3nju14oqtaen2mt5sk.example.com.   IN      NSEC3   86400   1 [flags] 1 abcd VTP9NUQBEH436S7J0K8TI2A32MMKCUUL NS SOA MX RRSIG DNSKEY NSEC3PARAM
+1      vtnq6ocn2vkuiv3nju14oqtaen2mt5sk.example.com.   IN      RRSIG   86400   NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ...
+2      .       IN      OPT     32768   
+Rcode: 3 (Non-Existent domain), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='host-1234x.example.com.', qtype=NSEC