mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
103
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c834ee635c | ||
|
|
7977ef28f5 | ||
|
|
c86c267b8b | ||
|
|
3963af8d0b | ||
|
|
3d6a4c7d6e | ||
|
|
2217c9b96e | ||
|
|
6592c73d56 | ||
|
|
8687d69131 | ||
|
|
c622a71a28 | ||
|
|
ecfc6a70ce | ||
|
|
a23c5347a7 | ||
|
|
1ae8be6847 | ||
|
|
f0268d3e83 | ||
|
|
c904a3d375 | ||
|
|
b451cc4af7 | ||
|
|
f9713f9fe5 | ||
|
|
dfac72edfc | ||
|
|
64e102aacb | ||
|
|
bebd6c0f96 | ||
|
|
63aa70ab32 | ||
|
|
7b59014ba3 | ||
|
|
156846e6c4 | ||
|
|
aea2a821b9 | ||
|
|
cacdfee755 | ||
|
|
e3c1981a6a | ||
|
|
e2efd17007 | ||
|
|
4a2dc1df48 | ||
|
|
5c79fd9a0b | ||
|
|
4a3a4f474f | ||
|
|
708581579c | ||
|
|
af1d430759 | ||
|
|
da72734240 | ||
|
|
54175a4180 | ||
|
|
888d5ce9f9 | ||
|
|
b1bb4a4592 | ||
|
|
3b88577dd1 | ||
|
|
6634b8bcc5 | ||
|
|
3d7dfe2f36 | ||
|
|
baee7885bd | ||
|
|
e55b3a2a4c | ||
|
|
b5a2de1292 | ||
|
|
5ed0840dc2 | ||
|
|
9bbb34fc38 | ||
|
|
433bb1c7bc | ||
|
|
f3b960e72b | ||
|
|
5bd31c9569 | ||
|
|
4f245e0e5b | ||
|
|
e4069e5619 | ||
|
|
a3ec9a974f | ||
|
|
479b954118 | ||
|
|
0955238cd3 | ||
|
|
57dd6a971d | ||
|
|
6a831e3063 | ||
|
|
3807bf00da | ||
|
|
9022381be4 | ||
|
|
ca147a147d | ||
|
|
5147e5aee9 | ||
|
|
6466513cc5 | ||
|
|
7a1a615fd3 | ||
|
|
81d774fb11 | ||
|
|
0254317e0d | ||
|
|
dc37849546 | ||
|
|
766666139b | ||
|
|
86e78fcacc | ||
|
|
47a2d71fd3 | ||
|
|
0719ef21fa | ||
|
|
6d5f22b56d | ||
|
|
b5beb800c8 | ||
|
|
fe63b25441 | ||
|
|
0afbb68b40 | ||
|
|
4562cd372c | ||
|
|
418ef3765d | ||
|
|
29c8b3edba | ||
|
|
5214912555 | ||
|
|
f2c609b9a5 | ||
|
|
aa22fd936e | ||
|
|
4bbb74da39 | ||
|
|
dd4ee42eb6 | ||
|
|
8b95785b8c | ||
|
|
bb4ddab77a | ||
|
|
69354298fc | ||
|
|
bbcf5d122a | ||
|
|
497161f72f | ||
|
|
31e8118b76 | ||
|
|
8811bd4844 | ||
|
|
0f02479dea | ||
|
|
364edccebc | ||
|
|
3d9242b3d3 | ||
|
|
3f378c962f | ||
|
|
4ca37bcadf | ||
|
|
19492da154 | ||
|
|
182e580fe2 | ||
|
|
eefb417c09 | ||
|
|
4fd0d84e66 | ||
|
|
ea0973002f | ||
|
|
8fcc4c98b6 | ||
|
|
7edc1e0fc4 | ||
|
|
3674e4813c | ||
|
|
5d11af34dc | ||
|
|
e29ee129a3 | ||
|
|
86526c75a3 | ||
|
|
d9d6dd31dc | ||
|
|
e6573fc337 |
+407
-556
File diff suppressed because it is too large
Load Diff
Vendored
+202
-146
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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=="
|
||||
|
||||
@@ -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>`,
|
||||
|
||||
@@ -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
|
||||
----------------------
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+285
-29
@@ -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
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+16
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
Vendored
+176
@@ -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
|
||||
Vendored
+57
@@ -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
|
||||
Vendored
+57
@@ -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
|
||||
Vendored
+1228
File diff suppressed because it is too large
Load Diff
Vendored
+57
@@ -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
|
||||
Vendored
+57
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+517
@@ -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 */
|
||||
Reference in New Issue
Block a user