Compare commits

...
Author SHA1 Message Date
Willem Toorop c834ee635c Fix function signature for compiling test 2025-11-03 11:15:11 +01:00
Willem Toorop 7977ef28f5 distribute can send out responses tsig signed 2025-11-01 14:32:09 +01:00
Willem Toorop c86c267b8b Forgot to include util/allow_response_list.[ch] 2025-11-01 13:12:35 +01:00
Willem Toorop 3963af8d0b configurable ranges and tsig to allow responses
Configurable with the "allow-response:" option in the "server:" section.
Usage:
	allow-response: <IP netblock> <tsig key-name | NOKEY | BLOCKED>
2025-11-01 12:52:48 +01:00
Willem Toorop 3d6a4c7d6e Const string for tsig lookups 2025-10-31 15:45:34 +01:00
Willem Toorop 2217c9b96e Merge branch 'master' into update-with-branches/poisonlicious 2025-10-30 09:48:57 +01:00
Willem Toorop 6592c73d56 Merge branch 'xfr-tsig' into update-with-branches/poisonlicious 2025-10-30 09:45:11 +01:00
W.C.A. Wijngaards 8687d69131 Merge branch 'master' into xfr-tsig 2025-10-01 15:52:40 +02:00
W.C.A. Wijngaards c622a71a28 - xfr-tsig, flip buffer after tsig_sign_reply, but not for error_encode. 2025-10-01 15:52:15 +02:00
W.C.A. Wijngaards ecfc6a70ce - xfr-tsig, note tsig-key support for fast_reload. 2025-09-12 16:38:09 +02:00
W.C.A. Wijngaards a23c5347a7 - xfr-tsig, unit test shows zonefile that is created. 2025-09-12 15:43:45 +02:00
W.C.A. Wijngaards 1ae8be6847 - xfr-tsig, fast reload support for tsig keys. 2025-09-12 15:38:39 +02:00
W.C.A. Wijngaards f0268d3e83 - xfr-tsig, log TSIG key name with zone and notify information. Clear tsig
data before making a new one.
2025-09-12 14:58:49 +02:00
W.C.A. Wijngaards c904a3d375 - xfr-tsig, remove rpl unit test. 2025-09-12 11:23:29 +02:00
W.C.A. Wijngaards b451cc4af7 - xfr-tsig, add tdir test that performs tsig signed zone transfer. 2025-09-12 10:40:23 +02:00
W.C.A. Wijngaards f9713f9fe5 Merge branch 'master' into xfr-tsig 2025-09-12 09:27:23 +02:00
W.C.A. Wijngaards dfac72edfc - xfr-tsig, unit test use to make tsig for rpl. 2025-09-11 17:05:58 +02:00
W.C.A. Wijngaards 64e102aacb - xfr-tsig, fix notify tsig answer, fix parse edns allows TSIG,
unit test for auth zone with notify with tsig and notify answer with tsig.
2025-09-11 16:21:38 +02:00
W.C.A. Wijngaards bebd6c0f96 - xfr-tsig, use tsig_parse_verify_reply_xfr for zone transfers with TSIG. 2025-09-10 15:45:37 +02:00
W.C.A. Wijngaards 63aa70ab32 - xfr-tsig, unit test for tsig sign every couple packets, and verify that. 2025-09-10 15:26:57 +02:00
W.C.A. Wijngaards 7b59014ba3 - xfr-tsig, unit test with another trace of tsig every couple packets. 2025-09-09 16:24:55 +02:00
W.C.A. Wijngaards 156846e6c4 - xfr-tsig, unit test to verify tsig every couple packets. 2025-09-09 15:50:14 +02:00
W.C.A. Wijngaards aea2a821b9 - xfr-tsig, unit test for tsig-verify-reply-xfr, with output that works
with dig and NSD.
2025-09-09 15:40:51 +02:00
W.C.A. Wijngaards cacdfee755 Merge branch 'master' into xfr-tsig 2025-09-09 14:38:03 +02:00
W.C.A. Wijngaards e3c1981a6a - xfr-tsig, fix algorithm name write in xfr reply tsig and unit test
that works with output that works with dig and NSD.
2025-09-09 14:36:33 +02:00
W.C.A. Wijngaards e2efd17007 - xfr-tsig, unit test tsig-sign-reply-xfr implementation. 2025-09-05 16:45:15 +02:00
W.C.A. Wijngaards 4a2dc1df48 Merge branch 'master' into xfr-tsig 2025-09-05 15:00:31 +02:00
W.C.A. Wijngaards 5c79fd9a0b - xfr-tsig, tsig_parse_verify_reply_xfr and tsig_sign_reply_xfr. 2025-09-05 14:55:36 +02:00
W.C.A. Wijngaards 4a3a4f474f Merge branch 'master' into xfr-tsig 2025-08-27 16:30:03 +02:00
W.C.A. Wijngaards 708581579c - xfr-tsig, add test case with AXFR packet with TSIG. 2025-08-27 15:52:08 +02:00
W.C.A. Wijngaards af1d430759 - xfr-tsig, log rcode for received notifies. 2025-08-20 15:55:29 +02:00
W.C.A. Wijngaards da72734240 - xfr-tsig, tsig_get_mem function. 2025-08-19 16:46:12 +02:00
W.C.A. Wijngaards 54175a4180 Merge branch 'master' into xfr-tsig 2025-08-19 15:27:43 +02:00
W.C.A. Wijngaards 888d5ce9f9 - xfr-tsig, TSIG for SOA probe, notify, and on xfr first packet. 2025-08-19 15:27:16 +02:00
W.C.A. Wijngaards b1bb4a4592 - xfr-tsig, check that tsig keys exist at startup and in unbound-checkconf. 2025-07-31 17:02:55 +02:00
W.C.A. Wijngaards 3b88577dd1 Merge branch 'master' into xfr-tsig 2025-07-31 15:59:25 +02:00
W.C.A. Wijngaards 6634b8bcc5 - xfr-tsig, primary-tsig: addr tsig and allow-notify-tsig: addr tsig. 2025-07-31 14:43:43 +02:00
W.C.A. Wijngaards 3d7dfe2f36 - xfr-tsig, unit test for tsig_verify_reply for failed tsig. 2025-07-23 16:35:25 +02:00
W.C.A. Wijngaards baee7885bd Merge branch 'master' into xfr-tsig 2025-07-23 16:23:58 +02:00
W.C.A. Wijngaards e55b3a2a4c - xfr-tsig, unit test for tsig_verify_reply. 2025-07-23 16:16:41 +02:00
Willem Toorop b5a2de1292 allow-response: config option 2025-07-20 13:30:29 +02:00
Willem Toorop 5ed0840dc2 Poisonlicious PoC with new tsig code 2025-07-19 15:19:00 +02:00
Willem Toorop 9bbb34fc38 Link tsig.lo only once 2025-07-19 15:11:15 +02:00
Willem Toorop 433bb1c7bc Merge branch 'updated-with-master/xfr-tsig' into hackathon/poisonlicious-new-tsig-code 2025-07-19 15:02:30 +02:00
Willem Toorop f3b960e72b Merge branch 'master' into xfr-tsig-update 2025-07-19 14:42:44 +02:00
Willem Toorop 5bd31c9569 A typo and a reorder (without impact) 2025-07-19 14:35:38 +02:00
Willem Toorop 4f245e0e5b Merge branch 'master' into hackathon/poisonlicious-update 2025-07-19 14:23:50 +02:00
W.C.A. Wijngaards e4069e5619 Merge branch 'master' into xfr-tsig 2025-07-11 15:27:40 +02:00
W.C.A. Wijngaards a3ec9a974f - xfr-tsig, member comments for struct tsig_calc_state_crypto. 2025-07-11 15:18:11 +02:00
W.C.A. Wijngaards 479b954118 - xfr-tsig, implemented tsig_calc_state_crypto. 2025-07-11 10:08:48 +02:00
W.C.A. Wijngaards 0955238cd3 - xfr-tsig, tsig_verify_reply function. 2025-06-27 14:26:15 +02:00
W.C.A. Wijngaards 57dd6a971d - xfr-tsig, extra unit tests for tsig_sign_reply. 2025-06-27 11:29:41 +02:00
W.C.A. Wijngaards 6a831e3063 - xfr-tsig, more explanation in testcode/unittsig.c. 2025-06-27 11:03:25 +02:00
W.C.A. Wijngaards 3807bf00da - xfr-tsig, unit test for tsig_sign_reply. 2025-06-27 10:59:36 +02:00
W.C.A. Wijngaards 9022381be4 - xfr-tsig, more explanation in testcode/unittsig.c. 2025-06-27 09:29:57 +02:00
W.C.A. Wijngaards ca147a147d - xfr-tsig, unit test for tsig_sign_shared and tsig_verify_shared. 2025-06-27 09:24:51 +02:00
W.C.A. Wijngaards 5147e5aee9 - xfr-tsig, tsig_sign_shared function. 2025-06-27 08:52:32 +02:00
W.C.A. Wijngaards 6466513cc5 - xfr-tsig, unit test argument parse code. 2025-06-26 16:59:44 +02:00
W.C.A. Wijngaards 7a1a615fd3 - xfr-tsig, tsig_verify_shared function. 2025-06-26 15:11:25 +02:00
W.C.A. Wijngaards 81d774fb11 - xfr-tsig, tsig_sign_reply function. 2025-06-26 12:41:10 +02:00
W.C.A. Wijngaards 0254317e0d - xfr-tsig, fix unit test parse of tsig error code. 2025-06-25 14:52:16 +02:00
W.C.A. Wijngaards dc37849546 - xfr-tsig, test cases for BADTRUNC and not parseable. 2025-06-25 14:19:22 +02:00
W.C.A. Wijngaards 766666139b Merge branch 'master' into xfr-tsig 2025-06-25 14:05:06 +02:00
W.C.A. Wijngaards 86e78fcacc xfr-tsig, remove debug 2025-06-25 14:03:52 +02:00
W.C.A. Wijngaards 47a2d71fd3 - xfr-tsig, unit test cases for tsig errors. 2025-06-25 14:03:12 +02:00
W.C.A. Wijngaards 0719ef21fa - xfr-tsig, unit test for tsig_verify_query. 2025-06-25 12:06:15 +02:00
W.C.A. Wijngaards 6d5f22b56d - xfr-tsig, fix tsig_verify_query. 2025-06-25 10:21:42 +02:00
W.C.A. Wijngaards b5beb800c8 - xfr-tsig, tsig_find_rr function. 2025-06-24 16:51:41 +02:00
W.C.A. Wijngaards fe63b25441 - xfr-tsig, parse and verify query tsig. 2025-06-24 16:31:18 +02:00
W.C.A. Wijngaards 0afbb68b40 - xfr-tsig, other data content matches the other len when written. 2025-06-20 16:57:24 +02:00
W.C.A. Wijngaards 4562cd372c - xfr-tsig, whitespace. 2025-06-20 14:43:19 +02:00
W.C.A. Wijngaards 418ef3765d Merge branch 'master' into xfr-tsig 2025-06-20 14:33:02 +02:00
W.C.A. Wijngaards 29c8b3edba - xfr-tsig, unit tests for md5, sha1, sha224, sha256, sha384 and sha512. 2025-06-20 14:31:44 +02:00
W.C.A. Wijngaards 5214912555 Merge branch 'master' into xfr-tsig 2025-06-20 12:14:13 +02:00
W.C.A. Wijngaards f2c609b9a5 - xfr-tsig, unit test for tsig_sign_query. 2025-06-20 12:13:51 +02:00
W.C.A. Wijngaards aa22fd936e - xfr-tsig, test buffer size. 2025-06-18 17:01:35 +02:00
W.C.A. Wijngaards 4bbb74da39 - xfr-tsig, tsig test. 2025-06-18 16:41:10 +02:00
W.C.A. Wijngaards dd4ee42eb6 - xfr-tsig, tsig_sign_query. 2025-06-18 15:00:18 +02:00
W.C.A. Wijngaards 8b95785b8c - xfr-tsig, tsig functions. 2025-06-18 12:18:20 +02:00
W.C.A. Wijngaards bb4ddab77a Merge branch 'master' into xfr-tsig 2025-06-17 16:55:18 +02:00
W.C.A. Wijngaards 69354298fc - xfr-tsig, tsig_create and tsig_delete. 2025-06-17 16:54:52 +02:00
W.C.A. Wijngaards bbcf5d122a Merge branch 'master' into xfr-tsig 2025-06-16 17:00:12 +02:00
W.C.A. Wijngaards 497161f72f - xfr-tsig, tsig_verify return failure comment improved. 2025-06-16 16:59:53 +02:00
W.C.A. Wijngaards 31e8118b76 - xfr-tsig, man page and example config. 2025-06-13 16:32:36 +02:00
W.C.A. Wijngaards 8811bd4844 - xfr-tsig, tsig-key, with name, algorithm and secret options. 2025-06-13 12:12:49 +02:00
W.C.A. Wijngaards 0f02479dea - xfr-tsig, fix algorithm lookup. 2025-06-13 10:17:47 +02:00
W.C.A. Wijngaards 364edccebc - xfr-tsig, algorithm table. 2025-06-13 10:15:41 +02:00
W.C.A. Wijngaards 3d9242b3d3 - xfr-tsig, key table. 2025-06-12 16:05:10 +02:00
W.C.A. Wijngaards 3f378c962f - xfr-tsig, check rdata length in tsig verify. 2025-06-12 14:34:56 +02:00
W.C.A. Wijngaards 4ca37bcadf Merge branch 'master' into xfr-tsig 2025-06-12 12:17:13 +02:00
W.C.A. Wijngaards 19492da154 - xfr-tsig, check buffer remaining in tsig verify. 2025-06-12 11:50:11 +02:00
W.C.A. Wijngaards 182e580fe2 - xfr-tsig, fix warning in compile of declaration. 2025-06-12 09:57:23 +02:00
W.C.A. Wijngaards eefb417c09 - xfr-tsig, const for dname compare and fix warnings in compile. 2025-06-12 09:53:56 +02:00
W.C.A. Wijngaards 4fd0d84e66 - xfr-tsig, update header comment. 2025-06-12 09:49:20 +02:00
W.C.A. Wijngaards ea0973002f - xfr-tsig, constant time memcmp is used. 2025-06-12 09:34:07 +02:00
W.C.A. Wijngaards 8fcc4c98b6 Merge branch 'master' into xfr-tsig 2025-06-12 09:29:28 +02:00
W.C.A. Wijngaards 7edc1e0fc4 - xfr-tsig, import the tsig verify code from hackathon/poisonlicious branch. 2025-06-12 09:25:54 +02:00
Willem Toorop 3674e4813c A bit better TSIG handling 2025-03-25 16:46:42 +01:00
Willem Toorop 5d11af34dc Verification of incoming responses with TSIG
For now with a hardcoded TSIG key
2025-03-17 09:25:13 +01:00
Willem Toorop e29ee129a3 Fix CI 2025-03-16 10:17:53 +01:00
Willem Toorop 86526c75a3 Send responses just before they enter the cache
Configured with the `distribute:` option in the `server:` section in the config.
2025-03-16 09:21:11 +01:00
Willem Toorop d9d6dd31dc Store responses received on listen interface in cache 2025-03-15 16:22:29 +01:00
W.C.A. Wijngaards e6573fc337 - xfr-tsig, create util/tsig.c and util/tsig.h. 2023-04-14 14:05:15 +02:00
55 changed files with 9239 additions and 1239 deletions
+407 -556
View File
File diff suppressed because it is too large Load Diff
Vendored
+202 -146
View File
@@ -1,6 +1,6 @@
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,8 @@
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
#
# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
# Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software
# Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is free software; the Free Software Foundation gives
@@ -45,7 +46,7 @@ m4_define([_LT_COPYING], [dnl
# along with this program. If not, see <http://www.gnu.org/licenses/>.
])
# serial 58 LT_INIT
# serial 59 LT_INIT
# LT_PREREQ(VERSION)
@@ -195,6 +196,7 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
m4_require([_LT_CMD_RELOAD])dnl
m4_require([_LT_DECL_FILECMD])dnl
m4_require([_LT_CHECK_MAGIC_METHOD])dnl
m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
m4_require([_LT_CMD_OLD_ARCHIVE])dnl
@@ -233,8 +235,8 @@ esac
ofile=libtool
can_build_shared=yes
# All known linkers require a '.a' archive for static linking (except MSVC,
# which needs '.lib').
# All known linkers require a '.a' archive for static linking (except MSVC and
# ICC, which need '.lib').
libext=a
with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -736,7 +738,6 @@ _LT_CONFIG_SAVE_COMMANDS([
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services.
@@ -786,7 +787,7 @@ _LT_EOF
# if finds mixed CR/LF and LF-only lines. Since sed operates in
# text mode, it properly converts lines to CR/LF. This bash problem
# is reportedly fixed, but why not run on old versions too?
sed '$q' "$ltmain" >> "$cfgfile" \
$SED '$q' "$ltmain" >> "$cfgfile" \
|| (rm -f "$cfgfile"; exit 1)
mv -f "$cfgfile" "$ofile" ||
@@ -1048,8 +1049,8 @@ int forced_loaded() { return 2;}
_LT_EOF
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
$AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
$AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
cat > conftest.c << _LT_EOF
@@ -1073,17 +1074,12 @@ _LT_EOF
_lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
darwin1.*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
darwin*) # darwin 5.x on
# if running on 10.5 or later, the deployment target defaults
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
10.[[012]][[,.]]*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
10.*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
darwin*)
case $MACOSX_DEPLOYMENT_TARGET,$host in
10.[[012]],*|,*powerpc*-darwin[[5-8]]*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
esac
;;
esac
@@ -1132,12 +1128,12 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
output_verbose_link_cmd=func_echo_all
_LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
_LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
m4_if([$1], [CXX],
[ if test yes != "$lt_cv_apple_cc_single_mod"; then
_LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
fi
],[])
else
@@ -1251,7 +1247,8 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
# _LT_WITH_SYSROOT
# ----------------
AC_DEFUN([_LT_WITH_SYSROOT],
[AC_MSG_CHECKING([for sysroot])
[m4_require([_LT_DECL_SED])dnl
AC_MSG_CHECKING([for sysroot])
AC_ARG_WITH([sysroot],
[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
[Search for dependent libraries within DIR (or the compiler's sysroot
@@ -1268,7 +1265,7 @@ case $with_sysroot in #(
fi
;; #(
/*)
lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"`
;; #(
no|'')
;; #(
@@ -1298,7 +1295,7 @@ ia64-*-hpux*)
# options accordingly.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*ELF-32*)
HPUX_IA64_MODE=32
;;
@@ -1315,7 +1312,7 @@ ia64-*-hpux*)
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
if test yes = "$lt_cv_prog_gnu_ld"; then
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -melf32bsmip"
;;
@@ -1327,7 +1324,7 @@ ia64-*-hpux*)
;;
esac
else
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -32"
;;
@@ -1349,7 +1346,7 @@ mips64*-*linux*)
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
emul=elf
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*32-bit*)
emul="${emul}32"
;;
@@ -1357,7 +1354,7 @@ mips64*-*linux*)
emul="${emul}64"
;;
esac
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*MSB*)
emul="${emul}btsmip"
;;
@@ -1365,7 +1362,7 @@ mips64*-*linux*)
emul="${emul}ltsmip"
;;
esac
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*N32*)
emul="${emul}n32"
;;
@@ -1385,14 +1382,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# not appear in the list.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
case `$FILECMD conftest.o` in
*32-bit*)
case $host in
x86_64-*kfreebsd*-gnu)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
case `/usr/bin/file conftest.o` in
case `$FILECMD conftest.o` in
*x86-64*)
LD="${LD-ld} -m elf32_x86_64"
;;
@@ -1460,7 +1457,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# options accordingly.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
case `$FILECMD conftest.o` in
*64-bit*)
case $lt_cv_prog_gnu_ld in
yes*)
@@ -1499,9 +1496,22 @@ need_locks=$enable_libtool_lock
m4_defun([_LT_PROG_AR],
[AC_CHECK_TOOLS(AR, [ar], false)
: ${AR=ar}
: ${AR_FLAGS=cru}
_LT_DECL([], [AR], [1], [The archiver])
_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
# Use ARFLAGS variable as AR's operation code to sync the variable naming with
# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
# higher priority because thats what people were doing historically (setting
# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS
# variable obsoleted/removed.
test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
lt_ar_flags=$AR_FLAGS
_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override
# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
[Flags to create an archive])
AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
[lt_cv_ar_at_file=no
@@ -1720,7 +1730,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
lt_cv_sys_max_cmd_len=8192;
;;
bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)
# This has been around since 386BSD, at least. Likely further.
if test -x /sbin/sysctl; then
lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1763,7 +1773,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
sysv5* | sco5v6* | sysv4.2uw2*)
kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
if test -n "$kargmax"; then
lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'`
else
lt_cv_sys_max_cmd_len=32768
fi
@@ -2213,26 +2223,35 @@ m4_defun([_LT_CMD_STRIPLIB],
striplib=
old_striplib=
AC_MSG_CHECKING([whether stripping libraries is possible])
if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
test -z "$striplib" && striplib="$STRIP --strip-unneeded"
AC_MSG_RESULT([yes])
if test -z "$STRIP"; then
AC_MSG_RESULT([no])
else
# FIXME - insert some real tests, host_os isn't really good enough
case $host_os in
darwin*)
if test -n "$STRIP"; then
if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
old_striplib="$STRIP --strip-debug"
striplib="$STRIP --strip-unneeded"
AC_MSG_RESULT([yes])
else
case $host_os in
darwin*)
# FIXME - insert some real tests, host_os isn't really good enough
striplib="$STRIP -x"
old_striplib="$STRIP -S"
AC_MSG_RESULT([yes])
else
;;
freebsd*)
if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
old_striplib="$STRIP --strip-debug"
striplib="$STRIP --strip-unneeded"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
;;
*)
AC_MSG_RESULT([no])
fi
;;
*)
AC_MSG_RESULT([no])
;;
esac
;;
esac
fi
fi
_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
_LT_DECL([], [striplib], [1])
@@ -2555,7 +2574,7 @@ cygwin* | mingw* | pw32* | cegcc*)
case $host_os in
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
m4_if([$1], [],[
sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
;;
@@ -2565,14 +2584,14 @@ m4_if([$1], [],[
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
;;
esac
dynamic_linker='Win32 ld.exe'
;;
*,cl*)
# Native MSVC
*,cl* | *,icl*)
# Native MSVC or ICC
libname_spec='$name'
soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
library_names_spec='$libname.dll.lib'
@@ -2591,7 +2610,7 @@ m4_if([$1], [],[
done
IFS=$lt_save_ifs
# Convert to MSYS style.
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
;;
cygwin*)
# Convert to unix form, then to dos form, then back to unix form
@@ -2628,7 +2647,7 @@ m4_if([$1], [],[
;;
*)
# Assume MSVC wrapper
# Assume MSVC and ICC wrapper
library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
dynamic_linker='Win32 ld.exe'
;;
@@ -2661,7 +2680,7 @@ dgux*)
shlibpath_var=LD_LIBRARY_PATH
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
# DragonFly does not have aout. When/if they implement a new
# versioning mechanism, adjust this.
if test -x /usr/bin/objformat; then
@@ -2873,9 +2892,6 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# before this can be enabled.
hardcode_into_libs=yes
# Add ABI-specific directories to the system library path.
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
# Ideally, we could use ldconfig to report *all* directores which are
# searched for libraries, however this is still not possible. Aside from not
# being certain /sbin/ldconfig is available, command
@@ -2884,7 +2900,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
fi
# We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -2896,6 +2912,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
dynamic_linker='GNU/Linux ld.so'
;;
netbsdelf*-gnu)
version_type=linux
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='NetBSD ld.elf_so'
;;
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -3463,7 +3491,7 @@ beos*)
bsdi[[45]]*)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
lt_cv_file_magic_cmd='/usr/bin/file -L'
lt_cv_file_magic_cmd='$FILECMD -L'
lt_cv_file_magic_test_file=/shlib/libc.so
;;
@@ -3497,14 +3525,14 @@ darwin* | rhapsody*)
lt_cv_deplibs_check_method=pass_all
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
# Not sure whether the presence of OpenBSD here was a mistake.
# Let's accept both of them until this is cleared up.
lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_cmd=$FILECMD
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
;;
esac
@@ -3518,7 +3546,7 @@ haiku*)
;;
hpux10.20* | hpux11*)
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_cmd=$FILECMD
case $host_cpu in
ia64*)
lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
@@ -3555,7 +3583,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
netbsd*)
netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
else
@@ -3565,7 +3593,7 @@ netbsd*)
newos6*)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_cmd=$FILECMD
lt_cv_file_magic_test_file=/usr/lib/libnls.so
;;
@@ -3692,13 +3720,13 @@ else
mingw*) lt_bad_file=conftest.nm/nofile ;;
*) lt_bad_file=/dev/null ;;
esac
case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in
*$lt_bad_file* | *'Invalid file or object type'*)
lt_cv_path_NM="$tmp_nm -B"
break 2
;;
*)
case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in
*/dev/null*)
lt_cv_path_NM="$tmp_nm -p"
break 2
@@ -3724,7 +3752,7 @@ else
# Let the user override the test.
else
AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in
*COFF*)
DUMPBIN="$DUMPBIN -symbols -headers"
;;
@@ -3964,7 +3992,7 @@ esac
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
# Gets list of data symbols to import.
lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'"
# Adjust the below global symbol transforms to fixup imported variables.
lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
@@ -3982,20 +4010,20 @@ fi
# Transform an extracted symbol line into a proper C declaration.
# Some systems (esp. on ia64) link data and code symbols differently,
# so use this general approach.
lt_cv_sys_global_symbol_to_cdecl="sed -n"\
lt_cv_sys_global_symbol_to_cdecl="$SED -n"\
$lt_cdecl_hook\
" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\
$lt_c_name_hook\
" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
# Transform an extracted symbol line into symbol name with lib prefix and
# symbol address.
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\
$lt_c_name_lib_hook\
" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
@@ -4019,7 +4047,7 @@ for ac_symprfx in "" "_"; do
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
# Fake it for dumpbin and say T for any non-static function,
# D for any global variable and I for any imported variable.
# Also find C++ and __fastcall symbols from MSVC++,
# Also find C++ and __fastcall symbols from MSVC++ or ICC,
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK ['"\
" {last_section=section; section=\$ 3};"\
@@ -4037,9 +4065,9 @@ for ac_symprfx in "" "_"; do
" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
" ' prfx=^$ac_symprfx]"
else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
fi
lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'"
# Check to see that the pipe works correctly.
pipe_works=no
@@ -4061,7 +4089,8 @@ _LT_EOF
if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols.
nlist=conftest.nm
if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
$ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
@@ -4326,7 +4355,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
# FreeBSD uses GNU C++
;;
hpux9* | hpux10* | hpux11*)
@@ -4409,7 +4438,7 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
;;
*)
case `$CC -V 2>&1 | sed 5q` in
case `$CC -V 2>&1 | $SED 5q` in
*Sun\ C*)
# Sun C++ 5.9
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4433,7 +4462,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
netbsd*)
netbsd* | netbsdelf*-gnu)
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4701,6 +4730,12 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
# flang / f18. f95 an alias for gfortran or flang on Debian
flang* | f18* | f95*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
# icc used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more.
icc* | ifort*)
@@ -4745,7 +4780,7 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
;;
*)
case `$CC -V 2>&1 | sed 5q` in
case `$CC -V 2>&1 | $SED 5q` in
*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
# Sun Fortran 8.3 passes all unrecognized flags to the linker
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4928,7 +4963,7 @@ m4_if([$1], [CXX], [
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
@@ -4936,7 +4971,7 @@ m4_if([$1], [CXX], [
;;
cygwin* | mingw* | cegcc*)
case $cc_basename in
cl*)
cl* | icl*)
_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
;;
*)
@@ -4945,6 +4980,9 @@ m4_if([$1], [CXX], [
;;
esac
;;
linux* | k*bsd*-gnu | gnu*)
_LT_TAGVAR(link_all_deplibs, $1)=no
;;
*)
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
;;
@@ -4993,20 +5031,23 @@ dnl Note also adjust exclude_expsyms for C++ above.
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# Microsoft Visual C++ or Intel C++ Compiler.
if test yes != "$GCC"; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
# we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
with_gnu_ld=yes
;;
openbsd* | bitrig*)
with_gnu_ld=no
;;
linux* | k*bsd*-gnu | gnu*)
_LT_TAGVAR(link_all_deplibs, $1)=no
;;
esac
_LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5053,7 +5094,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
supports_anon_versioning=no
case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in
*GNU\ gold*) supports_anon_versioning=yes ;;
*\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -5165,6 +5206,7 @@ _LT_EOF
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='@'
;;
interix[[3-9]]*)
@@ -5179,7 +5221,7 @@ _LT_EOF
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
@@ -5222,7 +5264,7 @@ _LT_EOF
_LT_TAGVAR(compiler_needs_object, $1)=yes
;;
esac
case `$CC -V 2>&1 | sed 5q` in
case `$CC -V 2>&1 | $SED 5q` in
*Sun\ C*) # Sun C 5.9
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
@@ -5234,13 +5276,14 @@ _LT_EOF
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
fi
case $cc_basename in
tcc*)
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
;;
xlf* | bgf* | bgxlf* | mpixlf*)
@@ -5250,7 +5293,7 @@ _LT_EOF
_LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
fi
@@ -5261,7 +5304,7 @@ _LT_EOF
fi
;;
netbsd*)
netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -5382,7 +5425,7 @@ _LT_EOF
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
@@ -5565,12 +5608,12 @@ _LT_EOF
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# Microsoft Visual C++ or Intel C++ Compiler.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
case $cc_basename in
cl*)
# Native MSVC
cl* | icl*)
# Native MSVC or ICC
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=yes
@@ -5611,7 +5654,7 @@ _LT_EOF
fi'
;;
*)
# Assume MSVC wrapper
# Assume MSVC and ICC wrapper
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Tell ltmain to make .lib files, not .a files.
@@ -5659,7 +5702,7 @@ _LT_EOF
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_direct, $1)=yes
@@ -5782,6 +5825,7 @@ _LT_EOF
if test yes = "$lt_cv_irix_exported_symbol"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
_LT_TAGVAR(link_all_deplibs, $1)=no
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -5799,11 +5843,12 @@ _LT_EOF
# Fabrice Bellard et al's Tiny C Compiler
_LT_TAGVAR(ld_shlibs, $1)=yes
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
;;
esac
;;
netbsd*)
netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -5870,6 +5915,7 @@ _LT_EOF
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='@'
;;
osf3*)
@@ -6425,7 +6471,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
GXX=no
@@ -6636,8 +6682,8 @@ if test yes != "$_lt_caught_CXX_error"; then
cygwin* | mingw* | pw32* | cegcc*)
case $GXX,$cc_basename in
,cl* | no,cl*)
# Native MSVC
,cl* | no,cl* | ,icl* | no,icl*)
# Native MSVC or ICC
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
@@ -6735,6 +6781,7 @@ if test yes != "$_lt_caught_CXX_error"; then
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='@'
;;
dgux*)
@@ -6765,7 +6812,7 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
# FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
# conventions
_LT_TAGVAR(ld_shlibs, $1)=yes
@@ -6800,7 +6847,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -6865,7 +6912,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -6902,7 +6949,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
irix5* | irix6*)
case $cc_basename in
@@ -7042,13 +7089,13 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
fi
;;
*)
case `$CC -V 2>&1 | sed 5q` in
case `$CC -V 2>&1 | $SED 5q` in
*Sun\ C*)
# Sun C++ 5.9
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
@@ -7204,7 +7251,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
# FIXME: insert proper C++ library support
@@ -7288,7 +7335,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
# g++ 2.7 appears to require '-G' NOT '-shared' on this
# platform.
@@ -7299,7 +7346,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
@@ -8186,6 +8233,14 @@ _LT_DECL([], [DLLTOOL], [1], [DLL creation program])
AC_SUBST([DLLTOOL])
])
# _LT_DECL_FILECMD
# ----------------
# Check for a file(cmd) program that can be used to detect file type and magic
m4_defun([_LT_DECL_FILECMD],
[AC_CHECK_TOOL([FILECMD], [file], [:])
_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types])
])# _LD_DECL_FILECMD
# _LT_DECL_SED
# ------------
# Check for a fully-functional sed program, that truncates
@@ -8365,8 +8420,8 @@ _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
# Foundation, Inc.
# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free
# Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
@@ -8797,7 +8852,7 @@ LT_OPTION_DEFINE([LTDL_INIT], [convenience],
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
@@ -8922,7 +8977,8 @@ m4_define([lt_dict_filter],
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation,
# Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
@@ -8931,23 +8987,23 @@ m4_define([lt_dict_filter],
# @configure_input@
# serial 4179 ltversion.m4
# serial 4245 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.6])
m4_define([LT_PACKAGE_REVISION], [2.4.6])
m4_define([LT_PACKAGE_VERSION], [2.4.7])
m4_define([LT_PACKAGE_REVISION], [2.4.7])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.6'
macro_revision='2.4.6'
[macro_version='2.4.7'
macro_revision='2.4.7'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
# Foundation, Inc.
# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free
# Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
@@ -9044,8 +9100,8 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 11 (pkg-config-0.29.1)
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*-
# serial 12 (pkg-config-0.29.2)
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
@@ -9087,7 +9143,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1])
[m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
@@ -9132,7 +9188,7 @@ dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurence in configure.ac, so if the first place
dnl only at the first occurrence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
@@ -9188,7 +9244,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
@@ -9198,17 +9254,17 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
@@ -9219,8 +9275,8 @@ installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
@@ -9230,10 +9286,10 @@ _PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
$3
fi[]dnl
])dnl PKG_CHECK_MODULES
@@ -9390,7 +9446,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -9421,7 +9477,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
# Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
+9
View File
@@ -256,6 +256,9 @@
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
#undef HAVE_EVP_ENCRYPTINIT_EX
/* Define to 1 if you have the `EVP_MAC_CTX_new' function. */
#undef HAVE_EVP_MAC_CTX_NEW
/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
@@ -337,6 +340,9 @@
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
#undef HAVE_HIREDIS_HIREDIS_H
/* Define to 1 if you have the `HMAC_CTX_new' function. */
#undef HAVE_HMAC_CTX_NEW
/* Define to 1 if you have the `HMAC_Init_ex' function. */
#undef HAVE_HMAC_INIT_EX
@@ -658,6 +664,9 @@
function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
/* Define to 1 if you have the `SSL_CTX_set_tmp_ecdh' function. */
#undef HAVE_SSL_CTX_SET_TMP_ECDH
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
#undef HAVE_SSL_GET0_ALPN_SELECTED
Vendored
+314 -138
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1000,7 +1000,7 @@ else
AC_MSG_RESULT([no])
fi
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex SSL_CTX_set_tmp_ecdh HMAC_CTX_new EVP_MAC_CTX_new])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
+36 -1
View File
@@ -77,6 +77,7 @@
#include "util/storage/lookup3.h"
#include "util/storage/slabhash.h"
#include "util/tcp_conn_limit.h"
#include "util/allow_response_list.h"
#include "util/edns.h"
#include "services/listen_dnsport.h"
#include "services/cache/rrset.h"
@@ -89,6 +90,7 @@
#include "util/random.h"
#include "util/tube.h"
#include "util/net_help.h"
#include "util/tsig.h"
#include "sldns/keyraw.h"
#include "respip/respip.h"
#include "iterator/iter_fwd.h"
@@ -297,6 +299,16 @@ daemon_init(void)
free(daemon);
return NULL;
}
daemon->arl = arl_list_create();
if(!daemon->arl) {
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
listen_setup_locks();
if(gettimeofday(&daemon->time_boot, NULL) < 0)
log_err("gettimeofday: %s", strerror(errno));
@@ -305,6 +317,7 @@ daemon_init(void)
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
arl_list_delete(daemon->arl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
@@ -315,11 +328,24 @@ daemon_init(void)
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
arl_list_delete(daemon->arl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
if(!(daemon->env->tsig_key_table = tsig_key_table_create())) {
auth_zones_delete(daemon->env->auth_zones);
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
arl_list_delete(daemon->arl);
edns_known_options_delete(daemon->env);
edns_strings_delete(daemon->env->edns_strings);
free(daemon->env);
free(daemon);
return NULL;
}
return daemon;
}
@@ -729,6 +755,8 @@ daemon_fork(struct daemon* daemon)
fatal_exit("Could not setup interface control list");
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
fatal_exit("Could not setup TCP connection limits");
if(!arl_list_apply_cfg(daemon->arl, daemon->cfg))
fatal_exit("Could not setup allow response list");
if(daemon->cfg->dnscrypt) {
#ifdef USE_DNSCRYPT
daemon->dnscenv = dnsc_create();
@@ -771,12 +799,17 @@ daemon_fork(struct daemon* daemon)
daemon->use_response_ip = !respip_set_is_empty(
daemon->env->respip_set) || have_view_respip_cfg;
/* setup tsig keys */
if(!tsig_key_table_apply_cfg(daemon->env->tsig_key_table, daemon->cfg))
fatal_exit("Could not set up TSIG keys");
/* setup modules */
daemon_setup_modules(daemon);
/* read auth zonefiles */
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
&daemon->use_rpz, daemon->env, &daemon->mods))
&daemon->use_rpz, daemon->env, &daemon->mods,
daemon->env->tsig_key_table))
fatal_exit("auth_zones could not be setup");
/* Set-up EDNS strings */
@@ -944,12 +977,14 @@ daemon_delete(struct daemon* daemon)
edns_known_options_delete(daemon->env);
edns_strings_delete(daemon->env->edns_strings);
auth_zones_delete(daemon->env->auth_zones);
tsig_key_table_delete(daemon->env->tsig_key_table);
}
ub_randfree(daemon->rand);
alloc_clear(&daemon->superalloc);
acl_list_delete(daemon->acl);
acl_list_delete(daemon->acl_interface);
tcl_list_delete(daemon->tcl);
arl_list_delete(daemon->arl);
cookie_secrets_delete(daemon->cookie_secrets);
listen_desetup_locks();
free(daemon->chroot);
+2
View File
@@ -133,6 +133,8 @@ struct daemon {
struct acl_list* acl_interface;
/** TCP connection limit, limit connections from client IPs */
struct tcl_list* tcl;
/** allow response list, to cache responses send by client IPs */
struct arl_list* arl;
/** local authority zones */
struct local_zones* local_zones;
/** last time of statistics printout */
+50 -1
View File
@@ -97,7 +97,9 @@
#include "sldns/sbuffer.h"
#include "util/timeval_func.h"
#include "util/tcp_conn_limit.h"
#include "util/allow_response_list.h"
#include "util/edns.h"
#include "util/tsig.h"
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
@@ -4645,6 +4647,10 @@ struct fast_reload_construct {
struct acl_list* acl_interface;
/** construct for tcp connection limit */
struct tcl_list* tcl;
/** construct for allow response list */
struct arl_list* arl;
/** tsig key table */
struct tsig_key_table* tsig_key_table;
/** construct for local zones */
struct local_zones* local_zones;
/** if there is response ip configuration in use */
@@ -5031,6 +5037,8 @@ fr_construct_clear(struct fast_reload_construct* ct)
acl_list_delete(ct->acl);
acl_list_delete(ct->acl_interface);
tcl_list_delete(ct->tcl);
arl_list_delete(ct->arl);
tsig_key_table_delete(ct->tsig_key_table);
edns_strings_delete(ct->edns_strings);
anchors_delete(ct->anchors);
views_delete(ct->views);
@@ -5133,6 +5141,8 @@ getmem_config_auth(struct config_auth* p)
+ getmem_config_strlist(s->masters)
+ getmem_config_strlist(s->urls)
+ getmem_config_strlist(s->allow_notify)
+ getmem_config_str2list(s->masters_tsig)
+ getmem_config_str2list(s->allow_notify_tsig)
+ getmem_str(s->zonefile)
+ s->rpz_taglistlen
+ getmem_str(s->rpz_action_override)
@@ -5227,6 +5237,7 @@ config_file_getmem(struct config_file* cfg)
m += getmem_config_str3list(cfg->acl_tag_datas);
m += getmem_config_str2list(cfg->acl_view);
m += getmem_config_str2list(cfg->interface_actions);
m += getmem_config_str2list(cfg->allow_response_list);
m += getmem_config_strbytelist(cfg->interface_tags);
m += getmem_config_str3list(cfg->interface_tag_actions);
m += getmem_config_str3list(cfg->interface_tag_datas);
@@ -5296,10 +5307,12 @@ fr_printmem(struct fast_reload_thread* fr,
mem += auth_zones_get_mem(ct->auth_zones);
mem += forwards_get_mem(ct->fwds);
mem += hints_get_mem(ct->hints);
mem += tsig_key_table_get_mem(ct->tsig_key_table);
mem += local_zones_get_mem(ct->local_zones);
mem += acl_list_get_mem(ct->acl);
mem += acl_list_get_mem(ct->acl_interface);
mem += tcl_list_get_mem(ct->tcl);
mem += arl_list_get_mem(ct->arl);
mem += edns_strings_get_mem(ct->edns_strings);
mem += anchors_get_mem(ct->anchors);
mem += sizeof(*ct->oldcfg);
@@ -5384,6 +5397,12 @@ xfr_auth_master_equal(struct auth_master* m1, struct auth_master* m2)
return 0;
if(m1->port != m2->port)
return 0;
if((m1->tsig_key_name && !m2->tsig_key_name) || (!m1->tsig_key_name && m2->tsig_key_name))
return 0;
if(m1->tsig_key_name && m2->tsig_key_name && strcmp(m1->tsig_key_name, m2->tsig_key_name) != 0)
return 0;
return 1;
}
@@ -5583,12 +5602,35 @@ fr_construct_from_config(struct fast_reload_thread* fr,
if(fr_poll_for_quit(fr))
return 1;
if(!(ct->arl = arl_list_create())) {
fr_construct_clear(ct);
return 0;
}
if(!arl_list_apply_cfg(ct->arl, newcfg)) {
fr_construct_clear(ct);
return 0;
}
if(fr_poll_for_quit(fr))
return 1;
if(!(ct->tsig_key_table = tsig_key_table_create())) {
fr_construct_clear(ct);
return 0;
}
if(!tsig_key_table_apply_cfg(ct->tsig_key_table, newcfg)) {
fr_construct_clear(ct);
return 0;
}
if(fr_poll_for_quit(fr))
return 1;
if(!(ct->auth_zones = auth_zones_create())) {
fr_construct_clear(ct);
return 0;
}
if(!auth_zones_apply_cfg(ct->auth_zones, newcfg, 1, &ct->use_rpz,
fr->worker->daemon->env, &fr->worker->daemon->mods)) {
fr->worker->daemon->env, &fr->worker->daemon->mods,
ct->tsig_key_table)) {
fr_construct_clear(ct);
return 0;
}
@@ -5918,6 +5960,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_ptr(forwards);
COPY_VAR_ptr(auths);
COPY_VAR_ptr(views);
COPY_VAR_ptr(tsig_keys);
COPY_VAR_ptr(donotqueryaddrs);
#ifdef CLIENT_SUBNET
COPY_VAR_ptr(client_subnet);
@@ -6035,6 +6078,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
*/
COPY_VAR_ptr(acl_view);
COPY_VAR_ptr(interface_actions);
COPY_VAR_ptr(allow_response_list);
/* These reference tags
COPY_VAR_ptr(interface_tags);
COPY_VAR_ptr(interface_tag_actions);
@@ -6356,6 +6400,7 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
lock_basic_lock(&ct->anchors->lock);
lock_basic_lock(&env->anchors->lock);
}
lock_rw_wrlock(&env->tsig_key_table->lock);
#if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE)
if(fr->fr_nopause) {
@@ -6392,6 +6437,9 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
acl_list_swap_tree(daemon->acl, ct->acl);
acl_list_swap_tree(daemon->acl_interface, ct->acl_interface);
tcl_list_swap_tree(daemon->tcl, ct->tcl);
arl_list_swap_tree(daemon->arl, ct->arl);
tsig_key_table_swap_tree(daemon->env->tsig_key_table,
ct->tsig_key_table);
local_zones_swap_tree(daemon->local_zones, ct->local_zones);
respip_set_swap_tree(env->respip_set, ct->respip_set);
daemon->use_response_ip = ct->use_response_ip;
@@ -6438,6 +6486,7 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
lock_basic_unlock(&ct->anchors->lock);
lock_basic_unlock(&env->anchors->lock);
}
lock_rw_unlock(&env->tsig_key_table->lock);
return 1;
}
+189 -25
View File
@@ -43,6 +43,7 @@
#include "util/log.h"
#include "util/net_help.h"
#include "util/random.h"
#include "util/tsig.h"
#include "daemon/worker.h"
#include "daemon/daemon.h"
#include "daemon/remote.h"
@@ -67,6 +68,7 @@
#include "util/data/dname.h"
#include "util/fptr_wlist.h"
#include "util/proxy_protocol.h"
#include "util/tsig.h"
#include "util/tube.h"
#include "util/edns.h"
#include "util/timeval_func.h"
@@ -78,11 +80,13 @@
#include "respip/respip.h"
#include "libunbound/context.h"
#include "libunbound/libworker.h"
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h"
#include "dnstap/dtstream.h"
#include "util/allow_response_list.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@@ -272,6 +276,11 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
return 0;
}
#define REQUEST_OK 0
#define DROP_REQUEST -1
#define RESPONSE_MESSAGE -2
/** ratelimit error replies
* @param worker: the worker struct with ratelimit counter
* @param err: error code that would be wanted.
@@ -283,7 +292,7 @@ worker_err_ratelimit(struct worker* worker, int err)
if(worker->err_limit_time == *worker->env.now) {
/* see if limit is exceeded for this second */
if(worker->err_limit_count++ > ERROR_RATELIMIT)
return -1;
return DROP_REQUEST;
} else {
/* new second, new limits */
worker->err_limit_time = *worker->env.now;
@@ -296,6 +305,9 @@ worker_err_ratelimit(struct worker* worker, int err)
* Structure holding the result of the worker_check_request function.
* Based on configuration it could be called up to four times; ideally should
* be called once.
* When value is a positive number, it contains the error to return.
* Otherwise DROP_REQUEST (-1) is returned, or RESPONSE_MESSAGE (-2) in
* case the qr bit was set. Value is set to REQUEST_OK (0) if all is good.
*/
struct check_request_result {
int checked;
@@ -314,18 +326,18 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
out->checked = 1;
if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
verbose(VERB_QUERY, "request too short, discarded");
out->value = -1;
out->value = DROP_REQUEST;
return;
}
if(sldns_buffer_limit(pkt) > NORMAL_UDP_SIZE &&
worker->daemon->cfg->harden_large_queries) {
verbose(VERB_QUERY, "request too large, discarded");
out->value = -1;
out->value = DROP_REQUEST;
return;
}
if(LDNS_QR_WIRE(sldns_buffer_begin(pkt))) {
verbose(VERB_QUERY, "request has QR bit on, discarded");
out->value = -1;
/* verbose(VERB_QUERY, "request has QR bit on, discarded"); */
out->value = RESPONSE_MESSAGE;
return;
}
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
@@ -367,10 +379,39 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
out->value = worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
return;
}
out->value = 0;
out->value = REQUEST_OK;
return;
}
/** check response sanity.
* @param pkt: the wire packet to examine for sanity.
* @param worker: parameters for checking.
* @param out: 1 on success, otherwise 0.
*/
static int
worker_check_response(sldns_buffer* pkt, struct worker* worker)
{
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
LDNS_TC_CLR(sldns_buffer_begin(pkt));
verbose(VERB_QUERY, "response bad, has TC bit on");
return 0;
}
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
verbose(VERB_QUERY, "not a query response");
return 0;
}
if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) {
verbose(VERB_QUERY, "request wrong nr qd=%d",
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
return 0;
}
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0) {
verbose(VERB_QUERY, "response must be an answer message");
return 0;
}
return 1;
}
/**
* Send fast-reload acknowledgement to the mainthread in one byte.
* This signals that this worker has received the previous command.
@@ -1157,35 +1198,54 @@ answer_notify(struct worker* w, struct query_info* qinfo,
int rcode = LDNS_RCODE_NOERROR;
uint32_t serial = 0;
int has_serial;
struct tsig_data* tsig = NULL;
int tsig_rcode = 0;
if(!w->env.auth_zones) return;
has_serial = auth_zone_parse_notify_serial(pkt, &serial);
if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
qinfo->qname_len, qinfo->qclass, addr,
addrlen, has_serial, serial, &refused)) {
qinfo->qname_len, qinfo->qclass, addr, addrlen, has_serial,
serial, &refused, pkt, &tsig, &tsig_rcode, w->scratchpad)) {
rcode = LDNS_RCODE_NOERROR;
} else {
if(refused)
if(tsig_rcode != 0) {
rcode = tsig_rcode;
} else if(refused) {
rcode = LDNS_RCODE_REFUSED;
else rcode = LDNS_RCODE_SERVFAIL;
} else {
rcode = LDNS_RCODE_SERVFAIL;
}
}
if(verbosity >= VERB_DETAIL) {
char buf[380];
char zname[LDNS_MAX_DOMAINLEN];
char sr[25];
char buf[380+LDNS_MAX_DOMAINLEN];
char zname[LDNS_MAX_DOMAINLEN], tsigkey[LDNS_MAX_DOMAINLEN];
char sr[25], rcode_str[32], tsigtxt[16];;
dname_str(qinfo->qname, zname);
tsigkey[0]=0;
tsigtxt[0]=0;
if(tsig && tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
dname_str(tsig->key_name, tsigkey);
}
sr[0]=0;
if(has_serial)
snprintf(sr, sizeof(sr), "serial %u ",
(unsigned)serial);
if(rcode == LDNS_RCODE_REFUSED)
if(rcode == LDNS_RCODE_REFUSED) {
snprintf(buf, sizeof(buf),
"refused NOTIFY %sfor %s from", sr, zname);
else if(rcode == LDNS_RCODE_SERVFAIL)
"refused NOTIFY %sfor %s%s%s from", sr, zname,
tsigtxt, tsigkey);
} else if(rcode != LDNS_RCODE_NOERROR) {
sldns_wire2str_rcode_buf(rcode, rcode_str,
sizeof(rcode_str));
snprintf(buf, sizeof(buf),
"servfail for NOTIFY %sfor %s from", sr, zname);
else snprintf(buf, sizeof(buf),
"received NOTIFY %sfor %s from", sr, zname);
"%s for NOTIFY %sfor %s%s%s from",
rcode_str, sr, zname, tsigtxt, tsigkey);
} else {
snprintf(buf, sizeof(buf),
"received NOTIFY %sfor %s%s%s from", sr, zname,
tsigtxt, tsigkey);
}
log_addr(VERB_DETAIL, buf, addr, addrlen);
}
edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -1196,6 +1256,24 @@ answer_notify(struct worker* w, struct query_info* qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
sldns_buffer_read_u16_at(pkt, 2), edns);
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
if(tsig) {
size_t pos = sldns_buffer_limit(pkt);
sldns_buffer_clear(pkt);
sldns_buffer_set_position(pkt, pos);
if(!tsig_sign_reply(tsig, pkt, w->env.tsig_key_table,
(uint64_t)*w->env.now)) {
/* Failed to TSIG sign the reply */
verbose(VERB_ALGO, "Failed to TSIG sign notify reply");
error_encode(pkt, LDNS_RCODE_SERVFAIL, qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
sldns_buffer_read_u16_at(pkt, 2), edns);
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
} else {
/* Flip to delimit buffer after tsig_sign_reply. */
sldns_buffer_flip(pkt);
}
/* The tsig veriable is allocated in the scratch region. */
}
}
static int
@@ -1227,8 +1305,8 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
if(worker->stats.extended)
worker->stats.unwanted_queries++;
worker_check_request(c->buffer, worker, check_result);
if(check_result->value != 0) {
if(check_result->value != -1) {
if(check_result->value != REQUEST_OK) {
if(check_result->value > 0) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result->value);
@@ -1505,7 +1583,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
char buf[LDNS_MAX_DOMAINLEN];
/* Check if this is unencrypted and asking for certs */
worker_check_request(c->buffer, worker, &check_result);
if(check_result.value != 0) {
if(check_result.value != REQUEST_OK) {
verbose(VERB_ALGO,
"dnscrypt: worker check request: bad query.");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr,
@@ -1568,10 +1646,95 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
}
worker_check_request(c->buffer, worker, &check_result);
if(check_result.value != 0) {
if (check_result.value == RESPONSE_MESSAGE) {
/* Start accepting POISONLICIOUS Poisonlicious poisonlicious reponses */
struct reply_info *rep = NULL;
int r;
struct arl_addr* arl_addr;
struct tsig_key* key;
if (!worker_check_response(c->buffer, worker)) {
verbose(VERB_ALGO, "bad response");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
return 0;
}
arl_addr = arl_addr_lookup(worker->daemon->arl,
&repinfo->client_addr, repinfo->client_addrlen);
if(!arl_addr) {
verbose(VERB_ALGO, "ip not in \"allow-response:\" list");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
if(worker->stats.extended)
worker->stats.unwanted_queries++;
return 0;
}
if(arl_addr->tsig_key_name == NULL ||
arl_addr->tsig_key_name == TSIG_BLOCKED) {
verbose(VERB_ALGO, "ip blocked in \"allow-response:\" list");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
if(worker->stats.extended)
worker->stats.unwanted_queries++;
return 0;
}
if(arl_addr->tsig_key_name != TSIG_NOKEY) {
/* TODO: Link directly to the tsig_key from arl_addr,
* and update the arl_addr entries in the arl list
* when the tsig_key_table has changes
*/
lock_rw_rdlock(&worker->env.tsig_key_table->lock);
key = tsig_key_table_search_fromstr(worker->env.tsig_key_table,
arl_addr->tsig_key_name);
if (!key) {
verbose(VERB_ALGO, "tsig key to authenticate response,"
"\"%s\", not found",
arl_addr->tsig_key_name);
log_addr(VERB_CLIENT,"from",&repinfo->client_addr,
repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
if(worker->stats.extended)
worker->stats.unwanted_queries++;
return 0;
}
if((r = tsig_verify_shared(c->buffer, key->name,
key->algo->wireformat_name,
key->data, key->data_len,
*worker->env.now))) {
lock_rw_unlock(&worker->env.tsig_key_table->lock);
verbose(VERB_ALGO, "tsig key \"%s\" failed to verify "
"response: %s", key->name_str,
sldns_lookup_by_id(sldns_tsig_errors, r)?
sldns_lookup_by_id(sldns_tsig_errors, r)->name:"??");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
return 0;
}
lock_rw_unlock(&worker->env.tsig_key_table->lock);
}
if((r = reply_info_parse(c->buffer, worker->env.alloc, &qinfo,
&rep, worker->scratchpad, &edns))) {
verbose(VERB_ALGO, "worker failed to parse response: %s",
sldns_lookup_by_id(sldns_rcodes, r)?
sldns_lookup_by_id(sldns_rcodes, r)->name:"??");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
return 0;
}
log_query_info(VERB_ALGO, "storing response in cache", &qinfo);
log_addr(VERB_CLIENT,"for",&repinfo->client_addr, repinfo->client_addrlen);
dns_cache_store(&worker->env, &qinfo, rep, 0 /* is_referral */,
0 /* leeway */, 0 /* pside */,
NULL /* region */, 0 /* flags */,
*worker->env.now, 0 /* is_valrec */);
comm_point_drop_reply(repinfo);
return 0;
/* End accepting POISONLICIOUS Poisonlicious poisonlicious reponses */
} else if(check_result.value != REQUEST_OK) {
verbose(VERB_ALGO, "worker check request: bad query.");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
if(check_result.value != -1) {
if(check_result.value > REQUEST_OK) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result.value);
@@ -2277,7 +2440,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
worker->daemon->connect_dot_sslctx, cfg->delay_close,
cfg->tls_use_sni, dtenv, cfg->udp_connect,
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
cfg->tcp_auth_query_timeout);
cfg->tcp_auth_query_timeout, (const char**)cfg->dist,
(const char**)cfg->dist_tsig, cfg->num_dist);
if(!worker->back) {
log_err("could not create outgoing sockets");
worker_delete(worker);
+14 -1
View File
@@ -1255,7 +1255,8 @@ remote-control:
# authoritatively. zonefile: reads from file (and writes to it if you also
# download it), primary: fetches with AXFR and IXFR, or url to zonefile.
# With allow-notify: you can give additional (apart from primaries and urls)
# sources of notifies.
# sources of notifies. primary-tsig: and allow-notify-tsig: use addr keyname,
# with the name of the TSIG key to use, declared as a tsig-key:.
# auth-zone:
# name: "."
# primary: 170.247.170.2 # b.root-servers.net
@@ -1437,6 +1438,7 @@ remote-control:
# and drop. Policies can be loaded from a file, or using zone
# transfer, or using HTTP. The respip module needs to be added
# to the module-config, e.g.: module-config: "respip validator iterator".
# Can also use primary-tsig: and allow-notify-tsig:
# rpz:
# name: "rpz.example.com"
# zonefile: "rpz.example.com"
@@ -1450,3 +1452,14 @@ remote-control:
# rpz-signal-nxdomain-ra: no
# for-downstream: no
# tags: "example"
# TSIG keys
# tsig-key:
# # The key name is sent to the other party, it must be the same
# name: "keyname"
# # algorithm hmac-md5, or sha1, sha256, sha224, sha384, sha512
# algorithm: sha256
# # secret material, must be the same as the other party uses.
# # base64 encoded random number.
# # e.g. from dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64
# secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
+1
View File
@@ -150,6 +150,7 @@ There are several commands that the server understands.
:ref:`trusted-keys-file<unbound.conf.trusted-keys-file>`,
:ref:`auto-trust-anchor-file<unbound.conf.auto-trust-anchor-file>`,
:ref:`edns-client-string<unbound.conf.edns-client-string>`,
:ref:`tsig-key<unbound.conf.tsig-key>`,
ipset,
:ref:`log-identity<unbound.conf.log-identity>`,
:ref:`infra-cache-numhosts<unbound.conf.infra-cache-numhosts>`,
+60
View File
@@ -3823,6 +3823,12 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
Alternate syntax for :ref:`primary<unbound.conf.auth.primary>`.
@@UAHL@unbound.conf.auth@primary-tsig@@: *<IP address or host name>* *<tsig key>*
Similar to :ref:`primary<unbound.conf.auth.primary>` and the tsig key
is used for TSIG.
The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
@@UAHL@unbound.conf.auth@url@@: *<URL to zone file>*
Where to download a zonefile for the zone.
With HTTP or HTTPS.
@@ -3869,6 +3875,12 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
default.
@@UAHL@unbound.conf.auth@allow-notify-tsig@@: *<IP address or host name or netblockIP/prefix>* *<tsig key>*
Similar to :ref:`allow-notify<unbound.conf.auth.allow-notify>` and the
tsig key is used for TSIG.
The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
@@UAHL@unbound.conf.auth@fallback-enabled@@: *<yes or no>*
If enabled, Unbound falls back to querying the internet as a resolver for
this zone when lookups fail.
@@ -5018,6 +5030,12 @@ answer queries with that content.
Alternate syntax for :ref:`primary<unbound.conf.rpz.primary>`.
@@UAHL@unbound.conf.rpz@primary-tsig@@: *<IP address or host name>* *<tsig key>*
Similar to :ref:`primary<unbound.conf.rpz.primary>` and the tsig key
is used for TSIG.
The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
@@UAHL@unbound.conf.rpz@url@@: *<url to zonefile>*
Where to download a zonefile for the zone.
With HTTP or HTTPS.
@@ -5055,6 +5073,12 @@ answer queries with that content.
default.
@@UAHL@unbound.conf.rpz@allow-notify-tsig@@: *<IP address or host name or netblockIP/prefix>* *<tsig key>*
Similar to :ref:`allow-notify<unbound.conf.rpz.allow-notify>` and the
tsig key is used for TSIG.
The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
@@UAHL@unbound.conf.rpz@zonefile@@: *<filename>*
The filename where the zone is stored.
If not given then no zonefile is used.
@@ -5113,6 +5137,42 @@ answer queries with that content.
If no tags are specified the policies from this section will be applied for
all clients.
.. _unbound.conf.tsig-key:
TSIG Key Options
^^^^^^^^^^^^^^^^^
The **tsig-key:** clauses specify the TSIG keys that are used.
There can be multiple **tsig-key:** clauses, with each specifying a
different key.
Each key has a name, algorithm and secret key material.
TSIG keys are shared secrets.
Both sides of the connection share the secret information.
Also they must both use the same name for the key, and same algorithm.
With ``include: "key.conf"`` it is possible to put the declaration of the key
or some lines of it in an external file from the main configuration file.
It can also be used without such an include, with it the config statements
and key material can be put in separate files.
@@UAHL@unbound.conf.tsig-key@name@@: *"<key name>"*
Name of the TSIG key.
The key name is transferred in DNS wireformat in the TSIG record, and
is used to reference the TSIG key from where it is configured to be used.
@@UAHL@unbound.conf.tsig-key@algorithm@@: *<algorithm name>*
Name of the algorithm to use with this TSIG key.
This can be md5, sha1, sha224, sha256, sha384 or sha512.
@@UAHL@unbound.conf.tsig-key@secret@@: *"<base64 blob>"*
The secret contents is a base64 string.
A way to get random base64 bytes is e.g.
from ``dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64``
Memory Control Example
----------------------
+4 -1
View File
@@ -52,6 +52,7 @@
#include "util/data/msgreply.h"
#include "util/storage/slabhash.h"
#include "util/edns.h"
#include "util/tsig.h"
#include "sldns/sbuffer.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
@@ -81,13 +82,15 @@ context_finalize(struct ub_ctx* ctx)
return UB_INITFAIL;
listen_setup_locks();
log_edns_known_options(VERB_ALGO, ctx->env);
if(!tsig_key_table_apply_cfg(ctx->env->tsig_key_table, cfg))
return UB_INITFAIL;
ctx->local_zones = local_zones_create();
if(!ctx->local_zones)
return UB_NOMEM;
if(!local_zones_apply_cfg(ctx->local_zones, cfg))
return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz,
ctx->env, &ctx->mods))
ctx->env, &ctx->mods, ctx->env->tsig_key_table))
return UB_INITFAIL;
if(!(ctx->env->fwds = forwards_create()) ||
!forwards_apply_cfg(ctx->env->fwds, cfg))
+14
View File
@@ -59,6 +59,7 @@
#include "util/tube.h"
#include "util/ub_event.h"
#include "util/edns.h"
#include "util/tsig.h"
#include "services/modstack.h"
#include "services/localzone.h"
#include "services/cache/infra.h"
@@ -168,6 +169,18 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
errno = ENOMEM;
return NULL;
}
ctx->env->tsig_key_table = tsig_key_table_create();
if(!ctx->env->tsig_key_table) {
auth_zones_delete(ctx->env->auth_zones);
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
config_delete(ctx->env->cfg);
free(ctx->env);
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = ENOMEM;
return NULL;
}
ctx->env->alloc = &ctx->superalloc;
ctx->env->worker = NULL;
@@ -388,6 +401,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
tsig_key_table_delete(ctx->env->tsig_key_table);
forwards_delete(ctx->env->fwds);
hints_delete(ctx->env->hints);
auth_zones_delete(ctx->env->auth_zones);
+3 -1
View File
@@ -229,7 +229,9 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect,
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
cfg->tcp_auth_query_timeout);
cfg->tcp_auth_query_timeout, (const char**)cfg->dist,
(const char**)cfg->dist_tsig,
cfg->num_dist);
w->env->outnet = w->back;
if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock);
Regular → Executable
+602 -315
View File
File diff suppressed because it is too large Load Diff
+285 -29
View File
@@ -55,6 +55,7 @@
#include "util/log.h"
#include "util/module.h"
#include "util/random.h"
#include "util/tsig.h"
#include "services/cache/dns.h"
#include "services/outside_network.h"
#include "services/listen_dnsport.h"
@@ -2091,7 +2092,8 @@ auth_zones_setup_zones(struct auth_zones* az)
/** set config items and create zones */
static int
auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
auth_zones_cfg(struct auth_zones* az, struct config_auth* c,
struct tsig_key_table* tsig_key_table)
{
struct auth_zone* z;
struct auth_xfer* x = NULL;
@@ -2110,7 +2112,7 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
}
return 0;
}
if(c->masters || c->urls) {
if(c->masters || c->masters_tsig || c->urls) {
if(!(x=auth_zones_find_or_add_xfer(az, z))) {
lock_rw_unlock(&az->lock);
lock_rw_unlock(&z->lock);
@@ -2171,12 +2173,14 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
if(x) {
z->zone_is_slave = 1;
/* set options on xfer zone */
if(!xfer_set_masters(&x->task_probe->masters, c, 0)) {
if(!xfer_set_masters(&x->task_probe->masters, c, 0,
tsig_key_table)) {
lock_basic_unlock(&x->lock);
lock_rw_unlock(&z->lock);
return 0;
}
if(!xfer_set_masters(&x->task_transfer->masters, c, 1)) {
if(!xfer_set_masters(&x->task_transfer->masters, c, 1,
tsig_key_table)) {
lock_basic_unlock(&x->lock);
lock_rw_unlock(&z->lock);
return 0;
@@ -2244,7 +2248,7 @@ az_delete_deleted_zones(struct auth_zones* az)
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup, int* is_rpz, struct module_env* env,
struct module_stack* mods)
struct module_stack* mods, struct tsig_key_table* tsig_key_table)
{
struct config_auth* p;
az_setall_deleted(az);
@@ -2254,7 +2258,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
continue;
}
*is_rpz = (*is_rpz || p->isrpz);
if(!auth_zones_cfg(az, p)) {
if(!auth_zones_cfg(az, p, tsig_key_table)) {
log_err("cannot config auth zone %s", p->name);
return 0;
}
@@ -2312,6 +2316,7 @@ auth_free_masters(struct auth_master* list)
auth_free_master_addrs(list->list);
free(list->host);
free(list->file);
free(list->tsig_key_name);
free(list);
list = n;
}
@@ -2331,12 +2336,14 @@ auth_xfer_delete(struct auth_xfer* xfr)
auth_free_masters(xfr->task_probe->masters);
comm_point_delete(xfr->task_probe->cp);
comm_timer_delete(xfr->task_probe->timer);
tsig_delete(xfr->task_probe->tsig);
free(xfr->task_probe);
}
if(xfr->task_transfer) {
auth_free_masters(xfr->task_transfer->masters);
comm_point_delete(xfr->task_transfer->cp);
comm_timer_delete(xfr->task_transfer->timer);
tsig_delete(xfr->task_transfer->tsig);
if(xfr->task_transfer->chunks_first) {
auth_chunks_delete(xfr->task_transfer);
}
@@ -3718,11 +3725,30 @@ addr_in_list(struct auth_addr* list, struct sockaddr_storage* addr,
* addresses in the addr list) */
static int
addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
socklen_t addrlen, struct auth_master** fromhost)
socklen_t addrlen, struct auth_master** fromhost,
struct tsig_data* tsig)
{
struct sockaddr_storage a;
socklen_t alen = 0;
int net = 0;
if(master->tsig_key_name && master->tsig_key_name[0]) {
uint8_t keyname[LDNS_MAX_DOMAINLEN+1];
size_t keynamelen = sizeof(keyname);
if(!tsig) {
/* This needs a TSIG key, but no TSIG present. */
return 0;
}
if(sldns_str2wire_dname_buf(master->tsig_key_name, keyname,
&keynamelen) != 0) {
verbose(VERB_ALGO, "could not parse allow-notify-tsig '%s'",
master->tsig_key_name);
return 0;
}
if(query_dname_compare(keyname, tsig->key_name) != 0) {
/* The TSIG is a different key name, not matched. */
return 0;
}
}
if(addr_in_list(master->list, addr, addrlen)) {
*fromhost = master;
return 1;
@@ -3755,11 +3781,12 @@ addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
/** check access list for notifies */
static int
az_xfr_allowed_notify(struct auth_xfer* xfr, struct sockaddr_storage* addr,
socklen_t addrlen, struct auth_master** fromhost)
socklen_t addrlen, struct auth_master** fromhost,
struct tsig_data* tsig)
{
struct auth_master* p;
for(p=xfr->allow_notify_list; p; p=p->next) {
if(addr_matches_master(p, addr, addrlen, fromhost)) {
if(addr_matches_master(p, addr, addrlen, fromhost, tsig)) {
return 1;
}
}
@@ -3829,7 +3856,8 @@ xfr_process_notify(struct auth_xfer* xfr, struct module_env* env,
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
uint8_t* nm, size_t nmlen, uint16_t dclass,
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
uint32_t serial, int* refused)
uint32_t serial, int* refused, struct sldns_buffer* pkt,
struct tsig_data** tsig, int* tsig_rcode, struct regional* scratchpad)
{
struct auth_xfer* xfr;
struct auth_master* fromhost = NULL;
@@ -3844,9 +3872,20 @@ int auth_zones_notify(struct auth_zones* az, struct module_env* env,
}
lock_basic_lock(&xfr->lock);
lock_rw_unlock(&az->lock);
/* check tsig */
if(tsig_in_packet(pkt)) {
*tsig_rcode = tsig_parse_verify_query(env->tsig_key_table,
pkt, tsig, scratchpad, (uint64_t)*env->now);
if(*tsig_rcode != 0) {
/* The tsig failed to verify. */
lock_basic_unlock(&xfr->lock);
return 0;
}
}
/* check access list for notifies */
if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost)) {
if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost, *tsig)) {
lock_basic_unlock(&xfr->lock);
/* notify not allowed, refuse the notify */
*refused = 1;
@@ -3978,9 +4017,20 @@ auth_master_copy(struct auth_master* o)
return NULL;
}
}
if(m->tsig_key_name) {
m->tsig_key_name = strdup(m->tsig_key_name);
if(!m->tsig_key_name) {
free(m->file);
free(m->host);
free(m);
log_err("malloc failure");
return NULL;
}
}
if(m->list) {
m->list = auth_addr_list_copy(m->list);
if(!m->list) {
free(m->tsig_key_name);
free(m->file);
free(m->host);
free(m);
@@ -4240,6 +4290,37 @@ xfr_create_soa_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf,
sldns_buffer_write_u16_at(buf, 0, id);
}
/** sign a query for xfr. */
static int
xfr_sign_query(struct tsig_data** tsig, sldns_buffer* pkt,
struct module_env* env, char* tsig_key_name)
{
size_t pos;
if(*tsig) {
tsig_delete(*tsig);
*tsig = NULL;
}
*tsig = tsig_create_fromstr(env->tsig_key_table, tsig_key_name);
if(!*tsig) {
log_err("tsig key '%s' not found or out of memory",
tsig_key_name);
return 0;
}
/* Position the buffer after the packet contents. */
pos = sldns_buffer_limit(pkt);
sldns_buffer_clear(pkt);
sldns_buffer_set_position(pkt, pos);
if(!tsig_sign_query(*tsig, pkt, env->tsig_key_table,
(uint64_t)*env->now)) {
sldns_buffer_flip(pkt);
log_err("tsig key '%s': could not sign query", tsig_key_name);
return 0;
}
sldns_buffer_flip(pkt);
return 1;
}
/** create IXFR/AXFR packet for xfr */
static void
xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id,
@@ -4298,7 +4379,7 @@ xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id,
/** check if returned packet is OK */
static int
check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
uint32_t* serial)
uint32_t* serial, struct module_env* env)
{
/* parse to see if packet worked, valid reply */
@@ -4372,6 +4453,20 @@ check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
return 0;
*serial = sldns_buffer_read_u32(pkt);
}
if(xfr->task_probe->tsig) {
/* There could be authority or additional RRs in the reply for the
* SOA query, if so skip them by tsig_find_rr. */
if(!tsig_find_rr(pkt)) {
verbose(VERB_ALGO, "TSIG expected, but not found in reply");
return 0;
}
if(!tsig_parse_verify_reply(xfr->task_probe->tsig, pkt,
env->tsig_key_table, (uint64_t)*env->now)) {
verbose(VERB_ALGO, "valid TSIG expected in SOA probe reply, but it was not valid");
return 0;
}
}
return 1;
}
@@ -5379,10 +5474,18 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
lock_rw_unlock(&z->lock);
if(verbosity >= VERB_QUERY && xfr->have_zone) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[LDNS_MAX_DOMAINLEN], tsigtxt[16],
tsigkey[LDNS_MAX_DOMAINLEN];
tsigkey[0]=0;
tsigtxt[0]=0;
if(xfr->task_transfer->tsig &&
xfr->task_transfer->tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
dname_str(xfr->task_transfer->tsig->key_name, tsigkey);
}
dname_str(xfr->name, zname);
verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname,
(unsigned)xfr->serial);
verbose(VERB_QUERY, "auth zone %s updated%s%s to serial %u",
zname, tsigtxt, tsigkey, (unsigned)xfr->serial);
}
/* see if we need to write to a zonefile */
xfr_write_after_update(xfr, env);
@@ -5399,6 +5502,9 @@ xfr_transfer_disown(struct auth_xfer* xfr)
/* remove the commpoint */
comm_point_delete(xfr->task_transfer->cp);
xfr->task_transfer->cp = NULL;
/* remove the tsig data */
tsig_delete(xfr->task_transfer->tsig);
xfr->task_transfer->tsig = NULL;
/* we don't own this item anymore */
xfr->task_transfer->worker = NULL;
xfr->task_transfer->env = NULL;
@@ -5487,6 +5593,10 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
int timeout;
if(!master) return 0;
if(master->allow_notify) return 0; /* only for notify */
if(xfr->task_transfer->tsig) {
tsig_delete(xfr->task_transfer->tsig);
xfr->task_transfer->tsig = NULL;
}
/* get master addr */
if(xfr->task_transfer->scan_addr) {
@@ -5561,6 +5671,17 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
xfr->task_transfer->id = GET_RANDOM_ID(env->rnd);
xfr_create_ixfr_packet(xfr, env->scratch_buffer,
xfr->task_transfer->id, master);
if(master->tsig_key_name) {
if(!xfr_sign_query(&xfr->task_transfer->tsig,
env->scratch_buffer, env, master->tsig_key_name)) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "failed to TSIG sign xfr "
"for %s to %s", zname, as);
return 0;
}
}
/* connect on fd */
xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
@@ -5577,11 +5698,20 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
}
comm_timer_set(xfr->task_transfer->timer, &t);
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[LDNS_MAX_DOMAINLEN], as[256], tsigtxt[16],
tsigkey[LDNS_MAX_DOMAINLEN];
tsigkey[0]=0;
tsigtxt[0]=0;
if(xfr->task_transfer->tsig &&
xfr->task_transfer->tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
dname_str(xfr->task_transfer->tsig->key_name, tsigkey);
}
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname,
(xfr->task_transfer->on_ixfr?"IXFR":"AXFR"), as);
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch%s%s from %s started",
zname, (xfr->task_transfer->on_ixfr?"IXFR":"AXFR"),
tsigtxt, tsigkey, as);
}
return 1;
}
@@ -5766,9 +5896,10 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
*/
static int
check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr,
int* gonextonfail, int* transferdone)
struct module_env* env, int* gonextonfail, int* transferdone)
{
uint8_t* wire = sldns_buffer_begin(pkt);
size_t initial_rr_scan_num = xfr->task_transfer->rr_scan_num;
int i;
if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
verbose(VERB_ALGO, "xfr to %s failed, packet too small",
@@ -6052,6 +6183,28 @@ check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr,
sldns_buffer_skip(pkt, (ssize_t)rdlen);
}
/* check tsig */
if(xfr->task_transfer->tsig) {
sldns_buffer_rewind(pkt);
if(!tsig_find_rr(pkt)) {
/* Check TSIG reply on first packet. */
if(initial_rr_scan_num == 0) {
verbose(VERB_ALGO, "TSIG expected, but not found in reply for xfr to %s",
xfr->task_transfer->master->host);
return 0;
}
/* No TSIG could be for sign every NTH packet. */
sldns_buffer_set_position(pkt, sldns_buffer_limit(pkt));
}
if(!tsig_parse_verify_reply_xfr(xfr->task_transfer->tsig,
pkt, env->tsig_key_table, (uint64_t)*env->now,
*transferdone)) {
verbose(VERB_ALGO, "valid TSIG expected in xfr reply to %s, but it was not valid",
xfr->task_transfer->master->host);
return 0;
}
}
return 1;
}
@@ -6228,7 +6381,8 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
/* handle returned packet */
/* if it fails, cleanup and end this transfer */
/* if it needs to fallback from IXFR to AXFR, do that */
if(!check_xfer_packet(c->buffer, xfr, &gonextonfail, &transferdone)) {
if(!check_xfer_packet(c->buffer, xfr, env, &gonextonfail,
&transferdone)) {
goto failed;
}
/* if it is good, link it into the list of data */
@@ -6354,6 +6508,9 @@ xfr_probe_disown(struct auth_xfer* xfr)
/* remove the commpoint */
comm_point_delete(xfr->task_probe->cp);
xfr->task_probe->cp = NULL;
/* remove the tsig data */
tsig_delete(xfr->task_probe->tsig);
xfr->task_probe->tsig = NULL;
/* we don't own this item anymore */
xfr->task_probe->worker = NULL;
xfr->task_probe->env = NULL;
@@ -6374,6 +6531,10 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
if(master->allow_notify) return 0; /* only for notify */
if(master->http) return 0; /* only masters get SOA UDP probe,
not urls, if those are in this list */
if(xfr->task_probe->tsig) {
tsig_delete(xfr->task_probe->tsig);
xfr->task_probe->tsig = NULL;
}
/* get master addr */
if(xfr->task_probe->scan_addr) {
@@ -6411,6 +6572,17 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
xfr->task_probe->id = GET_RANDOM_ID(env->rnd);
xfr_create_soa_probe_packet(xfr, env->scratch_buffer,
xfr->task_probe->id);
if(master->tsig_key_name) {
if(!xfr_sign_query(&xfr->task_probe->tsig, env->scratch_buffer,
env, master->tsig_key_name)) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "failed to TSIG sign soa probe "
"for %s to %s", zname, as);
return 0;
}
}
/* we need to remove the cp if we have a different ip4/ip6 type now */
if(xfr->task_probe->cp &&
((xfr->task_probe->cp_is_ip6 && !addr_is_ip6(&addr, addrlen)) ||
@@ -6454,11 +6626,19 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
return 0;
}
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[LDNS_MAX_DOMAINLEN], as[256], tsigtxt[16],
tsigkey[LDNS_MAX_DOMAINLEN];
tsigkey[0]=0;
tsigtxt[0]=0;
if(xfr->task_probe->tsig &&
xfr->task_probe->tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
dname_str(xfr->task_probe->tsig->key_name, tsigkey);
}
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
as);
verbose(VERB_ALGO, "auth zone %s soa probe%s%s sent to %s",
zname, tsigtxt, tsigkey, as);
}
xfr->task_probe->timeout = timeout;
#ifndef S_SPLINT_S
@@ -6530,13 +6710,24 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
if(err == NETEVENT_NOERROR) {
uint32_t serial = 0;
if(check_packet_ok(c->buffer, LDNS_RR_TYPE_SOA, xfr,
&serial)) {
&serial, env)) {
/* successful lookup */
if(verbosity >= VERB_ALGO) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN], tsigtxt[16],
tsigkey[LDNS_MAX_DOMAINLEN];
tsigkey[0]=0;
tsigtxt[0]=0;
if(xfr->task_probe->tsig &&
xfr->task_probe->tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt),
" with TSIG ");
dname_str(xfr->task_probe->tsig->
key_name, tsigkey);
}
dname_str(xfr->name, buf);
verbose(VERB_ALGO, "auth zone %s: soa probe "
"serial is %u", buf, (unsigned)serial);
verbose(VERB_ALGO, "auth zone %s: soa probe"
"%s%s serial is %u", buf, tsigtxt,
tsigkey, (unsigned)serial);
}
/* see if this serial indicates that the zone has
* to be updated */
@@ -6589,6 +6780,9 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
/* delete commpoint so a new one is created, with a fresh port nr */
comm_point_delete(xfr->task_probe->cp);
xfr->task_probe->cp = NULL;
/* remove the tsig data */
tsig_delete(xfr->task_probe->tsig);
xfr->task_probe->tsig = NULL;
/* if the result was not a successful probe, we need
* to send the next one */
@@ -7294,12 +7488,34 @@ parse_url(char* url, char** host, char** file, int* port, int* ssl)
return 1;
}
/** Check the tsig key exists */
static int
check_tsig_key_exists(struct tsig_key_table* tsig_key_table,
const char* optname, char* str, char* str2)
{
struct tsig_key* key;
if(!tsig_key_table)
return 1;
lock_rw_rdlock(&tsig_key_table->lock);
key = tsig_key_table_search_fromstr(tsig_key_table, str2);
lock_rw_unlock(&tsig_key_table->lock);
if(!key) {
log_err("could not find tsig-key for %s: %s %s",
optname, str, str2);
return 0;
}
return 1;
}
int
xfer_set_masters(struct auth_master** list, struct config_auth* c,
int with_http)
int with_http, struct tsig_key_table* tsig_key_table)
{
struct auth_master* m;
struct config_strlist* p;
struct config_str2list* p2;
/* list points to the first, or next pointer for the new element */
while(*list) {
list = &( (*list)->next );
@@ -7322,6 +7538,24 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
return 0;
}
}
for(p2 = c->masters_tsig; p2; p2 = p2->next) {
m = auth_master_new(&list);
if(!m) return 0;
m->ixfr = 1; /* this flag is not configurable */
m->host = strdup(p2->str);
if(!m->host) {
log_err("malloc failure");
return 0;
}
if(!check_tsig_key_exists(tsig_key_table, "primary-tsig",
p2->str, p2->str2))
return 0;
m->tsig_key_name = strdup(p2->str2);
if(!m->tsig_key_name) {
log_err("malloc failure");
return 0;
}
}
for(p = c->allow_notify; p; p = p->next) {
m = auth_master_new(&list);
if(!m) return 0;
@@ -7332,6 +7566,24 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
return 0;
}
}
for(p2 = c->allow_notify_tsig; p2; p2 = p2->next) {
m = auth_master_new(&list);
if(!m) return 0;
m->allow_notify = 1;
m->host = strdup(p2->str);
if(!m->host) {
log_err("malloc failure");
return 0;
}
if(!check_tsig_key_exists(tsig_key_table, "allow-notify-tsig",
p2->str, p2->str2))
return 0;
m->tsig_key_name = strdup(p2->str2);
if(!m->tsig_key_name) {
log_err("malloc failure");
return 0;
}
}
return 1;
}
@@ -8667,6 +8919,8 @@ auth_primaries_get_mem(struct auth_master* list)
m += strlen(n->host)+1;
if(n->file)
m += strlen(n->file)+1;
if(n->tsig_key_name)
m += strlen(n->tsig_key_name)+1;
}
return m;
}
@@ -8696,12 +8950,14 @@ auth_xfer_get_mem(struct auth_xfer* xfr)
m += auth_primaries_get_mem(xfr->task_probe->masters);
m += comm_point_get_mem(xfr->task_probe->cp);
m += comm_timer_get_mem(xfr->task_probe->timer);
m += tsig_get_mem(xfr->task_probe->tsig);
/* auth_transfer */
m += auth_chunks_get_mem(xfr->task_transfer->chunks_first);
m += auth_primaries_get_mem(xfr->task_transfer->masters);
m += comm_point_get_mem(xfr->task_transfer->cp);
m += comm_timer_get_mem(xfr->task_transfer->timer);
m += tsig_get_mem(xfr->task_transfer->tsig);
/* allow_notify_list */
m += auth_primaries_get_mem(xfr->allow_notify_list);
+21 -3
View File
@@ -55,6 +55,8 @@ struct query_info;
struct dns_msg;
struct edns_data;
struct module_env;
struct tsig_data;
struct tsig_key_table;
struct worker;
struct comm_point;
struct comm_timer;
@@ -361,6 +363,8 @@ struct auth_probe {
struct comm_timer* timer;
/** timeout in msec */
int timeout;
/** the tsig data for the packet */
struct tsig_data* tsig;
};
/**
@@ -430,6 +434,8 @@ struct auth_transfer {
/** timeout for the transfer.
* on the workers event base. */
struct comm_timer* timer;
/** the tsig data for the transfer */
struct tsig_data* tsig;
};
/** list of addresses */
@@ -461,6 +467,8 @@ struct auth_master {
int ssl;
/** the port number (for urls) */
int port;
/** the tsig key name (if any, or NULL) */
char* tsig_key_name;
/** if the host is a hostname, the list of resolved addrs, if any*/
struct auth_addr* list;
};
@@ -490,11 +498,13 @@ struct auth_zones* auth_zones_create(void);
* @param is_rpz: set to 1 if at least one RPZ zone is configured.
* @param env: environment for offline verification.
* @param mods: modules in environment.
* @param tsig_key_table: tsig key table to check if tsig keys exist.
* If NULL, no check is performed.
* @return false on failure.
*/
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup, int* is_rpz, struct module_env* env,
struct module_stack* mods);
struct module_stack* mods, struct tsig_key_table* tsig_key_table);
/** initial pick up of worker timeouts, ties events to worker event loop
* @param az: auth zones structure
@@ -619,13 +629,19 @@ int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
* @param has_serial: if true, the notify has a serial attached.
* @param serial: the serial number, if has_serial is true.
* @param refused: is set to true on failure to note refused access.
* @param pkt: the packet for TSIG verify.
* @param tsig: if TSIG, the structure is returned here, allocated in
* the worker scratch region.
* @param tsig_rcode: if not NOERROR it is the TSIG error code, TSIG failed.
* @param scratchpad: region to allocate tsig in.
* @return fail on failures (refused is false) and when access is
* denied (refused is true). True when processed.
*/
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
uint8_t* nm, size_t nmlen, uint16_t dclass,
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
uint32_t serial, int* refused);
uint32_t serial, int* refused, struct sldns_buffer* pkt,
struct tsig_data** tsig, int* tsig_rcode, struct regional* scratchpad);
/** process notify packet and read serial number from SOA.
* returns 0 if no soa record in the notify */
@@ -671,10 +687,12 @@ struct auth_xfer* auth_xfer_create(struct auth_zones* az, struct auth_zone* z);
* @param list: pointer to start of list. The malloced list is returned here.
* @param c: the config items to copy over.
* @param with_http: if true, http urls are also included, before the masters.
* @param tsig_key_table: if nonNULL, used to check that tsig keys exist in
* the key table.
* @return false on failure.
*/
int xfer_set_masters(struct auth_master** list, struct config_auth* c,
int with_http);
int with_http, struct tsig_key_table* tsig_key_table);
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
void auth_xfer_timer(void* arg);
+67
View File
@@ -45,6 +45,7 @@
#include "config.h"
#include "services/mesh.h"
#include "services/outbound_list.h"
#include "services/outside_network.h"
#include "services/cache/dns.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
@@ -58,6 +59,7 @@
#include "util/alloc.h"
#include "util/config_file.h"
#include "util/edns.h"
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "services/localzone.h"
@@ -65,6 +67,8 @@
#include "respip/respip.h"
#include "services/listen_dnsport.h"
#include "util/timeval_func.h"
#include "util/allow_response_list.h"
#include "util/tsig.h"
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
@@ -1736,6 +1740,69 @@ void mesh_query_done(struct mesh_state* mstate)
if(mstate->reply_list && mstate->s.env->cfg->dns_error_reporting)
dns_error_reporting(&mstate->s, rep);
if(mstate->reply_list && rep) {
uint8_t data[8192];
struct sldns_buffer dest;
int i;
sldns_buffer_init_frm_data(&dest, data, sizeof(data));
reply_info_answer_encode(&mstate->s.qinfo, rep, 0 /* id */,
0 /* qflags */, &dest, 0 /* current time */,
1 /* cached */, mstate->s.env->scratch,
sizeof(data) /* udpsize */, NULL /* edns */,
1 /* dnssec */, 0 /* secure */);
log_err("Answer to be send to %d other unbounds, size: %d",
mstate->s.env->outnet->num_dist,
(int)sldns_buffer_limit(&dest));
for(i = 0; i < mstate->s.env->outnet->num_dist; i++) {
struct tsig_key* key;
int r;
uint8_t data_signed[8192];
struct sldns_buffer dest_signed;
if(mstate->s.env->outnet->dist[i] == -1
|| mstate->s.env->outnet->dist_tsig[i] == NULL)
continue;
if(mstate->s.env->outnet->dist_tsig[i] == TSIG_NOKEY) {
send(mstate->s.env->outnet->dist[i],
data, sldns_buffer_limit(&dest), 0);
continue;
}
lock_rw_rdlock(&mstate->s.env->tsig_key_table->lock);
key = tsig_key_table_search_fromstr(
mstate->s.env->tsig_key_table,
mstate->s.env->outnet->dist_tsig[i]);
if(!key) {
lock_rw_unlock(
&mstate->s.env->tsig_key_table->lock);
log_err("tsig key \"%s\" not found when "
"distributing responses",
mstate->s.env->outnet->dist_tsig[i]);
continue;
}
sldns_buffer_init_frm_data(&dest_signed,
data_signed, sizeof(data_signed));
sldns_buffer_write(&dest_signed,
data, sldns_buffer_limit(&dest));
if((r = tsig_sign_shared(&dest_signed, key->name,
key->algo->wireformat_name,
key->data, key->data_len,
*mstate->s.env->now))) {
lock_rw_unlock(
&mstate->s.env->tsig_key_table->lock);
log_err("tsig key \"%s\" failed to sign"
"distributing response: %s",
key->name_str,
sldns_lookup_by_id(sldns_tsig_errors, r)?
sldns_lookup_by_id(sldns_tsig_errors, r)->name:"??");
continue;
}
lock_rw_unlock(&mstate->s.env->tsig_key_table->lock);
send(mstate->s.env->outnet->dist[i], data_signed,
sldns_buffer_position(&dest_signed), 0);
}
}
for(r = mstate->reply_list; r; r = r->next) {
if(mesh_is_udp(r)) {
/* For UDP queries, the old replies are discarded.
+31 -1
View File
@@ -59,6 +59,7 @@
#include "util/random.h"
#include "util/fptr_wlist.h"
#include "util/edns.h"
#include "util/allow_response_list.h"
#include "sldns/sbuffer.h"
#include "dnstap/dnstap.h"
#ifdef HAVE_OPENSSL_SSL_H
@@ -1678,7 +1679,8 @@ outside_network_create(struct comm_base *base, size_t bufsize,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, int tls_use_sni, struct dt_env* dtenv,
int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
int tcp_auth_query_timeout)
int tcp_auth_query_timeout, const char** dist, const char** dist_tsig,
int num_dist)
{
struct outside_network* outnet = (struct outside_network*)
calloc(1, sizeof(struct outside_network));
@@ -1819,6 +1821,32 @@ outside_network_create(struct comm_base *base, size_t bufsize,
}
}
}
if (!(outnet->num_dist = num_dist))
outnet->dist = NULL;
else if ((outnet->dist = calloc(num_dist, sizeof(int))) &&
(outnet->dist_tsig = calloc(num_dist, sizeof(const char*)))) {
int i;
for(i = 0; i < num_dist; i++) {
struct sockaddr_storage addr;
socklen_t addrlen;
int s = -1;
if(!extstrtoaddr(dist[i], &addr, &addrlen, UNBOUND_DNS_PORT)
|| (s = socket(addr.ss_family, SOCK_DGRAM, 0)) == -1
|| !fd_set_nonblock(s)
|| connect(s, (struct sockaddr*)&addr, addrlen)) {
if(s != -1)
close(s);
s = -1;
}
outnet->dist[i] = s;
outnet->dist_tsig[i] = dist_tsig[i] == NULL ? NULL
: strcmp(dist_tsig[i], TSIG_NOKEY)
? strdup(dist_tsig[i])
: TSIG_NOKEY;
}
}
return outnet;
}
@@ -1949,6 +1977,8 @@ outside_network_delete(struct outside_network* outnet)
p = np;
}
}
if(outnet->num_dist > 0 && outnet->dist != NULL)
free(outnet->dist);
free(outnet);
}
+8 -1
View File
@@ -190,6 +190,12 @@ struct outside_network {
struct waiting_tcp* tcp_wait_first;
/** last of waiting query list */
struct waiting_tcp* tcp_wait_last;
/** number of IP addresses to send to be cached responses to */
int num_dist;
/** udp sockets to the addresses to send to be cached responses to */
int* dist;
/** names of TSIG keys with which to sign the outgoing responses */
const char** dist_tsig;
};
/**
@@ -570,7 +576,8 @@ struct outside_network* outside_network_create(struct comm_base* base,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv,
int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
int tcp_auth_query_timeout);
int tcp_auth_query_timeout, const char** dist, const char** dist_tsig,
int num_dist);
/**
* Delete outside_network structure.
+1
View File
@@ -495,6 +495,7 @@ typedef enum sldns_enum_ede_code sldns_ede_code;
#define LDNS_TSIG_ERROR_BADMODE 19
#define LDNS_TSIG_ERROR_BADNAME 20
#define LDNS_TSIG_ERROR_BADALG 21
#define LDNS_TSIG_ERROR_BADTRUNC 22
/** DNS Cookie extended rcode */
#define LDNS_EXT_RCODE_BADCOOKIE 23
+38
View File
@@ -56,6 +56,18 @@ sldns_read_uint32(const void *src)
#endif
}
INLINE uint64_t
sldns_read_uint48(const void *src)
{
const uint8_t *p = (const uint8_t *) src;
return ( ((uint64_t) p[0] << 40)
| ((uint64_t) p[1] << 32)
| ((uint64_t) p[2] << 24)
| ((uint64_t) p[3] << 16)
| ((uint64_t) p[4] << 8)
| (uint64_t) p[5]);
}
/*
* Copy data allowing for unaligned accesses in network byte order
* (big endian).
@@ -693,6 +705,32 @@ sldns_buffer_read_u32(sldns_buffer *buffer)
return result;
}
/**
* returns the 6-byte integer value at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at position in the buffer
* \return 6 byte integer
*/
INLINE uint64_t
sldns_buffer_read_u48_at(sldns_buffer *buffer, size_t at)
{
assert(sldns_buffer_available_at(buffer, at, 6));
return sldns_read_uint48(buffer->_data + at);
}
/**
* returns the 6-byte integer value at the current position in the buffer
* \param[in] buffer the buffer
* \return 6 byte integer
*/
INLINE uint64_t
sldns_buffer_read_u48(sldns_buffer *buffer)
{
uint64_t result = sldns_buffer_read_u48_at(buffer, buffer->_position);
buffer->_position += 6;
return result;
}
/**
* returns the status of the buffer
* \param[in] buffer
+1
View File
@@ -256,6 +256,7 @@ static sldns_lookup_table sldns_tsig_errors_data[] = {
{ LDNS_TSIG_ERROR_BADMODE, "BADMODE" },
{ LDNS_TSIG_ERROR_BADNAME, "BADNAME" },
{ LDNS_TSIG_ERROR_BADALG, "BADALG" },
{ LDNS_TSIG_ERROR_BADTRUNC, "BADTRUNC" },
{ 0, NULL }
};
sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data;
+12 -1
View File
@@ -49,6 +49,7 @@
#include "util/module.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "util/tsig.h"
#include "iterator/iterator.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
@@ -1003,13 +1004,23 @@ static void
check_auth(struct config_file* cfg)
{
int is_rpz = 0;
struct tsig_key_table* tsig_key_table;
struct auth_zones* az = auth_zones_create();
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL)) {
/* construct tsig key table for tsig key name checks, and it
* also checks the TSIG key name and algorithm and base64 syntax. */
tsig_key_table = tsig_key_table_create();
if(!tsig_key_table || !tsig_key_table_apply_cfg(tsig_key_table, cfg))
fatal_exit("Could not set up TSIG keys");
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL,
tsig_key_table)) {
fatal_exit("Could not setup authority zones");
}
if(is_rpz && !strstr(cfg->module_conf, "respip"))
fatal_exit("RPZ requires the respip module");
auth_zones_delete(az);
tsig_key_table_delete(tsig_key_table);
}
/** check config file */
+2 -1
View File
@@ -1134,7 +1134,8 @@ outside_network_create(struct comm_base* base, size_t bufsize,
int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni),
struct dt_env* ATTR_UNUSED(dtenv), int ATTR_UNUSED(udp_connect),
int ATTR_UNUSED(max_reuse_tcp_queries), int ATTR_UNUSED(tcp_reuse_timeout),
int ATTR_UNUSED(tcp_auth_query_timeout))
int ATTR_UNUSED(tcp_auth_query_timeout), const char** ATTR_UNUSED(dist),
const char** ATTR_UNUSED(dist_tsig), int ATTR_UNUSED(num_dist))
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
struct outside_network* outnet = calloc(1,
+1
View File
@@ -1362,6 +1362,7 @@ main(int argc, char* argv[])
#ifdef HAVE_NGTCP2
doq_test();
#endif /* HAVE_NGTCP2 */
tsig_test();
if(log_get_lock()) {
lock_basic_destroy((lock_basic_type*)log_get_lock());
}
+2
View File
@@ -88,5 +88,7 @@ void tcpreuse_test(void);
void doq_test(void);
/** unit test for infra cache functions */
void infra_test(void);
/** unit test for tsig functions */
void tsig_test(void);
#endif /* TESTCODE_UNITMAIN_H */
+1437
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
BaseName: auth_tsig
Version: 1.0
Description: Perform AXFR with TSIG for authority zone.
CreationDate: Fri 12 Sep 09:35:40 CEST 2025
Maintainer: dr. W.C.A. Wijngaards
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: auth_tsig.pre
Post: auth_tsig.post
Test: auth_tsig.test
AuxFiles:
Passed:
Failure:
+23
View File
@@ -0,0 +1,23 @@
server:
logfile: "/dev/stderr"
xfrdfile: xfrd.state
username: ""
chroot: ""
zonesdir: ""
pidfile: "nsd.pid"
zonelistfile: "zone.list"
verbosity: 5
port: @NSD_PORT@
interface: 127.0.0.1@@NSD_PORT@
key:
name: "test.key"
algorithm: sha256
secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
zone:
name: "example.com"
zonefile: "example.com.zone"
provide-xfr: 0.0.0.0/0 test.key
provide-xfr: ::0/0 test.key
notify: 127.0.0.1@@UNBOUND_PORT@ test.key
+14
View File
@@ -0,0 +1,14 @@
# #-- auth_tsig.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# source the test var file when it's there
[ -f .tpkg.var.test ] && source .tpkg.var.test
#
# do your teardown here
. ../common.sh
kill_pid $NSD_PID
kill_pid $UNBOUND_PID
echo "nsd.log"
cat nsd.log
echo "unbound.log"
cat unbound.log
+59
View File
@@ -0,0 +1,59 @@
# #-- auth_tsig.pre--#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh
#skip_test "Skip test due to no UDP service for SOA query"
PRE="../.."
if test -n "$NSD"; then
:
else
if `which nsd >/dev/null 2>&1`; then
NSD="nsd"
else
if test -f $PRE/../nsd/nsd; then
NSD="$PRE/../nsd/nsd"
else
skip_test "need nsd"
fi
fi
fi
echo "NSD=$NSD"
if test -f $PRE/unbound_do_valgrind_in_test; then
do_valgrind=yes
else
do_valgrind=no
fi
VALGRIND_FLAGS="--leak-check=full --show-leak-kinds=all"
get_random_port 2
UNBOUND_PORT=$RND_PORT
NSD_PORT=$(($RND_PORT + 1))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "NSD_PORT=$NSD_PORT" >> .tpkg.var.test
# make config file
sed -e 's/@UNBOUND_PORT\@/'$UNBOUND_PORT'/' -e 's/@NSD_PORT\@/'$NSD_PORT'/' < auth_tsig.ub.conf > ub.conf
sed -e 's/@UNBOUND_PORT\@/'$UNBOUND_PORT'/' -e 's/@NSD_PORT\@/'$NSD_PORT'/' < auth_tsig.nsd.conf > nsd.conf
# start nsd
$NSD -d -c nsd.conf >nsd.log 2>&1 &
NSD_PID=$!
echo "NSD_PID=$NSD_PID" >> .tpkg.var.test
# start unbound in the background
if test $do_valgrind = "yes"; then
valgrind $VALGRIND_FLAGS $PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
UNBOUND_PID=$!
else
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
UNBOUND_PID=$!
fi
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
cat .tpkg.var.test
wait_nsd_up nsd.log
wait_unbound_up unbound.log
+108
View File
@@ -0,0 +1,108 @@
# #-- auth_tsig.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
PRE="../.."
# do the test
echo "> dig www.example.com."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
if grep SERVFAIL outfile; then
echo "> try again"
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 10
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 10
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
echo "> check answer"
if grep "1.2.3.4" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi
# update the zonefile.
echo "www2.example.com. IN A 1.2.3.5" >> example.com.zone
mv example.com.zone tmp.zone
sed -e 's/2024082400/2024082401/' <tmp.zone >example.com.zone
echo ""
echo "new example.com.zone:"
cat example.com.zone
echo ""
# NSD reloads the zone file,
# sends notify to unbound, with TSIG.
# unbound replies to the notify, with TSIG.
# unbound fetches SOA record, with TSIG.
# unbound fetches zone transfer, with TSIG.
kill -1 `cat nsd.pid`
# test if the zone has updated.
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
if grep NXDOMAIN outfile; then
echo "> try again"
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
fi
if grep NXDOMAIN outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
fi
if grep NXDOMAIN outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
fi
if grep NXDOMAIN outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
fi
if grep NXDOMAIN outfile; then
echo "> try again"
sleep 10
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
fi
if grep NXDOMAIN outfile; then
echo "> try again"
sleep 10
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
fi
echo "> check answer"
if grep "1.2.3.5" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi
echo ""
echo "zonefile: unbound-example.com.zone"
cat unbound-example.com.zone
echo ""
exit 0
+26
View File
@@ -0,0 +1,26 @@
server:
verbosity: 7
num-threads: 1
interface: 127.0.0.1
port: @UNBOUND_PORT@
use-syslog: no
directory: ""
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
log-queries: yes
# This tsig key is used for testing.
tsig-key:
name: "test.key"
algorithm: sha256
secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
auth-zone:
name: "example.com"
zonefile: "unbound-example.com.zone"
for-upstream: yes
for-downstream: yes
primary-tsig: "127.0.0.1@@NSD_PORT@" test.key
allow-notify-tsig: "127.0.0.2@@NSD_PORT@" test.key
+4
View File
@@ -0,0 +1,4 @@
example.com. 240 IN SOA ns.nlnetlabs.nl. hostmaster.nlnetlabs.nl. 2024082400 28800 7200 604800 240
example.com. NS ns.example.com.
ns.example.com. IN A 192.0.2.1
www.example.com. A 1.2.3.4
+176
View File
@@ -0,0 +1,176 @@
# Test with algorithm MD5
file-algorithm md5
tsig-key:
name: "test.key"
algorithm: md5
secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
packet
# www.example.net. IN TXT
3a03010000010000000000000377777707657861
6d706c65036e65740000100001
endpacket
# check with the same contents
check-packet
3a03010000010000000000000377777707657861
6d706c65036e65740000100001
endpacket
# sign the query with <key> <timepoint> <expected function ret>
tsig-sign-query test.key 1750411954 1
check-packet
3a03010000010000000000010377777707657861
6d706c65036e657400001000010474657374036b
65790000fa00ff00000000003a08686d61632d6d
6435077369672d616c670372656703696e740000
0068552ab2012c0010d4a4778ce91160dc5dfd85
7e66f57bda3a0300000000
endpacket
# www.example.net A
packet
e707002000010000000000010377777707657861
6d706c65036e6574000001000100002910000000
00000000
endpacket
tsig-sign-query test.key 1750419725 1
check-packet
e707002000010000000000020377777707657861
6d706c65036e6574000001000100002910000000
000000000474657374036b65790000fa00ff0000
0000003a08686d61632d6d6435077369672d616c
670372656703696e740000006855490d012c0010
c00e00f1bafa240f41ee9cbe507b9802e7070000
0000
endpacket
tsig-verify-query test.key 1750419725 NOERROR NOERROR 0
# add some fudge to the time
packet
e707002000010000000000020377777707657861
6d706c65036e6574000001000100002910000000
000000000474657374036b65790000fa00ff0000
0000003a08686d61632d6d6435077369672d616c
670372656703696e740000006855490d012c0010
c00e00f1bafa240f41ee9cbe507b9802e7070000
0000
endpacket
tsig-verify-query test.key 1750419730 NOERROR NOERROR 0
# purposely make a bad digest
# changed 'www' (0x777777) to 'aaa' (0x616161)
packet
e707002000010000000000020361616107657861
6d706c65036e6574000001000100002910000000
000000000474657374036b65790000fa00ff0000
0000003a08686d61632d6d6435077369672d616c
670372656703696e740000006855490d012c0010
c00e00f1bafa240f41ee9cbe507b9802e7070000
0000
endpacket
tsig-verify-query test.key 1750419725 NOTAUTH BADSIG 0
# the wrong time is used, outside of the fudge region
packet
e707002000010000000000020377777707657861
6d706c65036e6574000001000100002910000000
000000000474657374036b65790000fa00ff0000
0000003a08686d61632d6d6435077369672d616c
670372656703696e740000006855490d012c0010
c00e00f1bafa240f41ee9cbe507b9802e7070000
0000
endpacket
tsig-verify-query test.key 1750819725 NOTAUTH BADTIME 1750819725
# An unknown key is used, 2222.key
packet
e707002000010000000000020377777707657861
6d706c65036e6574000001000100002910000000
000000000432323232036b65790000fa00ff0000
0000003a08686d61632d6d6435077369672d616c
670372656703696e740000006855490d012c0010
c00e00f1bafa240f41ee9cbe507b9802e7070000
0000
endpacket
tsig-verify-query 2222.key 1750419725 NOTAUTH BADKEY 0
# An unknown algorithm is used, hmac-UNK, 554e4b
packet
e707002000010000000000020377777707657861
6d706c65036e6574000001000100002910000000
000000000474657374036b65790000fa00ff0000
0000003a08686d61632d554e4b077369672d616c
670372656703696e740000006855490d012c0010
c00e00f1bafa240f41ee9cbe507b9802e7070000
0000
endpacket
tsig-verify-query test.key 1750419725 NOTAUTH BADKEY 0
# truncated hash
packet
e707002000010000000000020377777707657861
6d706c65036e6574000001000100002910000000
000000000474657374036b65790000fa00ff0000
0000003408686d61632d6d6435077369672d616c
670372656703696e740000006855490d012c000a
c00e00f1bafa240f41eee7070000
0000
endpacket
tsig-verify-query test.key 1750419725 NOTAUTH BADTRUNC 0
# TSIG does not parse, removed bytes from the end.
packet
e707002000010000000000020377777707657861
6d706c65036e6574000001000100002910000000
000000000474657374036b65790000fa00ff0000
0000003a08686d61632d6d6435077369672d616c
670372656703696e740000006855490d012c0010
c00e00f1bafa240f41ee9cbe507b9802
endpacket
tsig-verify-query . 1750419725 FORMERR NOERROR 0
# www.example.net A
packet
e707002000010000000000020377777707657861
6d706c65036e6574000001000100002910000000
000000000474657374036b65790000fa00ff0000
0000003a08686d61632d6d6435077369672d616c
670372656703696e740000006855490d012c0010
c00e00f1bafa240f41ee9cbe507b9802e7070000
0000
endpacket
tsig-sign-reply 1750419725 NOERROR 1
e707840000010001000000010377777707657861
6d706c65036e65740000010001c00c0001000100
000e1000040a141e2800002904d0000000000000
endpacket
# reply for www.example.net A
check-packet
e7078400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000003a08686d61632d6d6435077369672d616c670372656703696e740000006855490d012c0010dc3c138476fcb04cc138aa5c59647b86e70700000000
endpacket
# www.example.net A
packet
e707002000010000000000010377777707657861
6d706c65036e6574000001000100002910000000
00000000
endpacket
tsig-verify-reply test.key 1750419725 1 1
e7078400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000003a08686d61632d6d6435077369672d616c670372656703696e740000006855490d012c0010dc3c138476fcb04cc138aa5c59647b86e70700000000
endpacket
+57
View File
@@ -0,0 +1,57 @@
# Test with algorithm
file-algorithm sha1
tsig-key:
name: "test.key"
algorithm: sha1
secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
packet
# www.example.net. IN TXT
3a03010000010000000000000377777707657861
6d706c65036e65740000100001
endpacket
# sign the query with <key> <timepoint> <expected function ret>
tsig-sign-query test.key 1750411954 1
check-packet
3a030100000100000000000103777777076578616d706c65036e657400001000010474657374036b65790000fa00ff00000000002f09686d61632d7368613100000068552ab2012c0014ddea549c7a82a0c4309c0894f884adf9dcf7cd2c3a0300000000
endpacket
# www.example.net A
packet
092d0000000100000000000103777777076578616d706c65036e657400000100010000291000000000000000
endpacket
tsig-sign-query test.key 1750420740 1
check-packet
092d0000000100000000000203777777076578616d706c65036e6574000001000100002910000000000000000474657374036b65790000fa00ff00000000002f09686d61632d7368613100000068554d04012c0014f493f53a80f43dbd81df4f2feb7064de8247ba0b092d00000000
endpacket
tsig-verify-query test.key 1750420740 NOERROR NOERROR 0
packet
092d0000000100000000000203777777076578616d706c65036e6574000001000100002910000000000000000474657374036b65790000fa00ff00000000002f09686d61632d7368613100000068554d04012c0014f493f53a80f43dbd81df4f2feb7064de8247ba0b092d00000000
endpacket
tsig-sign-reply 1750420740 NOERROR 1
092d840000010001000000010377777707657861
6d706c65036e65740000010001c00c0001000100
000e1000040a141e2800002904d0000000000000
endpacket
# reply for www.example.net A
check-packet
092d8400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000002f09686d61632d7368613100000068554d04012c001475eace537fd51a9fbf192a10b20bfe824dd20318092d00000000
endpacket
# www.example.net A
packet
092d0000000100000000000103777777076578616d706c65036e657400000100010000291000000000000000
endpacket
tsig-verify-reply test.key 1750420740 1 1
092d8400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000002f09686d61632d7368613100000068554d04012c001475eace537fd51a9fbf192a10b20bfe824dd20318092d00000000
endpacket
+57
View File
@@ -0,0 +1,57 @@
# Test with algorithm
file-algorithm sha224
tsig-key:
name: "test.key"
algorithm: sha224
secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
packet
# www.example.net. IN TXT
3a03010000010000000000000377777707657861
6d706c65036e65740000100001
endpacket
# sign the query with <key> <timepoint> <expected function ret>
tsig-sign-query test.key 1750411954 1
check-packet
3a030100000100000000000103777777076578616d706c65036e657400001000010474657374036b65790000fa00ff0000000000390b686d61632d73686132323400000068552ab2012c001c104d12e4ccab950cb7690233661549b027567ea0c8beb868a7c1c4f33a0300000000
endpacket
# www.example.net A
packet
7e7e0000000100000000000103777777076578616d706c65036e657400000100010000291000000000000000
endpacket
tsig-sign-query test.key 1750421692 1
check-packet
7e7e0000000100000000000203777777076578616d706c65036e6574000001000100002910000000000000000474657374036b65790000fa00ff0000000000390b686d61632d736861323234000000685550bc012c001c03431f500872691d8780dafe326cdbe56ceaaca1d0ea3e3a262848e77e7e00000000
endpacket
tsig-verify-query test.key 1750421692 NOERROR NOERROR 0
packet
7e7e0000000100000000000203777777076578616d706c65036e6574000001000100002910000000000000000474657374036b65790000fa00ff0000000000390b686d61632d736861323234000000685550bc012c001c03431f500872691d8780dafe326cdbe56ceaaca1d0ea3e3a262848e77e7e00000000
endpacket
tsig-sign-reply 1750421692 NOERROR 1
7e7e840000010001000000010377777707657861
6d706c65036e65740000010001c00c0001000100
000e1000040a141e2800002904d0000000000000
endpacket
# reply for www.example.net A
check-packet
7e7e8400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff0000000000390b686d61632d736861323234000000685550bc012c001c0fa7ddec264122b5e0c3d1a64ed043c3d68582f0ae2ba2d5b3e186127e7e00000000
endpacket
# www.example.net A
packet
7e7e0000000100000000000103777777076578616d706c65036e657400000100010000291000000000000000
endpacket
tsig-verify-reply test.key 1750421692 1 1
7e7e8400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff0000000000390b686d61632d736861323234000000685550bc012c001c0fa7ddec264122b5e0c3d1a64ed043c3d68582f0ae2ba2d5b3e186127e7e00000000
endpacket
+1228
View File
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
# Test with algorithm
file-algorithm sha384
tsig-key:
name: "test.key"
algorithm: sha384
secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
packet
# www.example.net. IN TXT
3a03010000010000000000000377777707657861
6d706c65036e65740000100001
endpacket
# sign the query with <key> <timepoint> <expected function ret>
tsig-sign-query test.key 1750411954 1
check-packet
3a030100000100000000000103777777076578616d706c65036e657400001000010474657374036b65790000fa00ff00000000004d0b686d61632d73686133383400000068552ab2012c00302416b7442f06e5ab2f9814d391c48b73384ab59cccc7de20ecad999a38de62aaa1b61ac0cd3df299bab30776c92322f03a0300000000
endpacket
# www.example.net A
packet
aafc0000000100000000000103777777076578616d706c65036e657400000100010000291000000000000000
endpacket
tsig-sign-query test.key 1750421817 1
check-packet
aafc0000000100000000000203777777076578616d706c65036e6574000001000100002910000000000000000474657374036b65790000fa00ff00000000004d0b686d61632d73686133383400000068555139012c00300953f74bcc78dae61e9d93aad74e128dbc240a671de017efd3707235be7890cbf2a51255f5843438fbaa26d04caca506aafc00000000
endpacket
tsig-verify-query test.key 1750421817 NOERROR NOERROR 0
packet
aafc0000000100000000000203777777076578616d706c65036e6574000001000100002910000000000000000474657374036b65790000fa00ff00000000004d0b686d61632d73686133383400000068555139012c00300953f74bcc78dae61e9d93aad74e128dbc240a671de017efd3707235be7890cbf2a51255f5843438fbaa26d04caca506aafc00000000
endpacket
tsig-sign-reply 1750421817 NOERROR 1
aafc840000010001000000010377777707657861
6d706c65036e65740000010001c00c0001000100
000e1000040a141e2800002904d0000000000000
endpacket
# reply for www.example.net A
check-packet
aafc8400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000004d0b686d61632d73686133383400000068555139012c00301e895712f5633d84e82afd7b1dcdd792c5d51532c7a5f52701c9bd464f0d8f6cc735530d16417e8bf3cf104808554642aafc00000000
endpacket
# www.example.net A
packet
aafc0000000100000000000103777777076578616d706c65036e657400000100010000291000000000000000
endpacket
tsig-verify-reply test.key 1750421817 1 1
aafc8400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000004d0b686d61632d73686133383400000068555139012c00301e895712f5633d84e82afd7b1dcdd792c5d51532c7a5f52701c9bd464f0d8f6cc735530d16417e8bf3cf104808554642aafc00000000
endpacket
+57
View File
@@ -0,0 +1,57 @@
# Test with algorithm
file-algorithm sha512
tsig-key:
name: "test.key"
algorithm: sha512
secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
packet
# www.example.net. IN TXT
3a03010000010000000000000377777707657861
6d706c65036e65740000100001
endpacket
# sign the query with <key> <timepoint> <expected function ret>
tsig-sign-query test.key 1750411954 1
check-packet
3a030100000100000000000103777777076578616d706c65036e657400001000010474657374036b65790000fa00ff00000000005d0b686d61632d73686135313200000068552ab2012c00403cd816538bec85fea4ae45a6fb2e961622a4dfad2afa69da999c53133d02e9f2ba789a14b489678b83ab319662d2388fcc7286bfa11d88e71614c845e77584c43a0300000000
endpacket
# www.example.net A
packet
e74d0000000100000000000103777777076578616d706c65036e657400000100010000291000000000000000
endpacket
tsig-sign-query test.key 1750421867 1
check-packet
e74d0000000100000000000203777777076578616d706c65036e6574000001000100002910000000000000000474657374036b65790000fa00ff00000000005d0b686d61632d7368613531320000006855516b012c0040bbc78c7a8019119b79f89f3ed66d874acb3a29bfcd3ac75fce3779d60d41080fe536c03de404a9143314eabce88a0c5eff6204d94d3225cf42327322c8a48acae74d00000000
endpacket
tsig-verify-query test.key 1750421867 NOERROR NOERROR 0
packet
e74d0000000100000000000203777777076578616d706c65036e6574000001000100002910000000000000000474657374036b65790000fa00ff00000000005d0b686d61632d7368613531320000006855516b012c0040bbc78c7a8019119b79f89f3ed66d874acb3a29bfcd3ac75fce3779d60d41080fe536c03de404a9143314eabce88a0c5eff6204d94d3225cf42327322c8a48acae74d00000000
endpacket
tsig-sign-reply 1750421867 NOERROR 1
e74d840000010001000000010377777707657861
6d706c65036e65740000010001c00c0001000100
000e1000040a141e2800002904d0000000000000
endpacket
# reply for www.example.net A
check-packet
e74d8400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000005d0b686d61632d7368613531320000006855516b012c0040690c00d5e01a382b7a4c07739e0faab1a3c98f5bae1b49213032b7da070c4b985056894e1ebc88468d5d070d0589ea8032fb88f3a1902fa91211d2b4989bbb93e74d00000000
endpacket
# www.example.net A
packet
e74d0000000100000000000103777777076578616d706c65036e657400000100010000291000000000000000
endpacket
tsig-verify-reply test.key 1750421867 1 1
e74d8400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000005d0b686d61632d7368613531320000006855516b012c0040690c00d5e01a382b7a4c07739e0faab1a3c98f5bae1b49213032b7da070c4b985056894e1ebc88468d5d070d0589ea8032fb88f3a1902fa91211d2b4989bbb93e74d00000000
endpacket
+181
View File
@@ -0,0 +1,181 @@
/*
* util/allow_response_list.c - allow response list storage for the server.
*
* Copyright (c) 2025, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file helps the server discard excess TCP connections.
*/
#include "config.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/allow_response_list.h"
#include "services/localzone.h"
#include "sldns/str2wire.h"
const char* TSIG_NOKEY = "NOKEY";
const char* TSIG_BLOCKED = "BLOCKED";
struct arl_list*
arl_list_create(void)
{
struct arl_list* arl = (struct arl_list*)calloc(1,
sizeof(struct arl_list));
if(!arl)
return NULL;
arl->region = regional_create();
if(!arl->region) {
arl_list_delete(arl);
return NULL;
}
return arl;
}
static void
arl_list_free_node(rbnode_type* node, void* ATTR_UNUSED(arg))
{
struct arl_addr* n = (struct arl_addr*) node;
#ifdef THREADS_DISABLED
(void)n;
#endif
}
void
arl_list_delete(struct arl_list* arl)
{
if(!arl)
return;
traverse_postorder(&arl->tree, arl_list_free_node, NULL);
regional_destroy(arl->region);
free(arl);
}
/** insert new address into arl_list structure */
static struct arl_addr*
arl_list_insert(struct arl_list* arl, struct sockaddr_storage* addr,
socklen_t addrlen, int net, const char* tsig_key_name,
int complain_duplicates)
{
struct arl_addr* node = regional_alloc_zero(arl->region,
sizeof(struct arl_addr));
if(!node)
return NULL;
if(!tsig_key_name)
;
else if(strcmp(tsig_key_name, TSIG_NOKEY) == 0)
node->tsig_key_name = TSIG_NOKEY;
else if(strcmp(tsig_key_name, TSIG_BLOCKED) == 0)
node->tsig_key_name = TSIG_BLOCKED;
else
node->tsig_key_name = tsig_key_name;
if(!addr_tree_insert(&arl->tree, &node->node, addr, addrlen, net)) {
if(complain_duplicates)
verbose(VERB_QUERY, "duplicate arl address ignored.");
}
return node;
}
/** apply arl_list string */
static int
arl_list_str_cfg(struct arl_list* arl, const char* str, const char* s2,
int complain_duplicates)
{
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse allow response netblock: %s", str);
return 0;
}
if(!arl_list_insert(arl, &addr, addrlen, net, s2,
complain_duplicates)) {
log_err("out of memory");
return 0;
}
return 1;
}
/** read arl_list config */
static int
read_arl_list(struct arl_list* arl, struct config_file* cfg)
{
struct config_str2list* p;
for(p = cfg->allow_response_list; p; p = p->next) {
log_assert(p->str && p->str2);
if(!arl_list_str_cfg(arl, p->str, p->str2, 1))
return 0;
}
return 1;
}
int
arl_list_apply_cfg(struct arl_list* arl, struct config_file* cfg)
{
regional_free_all(arl->region);
addr_tree_init(&arl->tree);
if(!read_arl_list(arl, cfg))
return 0;
addr_tree_init_parents(&arl->tree);
return 1;
}
struct arl_addr*
arl_addr_lookup(struct arl_list* arl, struct sockaddr_storage* addr,
socklen_t addrlen)
{
return (struct arl_addr*)addr_tree_lookup(&arl->tree,
addr, addrlen);
}
size_t
arl_list_get_mem(struct arl_list* arl)
{
if(!arl) return 0;
return sizeof(*arl) + regional_get_mem(arl->region);
}
void arl_list_swap_tree(struct arl_list* arl, struct arl_list* data)
{
/* swap tree and region */
rbtree_type oldtree = arl->tree;
struct regional* oldregion = arl->region;
arl->tree = data->tree;
arl->region = data->region;
data->tree = oldtree;
data->region = oldregion;
}
+123
View File
@@ -0,0 +1,123 @@
/*
* util/allow_response_list.h - allow-response list storage for the server.
*
* Copyright (c) 2025, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file keeps track of the list of clients that are allowed to send
* responses to the server, so the server can store it in the cache.
*/
#ifndef UTIL_ALLOW_RESPONSE_LIST_H
#define UTIL_ALLOW_RESPONSE_LIST_H
#include "util/storage/dnstree.h"
#include "util/locks.h"
struct config_file;
struct regional;
/**
* allow response list storage structure
*/
struct arl_list {
/** regional for allocation */
struct regional* region;
/**
* Tree of the addresses that are allowed to send responses.
* contents of type arl_addr.
*/
rbtree_type tree;
};
extern const char* TSIG_NOKEY;
extern const char* TSIG_BLOCKED;
/**
*
* An address span that is allowed to send responses
*/
struct arl_addr {
/** node in address tree */
struct addr_tree_node node;
/** tsig key name, NULL means no key needed */
const char* tsig_key_name;
};
/**
* Create allow response list structure
* @return new structure or NULL on error.
*/
struct arl_list* arl_list_create(void);
/**
* Delete allow response list structure.
* @param arl: to delete.
*/
void arl_list_delete(struct arl_list* arl);
/**
* Process allow response list config.
* @param arl: where to store.
* @param cfg: config options.
* @return 0 on error.
*/
int arl_list_apply_cfg(struct arl_list* arl, struct config_file* cfg);
/**
* Lookup address to see its allow response list structure
* @param arl: structure for address storage.
* @param addr: address to check
* @param addrlen: length of addr.
* @return: arl structure from this address.
*/
struct arl_addr*
arl_addr_lookup(struct arl_list* arl, struct sockaddr_storage* addr,
socklen_t addrlen);
/**
* Get memory used by allow response list structure.
* @param arl: structure for address storage.
* @return bytes in use.
*/
size_t arl_list_get_mem(struct arl_list* arl);
/**
* Swap internal tree with preallocated entries.
* @param arl: the allow response list structure.
* @param data: the data structure used to take elements from. This contains
* the old elements on return.
*/
void arl_list_swap_tree(struct arl_list* arl, struct arl_list* data);
#endif /* UTIL_TCP_CONN_LIMIT_H */
+34 -1
View File
@@ -218,11 +218,15 @@ config_create(void)
cfg->ip_dscp = 0;
cfg->num_ifs = 0;
cfg->ifs = NULL;
cfg->num_dist = 0;
cfg->dist = NULL;
cfg->allow_response_list = NULL;
cfg->num_out_ifs = 0;
cfg->out_ifs = NULL;
cfg->stubs = NULL;
cfg->forwards = NULL;
cfg->auths = NULL;
cfg->tsig_keys = NULL;
#ifdef CLIENT_SUBNET
cfg->client_subnet = NULL;
cfg->client_subnet_zone = NULL;
@@ -932,7 +936,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
* max-client-subnet-ipv4, max-client-subnet-ipv6,
* min-client-subnet-ipv4, min-client-subnet-ipv6,
* max-ecs-tree-size-ipv4, max-ecs-tree-size-ipv6, ipsecmod_hook,
* ipsecmod_whitelist. */
* ipsecmod_whitelist, tsig-key. */
return 0;
}
return 1;
@@ -1109,6 +1113,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "log-time-iso", log_time_iso)
else O_DEC(opt, "num-threads", num_threads)
else O_IFC(opt, "interface", num_ifs, ifs)
else O_IFC(opt, "distribute", num_dist, dist)
else O_LS2(opt, "allow-response", allow_response_list)
else O_IFC(opt, "outgoing-interface", num_out_ifs, out_ifs)
else O_YNO(opt, "interface-automatic", if_automatic)
else O_STR(opt, "interface-automatic-ports", if_automatic_ports)
@@ -1439,6 +1445,7 @@ config_get_option(struct config_file* cfg, const char* opt,
* local-data-ptr - converted to local-data entries
* stub-zone, name, stub-addr, stub-host, stub-prime
* forward-zone, name, forward-addr, forward-host
* tsig-key
*/
else return 0;
return 1;
@@ -1645,6 +1652,8 @@ config_delauth(struct config_auth* p)
config_delstrlist(p->masters);
config_delstrlist(p->urls);
config_delstrlist(p->allow_notify);
config_deldblstrlist(p->masters_tsig);
config_deldblstrlist(p->allow_notify_tsig);
free(p->zonefile);
free(p->rpz_taglist);
free(p->rpz_action_override);
@@ -1710,6 +1719,27 @@ config_delviews(struct config_view* p)
}
}
void
config_deltsig_key(struct config_tsig_key* p)
{
if(!p) return;
free(p->name);
free(p->algorithm);
free(p->secret);
free(p);
}
void
config_deltsig_keys(struct config_tsig_key* p)
{
struct config_tsig_key* np;
while(p) {
np = p->next;
config_deltsig_key(p);
p = np;
}
}
void
config_del_strarray(char** array, int num)
{
@@ -1759,11 +1789,14 @@ config_delete(struct config_file* cfg)
free(cfg->log_identity);
}
config_del_strarray(cfg->ifs, cfg->num_ifs);
config_del_strarray(cfg->dist, cfg->num_dist);
config_deldblstrlist(cfg->allow_response_list);
config_del_strarray(cfg->out_ifs, cfg->num_out_ifs);
config_delstubs(cfg->stubs);
config_delstubs(cfg->forwards);
config_delauths(cfg->auths);
config_delviews(cfg->views);
config_deltsig_keys(cfg->tsig_keys);
config_delstrlist(cfg->donotqueryaddrs);
config_delstrlist(cfg->root_hints);
#ifdef CLIENT_SUBNET
+43
View File
@@ -45,6 +45,7 @@
struct config_stub;
struct config_auth;
struct config_view;
struct config_tsig_key;
struct config_strlist;
struct config_str2list;
struct config_str3list;
@@ -246,6 +247,16 @@ struct config_file {
/** interface description strings (IP addresses) */
char **ifs;
/** number of addresses to distribute new responses. */
int num_dist;
/** distribute description strings (IP addresses) */
char **dist;
/** distribute description strings (IP addresses) */
char **dist_tsig;
/** list of allowed responses, linked list */
struct config_str2list* allow_response_list;
/** number of outgoing interfaces to open.
* If 0 default all interfaces. */
int num_out_ifs;
@@ -262,6 +273,8 @@ struct config_file {
struct config_auth* auths;
/** the views definitions, linked list */
struct config_view* views;
/** the tsig-key definitions, linked list */
struct config_tsig_key* tsig_keys;
/** list of donotquery addresses, linked list */
struct config_strlist* donotqueryaddrs;
#ifdef CLIENT_SUBNET
@@ -850,6 +863,10 @@ struct config_auth {
struct config_strlist* urls;
/** list of allow-notify */
struct config_strlist* allow_notify;
/** list of masters with tsig key */
struct config_str2list* masters_tsig;
/** list of allow-notify with tsig key */
struct config_str2list* allow_notify_tsig;
/** zonefile (or NULL) */
char* zonefile;
/** provide downstream answers */
@@ -909,6 +926,20 @@ struct config_view {
struct config_str2list* respip_data;
};
/**
* Tsig-key config options
*/
struct config_tsig_key {
/** next in list */
struct config_tsig_key* next;
/** name of the tsig key */
char* name;
/** algorithm */
char* algorithm;
/** secret date, in base64 */
char* secret;
};
/**
* List of strings for config options
*/
@@ -1221,6 +1252,18 @@ void config_delview(struct config_view* p);
*/
void config_delviews(struct config_view* list);
/**
* Delete a tsig_key item
* @param p: tsig_key item
*/
void config_deltsig_key(struct config_tsig_key* p);
/**
* Delete items in config tsig_key list.
* @param list: list.
*/
void config_deltsig_keys(struct config_tsig_key* list);
/** check if config for remote control turns on IP-address interface
* with certificates or a named pipe without certificates. */
int options_remote_is_address(struct config_file* cfg);
+8
View File
@@ -276,6 +276,8 @@ use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
ip-address{COLON} { YDVAR(1, VAR_INTERFACE) }
distribute{COLON} { YDVAR(2, VAR_DISTRIBUTE ) }
allow-response{COLON} { YDVAR(2, VAR_ALLOW_RESPONSE) }
outgoing-interface{COLON} { YDVAR(1, VAR_OUTGOING_INTERFACE) }
interface-automatic{COLON} { YDVAR(1, VAR_INTERFACE_AUTOMATIC) }
interface-automatic-ports{COLON} { YDVAR(1, VAR_INTERFACE_AUTOMATIC_PORTS) }
@@ -362,8 +364,11 @@ rpz-signal-nxdomain-ra{COLON} { YDVAR(1, VAR_RPZ_SIGNAL_NXDOMAIN_RA) }
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
master{COLON} { YDVAR(1, VAR_MASTER) }
primary{COLON} { YDVAR(1, VAR_MASTER) }
master-tsig{COLON} { YDVAR(2, VAR_MASTER_TSIG) }
primary-tsig{COLON} { YDVAR(2, VAR_MASTER_TSIG) }
url{COLON} { YDVAR(1, VAR_URL) }
allow-notify{COLON} { YDVAR(1, VAR_ALLOW_NOTIFY) }
allow-notify-tsig{COLON} { YDVAR(2, VAR_ALLOW_NOTIFY_TSIG) }
for-downstream{COLON} { YDVAR(1, VAR_FOR_DOWNSTREAM) }
for-upstream{COLON} { YDVAR(1, VAR_FOR_UPSTREAM) }
fallback-enabled{COLON} { YDVAR(1, VAR_FALLBACK_ENABLED) }
@@ -608,6 +613,9 @@ iter-scrub-ns{COLON} { YDVAR(1, VAR_ITER_SCRUB_NS) }
iter-scrub-cname{COLON} { YDVAR(1, VAR_ITER_SCRUB_CNAME) }
max-global-quota{COLON} { YDVAR(1, VAR_MAX_GLOBAL_QUOTA) }
iter-scrub-promiscuous{COLON} { YDVAR(1, VAR_ITER_SCRUB_PROMISCUOUS) }
tsig-key{COLON} { YDVAR(0, VAR_TSIG_KEY) }
algorithm{COLON} { YDVAR(1, VAR_ALGORITHM) }
secret{COLON} { YDVAR(1, VAR_SECRET) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
/* Quoted strings. Strip leading and ending quotes */
+141 -10
View File
@@ -47,7 +47,9 @@
#include "util/configyyrename.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/tsig.h"
#include "sldns/str2wire.h"
#include "sldns/parseutil.h"
int ub_c_lex(void);
void ub_c_error(const char *message);
@@ -73,8 +75,9 @@ extern struct config_parser_state* cfg_parser;
%token <str> STRING_ARG
%token VAR_FORCE_TOPLEVEL
%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
%token VAR_OUTGOING_RANGE VAR_INTERFACE VAR_PREFER_IP4
%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_NAT64 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP
%token VAR_OUTGOING_RANGE VAR_INTERFACE VAR_DISTRIBUTE VAR_ALLOW_RESPONSE
%token VAR_PREFER_IP4 VAR_DO_IP4 VAR_DO_IP6 VAR_DO_NAT64 VAR_PREFER_IP6
%token VAR_DO_UDP VAR_DO_TCP
%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_TCP_IDLE_TIMEOUT
%token VAR_EDNS_TCP_KEEPALIVE VAR_EDNS_TCP_KEEPALIVE_TIMEOUT
%token VAR_SOCK_QUEUE_TIMEOUT
@@ -190,6 +193,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_CACHEDB_REDISCONNECTTIMEOUT VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
%token VAR_MASTER_TSIG VAR_ALLOW_NOTIFY_TSIG
%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
@@ -217,6 +221,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_COOKIE_SECRET_FILE VAR_ITER_SCRUB_NS VAR_ITER_SCRUB_CNAME
%token VAR_MAX_GLOBAL_QUOTA VAR_HARDEN_UNVERIFIED_GLUE VAR_LOG_TIME_ISO
%token VAR_ITER_SCRUB_PROMISCUOUS
%token VAR_TSIG_KEY VAR_ALGORITHM VAR_SECRET
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -225,7 +230,7 @@ toplevelvar: serverstart contents_server | stub_clause |
rcstart contents_rc | dtstart contents_dt | view_clause |
dnscstart contents_dnsc | cachedbstart contents_cachedb |
ipsetstart contents_ipset | authstart contents_auth |
rpzstart contents_rpz | dynlibstart contents_dl |
rpzstart contents_rpz | dynlibstart contents_dl | tsig_key_clause |
force_toplevel
;
force_toplevel: VAR_FORCE_TOPLEVEL
@@ -250,7 +255,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_tcp_mss | server_outgoing_tcp_mss | server_tcp_idle_timeout |
server_tcp_keepalive | server_tcp_keepalive_timeout |
server_sock_queue_timeout |
server_interface | server_chroot | server_username |
server_interface | server_distribute | server_allow_response |
server_chroot | server_username |
server_directory | server_logfile | server_pidfile |
server_msg_cache_size | server_msg_cache_slabs |
server_num_queries_per_thread | server_rrset_cache_size |
@@ -465,9 +471,10 @@ authstart: VAR_AUTH_ZONE
;
contents_auth: contents_auth content_auth
| ;
content_auth: auth_name | auth_zonefile | auth_master | auth_url |
auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
auth_allow_notify | auth_zonemd_check | auth_zonemd_reject_absence
content_auth: auth_name | auth_zonefile | auth_master | auth_master_tsig |
auth_url | auth_for_downstream | auth_for_upstream |
auth_fallback_enabled | auth_allow_notify | auth_allow_notify_tsig |
auth_zonemd_check | auth_zonemd_reject_absence
;
rpz_tag: VAR_TAGS STRING_ARG
@@ -562,9 +569,10 @@ rpzstart: VAR_RPZ
;
contents_rpz: contents_rpz content_rpz
| ;
content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url |
auth_allow_notify | rpz_action_override | rpz_cname_override |
rpz_log | rpz_log_name | rpz_signal_nxdomain_ra | auth_for_downstream
content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master |
auth_master_tsig | auth_url | auth_allow_notify |
auth_allow_notify_tsig | rpz_action_override | rpz_cname_override |
rpz_log | rpz_log_name | rpz_signal_nxdomain_ra | auth_for_downstream
;
server_num_threads: VAR_NUM_THREADS STRING_ARG
{
@@ -814,6 +822,37 @@ server_interface: VAR_INTERFACE STRING_ARG
cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = $2;
}
;
server_distribute: VAR_DISTRIBUTE STRING_ARG STRING_ARG
{
OUTYY(("P(server_distribute: %s %s)\n", $2, $3));
if(cfg_parser->cfg->num_dist == 0) {
cfg_parser->cfg->dist = calloc(1, sizeof(char*));
cfg_parser->cfg->dist_tsig = calloc(1, sizeof(char*));
}
else {
cfg_parser->cfg->dist = realloc(cfg_parser->cfg->dist,
(cfg_parser->cfg->num_dist+1)*sizeof(char*));
cfg_parser->cfg->dist_tsig = realloc(
cfg_parser->cfg->dist_tsig,
(cfg_parser->cfg->num_dist+1)*sizeof(char*));
}
if(!cfg_parser->cfg->dist || !cfg_parser->cfg->dist_tsig)
yyerror("out of memory");
else {
cfg_parser->cfg->dist[cfg_parser->cfg->num_dist] = $2;
cfg_parser->cfg->dist_tsig[cfg_parser->cfg->num_dist]
= $3;
cfg_parser->cfg->num_dist += 1;
}
}
;
server_allow_response: VAR_ALLOW_RESPONSE STRING_ARG STRING_ARG
{
OUTYY(("P(allow_response: %s %s)\n", $2, $3));
if(!cfg_str2list_insert(&cfg_parser->cfg->allow_response_list, $2, $3))
fatal_exit("out of memory adding acl for responses");
}
;
server_outgoing_interface: VAR_OUTGOING_INTERFACE STRING_ARG
{
OUTYY(("P(server_outgoing_interface:%s)\n", $2));
@@ -3263,6 +3302,14 @@ auth_master: VAR_MASTER STRING_ARG
yyerror("out of memory");
}
;
auth_master_tsig: VAR_MASTER_TSIG STRING_ARG STRING_ARG
{
OUTYY(("P(master-tsig:%s)\n", $2));
if(!cfg_str2list_insert(&cfg_parser->cfg->auths->masters_tsig,
$2, $3))
yyerror("out of memory");
}
;
auth_url: VAR_URL STRING_ARG
{
OUTYY(("P(url:%s)\n", $2));
@@ -3278,6 +3325,14 @@ auth_allow_notify: VAR_ALLOW_NOTIFY STRING_ARG
yyerror("out of memory");
}
;
auth_allow_notify_tsig: VAR_ALLOW_NOTIFY_TSIG STRING_ARG STRING_ARG
{
OUTYY(("P(allow-notify-tsig:%s)\n", $2));
if(!cfg_str2list_insert(
&cfg_parser->cfg->auths->allow_notify_tsig, $2, $3))
yyerror("out of memory");
}
;
auth_zonemd_check: VAR_ZONEMD_CHECK STRING_ARG
{
OUTYY(("P(zonemd-check:%s)\n", $2));
@@ -3746,6 +3801,82 @@ dl_file: VAR_DYNLIB_FILE STRING_ARG
yyerror("out of memory");
}
;
tsig_key_clause: tsig_key_start contents_tsig_key
{
/* tsig-key end */
if(cfg_parser->cfg->tsig_keys) {
if(!cfg_parser->cfg->tsig_keys->name)
yyerror("tsig-key without name");
else if(!cfg_parser->cfg->tsig_keys->algorithm)
ub_c_error_msg("tsig-key %s has no algorithm",
cfg_parser->cfg->tsig_keys->name);
else if(!cfg_parser->cfg->tsig_keys->secret)
ub_c_error_msg("tsig-key %s has no secret blob",
cfg_parser->cfg->tsig_keys->name);
}
}
;
tsig_key_start: VAR_TSIG_KEY
{
struct config_tsig_key* s;
OUTYY(("\nP(tsig-key:)\n"));
cfg_parser->started_toplevel = 1;
s = (struct config_tsig_key*)calloc(1,
sizeof(struct config_tsig_key));
if(s) {
s->next = cfg_parser->cfg->tsig_keys;
cfg_parser->cfg->tsig_keys = s;
} else {
yyerror("out of memory");
}
}
;
contents_tsig_key: contents_tsig_key content_tsig_key
| ;
content_tsig_key: tsig_key_name | tsig_key_algorithm | tsig_key_secret
;
tsig_key_name: VAR_NAME STRING_ARG
{
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
size_t len = sizeof(buf);
int r;
OUTYY(("P(name:%s)\n", $2));
free(cfg_parser->cfg->tsig_keys->name);
cfg_parser->cfg->tsig_keys->name = $2;
if((r=sldns_str2wire_dname_buf($2, buf, &len))!=0)
ub_c_error_msg("could not parse tsig key name"
" '%s':%d: %s", $2, LDNS_WIREPARSE_OFFSET(r),
sldns_get_errorstr_parse(r));
}
tsig_key_algorithm: VAR_ALGORITHM STRING_ARG
{
OUTYY(("P(algorithm:%s)\n", $2));
free(cfg_parser->cfg->tsig_keys->algorithm);
cfg_parser->cfg->tsig_keys->algorithm = $2;
if(!tsig_algo_check_name($2))
ub_c_error_msg("could not parse tsig key algorithm '%s'",
$2);
}
tsig_key_secret: VAR_SECRET STRING_ARG
{
uint8_t data[16384];
int size;
OUTYY(("P(secret:%s)\n", $2));
free(cfg_parser->cfg->tsig_keys->secret);
cfg_parser->cfg->tsig_keys->secret = $2;
size = sldns_b64_pton($2, data, sizeof(data));
if(size == -1) {
ub_c_error_msg("cannot base64 decode tsig secret %s",
cfg_parser->cfg->tsig_keys->name?
cfg_parser->cfg->tsig_keys->name:"");
} else if(size != 0) {
explicit_bzero(data, size);
}
}
server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
{
OUTYY(("P(disable_dnssec_lame_check:%s)\n", $2));
+1 -1
View File
@@ -97,7 +97,7 @@ dname_valid(uint8_t* dname, size_t maxlen)
/** compare uncompressed, noncanonical, registers are hints for speed */
int
query_dname_compare(register uint8_t* d1, register uint8_t* d2)
query_dname_compare(register const uint8_t* d1, register const uint8_t* d2)
{
register uint8_t lab1, lab2;
log_assert(d1 && d2);
+1 -1
View File
@@ -96,7 +96,7 @@ void pkt_dname_tolower(struct sldns_buffer* pkt, uint8_t* dname);
* @return: -1, 0, or +1 depending on comparison results.
* Sort order is first difference found. not the canonical ordering.
*/
int query_dname_compare(uint8_t* d1, uint8_t* d2);
int query_dname_compare(const uint8_t* d1, const uint8_t* d2);
/**
* Determine correct, compressed, dname present in packet.
+26 -4
View File
@@ -1282,10 +1282,32 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
return LDNS_RCODE_FORMERR;
}
/* check edns section is present */
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) {
return LDNS_RCODE_FORMERR;
}
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) == 0) {
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 0) {
int i, edns_found = 0;
for(i=0; i<(int)LDNS_ARCOUNT(sldns_buffer_begin(pkt)); i++) {
if(sldns_buffer_remaining(pkt) < 1)
return LDNS_RCODE_FORMERR;
if(sldns_buffer_current(pkt)[0] == 0) {
/* The domain name is the root of length 1. */
/* See if the RR Type is OPT. */
if(sldns_buffer_remaining(pkt) < 3)
return LDNS_RCODE_FORMERR;
if(sldns_buffer_read_u16_at(pkt,
sldns_buffer_position(pkt)+1) ==
LDNS_RR_TYPE_OPT) {
/* This is the EDNS OPT record */
edns_found = 1;
break;
}
}
if(!skip_pkt_rrs(pkt, 1))
return LDNS_RCODE_FORMERR;
}
if(!edns_found) {
edns->udp_size = 512;
return 0;
}
} else if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) == 0) {
edns->udp_size = 512;
return 0;
}
+2
View File
@@ -72,6 +72,7 @@
#include "libunbound/libworker.h"
#include "libunbound/context.h"
#include "libunbound/worker.h"
#include "util/tsig.h"
#include "util/tube.h"
#include "util/config_file.h"
#include "daemon/remote.h"
@@ -262,6 +263,7 @@ fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *))
else if(fptr == &auth_zone_cmp) return 1;
else if(fptr == &auth_data_cmp) return 1;
else if(fptr == &auth_xfer_cmp) return 1;
else if(fptr == &tsig_key_compare) return 1;
#ifdef HAVE_NGTCP2
else if(fptr == &doq_conn_cmp) return 1;
else if(fptr == &doq_conid_cmp) return 1;
+3
View File
@@ -181,6 +181,7 @@ struct views;
struct respip_set;
struct respip_client_info;
struct respip_addr_info;
struct tsig_key_table;
struct module_stack;
/** Maximum number of modules in operation */
@@ -534,6 +535,8 @@ struct module_env {
struct views* views;
/** response-ip set with associated actions and tags. */
struct respip_set* respip_set;
/** the TSIG keys */
struct tsig_key_table* tsig_key_table;
/** module specific data. indexed by module id. */
void* modinfo[MAX_MODULE];
+2463
View File
File diff suppressed because it is too large Load Diff
+517
View File
@@ -0,0 +1,517 @@
/*
* util/tsig.h - handle TSIG signatures.
*
* Copyright (c) 2023, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file provides functions to create and verify TSIG RRs.
*/
#ifndef UTIL_TSIG_H
#define UTIL_TSIG_H
#include "util/locks.h"
#include "util/rbtree.h"
struct sldns_buffer;
struct config_file;
struct config_tsig_key;
struct regional;
struct tsig_calc_state_crypto;
/**
* TSIG record, the RR that is in the packet.
* The RR Type is TSIG and the RR class is CLASS_ANY. The TTL is 0.
*/
struct tsig_record {
/** domain name of the RR, the key name. */
uint8_t* key_name;
/** length of the key_name */
size_t key_name_len;
/** the position of the TSIG RR in the packet, it is before the owner
* name. */
size_t tsig_pos;
/** the algorithm name, as a domain name. */
uint8_t* algorithm_name;
/** length of the algorithm_name */
size_t algorithm_name_len;
/** the signed time, 48bits on the wire */
uint64_t signed_time;
/** the fudge time */
uint16_t fudge_time;
/** the mac size, uint16_t on the wire */
size_t mac_size;
/** the mac data */
uint8_t* mac_data;
/** the original query id */
uint16_t original_query_id;
/** the tsig error code */
uint16_t error_code;
/** length of the other data, uint16_t on the wire */
size_t other_size;
/** the other data */
uint8_t* other_data;
/** if the other size is 48bit, the timestamp in it. */
uint64_t other_time;
};
/**
* TSIG data. This keeps track of the information between packets,
* for the TSIG signature, and state, errors, key.
*/
struct tsig_data {
/** The key name, in wireformat */
uint8_t* key_name;
/** length of the key name */
size_t key_name_len;
/** The algo name, if the key could not be found. If NULL, it can
* be found in the tsig_key algo. */
uint8_t* algo_name;
/** length of the algo name */
size_t algo_name_len;
/** mac size */
size_t mac_size;
/** digest buffer */
uint8_t* mac;
/** original query ID */
uint16_t original_query_id;
/** the TSIG class */
uint16_t klass;
/** the TSIG TTL */
uint16_t ttl;
/** the time signed, 48bit */
uint64_t time_signed;
/** fudge amount of time_signed */
uint16_t fudge;
/** the TSIG error code */
uint16_t error;
/** other data length, 6 for other_time as failed time. */
uint16_t other_len;
/** if other len 6, this is 48bit time of error. */
uint64_t other_time;
/** For zone transfers, there are several packets and TSIGs,
* this keeps track of the tsig calculation state. It is malloced,
* and the tsig has to be deleted to free it. */
struct tsig_calc_state_crypto* calc_state;
/** For the first packet it is 0, for later packets 1. */
int later_packet;
/** The number of update only packets without a tsig. */
int num_updates;
/** The number of packets after which to sign with TSIG, 1 is every
* time. */
int every_nth;
};
/**
* TSIG algorithm. This is the HMAC algorithm used for the TSIG mac.
*/
struct tsig_algorithm {
/** Short name of the algorithm, like "hmac-md5" */
char* short_name;
/**
* Full wireformat name of the algorith, such as
* "hmac-md5.sig-alg.reg.int."
* In canonical format, that is in lowercase.
*/
uint8_t* wireformat_name;
/** length of the wireformat_name */
size_t wireformat_name_len;
/** digest name, like "md5" */
const char* digest;
/** the maximum size of the digest from the algorithm, in bytes,
* like 16 for MD5, and 20 for SHA1. */
size_t max_digest_size;
};
/**
* TSIG key. This is used to sign and verify packets.
*/
struct tsig_key {
/** the rbtree node */
rbnode_type node;
/** name of the key as string */
char* name_str;
/** the algorithm structure */
struct tsig_algorithm* algo;
/**
* Name of the key, in wireformat.
* The key name has to be transferred as a domain name, of the TSIG
* RR and thus the key name has to be a wireformat domain name.
*/
uint8_t* name;
/** length of name */
size_t name_len;
/** the data, with the secret portion of the key. decoded from the
* base64 string with the secret. */
uint8_t* data;
/** the size of the data */
size_t data_len;
};
/**
* The TSIG key storage. Keys are stored by name.
* They are read from config.
*/
struct tsig_key_table {
/* Lock on the tsig key table and all keys.
* This lock is after the forwards, hints and anchor locks. */
lock_rw_type lock;
/* Tree of tsig keys, by wireformat name. */
struct rbtree_type* tree;
};
/**
* Create TSIG key table.
* @return NULL on alloc failure.
*/
struct tsig_key_table* tsig_key_table_create(void);
/**
* Delete TSIG key table. And the keys in it.
* @param key_table: to delete.
*/
void tsig_key_table_delete(struct tsig_key_table* key_table);
/** Add a key to the TSIG key table. */
int tsig_key_table_add_key(struct tsig_key_table* key_table,
struct config_tsig_key* s);
/** Delete a key from the TSIG key table. */
void tsig_key_table_del_key_fromstr(struct tsig_key_table* key_table,
char* name);
/**
* Apply config to the tsig key table.
* @param key_table: the tsig key table.
* @param cfg: the config to read.
* @return false on failure.
*/
int tsig_key_table_apply_cfg(struct tsig_key_table* key_table,
struct config_file* cfg);
/**
* Find key in key table. Caller must hold lock on the table.
* @param key_table: the tsig key table.
* @param name: name to look for in wireformat.
* @param namelen: length of name.
* @return the found key or NULL if not found. The item is locked
* by the key_table lock.
*/
struct tsig_key* tsig_key_table_search(struct tsig_key_table* key_table,
uint8_t* name, size_t namelen);
/**
* Find key in key table. Caller must hold lock on the table.
* @param key_table: the tsig key table.
* @param name: the name in string format, it is parsed to wireformat.
* @return the found key or NULL if not found or NULL on parse error of the
* key name as a domain name. The item is locked by the key_table lock.
*/
struct tsig_key* tsig_key_table_search_fromstr(
struct tsig_key_table* key_table, const char* name);
/**
* Get memory usage of tsig key table.
* @param tsig_key_table: the tsig key table.
* @return memory use.
*/
size_t tsig_key_table_get_mem(struct tsig_key_table* tsig_key_table);
/**
* Swap internal tree with preallocated entries. Caller should manage
* the locks.
* @param tsig_key_table: the tsig_key_table data structure.
* @param data: the data structure used to take elements from. This contains
* the old elements on return.
*/
void tsig_key_table_swap_tree(struct tsig_key_table* tsig_key_table,
struct tsig_key_table* data);
/**
* Delete TSIG key.
* @param key: to delete
*/
void tsig_key_delete(struct tsig_key* key);
/**
* See if an algorithm name is in the list of accepted algorithm names.
* @param algo_name: string to check
* @return 0 on failure.
*/
int tsig_algo_check_name(const char* algo_name);
/**
* Get the TSIG algorithm for the algorithm name.
* @param algo_name: string to find.
* @return NULL on failure, tsig algorithm structure.
*/
struct tsig_algorithm* tsig_algo_find_name(const char* algo_name);
/**
* Get the TSIG algorithm for the algorithm wireformat name.
* @param algo: wireformat algorithm name to find.
* @return NULL on failure, tsig algorithm structure.
*/
struct tsig_algorithm* tsig_algo_find_wire(uint8_t* algo);
/**
* Sign pkt with the name (domain name), algorithm and key in Base64.
* out 0 on success, -1 on failure.
* For a shared packet with contents. This signs a reply packet without
* the prior hash, since there is no prior packet.
*/
int tsig_sign_shared(struct sldns_buffer* pkt, const uint8_t* name,
const uint8_t* alg, const uint8_t* secret, size_t secret_len,
uint64_t now);
/**
* Verify pkt with the name (domain name), algorithm and key in Base64.
* out 0 on success, an error code otherwise.
* For a shared packet with contents. This verifies a reply packet without
* the prior hash, since there is no prior packet.
* out 0 on success, on failure:
* -1 for malformed, no tsig RR, or too large for buffer.
* >0 rcode with a TSIG error code otherwise.
*/
int tsig_verify_shared(struct sldns_buffer* pkt, const uint8_t* name,
const uint8_t* alg, const uint8_t* secret, size_t secret_len,
uint64_t now);
/** Compare function for the key table keys. */
int tsig_key_compare(const void* v1, const void* v2);
/**
* Find tsig key and create new tsig data.
* @param key_table: the tsig key table.
* @param name: key name in wireformat.
* @param namelen: length of name.
* @return NULL if not found, or alloc failure.
*/
struct tsig_data* tsig_create(struct tsig_key_table* key_table,
uint8_t* name, size_t namelen);
/**
* Find tsig key and create new tsig data.
* @param key_table: the tsig key table.
* @param name: key name string.
* @return NULL if not found, or alloc failure, or could not parse string.
*/
struct tsig_data* tsig_create_fromstr(struct tsig_key_table* key_table,
char* name);
/**
* Delete tsig data.
* @param tsig: the tsig data to delete.
*/
void tsig_delete(struct tsig_data* tsig);
/**
* Get memory usage of tsig data.
* @param rsig: the tsig data.
* @return memory use.
*/
size_t tsig_get_mem(struct tsig_data* tsig);
/**
* Sign a query with TSIG. Appends the TSIG record.
* @param tsig: the tsig data, keeps state to verify reply.
* @param pkt: query packet. position must be at end of packet.
* @param key_table: the tsig key table is used to fetch the key details.
* @param now: time to sign the query, the current time.
* @return false on failure.
*/
int tsig_sign_query(struct tsig_data* tsig, struct sldns_buffer* pkt,
struct tsig_key_table* key_table, uint64_t now);
/**
* Verify a query with TSIG.
* @param tsig: the tsig data, keep state to sign reply.
* @param pkt: the query packet.
* @param key: the key with algorithm, caller must hold lock.
* @param rr: the tsig record parsed from the query.
* @param now: time that is used, the current time.
* @return rcode with failure for alloc failure or malformed wireformat.
* 0 NOERROR is success, if tsig is nonNULL it has either verified
* or contains a TSIG error.
*/
int tsig_verify_query(struct tsig_data* tsig, struct sldns_buffer* pkt,
struct tsig_key* key, struct tsig_record* rr, uint64_t now);
/**
* Look up key from TSIG in packet.
* @param key_table: the tsig key table.
* @param pkt: the packet to look at TSIG.
* @param rr: the TSIG record parsed.
* @param tsig_ret: the tsig key is returned here. Or it can be NULL, no TSIG.
* @param region: if nonNULL used to allocate.
* @param key: if the key is in the key_table the key is returned.
* On success the key table is locked for the key.
* @return fail for alloc failure servfail or wireformat malformed formerr,
* success has 0 NOERROR, for no TSIG in packet with tsig returned NULL,
* and for key not found with tsig returned with a tsig error in it,
* and for key found with tsig returned with tsig in it.
* After this call, the return value is the rcode for failure. Then the
* tsig, is NULL for no TSIG, or nonNULL, with a TSIG error or content that
* can be verified with tsig_verify_query.
*/
int tsig_lookup_key(struct tsig_key_table* key_table,
struct sldns_buffer* pkt, struct tsig_record* rr,
struct tsig_data** tsig_ret, struct regional* region,
struct tsig_key** key);
/**
* Parse a TSIG from the packet. Current position is just before it.
* @param pkt: the packet.
* @param rr: data filled in, with pointers to the packet buffer.
* The key name can be compressed.
* @return 0 if OK, otherwise an RCODE.
*/
int tsig_parse(struct sldns_buffer* pkt, struct tsig_record* rr);
/**
* Parse and verify the TSIG in query packet.
* @param key_table: the tsig key table.
* @param pkt: the packet
* @param tsig: the tsig key is returned. Or it can be NULL.
* @param region: if nonNULL used to allocate.
* @param now: time that is used, the current time.
* @return rcode with failure for alloc failure or malformed wireformat.
* 0 NOERROR is success, if tsig is nonNULL it has either verified
* or contains a TSIG error.
*/
int tsig_parse_verify_query(struct tsig_key_table* key_table,
struct sldns_buffer* pkt, struct tsig_data** tsig,
struct regional* region, uint64_t now);
/**
* Sign a reply with TSIG. Appends the TSIG record.
* @param tsig: the tsig data.
* @param pkt: the packet to sign.
* @param key_table: the tsig key table is used to fetch the key details.
* @param now: time to sign the query, the current time.
* @return false on failure.
*/
int tsig_sign_reply(struct tsig_data* tsig, struct sldns_buffer* pkt,
struct tsig_key_table* key_table, uint64_t now);
/**
* Verify a reply with TSIG.
* @param tsig: the tsig data.
* @param pkt: the reply to verify.
* @param key: the key with algorithm, caller must hold lock.
* @param rr: the tsig record parsed from the reply.
* @param now: time to sign the query, the current time.
* @return false on failure, like
* alloc failure, wireformat malformed, did not verify.
*/
int tsig_verify_reply(struct tsig_data* tsig, struct sldns_buffer* pkt,
struct tsig_key* key, struct tsig_record* rr, uint64_t now);
/**
* Verify a reply with TSIG.
* @param tsig: the tsig data.
* @param pkt: the reply to verify.
* @param key_table: the tsig key table is used to fetch the key details.
* @param now: time to sign the query, the current time.
* @return false on failure, like
* alloc failure, wireformat malformed, did not verify.
*/
int tsig_parse_verify_reply(struct tsig_data* tsig, struct sldns_buffer* pkt,
struct tsig_key_table* key_table, uint64_t now);
/**
* Calculate reserved space for TSIG.
* @param tsig: the tsig data
* @return number of bytes to keep reserved for the TSIG added.
*/
size_t tsig_reserved_space(struct tsig_data* tsig);
/**
* See if the packet has a TSIG record, or not.
* @param pkt: the packet.
* @return false if malformed or no tsig. If found, the position is
* just before the TSIG record. So it can be parsed.
*/
int tsig_find_rr(struct sldns_buffer* pkt);
/**
* See if the packet as a TSIG, or not. Like tsig_find_rr, but it logs
* no error for absence of a TSIG.
* @param pkt: the packet
* @return false if malformed, and false if no tsig. true if tsig,
* and the position is just before the TSIG record. So it can be parsed.
*/
int tsig_in_packet(struct sldns_buffer* pkt);
/**
* Sign XFR reply with TSIG. Appends the TSIG record. Call for later
* packets too.
* @param tsig: the tsig data. It must be malloced for the crypto state.
* @param pkt: the packet to sign.
* @param key_table: the tsig key table is used to fetch the key details.
* @param now: time to sign the query, the current time.
* @param last_packet: set to true for the last packet, that needs to be
* TSIG signed.
* @return false on failure.
*/
int tsig_sign_reply_xfr(struct tsig_data* tsig, struct sldns_buffer* pkt,
struct tsig_key_table* key_table, uint64_t now, int last_packet);
/**
* Verify XFR reply with TSIG.
* @param tsig: the tsig data.
* @param pkt: the reply to verify.
* @param rr: the tsig record parsed from the reply.
* @param now: time to sign the query, the current time.
* @return false on failure, like
* alloc failure, wireformat malformed, did not verify.
*/
int tsig_verify_reply_xfr(struct tsig_data* tsig, struct sldns_buffer* pkt,
struct tsig_record* rr, uint64_t now);
/**
* Parse and verify XFR reply with TSIG. Position at the TSIG record, or
* at end of packet if no TSIG record.
* @param tsig: the tsig data.
* @param pkt: the reply to verify.
* @param key_table: the tsig key table is used to fetch the key details.
* @param now: time to sign the query, the current time.
* @param last_packet: set true for the last packet, it must have a TSIG.
* @return false on failure, like
* alloc failure, wireformat malformed, did not verify.
*/
int tsig_parse_verify_reply_xfr(struct tsig_data* tsig,
struct sldns_buffer* pkt, struct tsig_key_table* key_table,
uint64_t now, int last_packet);
#endif /* UTIL_TSIG_H */