Merge branch 'features/zeroconf-dnssec' into release/v1.2.0

This commit is contained in:
Willem Toorop 2017-09-20 15:45:27 +02:00
commit 7c229c40cd
36 changed files with 3287 additions and 104 deletions

3
.gitmodules vendored
View File

@ -2,6 +2,9 @@
path = src/jsmn
url = https://github.com/getdnsapi/jsmn.git
branch = getdns
[submodule "src/yxml"]
path = src/yxml
url = git://g.blicky.net/yxml.git
[submodule "stubby"]
path = stubby
url = https://github.com/getdnsapi/stubby.git

View File

@ -12,6 +12,7 @@ addons:
- check
- libevent-dev
- libev-dev
- libuv-dev
- valgrind
- clang
- wget

View File

@ -198,6 +198,7 @@ $(distdir):
mkdir -p $(distdir)/src/gldns
mkdir -p $(distdir)/src/tools
mkdir -p $(distdir)/src/jsmn
mkdir -p $(distdir)/src/yxml
mkdir -p $(distdir)/doc
mkdir -p $(distdir)/spec
mkdir -p $(distdir)/spec/example
@ -253,6 +254,9 @@ $(distdir):
cp $(srcdir)/src/jsmn/*.[ch] $(distdir)/src/jsmn
cp $(srcdir)/src/jsmn/LICENSE $(distdir)/src/jsmn
cp $(srcdir)/src/jsmn/README.md $(distdir)/src/jsmn
cp $(srcdir)/src/yxml/*.[ch] $(distdir)/src/yxml
cp $(srcdir)/src/yxml/COPYING $(distdir)/src/yxml
cp $(srcdir)/src/yxml/yxml.pod $(distdir)/src/yxml
rm -f $(distdir)/Makefile $(distdir)/src/Makefile $(distdir)/src/getdns/getdns.h $(distdir)/spec/example/Makefile $(distdir)/src/test/Makefile $(distdir)/doc/Makefile $(distdir)/src/config.h
distcheck: $(distdir).tar.gz

View File

@ -163,7 +163,8 @@ AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub deb
AC_ARG_ENABLE(debug-daemon, AC_HELP_STRING([--enable-debug-daemon], [Enable daemon debugging messages]))
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
AC_ARG_ENABLE(debug-server, AC_HELP_STRING([--enable-debug-server], [Enable server debugging messages]))
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable all debugging messages]))
AC_ARG_ENABLE(debug-anchor, AC_HELP_STRING([--enable-debug-anchor], [Enable anchor debugging messages]))
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable scheduling, stub and dnssec debugging]))
case "$enable_all_debugging" in
yes)
enable_debug_req=yes
@ -172,6 +173,7 @@ case "$enable_all_debugging" in
enable_debug_daemon=yes
enable_debug_sec=yes
enable_debug_server=yes
enable_debug_anchor=yes
;;
no|*)
;;
@ -218,6 +220,13 @@ case "$enable_debug_server" in
no|*)
;;
esac
case "$enable_debug_anchor" in
yes)
AC_DEFINE_UNQUOTED([ANCHOR_DEBUG], [1], [Define this enable printing of anchor debugging messages.])
;;
no|*)
;;
esac
dnl Hidden debugging options
@ -281,6 +290,33 @@ case "$enable_native_stub_dnssec" in
;;
esac
# check wether strptime also works
AC_DEFUN([AC_CHECK_STRPTIME_WORKS],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(whether strptime works)
if test c${cross_compiling} = cno; then
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#define _XOPEN_SOURCE 600
#include <time.h>
int main(void) { struct tm tm; char *res;
res = strptime("2010-07-15T00:00:00+00:00", "%t%Y%t-%t%m%t-%t%d%tT%t%H%t:%t%M%t:%t%S%t", &tm);
if (!res) return 2;
res = strptime("20070207111842", "%Y%m%d%H%M%S", &tm);
if (!res) return 1; return 0; }
]])] , [eval "ac_cv_c_strptime_works=yes"], [eval "ac_cv_c_strptime_works=no"])
else
eval "ac_cv_c_strptime_works=maybe"
fi
AC_MSG_RESULT($ac_cv_c_strptime_works)
if test $ac_cv_c_strptime_works = no; then
AC_LIBOBJ(strptime)
else
AC_DEFINE_UNQUOTED([STRPTIME_WORKS], 1, [use default strptime.])
fi
])dnl
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
# search to set include and library paths right
# find libidn (no libidn on windows though)
AC_CHECK_HEADERS([windows.h winsock.h stdio.h winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
@ -1438,6 +1474,12 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
# endif
#endif
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
#define strptime unbound_strptime
struct tm;
char *strptime(const char *s, const char *format, struct tm *tm);
#endif
#ifdef HAVE_LIBUNBOUND
# include <unbound.h>
# ifdef HAVE_UNBOUND_EVENT_H

View File

@ -91,12 +91,13 @@ COMPAT_OBJ=$(LIBOBJS:.o=.lo)
UTIL_OBJ=rbtree.lo val_secalgo.lo lruhash.lo lookup3.lo locks.lo
JSMN_OBJ=jsmn.lo
YXML_OBJ=yxml.lo
YAML_OBJ=convert_yaml_to_json.lo
EXTENSION_OBJ=$(DEFAULT_EVENTLOOP_OBJ) libevent.lo libev.lo
NON_C99_OBJS=context.lo libuv.lo
NON_C99_OBJS=libuv.lo context.lo anchor.lo
.SUFFIXES: .c .o .a .lo .h
@ -128,9 +129,15 @@ $(JSMN_OBJ):
$(YAML_OBJ):
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/yaml/$(@:.lo=.c) -o $@
$(YXML_OBJ):
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -I$(srcdir)/yxml -DYXML_GETDNS -Wno-unused-parameter -c $(srcdir)/yxml/$(@:.lo=.c) -o $@
$(EXTENSION_OBJ):
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) -c $(srcdir)/extension/$(@:.lo=.c) -o $@
anchor.lo:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) $(C99COMPATFLAGS) -c $(srcdir)/anchor.c -o anchor.lo
context.lo:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) $(C99COMPATFLAGS) -c $(srcdir)/context.c -o context.lo
@ -177,9 +184,8 @@ libgetdns_ext_uv.la: libgetdns.la libuv.lo
libgetdns_ext_ev.la: libgetdns.la libev.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ libev.lo libgetdns.la $(LDFLAGS) $(EXTENSION_LIBEV_LDFLAGS) $(EXTENSION_LIBEV_EXT_LIBS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/extension/libev.symbols
libgetdns.la: $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YAML_OBJ)
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YAML_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
libgetdns.la: $(GETDNS_OBJ) version.lo context.lo anchor.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YXML_OBJ) $(YAML_OBJ)
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(GETDNS_OBJ) version.lo context.lo anchor.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YXML_OBJ) $(YAML_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
test: default
cd test && $(MAKE) $@
@ -231,7 +237,8 @@ Makefile: $(srcdir)/Makefile.in ../config.status
depend:
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iutil/auxiliary *.c gldns/*.c compat/*.c util/*.c jsmn/*.c yaml/*.c extension/*.c| \
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iyxml -Iutil/auxiliary *.c gldns/*.c compat/*.c util/*.c jsmn/*.c yxml/*.c yaml/*.c extension/*.c| \
sed -e "s? $$blddir/? ?g" \
-e 's? gldns/? $$(srcdir)/gldns/?g' \
-e 's? compat/? $$(srcdir)/compat/?g' \
@ -239,6 +246,7 @@ depend:
-e 's? util/? $$(srcdir)/util/?g' \
-e 's? jsmn/? $$(srcdir)/jsmn/?g' \
-e 's? yaml/? $$(srcdir)/yaml/?g' \
-e 's? yxml/? $$(srcdir)/yxml/?g' \
-e 's? extension/? $$(srcdir)/extension/?g' \
-e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
-e 's? \$$(srcdir)/config\.h? config.h?g' \
@ -257,21 +265,34 @@ depend:
FORCE:
# Dependencies for gldns, utils, the extensions and compat functions
anchor.lo anchor.o: $(srcdir)/anchor.c \
config.h \
$(srcdir)/debug.h $(srcdir)/anchor.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/context.h \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/yxml/yxml.h $(srcdir)/gldns/parseutil.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/general.h $(srcdir)/util-internal.h
const-info.lo const-info.o: $(srcdir)/const-info.c \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/const-info.h
context.lo context.o: $(srcdir)/context.c \
config.h \
$(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
$(srcdir)/anchor.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h \
$(srcdir)/dict.h $(srcdir)/pubkey-pinning.h
convert.lo convert.o: $(srcdir)/convert.c \
config.h \
@ -307,11 +328,11 @@ dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h \
$(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/util/val_secalgo.h \
$(srcdir)/util/orig-headers/val_secalgo.h
$(srcdir)/util/orig-headers/val_secalgo.h $(srcdir)/anchor.h
general.lo general.o: $(srcdir)/general.c \
config.h \
$(srcdir)/general.h \
@ -322,9 +343,9 @@ general.lo general.o: $(srcdir)/general.c \
$(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \
$(srcdir)/mdns.h
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \
$(srcdir)/mdns.h $(srcdir)/anchor.h
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
@ -344,8 +365,8 @@ mdns.lo mdns.o: $(srcdir)/mdns.c \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/general.h $(srcdir)/gldns/rrdef.h $(srcdir)/util-internal.h $(srcdir)/mdns.h \
$(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/lookup3.h \
$(srcdir)/util/orig-headers/lookup3.h
pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
@ -358,8 +379,8 @@ pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h
request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
config.h \
$(srcdir)/types-internal.h \
@ -394,7 +415,8 @@ server.lo server.o: $(srcdir)/server.c \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h
stub.lo stub.o: $(srcdir)/stub.c \
config.h \
$(srcdir)/debug.h $(srcdir)/stub.h \
@ -417,8 +439,8 @@ sync.lo sync.o: $(srcdir)/sync.c \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h \
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
$(srcdir)/gldns/wire2str.h
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \
config.h \
@ -485,6 +507,8 @@ sha512.lo sha512.o: $(srcdir)/compat/sha512.c \
config.h
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \
config.h
strptime.lo strptime.o: $(srcdir)/compat/strptime.c \
config.h
locks.lo locks.o: $(srcdir)/util/locks.c \
config.h \
$(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
@ -511,6 +535,7 @@ val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \
$(srcdir)/gldns/rrdef.h $(srcdir)/util/auxiliary/sldns/keyraw.h $(srcdir)/gldns/keyraw.h \
$(srcdir)/util/auxiliary/sldns/sbuffer.h $(srcdir)/gldns/gbuffer.h
jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h
yxml.lo yxml.o: $(srcdir)/yxml/yxml.c $(srcdir)/yxml/yxml.h
libev.lo libev.o: $(srcdir)/extension/libev.c \
config.h \
$(srcdir)/types-internal.h \
@ -540,4 +565,4 @@ select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \
$(srcdir)/extension/select_eventloop.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/debug.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h

1916
src/anchor.c Normal file

File diff suppressed because it is too large Load Diff

59
src/anchor.h Normal file
View File

@ -0,0 +1,59 @@
/**
*
* /brief functions for DNSSEC trust anchor management
*
*/
/*
* Copyright (c) 2017, NLnet Labs
* All rights reserved.
*
* 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 names of the copyright holders 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 Verisign, Inc. 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.
*/
#ifndef ANCHOR_H_
#define ANCHOR_H_
#include "getdns/getdns.h"
#include "getdns/getdns_extra.h"
#include <time.h>
#include "rr-iter.h"
void _getdns_context_equip_with_anchor(getdns_context *context, uint64_t *now_ms);
void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop);
#define MAX_KSKS 16
#define RRSIG_RDATA_LEN 16
typedef struct _getdns_ksks {
size_t n;
uint16_t ids[MAX_KSKS];
size_t n_rrsigs;
uint8_t rrsigs[MAX_KSKS][RRSIG_RDATA_LEN];
} _getdns_ksks;
void _getdns_context_update_root_ksk(
getdns_context *context, _getdns_rrset *dnskey_set);
#endif
/* anchor.h */

345
src/compat/strptime.c Normal file
View File

@ -0,0 +1,345 @@
/** strptime workaround (for oa macos leopard)
* This strptime follows the man strptime (2001-11-12)
* conforming to SUSv2, POSIX.1-2001
*
* This very simple version of strptime has no:
* - E alternatives
* - O alternatives
* - Glibc additions
* - Does not process week numbers
* - Does not properly processes year day
*
* LICENSE
* Copyright (c) 2008, NLnet Labs, Matthijs Mekking
* All rights reserved.
*
* 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 NLnetLabs 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 OWNER 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.
**/
#include "config.h"
#ifndef HAVE_CONFIG_H
#include <time.h>
#endif
#ifndef STRPTIME_WORKS
#define TM_YEAR_BASE 1900
#include <ctype.h>
#include <string.h>
static const char *abb_weekdays[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
};
static const char *full_weekdays[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", NULL
};
static const char *abb_months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
};
static const char *full_months[] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December", NULL
};
static const char *ampm[] = {
"am", "pm", NULL
};
static int
match_string(const char **buf, const char **strs)
{
int i = 0;
for (i = 0; strs[i] != NULL; i++) {
int len = strlen(strs[i]);
if (strncasecmp (*buf, strs[i], len) == 0) {
*buf += len;
return i;
}
}
return -1;
}
static int
str2int(const char **buf, int max)
{
int ret=0, count=0;
while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
ret = ret*10 + (*buf[0] - '0');
(*buf)++;
count++;
}
if (!count)
return -1;
return ret;
}
/** Converts the character string s to values which are stored in tm
* using the format specified by format
**/
char *
unbound_strptime(const char *s, const char *format, struct tm *tm)
{
int c, ret;
int split_year = 0;
while ((c = *format) != '\0') {
/* whitespace, literal or format */
if (isspace((unsigned char)c)) { /* whitespace */
/** whitespace matches zero or more whitespace characters in the
* input string.
**/
while (isspace((unsigned char)*s))
s++;
}
else if (c == '%') { /* format */
format++;
c = *format;
switch (c) {
case '%': /* %% is converted to % */
if (*s != c) {
return NULL;
}
s++;
break;
case 'a': /* weekday name, abbreviated or full */
case 'A':
ret = match_string(&s, full_weekdays);
if (ret < 0)
ret = match_string(&s, abb_weekdays);
if (ret < 0) {
return NULL;
}
tm->tm_wday = ret;
break;
case 'b': /* month name, abbreviated or full */
case 'B':
case 'h':
ret = match_string(&s, full_months);
if (ret < 0)
ret = match_string(&s, abb_months);
if (ret < 0) {
return NULL;
}
tm->tm_mon = ret;
break;
case 'c': /* date and time representation */
if (!(s = unbound_strptime(s, "%x %X", tm))) {
return NULL;
}
break;
case 'C': /* century number */
ret = str2int(&s, 2);
if (ret < 0 || ret > 99) { /* must be in [00,99] */
return NULL;
}
if (split_year) {
tm->tm_year = ret*100 + (tm->tm_year%100);
}
else {
tm->tm_year = ret*100 - TM_YEAR_BASE;
split_year = 1;
}
break;
case 'd': /* day of month */
case 'e':
ret = str2int(&s, 2);
if (ret < 1 || ret > 31) { /* must be in [01,31] */
return NULL;
}
tm->tm_mday = ret;
break;
case 'D': /* equivalent to %m/%d/%y */
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
return NULL;
}
break;
case 'H': /* hour */
ret = str2int(&s, 2);
if (ret < 0 || ret > 23) { /* must be in [00,23] */
return NULL;
}
tm->tm_hour = ret;
break;
case 'I': /* 12hr clock hour */
ret = str2int(&s, 2);
if (ret < 1 || ret > 12) { /* must be in [01,12] */
return NULL;
}
if (ret == 12) /* actually [0,11] */
ret = 0;
tm->tm_hour = ret;
break;
case 'j': /* day of year */
ret = str2int(&s, 2);
if (ret < 1 || ret > 366) { /* must be in [001,366] */
return NULL;
}
tm->tm_yday = ret;
break;
case 'm': /* month */
ret = str2int(&s, 2);
if (ret < 1 || ret > 12) { /* must be in [01,12] */
return NULL;
}
/* months go from 0-11 */
tm->tm_mon = (ret-1);
break;
case 'M': /* minute */
ret = str2int(&s, 2);
if (ret < 0 || ret > 59) { /* must be in [00,59] */
return NULL;
}
tm->tm_min = ret;
break;
case 'n': /* arbitrary whitespace */
case 't':
while (isspace((unsigned char)*s))
s++;
break;
case 'p': /* am pm */
ret = match_string(&s, ampm);
if (ret < 0) {
return NULL;
}
if (tm->tm_hour < 0 || tm->tm_hour > 11) { /* %I */
return NULL;
}
if (ret == 1) /* pm */
tm->tm_hour += 12;
break;
case 'r': /* equivalent of %I:%M:%S %p */
if (!(s = unbound_strptime(s, "%I:%M:%S %p", tm))) {
return NULL;
}
break;
case 'R': /* equivalent of %H:%M */
if (!(s = unbound_strptime(s, "%H:%M", tm))) {
return NULL;
}
break;
case 'S': /* seconds */
ret = str2int(&s, 2);
/* 60 may occur for leap seconds */
/* earlier 61 was also allowed */
if (ret < 0 || ret > 60) { /* must be in [00,60] */
return NULL;
}
tm->tm_sec = ret;
break;
case 'T': /* equivalent of %H:%M:%S */
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
return NULL;
}
break;
case 'U': /* week number, with the first Sun of Jan being w1 */
ret = str2int(&s, 2);
if (ret < 0 || ret > 53) { /* must be in [00,53] */
return NULL;
}
/** it is hard (and not necessary for nsd) to determine time
* data from week number.
**/
break;
case 'w': /* day of week */
ret = str2int(&s, 1);
if (ret < 0 || ret > 6) { /* must be in [0,6] */
return NULL;
}
tm->tm_wday = ret;
break;
case 'W': /* week number, with the first Mon of Jan being w1 */
ret = str2int(&s, 2);
if (ret < 0 || ret > 53) { /* must be in [00,53] */
return NULL;
}
/** it is hard (and not necessary for nsd) to determine time
* data from week number.
**/
break;
case 'x': /* date format */
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
return NULL;
}
break;
case 'X': /* time format */
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
return NULL;
}
break;
case 'y': /* last two digits of a year */
ret = str2int(&s, 2);
if (ret < 0 || ret > 99) { /* must be in [00,99] */
return NULL;
}
if (split_year) {
tm->tm_year = ((tm->tm_year/100) * 100) + ret;
}
else {
split_year = 1;
/** currently:
* if in [0,68] we are in 21th century,
* if in [69,99] we are in 20th century.
**/
if (ret < 69) /* 2000 */
ret += 100;
tm->tm_year = ret;
}
break;
case 'Y': /* year */
ret = str2int(&s, 4);
if (ret < 0 || ret > 9999) {
return NULL;
}
tm->tm_year = ret - TM_YEAR_BASE;
break;
case '\0':
default: /* unsupported, cannot match format */
return NULL;
break;
}
}
else { /* literal */
/* if input cannot match format, return NULL */
if (*s != c)
return NULL;
s++;
}
format++;
}
/* return pointer to remainder of s */
return (char*) s;
}
#endif /* STRPTIME_WORKS */

View File

@ -82,6 +82,9 @@ static struct const_info consts_info[] = {
{ 622, "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT },
{ 623, "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT },
{ 624, "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT },
{ 625, "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL", GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL_TEXT },
{ 626, "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA", GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA_TEXT },
{ 627, "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL", GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL_TEXT },
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
@ -174,6 +177,9 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 },
{ "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 },
{ "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 },
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL", 625 },
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA", 626 },
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL", 627 },
{ "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 },
{ "GETDNS_DNSSEC_BOGUS", 401 },
{ "GETDNS_DNSSEC_INDETERMINATE", 402 },

View File

@ -35,11 +35,13 @@
*/
#include "config.h"
#include "anchor.h"
#ifndef USE_WINSOCK
#include <arpa/inet.h>
#include <sys/time.h>
#include <netdb.h>
#include <pwd.h>
#else
#include <winsock2.h>
#include <iphlpapi.h>
@ -68,7 +70,6 @@ typedef unsigned short in_port_t;
#endif
#include <stdbool.h>
#include "config.h"
#ifdef HAVE_LIBUNBOUND
#include <unbound.h>
#endif
@ -1362,6 +1363,37 @@ static void _getdns_check_expired_pending_netreqs_cb(void *arg)
_getdns_check_expired_pending_netreqs((getdns_context *)arg, &now_ms);
}
static const char *_getdns_default_root_anchor_url =
"http://data.iana.org/root-anchors/root-anchors.xml";
/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */
static const char *_getdns_default_root_anchor_verify_CA =
"-----BEGIN CERTIFICATE-----\n"
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
"-----END CERTIFICATE-----\n";
static const char *_getdns_default_root_anchor_verify_email =
"dnssec@iana.org";
/*
* getdns_context_create
*
@ -1461,6 +1493,20 @@ getdns_context_create_with_extended_memory_functions(
result->suffixes = no_suffixes;
result->suffixes_len = sizeof(no_suffixes);
result->trust_anchors_source = GETDNS_TASRC_NONE;
result->can_write_appdata = PROP_UNKNOWN;
result->root_anchor_url = _getdns_default_root_anchor_url;
result->root_anchor_verify_email
= _getdns_default_root_anchor_verify_email;
result->root_anchor_verify_CA = _getdns_default_root_anchor_verify_CA;
(void) memset(&result->root_ksk, 0, sizeof(result->root_ksk));
(void) memset(&result->a, 0, sizeof(result->a));
(void) memset(&result->aaaa, 0, sizeof(result->aaaa));
result->a.fd = -1;
result->aaaa.fd = -1;
gldns_buffer_init_vfixed_frm_data(&gbuf, result->trust_anchors_spc
, sizeof(result->trust_anchors_spc));
@ -1478,12 +1524,16 @@ getdns_context_create_with_extended_memory_functions(
, result->trust_anchors
, result->trust_anchors_len);
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
GETDNS_FREE(result->mf, result->trust_anchors);
result->trust_anchors = NULL;
result->trust_anchors_len = 0;
}
} else
result->trust_anchors_source = GETDNS_TASRC_ZONE;
}
} else
} else {
result->trust_anchors = result->trust_anchors_spc;
result->trust_anchors_source = GETDNS_TASRC_ZONE;
}
result->upstreams = NULL;
@ -1517,6 +1567,9 @@ getdns_context_create_with_extended_memory_functions(
result->return_call_reporting = 0;
result->specify_class = GETDNS_RRCLASS_IN;
result->sys_ctxt = NULL;
result->ta_notify = NULL;
/* state data used to detect changes to the system config files
*/
result->fchg_resolvconf = NULL;
@ -1553,7 +1606,15 @@ getdns_context_create_with_extended_memory_functions(
#endif
/* Only initialise SSL once and ideally in a thread-safe manner */
if (ssl_init == false) {
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
OpenSSL_add_all_algorithms();
SSL_library_init();
#else
OPENSSL_init_crypto( OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
(void)OPENSSL_init_ssl(0, NULL);
#endif
ssl_init = true;
}
#ifdef HAVE_PTHREAD
@ -1561,7 +1622,6 @@ getdns_context_create_with_extended_memory_functions(
#else
/* XXX implement Windows-style unlock here */
#endif
#ifdef HAVE_LIBUNBOUND
result->unbound_ctx = NULL;
if ((r = rebuild_ub_ctx(result)))
@ -1636,6 +1696,10 @@ getdns_context_destroy(struct getdns_context *context)
return;
context->destroying = 1;
if (context->sys_ctxt)
getdns_context_destroy(context->sys_ctxt);
/* cancel all outstanding requests */
cancel_outstanding_requests(context);
@ -2648,9 +2712,11 @@ getdns_context_set_dnssec_trust_anchors(
context->trust_anchors = _getdns_list2wire(value,
context->trust_anchors_spc, &context->trust_anchors_len,
&context->mf);
context->trust_anchors_source = GETDNS_TASRC_APP;
} else {
context->trust_anchors = NULL;
context->trust_anchors_len = 0;
context->trust_anchors_source = GETDNS_TASRC_NONE;
}
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS);
return GETDNS_RETURN_GOOD;
@ -4542,4 +4608,326 @@ getdns_context_config(getdns_context *context, const getdns_dict *config_dict)
return r;
}
static size_t _getdns_get_appdata(char *path)
{
size_t len;
#ifdef USE_WINSOCK
# define APPDATA_SUBDIR "getdns"
if (! SUCCEEDED(SHGetFolderPath(NULL,
CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path)))
DEBUG_ANCHOR("ERROR %s(): Could not get \%AppData\% directory\n"
, __FUNC__);
else if ((len = strlen(path)) + sizeof(APPDATA_SUBDIR) + 2 >= PATH_MAX)
DEBUG_ANCHOR("ERROR %s(): Home path too long for appdata\n"
, __FUNC__);
#else
# define APPDATA_SUBDIR ".getdns"
struct passwd *p = getpwuid(getuid());
char *home = NULL;
if (!(home = p ? p->pw_dir : getenv("HOME")))
DEBUG_ANCHOR("ERROR %s(): Could not get home directory\n"
, __FUNC__);
else if ((len = strlen(home)) + sizeof(APPDATA_SUBDIR) + 2 >= PATH_MAX)
DEBUG_ANCHOR("ERROR %s(): Home path too long for appdata\n"
, __FUNC__);
else if (!strcpy(path, home))
; /* strcpy returns path always */
#endif
else {
if (len == 0 || ( path[len - 1] != '/'
&& path[len - 1] != '\\')) {
path[len++] = '/';
path[len ] = '\0';
}
(void) strcpy(path + len, APPDATA_SUBDIR);
len += sizeof(APPDATA_SUBDIR) - 1;
if (mkdir(path, 0755) < 0 && errno != EEXIST)
DEBUG_ANCHOR("ERROR %s(): Could not mkdir %s: %s\n"
, __FUNC__, path, strerror(errno));
else {
path[len++] = '/';
path[len ] = '\0';
return len;
}
}
return 0;
}
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn)
{
char path[PATH_MAX];
FILE *f = NULL;
size_t len;
(void) context;
if (!(len = _getdns_get_appdata(path)))
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
, __FUNC__);
else if (len + strlen(fn) >= sizeof(path))
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
else if (!strcpy(path + len, fn))
; /* strcpy returns path + len always */
else if (!(f = fopen(path, "r")))
DEBUG_ANCHOR("ERROR %s(): Opening \"%s\": %s\n"
, __FUNC__, path, strerror(errno));
return f;
}
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz)
{
FILE *f = NULL;
if (!(f = _getdns_context_get_priv_fp(context, fn)))
; /* pass */
else if ((*file_sz = fread(buf, 1, buf_len, f)) < (buf_len - 1) && feof(f)) {
buf[*file_sz] = 0;
(void) fclose(f);
return buf;
}
else if (fseek(f, 0, SEEK_END) < 0)
DEBUG_ANCHOR("ERROR %s(): Determining size of \"%s\": %s\n"
, __FUNC__, fn, strerror(errno));
else if (!(buf = GETDNS_XMALLOC(
context->mf, uint8_t, (buf_len = ftell(f) + 1))))
DEBUG_ANCHOR("ERROR %s(): Allocating %d memory for \"%s\"\n"
, __FUNC__, (int)buf_len, fn);
else {
rewind(f);
if ((*file_sz = fread(buf, 1, buf_len, f)) >= buf_len || !feof(f)) {
GETDNS_FREE(context->mf, buf);
DEBUG_ANCHOR("ERROR %s(): Reading \"%s\": %s\n"
, __FUNC__, fn, strerror(errno));
}
else {
buf[*file_sz] = 0;
(void) fclose(f);
return buf;
}
}
if (f)
(void) fclose(f);
return NULL;
}
int _getdns_context_write_priv_file(getdns_context *context,
const char *fn, getdns_bindata *content)
{
char path[PATH_MAX], tmpfn[PATH_MAX];
int fd = -1;
FILE *f = NULL;
size_t len;
if (!(len = _getdns_get_appdata(path)))
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
, __FUNC__);
else if (len + 6 >= sizeof(tmpfn)
|| len + strlen(fn) >= sizeof(path))
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
else if (snprintf(tmpfn, sizeof(tmpfn), "%sXXXXXX", path) < 0)
DEBUG_ANCHOR("ERROR %s(): Creating temporary filename template\n"
, __FUNC__);
else if (!strcpy(path + len, fn))
; /* strcpy returns path + len always */
else if ((fd = mkstemp(tmpfn)) < 0)
DEBUG_ANCHOR("ERROR %s(): Creating temporary file: %s\n"
, __FUNC__, strerror(errno));
else if (!(f = fdopen(fd, "w")))
DEBUG_ANCHOR("ERROR %s(): Opening temporary file: %s\n"
, __FUNC__, strerror(errno));
else if (fwrite(content->data, 1, content->size, f) < content->size)
DEBUG_ANCHOR("ERROR %s(): Writing temporary file: %s\n"
, __FUNC__, strerror(errno));
else if (fclose(f) < 0)
DEBUG_ANCHOR("ERROR %s(): Closing temporary file: %s\n"
, __FUNC__, strerror(errno));
else if (rename(tmpfn, path) < 0)
DEBUG_ANCHOR("ERROR %s(): Renaming temporary file: %s\n"
, __FUNC__, strerror(errno));
else {
context->can_write_appdata = PROP_ABLE;
return 1;
}
if (f)
(void) fclose(f);
else if (fd >= 0)
(void) close(fd);
context->can_write_appdata = PROP_UNABLE;
return 0;
}
int _getdns_context_can_write_appdata(getdns_context *context)
{
char test_fn[30], path[PATH_MAX];
size_t len;
getdns_bindata test_content = { 4, (void *)"TEST" };
if (context->can_write_appdata == PROP_ABLE)
return 1;
else if (context->can_write_appdata == PROP_UNABLE)
return 0;
(void) snprintf( test_fn, sizeof(test_fn)
, "write-test-%d.tmp", arc4random());
if (!_getdns_context_write_priv_file(context, test_fn, &test_content))
return 0;
if (!(len = _getdns_get_appdata(path)))
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
, __FUNC__);
else if (len + strlen(test_fn) >= sizeof(path))
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
else if (!strcpy(path + len, test_fn))
; /* strcpy returns path + len always */
else if (unlink(path) < 0)
DEBUG_ANCHOR("ERROR %s(): Unlinking write test file \"%s\": %s\n"
, __FUNC__, path, strerror(errno));
return 1;
}
getdns_return_t
getdns_context_set_trust_anchor_url(
getdns_context *context, const char *zone, const char *url)
{
const char *path;
size_t path_len;
if (!context || !url)
return GETDNS_RETURN_INVALID_PARAMETER;
if (zone && !(zone[0] == '.' && zone[1] == '\0'))
return GETDNS_RETURN_NOT_IMPLEMENTED;
if (! ((url[0] == 'h' || url[0] == 'H')
&& (url[1] == 't' || url[1] == 'T')
&& (url[2] == 't' || url[2] == 'T')
&& (url[3] == 'p' || url[3] == 'P')
&& url[4] == ':' && url[5] == '/' && url[6] == '/'
&& (path = strchr(url + 7, '/'))))
return GETDNS_RETURN_NOT_IMPLEMENTED;
path_len = strlen(path);
if (! ( path_len >= 5
&& path[path_len - 4] == '.'
&& (path[path_len - 3] == 'x' || path[path_len - 3] == 'X')
&& (path[path_len - 2] == 'm' || path[path_len - 2] == 'M')
&& (path[path_len - 1] == 'l' || path[path_len - 1] == 'L')))
return GETDNS_RETURN_NOT_IMPLEMENTED;
context->root_anchor_url = url;
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL);
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_trust_anchor_url(
getdns_context *context, const char *zone, const char **url)
{
if (!context || !url)
return GETDNS_RETURN_INVALID_PARAMETER;
if (zone && (zone[0] != '.' || zone[1] != '\0'))
return GETDNS_RETURN_NOT_IMPLEMENTED;
*url = context && context->root_anchor_url
? context->root_anchor_url
: _getdns_default_root_anchor_url;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_set_trust_anchor_verify_CA(
getdns_context *context, const char *zone, const char *verify_CA)
{
if (!context || !verify_CA)
return GETDNS_RETURN_INVALID_PARAMETER;
if (zone && (zone[0] != '.' || zone[1] != '\0'))
return GETDNS_RETURN_NOT_IMPLEMENTED;
context->root_anchor_verify_CA = verify_CA;
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA);
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_trust_anchor_verify_CA(
getdns_context *context, const char *zone, const char **verify_CA)
{
if (!verify_CA)
return GETDNS_RETURN_INVALID_PARAMETER;
if (zone && (zone[0] != '.' || zone[1] != '\0'))
return GETDNS_RETURN_NOT_IMPLEMENTED;
*verify_CA = context && context->root_anchor_verify_CA
? context->root_anchor_verify_CA
: _getdns_default_root_anchor_verify_CA;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_set_trust_anchor_verify_email(
getdns_context *context, const char *zone, const char *verify_email)
{
if (!context || !verify_email)
return GETDNS_RETURN_INVALID_PARAMETER;
if (zone && (zone[0] != '.' || zone[1] != '\0'))
return GETDNS_RETURN_NOT_IMPLEMENTED;
context->root_anchor_verify_email = verify_email;
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL);
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_trust_anchor_verify_email(
getdns_context *context, const char *zone, const char **verify_email)
{
if (!verify_email)
return GETDNS_RETURN_INVALID_PARAMETER;
if (zone && (zone[0] != '.' || zone[1] != '\0'))
return GETDNS_RETURN_NOT_IMPLEMENTED;
*verify_email = context && context->root_anchor_verify_email
? context->root_anchor_verify_email
: _getdns_default_root_anchor_verify_email;
return GETDNS_RETURN_GOOD;
}
/* context.c */

View File

@ -48,6 +48,8 @@
#ifdef HAVE_MDNS_SUPPORT
#include "util/lruhash.h"
#endif
#include "rr-iter.h"
#include "anchor.h"
struct getdns_dns_req;
struct ub_ctx;
@ -92,6 +94,16 @@ typedef enum getdns_conn_state {
GETDNS_CONN_BACKOFF
} getdns_conn_state_t;
typedef enum getdns_tasrc {
GETDNS_TASRC_NONE,
GETDNS_TASRC_ZONE,
GETDNS_TASRC_APP,
GETDNS_TASRC_FETCHING,
GETDNS_TASRC_XML,
GETDNS_TASRC_XML_UPDATE,
GETDNS_TASRC_FAILED
} getdns_tasrc;
typedef enum getdns_tsig_algo {
GETDNS_NO_TSIG = 0, /* Do not use tsig */
GETDNS_HMAC_MD5 = 1, /* 128 bits */
@ -103,6 +115,7 @@ typedef enum getdns_tsig_algo {
GETDNS_HMAC_SHA512 = 7
} getdns_tsig_algo;
typedef struct getdns_tsig_info {
getdns_tsig_algo alg;
const char *name;
@ -256,6 +269,44 @@ typedef struct getdns_upstreams {
getdns_upstream upstreams[];
} getdns_upstreams;
typedef enum tas_state {
TAS_LOOKUP_ADDRESSES = 0,
TAS_WRITE_GET_XML,
TAS_READ_XML_HDR,
TAS_READ_XML_DOC,
TAS_WRITE_GET_PS7,
TAS_READ_PS7_HDR,
TAS_READ_PS7_DOC,
TAS_DONE,
TAS_RETRY,
TAS_RETRY_GET_PS7,
TAS_RETRY_PS7_HDR,
TAS_RETRY_PS7_DOC,
TAS_RETRY_DONE
} tas_state;
typedef enum _getdns_property {
PROP_INHERIT = 0,
PROP_UNKNOWN = 1,
PROP_UNABLE = 2,
PROP_ABLE = 3
} _getdns_property;
typedef struct tas_connection {
getdns_eventloop *loop;
getdns_network_req *req;
_getdns_rrset_spc rrset_spc;
_getdns_rrset *rrset;
_getdns_rrtype_iter rr_spc;
_getdns_rrtype_iter *rr;
int fd;
getdns_eventloop_event event;
tas_state state;
getdns_tcp_state tcp;
char *http;
getdns_bindata xml;
} tas_connection;
struct getdns_context {
/* Context values */
getdns_resolution_t resolution_type;
@ -277,8 +328,23 @@ struct getdns_context {
const uint8_t *suffixes;
/* Length of all suffixes in the suffix buffer */
size_t suffixes_len;
uint8_t *trust_anchors;
size_t trust_anchors_len;
getdns_tasrc trust_anchors_source;
tas_connection a;
tas_connection aaaa;
uint8_t tas_hdr_spc[512];
_getdns_property can_write_appdata;
const char *root_anchor_url;
const char *root_anchor_verify_CA;
const char *root_anchor_verify_email;
_getdns_ksks root_ksk;
getdns_upstreams *upstreams;
uint16_t limit_outstanding_queries;
uint32_t dnssec_allowed_skew;
@ -373,6 +439,18 @@ struct getdns_context {
unsigned return_call_reporting : 1;
uint16_t specify_class;
/*
* Context for doing system queries.
* For example to resolve data.iana.org or to resolver the addresses
* of upstreams without specified addresses.
*/
getdns_context *sys_ctxt;
/* List of dnsreqs that want to be notified when we have fetched a
* trust anchor from data.iana.org.
*/
getdns_dns_req *ta_notify;
/*
* state data used to detect changes to the system config files
*/
@ -471,6 +549,15 @@ void _getdns_upstreams_dereference(getdns_upstreams *upstreams);
void _getdns_upstream_shutdown(getdns_upstream *upstream);
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn);
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz);
int _getdns_context_write_priv_file(getdns_context *context,
const char *fn, getdns_bindata *content);
int _getdns_context_can_write_appdata(getdns_context *context);
void _getdns_upstream_reset(getdns_upstream *upstream);
#endif /* _GETDNS_CONTEXT_H_ */

View File

@ -47,41 +47,41 @@
#ifdef GETDNS_ON_WINDOWS
#define DEBUG_ON(...) do { \
struct timeval tv; \
struct tm tm; \
char buf[10]; \
time_t tsec; \
struct timeval tv_dEbUgSyM; \
struct tm tm_dEbUgSyM; \
char buf_dEbUgSyM[10]; \
time_t tsec_dEbUgSyM; \
\
gettimeofday(&tv, NULL); \
tsec = (time_t) tv.tv_sec; \
gmtime_s(&tm, (const time_t *) &tsec); \
strftime(buf, 10, "%H:%M:%S", &tm); \
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
gettimeofday(&tv_dEbUgSyM, NULL); \
tsec = (time_t) tv_dEbUgSyM.tv_sec; \
gmtime_s(&tm_dEbUgSyM, (const time_t *) &tsec_dEbUgSyM); \
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
fprintf(stderr, __VA_ARGS__); \
} while (0)
#else
#define DEBUG_ON(...) do { \
struct timeval tv; \
struct tm tm; \
char buf[10]; \
struct timeval tv_dEbUgSyM; \
struct tm tm_dEbUgSyM; \
char buf_dEbUgSyM[10]; \
\
gettimeofday(&tv, NULL); \
gmtime_r(&tv.tv_sec, &tm); \
strftime(buf, 10, "%H:%M:%S", &tm); \
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
gettimeofday(&tv_dEbUgSyM, NULL); \
gmtime_r(&tv_dEbUgSyM.tv_sec, &tm_dEbUgSyM); \
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
fprintf(stderr, __VA_ARGS__); \
} while (0)
#endif
#define DEBUG_NL(...) do { \
struct timeval tv; \
struct tm tm; \
char buf[10]; \
struct timeval tv_dEbUgSyM; \
struct tm tm_dEbUgSyM; \
char buf_dEbUgSyM[10]; \
\
gettimeofday(&tv, NULL); \
gmtime_r(&tv.tv_sec, &tm); \
strftime(buf, 10, "%H:%M:%S", &tm); \
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
gettimeofday(&tv_dEbUgSyM, NULL); \
gmtime_r(&tv_dEbUgSyM.tv_sec, &tm_dEbUgSyM); \
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (0)
@ -162,14 +162,25 @@ static inline void debug_req(const char *msg, getdns_network_req *netreq)
#define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__)
#endif
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
#include <time.h>
#define DEBUG_ANCHOR(...) DEBUG_ON(__VA_ARGS__)
#else
#define DEBUG_ANCHOR(...) DEBUG_OFF(__VA_ARGS__)
#endif
#if (defined(REQ_DEBUG) && REQ_DEBUG) || \
(defined(SCHED_DEBUG) && SCHED_DEBUG) || \
(defined(STUB_DEBUG) && STUB_DEBUG) || \
(defined(DAEMON_DEBUG) && DAEMON_DEBUG) || \
(defined(SEC_DEBUG) && SEC_DEBUG) || \
(defined(SERVER_DEBUG) && SERVER_DEBUG) || \
(defined(MDNS_DEBUG) && MDNS_DEBUG)
(defined(MDNS_DEBUG) && MDNS_DEBUG) || \
(defined(ANCHOR_DEBUG) && ANCHOR_DEBUG)
#define DEBUGGING 1
static inline int
_getdns_ERR_print_errors_cb_f(const char *str, size_t len, void *u)
{ DEBUG_ON("%.*s (u: %p)\n", (int)len, str, u); return 1; }
#endif
#endif

View File

@ -209,6 +209,7 @@
#include "dict.h"
#include "list.h"
#include "util/val_secalgo.h"
#include "anchor.h"
#define SIGNATURE_VERIFIED 0x10000
#define NSEC3_ITERATION_COUNT_HIGH 0x20000
@ -2544,8 +2545,13 @@ static int chain_node_get_trusted_keys(
} else
return GETDNS_DNSSEC_BOGUS;
if (GETDNS_DNSSEC_SECURE != (s = chain_node_get_trusted_keys(
mf, now, skew, node->parent, ta, keys)))
s = chain_node_get_trusted_keys(mf, now, skew, node->parent, ta, keys);
/* Set dnssec status on root DNSKEY request (for TA management) */
if (!node->parent && node->dnskey_req &&
node->dnskey.name && *node->dnskey.name == 0)
node->dnskey_req->dnssec_status = s;
if (s != GETDNS_DNSSEC_SECURE)
return s;
/* keys is an authenticated dnskey rrset always now (i.e. ZSK) */
@ -2750,6 +2756,33 @@ static void chain_set_netreq_dnssec_status(chain_head *chain, _getdns_rrset_iter
}
}
}
static void chain_clear_netreq_dnssec_status(chain_head *chain)
{
chain_head *head;
size_t node_count;
chain_node *node;
/* The netreq status is the worst for any head */
for (head = chain; head; head = head->next) {
if (!head->netreq)
continue;
head->netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
for ( node_count = head->node_count, node = head->parent
; node && node_count ; node_count--, node = node->parent ) {
node->ds_signer = -1;
node->dnskey_signer = -1;
if ( ! node->parent && node->dnskey_req
&& node->dnskey.name && !*node->dnskey.name) {
node->dnskey_req->dnssec_status =
GETDNS_DNSSEC_INDETERMINATE;
}
}
}
}
#endif
/* The DNSSEC status of all heads for a chain structure is evaluated by
@ -2997,6 +3030,22 @@ static void append_empty_ds2val_chain_list(
if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
getdns_dict_destroy(rr_dict);
}
static inline chain_node *_to_the_root(chain_node *node)
{
while (node->parent) node = node->parent;
return node;
}
int _getdns_bogus(getdns_dns_req *dnsreq)
{
getdns_network_req **netreq_p, *netreq;
for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
if (netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
return 1;
}
return 0;
}
static void check_chain_complete(chain_head *chain)
{
@ -3017,23 +3066,33 @@ static void check_chain_complete(chain_head *chain)
dnsreq = chain->netreq->owner;
context = dnsreq->context;
if (dnsreq->waiting_for_ta) {
getdns_dns_req **d;
for (d = &context->ta_notify; *d; d = &(*d)->ta_notify) {
if (*d == dnsreq) {
*d = dnsreq->ta_notify;
dnsreq->ta_notify = NULL;
break;
}
}
} else {
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING) {
dnsreq->waiting_for_ta = 1;
dnsreq->ta_notify = context->ta_notify;
context->ta_notify = dnsreq;
return;
}
}
#ifdef STUB_NATIVE_DNSSEC
/* Perform validation only on GETDNS_RESOLUTION_STUB (unbound_id == -1)
* Or when asked for the validation chain (to identify the RRSIGs that
* signed the RRSETs, so that only those will be included in the
* validation chain)
* In any case we must have a trust anchor.
*/
if (( chain->netreq->unbound_id == -1
|| dnsreq->dnssec_return_validation_chain)
&& context->trust_anchors)
if (context->trust_anchors)
chain_set_netreq_dnssec_status(chain,_getdns_rrset_iter_init(&tas_iter,
context->trust_anchors, context->trust_anchors_len,
SECTION_ANSWER));
#else
if (dnsreq->dnssec_return_validation_chain
&& context->trust_anchors)
if (context->trust_anchors)
(void) chain_validate_dnssec(priv_getdns_context_mf(context),
time(NULL), context->dnssec_allowed_skew,
@ -3042,10 +3101,52 @@ static void check_chain_complete(chain_head *chain)
, context->trust_anchors_len
, SECTION_ANSWER));
#endif
if (context->trust_anchors_source == GETDNS_TASRC_XML) {
if ((head = chain) && (node = _to_the_root(head->parent)) &&
node->dnskey.name && *node->dnskey.name == 0)
_getdns_context_update_root_ksk(context,&node->dnskey);
} else if (_getdns_bogus(dnsreq)) {
DEBUG_ANCHOR("Request was bogus!\n");
if ((head = chain) && (node = _to_the_root(head->parent))
&& node->dnskey.name && *node->dnskey.name == 0
&& node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS){
DEBUG_ANCHOR("root DNSKEY set was bogus!\n");
if (!dnsreq->waiting_for_ta) {
uint64_t now = 0;
dnsreq->waiting_for_ta = 1;
_getdns_context_equip_with_anchor(
context, &now);
if (context->trust_anchors_source
== GETDNS_TASRC_XML) {
chain_clear_netreq_dnssec_status(chain);
check_chain_complete(chain);
return;
}
_getdns_start_fetching_ta(
context, dnsreq->loop);
if (dnsreq->waiting_for_ta &&
context->trust_anchors_source
== GETDNS_TASRC_FETCHING) {
chain_clear_netreq_dnssec_status(chain);
dnsreq->ta_notify = context->ta_notify;
context->ta_notify = dnsreq;
return;
}
}
}
}
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
if ( dnsreq->dnssec_roadblock_avoidance
&& !dnsreq->avoid_dnssec_roadblocks
&& dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) {
&& _getdns_bogus(dnsreq)) {
getdns_network_req **netreq_p, *netreq;
uint64_t now_ms = 0;
@ -3095,6 +3196,7 @@ static void check_chain_complete(chain_head *chain)
return;
}
#endif
dnsreq->waiting_for_ta = 0;
val_chain_list = dnsreq->dnssec_return_validation_chain
? getdns_list_create_with_context(context) : NULL;
@ -3161,6 +3263,45 @@ static void check_chain_complete(chain_head *chain)
_getdns_call_user_callback(dnsreq, response_dict);
}
void _getdns_ta_notify_dnsreqs(getdns_context *context)
{
getdns_dns_req **dnsreq_p, *dnsreq = NULL;
uint64_t now_ms = 0;
assert(context);
if (context->trust_anchors_source == GETDNS_TASRC_NONE ||
context->trust_anchors_source == GETDNS_TASRC_FETCHING)
return;
dnsreq_p = &context->ta_notify;
while ((dnsreq = *dnsreq_p)) {
assert(dnsreq->waiting_for_ta);
if (dnsreq->chain)
check_chain_complete(dnsreq->chain);
else {
getdns_network_req *netreq, **netreq_p;
int r = GETDNS_RETURN_GOOD;
(void) _getdns_context_prepare_for_resolution(context, 0);
*dnsreq_p = dnsreq->ta_notify;
for ( netreq_p = dnsreq->netreqs
; !r && (netreq = *netreq_p)
; netreq_p++ ) {
if (!(r = _getdns_submit_netreq(netreq, &now_ms)))
continue;
if (r == DNS_REQ_FINISHED)
break;
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
}
}
assert(*dnsreq_p != dnsreq);
}
}
void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq)
{
chain_head *head = dnsreq->chain, *next;
@ -3243,6 +3384,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
if (dnsreq->avoid_dnssec_roadblocks && chain->lock == 0)
; /* pass */
else for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
if (! netreq->response
|| netreq->response_len < GLDNS_HEADER_SIZE
@ -3253,7 +3395,10 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
continue;
}
} else if (netreq->unbound_id != -1)
netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
add_pkt2val_chain( &dnsreq->my_mf, &chain
, netreq->response, netreq->response_len
, netreq

View File

@ -48,6 +48,7 @@
void _getdns_get_validation_chain(getdns_dns_req *dns_req);
void _getdns_cancel_validation_chain(getdns_dns_req *dns_req);
void _getdns_validation_chain_timeout(getdns_dns_req *dns_req);
void _getdns_ta_notify_dnsreqs(getdns_context *context);
uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);
@ -66,6 +67,8 @@ static inline int _dnssec_rdata_to_canonicalize(uint16_t rr_type)
|| rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG;
}
int _getdns_bogus(getdns_dns_req *dns_req);
#endif
/* dnssec.h */

View File

@ -172,6 +172,9 @@ getdns_libuv_timeout_cb(uv_timer_t *timer, int status)
#endif
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
#ifndef HAVE_NEW_UV_TIMER_CB
(void)status;
#endif
assert(el_ev->timeout_cb);
DEBUG_UV("enter libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n"
, el_ev, el_ev->ev);

View File

@ -296,7 +296,8 @@ poll_read_cb(int fd, getdns_eventloop_event *event)
(void)fd;
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->read_cb(event->userarg);
if (event && event->read_cb)
event->read_cb(event->userarg);
}
static void
@ -306,14 +307,16 @@ poll_write_cb(int fd, getdns_eventloop_event *event)
(void)fd;
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->write_cb(event->userarg);
if (event && event->write_cb)
event->write_cb(event->userarg);
}
static void
poll_timeout_cb(getdns_eventloop_event *event)
{
DEBUG_SCHED( "%s(event: %p)\n", __FUNC__, (void *)event);
event->timeout_cb(event->userarg);
if (event && event->timeout_cb)
event->timeout_cb(event->userarg);
}
static void

View File

@ -34,6 +34,7 @@
#include "config.h"
#include "getdns/getdns.h"
#include "getdns/getdns_extra.h"
#include "types-internal.h"
/* No more than select's capability queries can be outstanding,
* The number of outstanding timeouts should be less or equal then

View File

@ -54,6 +54,7 @@
#include "dict.h"
#include "mdns.h"
#include "debug.h"
#include "anchor.h"
void _getdns_call_user_callback(getdns_dns_req *dnsreq, getdns_dict *response)
{
@ -213,13 +214,15 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
#endif
#ifdef STUB_NATIVE_DNSSEC
|| (dns_req->context->resolution_type == GETDNS_RESOLUTION_STUB
|| ( dns_req->context->resolution_type == GETDNS_RESOLUTION_STUB
&& !dns_req->avoid_dnssec_roadblocks
&& (dns_req->dnssec_return_status ||
dns_req->dnssec_return_only_secure ||
dns_req->dnssec_return_all_statuses
))
#endif
|| ( dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING
&& _getdns_bogus(dns_req))
)) {
/* Reschedule timeout for this DNS request
*/
@ -235,6 +238,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
#if defined(REQ_DEBUG) && REQ_DEBUG
debug_req("getting validation chain for ", *dns_req->netreqs);
#endif
DEBUG_ANCHOR("Valchain lookup\n");
_getdns_get_validation_chain(dns_req);
} else
_getdns_call_user_callback(
@ -570,11 +574,6 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
if (extensions && (r = validate_extensions(extensions)))
return r;
/* Set up the context assuming we won't use the specified namespaces.
This is (currently) identical to setting up a pure DNS namespace */
if ((r = _getdns_context_prepare_for_resolution(context, 0)))
return r;
/* create the request */
if (!(req = _getdns_dns_req_new(
context, loop, name, request_type, extensions, &now_ms)))
@ -590,7 +589,28 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
_getdns_context_track_outbound_request(req);
if (!usenamespaces)
if (req->dnssec_extension_set) {
if (context->trust_anchors_source == GETDNS_TASRC_XML_UPDATE)
_getdns_start_fetching_ta(context, loop);
else if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
_getdns_context_equip_with_anchor(context, &now_ms);
if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
_getdns_start_fetching_ta(context, loop);
}
}
}
if (!usenamespaces) {
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING
&& context->resolution_type == GETDNS_RESOLUTION_RECURSING
&& context->resolution_type != context->resolution_type_set) {
req->waiting_for_ta = 1;
req->ta_notify = context->ta_notify;
context->ta_notify = req;
return GETDNS_RETURN_GOOD;
}
(void) _getdns_context_prepare_for_resolution(context, 0);
/* issue all network requests */
for ( netreq_p = req->netreqs
; !r && (netreq = *netreq_p)
@ -605,7 +625,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
}
}
else for (i = 0; i < context->namespace_count; i++) {
} else for (i = 0; i < context->namespace_count; i++) {
if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) {
if (!(r = _getdns_context_local_namespace_resolve(
@ -639,6 +659,15 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
}
#endif /* HAVE_MDNS_SUPPORT */
} else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) {
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING
&& context->resolution_type == GETDNS_RESOLUTION_RECURSING
&& context->resolution_type != context->resolution_type_set) {
req->waiting_for_ta = 1;
req->ta_notify = context->ta_notify;
context->ta_notify = req;
return GETDNS_RETURN_GOOD;
}
(void) _getdns_context_prepare_for_resolution(context, 0);
/* TODO: We will get a good return code here even if
the name is not found (NXDOMAIN). We should consider

View File

@ -79,6 +79,13 @@ extern "C" {
#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT "Change related to getdns_context_set_tls_backoff_time"
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES 624
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT "Change related to getdns_context_set_tls_connection_retries"
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL 625
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL_TEXT "Change related to getdns_context_set_trust_anchor_url"
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA 626
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA_TEXT "Change related to getdns_context_set_trust_anchor_verify_ca"
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL 627
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL_TEXT "Change related to getdns_context_set_trust_anchor_verify_email"
/** @}
*/
@ -537,6 +544,28 @@ getdns_return_t
getdns_context_set_logfunc(getdns_context *context, void *userarg,
uint64_t system, getdns_loglevel_type level, getdns_logfunc_type func);
/**
*
*/
getdns_return_t
getdns_context_set_trust_anchor_url(
getdns_context *context, const char *zone, const char *url);
/**
*
*/
getdns_return_t
getdns_context_set_trust_anchor_verify_CA(
getdns_context *context, const char *zone, const char *verify_CA);
/**
*
*/
getdns_return_t
getdns_context_set_trust_anchor_verify_email(
getdns_context *context, const char *zone, const char *verify_email);
/**
* Get the current resolution type setting from this context.
* @see getdns_context_set_resolution_type
@ -902,6 +931,28 @@ getdns_return_t
getdns_context_get_update_callback(getdns_context *context, void **userarg,
void (**value) (getdns_context *, getdns_context_code_t, void *));
/**
*
*/
getdns_return_t
getdns_context_get_trust_anchor_url(
getdns_context *context, const char *zone, const char **url);
/**
*
*/
getdns_return_t
getdns_context_get_trust_anchor_verify_CA(
getdns_context *context, const char *zone, const char **verify_CA);
/**
*
*/
getdns_return_t
getdns_context_get_trust_anchor_verify_email(
getdns_context *context, const char *zone, const char **verify_email);
/** @}
*/

View File

@ -95,7 +95,7 @@ gldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
}
}
uint16_t gldns_calc_keytag_raw(uint8_t* key, size_t keysize)
uint16_t gldns_calc_keytag_raw(const uint8_t* key, size_t keysize)
{
if(keysize < 4) {
return 0;

View File

@ -44,7 +44,7 @@ size_t gldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
* \param[in] keysize length of key data.
* \return the keytag
*/
uint16_t gldns_calc_keytag_raw(uint8_t* key, size_t keysize);
uint16_t gldns_calc_keytag_raw(const uint8_t* key, size_t keysize);
#if GLDNS_BUILD_CONFIG_HAVE_SSL
/**

View File

@ -33,6 +33,9 @@ getdns_context_get_tls_authentication
getdns_context_get_tls_backoff_time
getdns_context_get_tls_connection_retries
getdns_context_get_tls_query_padding_blocksize
getdns_context_get_trust_anchor_url
getdns_context_get_trust_anchor_verify_CA
getdns_context_get_trust_anchor_verify_email
getdns_context_get_update_callback
getdns_context_get_upstream_recursive_servers
getdns_context_process_async
@ -67,6 +70,9 @@ getdns_context_set_tls_authentication
getdns_context_set_tls_backoff_time
getdns_context_set_tls_connection_retries
getdns_context_set_tls_query_padding_blocksize
getdns_context_set_trust_anchor_url
getdns_context_set_trust_anchor_verify_CA
getdns_context_set_trust_anchor_verify_email
getdns_context_set_update_callback
getdns_context_set_upstream_recursive_servers
getdns_context_set_use_threads

View File

@ -914,6 +914,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
dnssec_return_full_validation_chain;
result->dnssec_return_validation_chain = dnssec_return_validation_chain
|| dnssec_return_full_validation_chain;
result->dnssec_extension_set = dnssec_extension_set;
result->edns_cookies = edns_cookies;
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
result->dnssec_roadblock_avoidance = dnssec_roadblock_avoidance;
@ -940,8 +941,10 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
result->upstreams->referenced++;
result->finished_next = NULL;
result->ta_notify = NULL;
result->freed = NULL;
result->validating = 0;
result->waiting_for_ta = 0;
result->is_dns_request = 1;
result->request_timed_out = 0;
result->chain = NULL;

View File

@ -66,18 +66,6 @@
#include "general.h"
#include "pubkey-pinning.h"
#ifdef USE_WINSOCK
typedef u_short sa_family_t;
#define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\
WSAGetLastError() == WSAEWOULDBLOCK)
#define _getdns_EINPROGRESS (WSAGetLastError() == WSAEINPROGRESS)
#define _getdns_EMFILE (WSAGetLastError() == WSAEMFILE)
#else
#define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK)
#define _getdns_EINPROGRESS (errno == EINPROGRESS)
#define _getdns_EMFILE (errno == EMFILE)
#endif
/* WSA TODO:
* STUB_TCP_WOULDBLOCK added to deal with edge triggered event loops (versus
* level triggered). See also lines containing WSA TODO below...

View File

@ -25,4 +25,4 @@ done
rm -fr "${BUILDDIR}/build"
mkdir "${BUILDDIR}/build"
cd "${BUILDDIR}/build"
"${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install"
"${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-debug-anchor

View File

@ -15,6 +15,11 @@ find . -type f -name "Makefile.in" -print0 | xargs -0 rm -f && (
)
(
cd "${BUILDDIR}/build-event-loops"
if test "`hostname`" != "bonobo"
then
echo Sorry, running dependency test on bonobo only
exit 0
fi
if ! ./config.status --config | grep -q 'enable-all-drafts.*--with-libevent.*--with-libev.*--with-libuv'
then
echo Skipping because not covering enough code

View File

@ -5,10 +5,43 @@
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build-event-loops"
if make -j 4 test
make -j 4 test
if test -e "${BUILDDIR}/build-event-loops/src/test/fails"
then
if test -e "${BUILDDIR}/build-event-loops/src/test/fails"
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns.failed"
then
exit 1
echo ""
echo "********************"
echo "*** check_getdns ***"
echo "********************"
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns.log"
fi
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_event.failed"
then
echo ""
echo "**************************"
echo "*** check_getdns_event ***"
echo "**************************"
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_event.log"
fi
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_ev.failed"
then
echo ""
echo "***********************"
echo "*** check_getdns_ev ***"
echo "***********************"
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_ev.log"
fi
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_uv.failed"
then
echo ""
echo "***********************"
echo "*** check_getdns_uv ***"
echo "***********************"
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_uv.log"
fi
exit 1
else
exit 0
fi

View File

@ -25,4 +25,4 @@ do
done
lcov $LCOV_MERGE -o run-all.info
genhtml run-all.info --output-directory coverage-html
"${TPKG}" r
"${TPKG}" -n -1 r

View File

@ -17,4 +17,4 @@ do
# trap keyboard interrupt (control-c)
trap control_c 2
done
"${TPKG}" r
"${TPKG}" -n -1 r

View File

@ -31,7 +31,7 @@ do
fi
done
echo "${ALL}" >> Makefile
printf '\t"%s" r\n\n' "${TPKG}" >> Makefile
printf '\t"%s" -n -1 r\n\n' "${TPKG}" >> Makefile
printf 'clean:\n\t"%s" clean\n\trm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info\n\n' "${TPKG}" >> Makefile
for P in ${OTHERS}
do

View File

@ -193,6 +193,8 @@ function usage() {
out " -p PRI\tlog using PRI as priority"
out " -k\t\tdon't remove test directory when creating/executing a tpkg package"
out " -n NUM\tif less than NUM of the tests are passed exit with 1"
out " \t\tOtherwise exit with 0. When NUM is -1, no tests may fail"
out " \t\tOnly valid when running tpkg report"
out " \t\tOtherwise exit with 0. Only valid when running tpkg report"
out " -b DIR\tuse DIR is a base directory in stead of ."
out " -a ARGS\tpass the string ARGS through to the test scripts"
@ -330,11 +332,12 @@ function report() {
if [[ $passed -lt $TPKG_PASS ]]; then
exit 1
fi
elif [[ $failed -gt 0 ]]; then
exit 1
else
exit 0
elif [[ $TPKG_PASS -lt 0 ]]; then
if [[ $failed -gt 0 ]]; then
exit 1
fi
fi
exit 0
}
# clone test1 to test2

View File

@ -171,7 +171,7 @@ typedef enum network_req_state_enum
/* State for async tcp stub resolving */
typedef struct getdns_tcp_state {
uint8_t *write_buf;
const uint8_t *write_buf;
size_t write_buf_len;
size_t written;
@ -300,6 +300,7 @@ typedef struct getdns_dns_req {
unsigned dnssec_return_all_statuses : 1;
unsigned dnssec_return_validation_chain : 1;
unsigned dnssec_return_full_validation_chain : 1;
unsigned dnssec_extension_set : 1;
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
unsigned dnssec_roadblock_avoidance : 1;
unsigned avoid_dnssec_roadblocks : 1;
@ -324,6 +325,7 @@ typedef struct getdns_dns_req {
* freed is touched by _getdns_submit_netreq only
*/
unsigned validating : 1;
unsigned waiting_for_ta : 1;
int *freed;
/* Validation chain to be canceled when this request is canceled */
@ -365,6 +367,11 @@ typedef struct getdns_dns_req {
*/
struct getdns_dns_req *finished_next;
/* Linked list pointer for dns requests, which need to validate DNSSEC
* and are waiting for the root trust-anchors fetch.
*/
struct getdns_dns_req *ta_notify;
/* network requests for this dns request.
* The array is terminated with NULL.
*

View File

@ -218,5 +218,18 @@ INLINE uint64_t _getdns_ms_until_expiry2(uint64_t expires, uint64_t *now_ms)
return *now_ms >= expires ? 0 : expires - *now_ms;
}
#ifdef USE_WINSOCK
typedef u_short sa_family_t;
#define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\
WSAGetLastError() == WSAEWOULDBLOCK)
#define _getdns_EINPROGRESS (WSAGetLastError() == WSAEINPROGRESS)
#define _getdns_EMFILE (WSAGetLastError() == WSAEMFILE)
#else
#define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK)
#define _getdns_EINPROGRESS (errno == EINPROGRESS)
#define _getdns_EMFILE (errno == EMFILE)
#endif
#endif
/* util-internal.h */

View File

@ -45,6 +45,8 @@
#define sec_status_insecure _getdns_sec_status_insecure
#define sec_status_unchecked _getdns_sec_status_unchecked
#define sec_status_bogus _getdns_sec_status_bogus
#define fake_sha1 _getdns_fake_sha1
#define fake_dsa _getdns_fake_dsa
enum sec_status { sec_status_bogus = 0
, sec_status_unchecked = 0

1
src/yxml Submodule

@ -0,0 +1 @@
Subproject commit 10f968b0e78b9aeee357d0de81a46b445c3fb27b

2
stubby

@ -1 +1 @@
Subproject commit 6d97f4323f2706a2dfcffc7172bd3f71223974a8
Subproject commit 6114230904d9413514d521358ca7956aac99e822