From 767ca21bc075477121a7f1e07827ce25f12d8512 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sat, 25 Mar 2017 19:02:51 +0100 Subject: [PATCH 01/41] Debugging for anchor management --- configure.ac | 7 +++++++ src/debug.h | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2d5deeab..89f07be8 100644 --- a/configure.ac +++ b/configure.ac @@ -201,6 +201,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 diff --git a/src/debug.h b/src/debug.h index 9c5fa6f1..60c2c5a4 100644 --- a/src/debug.h +++ b/src/debug.h @@ -139,12 +139,20 @@ #define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__) #endif +#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG +#include +#define DEBUG_ANCHOR(...) DEBUG_ON(__VA_ARGS__) +#else +#define DEBUG_ANCHOR(...) DEBUG_OFF(__VA_ARGS__) +#endif + #if (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 #endif From edecca8b633c00955dbe29f67dca27aacf2ae1c7 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 27 Mar 2017 09:21:29 -0500 Subject: [PATCH 02/41] smime verification of root-anchors.xml in ~/.getdns --- configure.ac | 2 + spec/example/Makefile.in | 24 +-- src/Makefile.in | 427 ++++++++++++++------------------------- src/anchor.c | 305 ++++++++++++++++++++++++++++ src/anchor.h | 42 ++++ src/context.c | 4 +- src/test/Makefile.in | 71 ++----- src/tools/Makefile.in | 7 +- 8 files changed, 539 insertions(+), 343 deletions(-) create mode 100644 src/anchor.c create mode 100644 src/anchor.h diff --git a/configure.ac b/configure.ac index 31de7f16..bc0c6e84 100644 --- a/configure.ac +++ b/configure.ac @@ -155,6 +155,7 @@ 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(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) @@ -163,6 +164,7 @@ case "$enable_all_debugging" in enable_debug_daemon=yes enable_debug_sec=yes enable_debug_server=yes + enable_debug_anchor=yes ;; no|*) ;; diff --git a/spec/example/Makefile.in b/spec/example/Makefile.in index 8ff7f2d1..7bf5e016 100644 --- a/spec/example/Makefile.in +++ b/spec/example/Makefile.in @@ -149,24 +149,16 @@ depend: # Dependencies for the examples example-all-functions.lo example-all-functions.o: $(srcdir)/example-all-functions.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h \ - ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ - ../../src/getdns/getdns_extra.h -example-reverse.lo example-reverse.o: $(srcdir)/example-reverse.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h \ - ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ + ../../src/config.h ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h ../../src/getdns/getdns_extra.h +example-reverse.lo example-reverse.o: $(srcdir)/example-reverse.c $(srcdir)/getdns_libevent.h ../../src/config.h \ + ../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ ../../src/getdns/getdns_extra.h example-simple-answers.lo example-simple-answers.o: $(srcdir)/example-simple-answers.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h \ - ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ - ../../src/getdns/getdns_extra.h + ../../src/config.h ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h ../../src/getdns/getdns_extra.h example-synchronous.lo example-synchronous.o: $(srcdir)/example-synchronous.c $(srcdir)/getdns_core_only.h \ ../../src/getdns/getdns.h -example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h \ - ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ +example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h ../../src/config.h \ + ../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ ../../src/getdns/getdns_extra.h diff --git a/src/Makefile.in b/src/Makefile.in index c1cb8f12..4813b6e7 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -67,7 +67,7 @@ C99COMPATFLAGS=@C99COMPATFLAGS@ DEFAULT_EVENTLOOP_OBJ=@DEFAULT_EVENTLOOP@.lo -GETDNS_OBJ=const-info.lo convert.lo dict.lo dnssec.lo general.lo \ +GETDNS_OBJ=anchor.lo const-info.lo convert.lo dict.lo dnssec.lo general.lo \ list.lo request-internal.lo pubkey-pinning.lo rr-dict.lo \ rr-iter.lo server.lo stub.lo sync.lo ub_loop.lo util-internal.lo \ mdns.lo @@ -216,287 +216,170 @@ depend: FORCE: # Dependencies for gldns, utils, the extensions and compat functions -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 \ - getdns/getdns.h \ - getdns/getdns_extra.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)/dict.h $(srcdir)/pubkey-pinning.h -convert.lo convert.o: $(srcdir)/convert.c \ - config.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/util-internal.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)/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)/rr-iter.h \ - $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h \ - $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h \ - $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h -dict.lo dict.o: $(srcdir)/dict.c \ - config.h \ - $(srcdir)/types-internal.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h \ - $(srcdir)/gldns/parseutil.h -dnssec.lo dnssec.o: $(srcdir)/dnssec.c \ - config.h \ - $(srcdir)/debug.h \ - getdns/getdns.h \ - $(srcdir)/context.h \ - getdns/getdns_extra.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)/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 -general.lo general.o: $(srcdir)/general.c \ - config.h \ - $(srcdir)/general.h \ - getdns/getdns.h \ - $(srcdir)/types-internal.h \ - getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h \ - $(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 -list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h \ - config.h \ - $(srcdir)/context.h $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ +anchor.lo anchor.o: $(srcdir)/anchor.c config.h $(srcdir)/debug.h $(srcdir)/anchor.h getdns/getdns.h +const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h getdns/getdns_extra.h \ + getdns/getdns.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 getdns/getdns.h getdns/getdns_extra.h \ + getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/ub_loop.h $(srcdir)/server.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)/dict.h \ + $(srcdir)/pubkey-pinning.h +convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns_extra.h \ + getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h +dict.lo dict.o: $(srcdir)/dict.c config.h $(srcdir)/types-internal.h getdns/getdns.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ + getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ + $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h \ + $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/parseutil.h +dnssec.lo dnssec.o: $(srcdir)/dnssec.c config.h $(srcdir)/debug.h getdns/getdns.h $(srcdir)/context.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/ub_loop.h $(srcdir)/server.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)/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 +general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/general.h getdns/getdns.h $(srcdir)/types-internal.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ + $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ + getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/server.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 +list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \ + getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h \ + config.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h -mdns.lo mdns.o: $(srcdir)/mdns.c \ - config.h \ - $(srcdir)/debug.h $(srcdir)/context.h \ - getdns/getdns.h \ - getdns/getdns_extra.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)/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/fptr_wlist.h $(srcdir)/util/lookup3.h \ - $(srcdir)/util/orig-headers/lookup3.h -pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \ - config.h \ - $(srcdir)/debug.h \ - getdns/getdns.h \ - $(srcdir)/context.h \ - getdns/getdns_extra.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 \ +mdns.lo mdns.o: $(srcdir)/mdns.c config.h $(srcdir)/debug.h $(srcdir)/context.h getdns/getdns.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/ub_loop.h $(srcdir)/server.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 +pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c config.h $(srcdir)/debug.h getdns/getdns.h \ + $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h \ + config.h $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h -request-internal.lo request-internal.o: $(srcdir)/request-internal.c \ - config.h \ - $(srcdir)/types-internal.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h \ - $(srcdir)/convert.h $(srcdir)/general.h -rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \ - config.h \ - getdns/getdns.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - getdns/getdns_extra.h \ +request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \ + getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ + getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ + $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/convert.h $(srcdir)/general.h +rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h config.h getdns/getdns.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/util-internal.h $(srcdir)/context.h getdns/getdns_extra.h getdns/getdns.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)/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)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h -rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ - config.h \ - getdns/getdns.h \ + $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ + getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ + $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h +rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h config.h getdns/getdns.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h -server.lo server.o: $(srcdir)/server.c \ - config.h \ - getdns/getdns_extra.h \ - getdns/getdns.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)/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 -stub.lo stub.o: $(srcdir)/stub.c \ - config.h \ - $(srcdir)/debug.h $(srcdir)/stub.h \ - getdns/getdns.h \ - $(srcdir)/types-internal.h \ - getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h \ - $(srcdir)/rr-dict.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)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h -sync.lo sync.o: $(srcdir)/sync.c \ - getdns/getdns.h \ - config.h \ - $(srcdir)/context.h \ - getdns/getdns_extra.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)/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 \ +server.lo server.o: $(srcdir)/server.c config.h getdns/getdns_extra.h getdns/getdns.h \ + $(srcdir)/context.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h +stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/debug.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ + $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h +sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h getdns/getdns_extra.h \ + getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ + $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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)/gldns/wire2str.h -ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \ - config.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h -util-internal.lo util-internal.o: $(srcdir)/util-internal.c \ - config.h \ - getdns/getdns.h \ - $(srcdir)/dict.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/types-internal.h \ - getdns/getdns_extra.h \ - $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(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)/rr-iter.h \ - $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ - $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h -gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \ - config.h \ +ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h config.h getdns/getdns.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h +util-internal.lo util-internal.o: $(srcdir)/util-internal.c config.h getdns/getdns.h $(srcdir)/dict.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/types-internal.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ + getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ + $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h \ + $(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h +version.lo version.o: version.c +gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c config.h $(srcdir)/gldns/gbuffer.h +keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c config.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h +parse.lo parse.o: $(srcdir)/gldns/parse.c config.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h \ $(srcdir)/gldns/gbuffer.h -keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c \ - config.h \ - $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h -parse.lo parse.o: $(srcdir)/gldns/parse.c \ - config.h \ - $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h -parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c \ - config.h \ - $(srcdir)/gldns/parseutil.h -rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c \ - config.h \ - $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h -str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c \ - config.h \ - $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h -wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c \ - config.h \ - $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/keyraw.h -arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c \ - config.h -arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c \ - config.h \ - $(srcdir)/compat/chacha_private.h -arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c \ - config.h -explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c \ - config.h -getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c \ - config.h -getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c \ - config.h -getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c \ - config.h +parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c config.h $(srcdir)/gldns/parseutil.h +rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h +str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c config.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h +wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c config.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \ + $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/keyraw.h +arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h +arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h +arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c config.h +explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h +getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h +getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h +getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c -gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c \ - config.h -inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c \ - config.h -inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c \ - config.h -sha512.lo sha512.o: $(srcdir)/compat/sha512.c \ - config.h -strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.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 -lookup3.lo lookup3.o: $(srcdir)/util/lookup3.c \ - config.h \ - $(srcdir)/util/auxiliary/util/storage/lookup3.h $(srcdir)/util/lookup3.h \ - $(srcdir)/util/orig-headers/lookup3.h -lruhash.lo lruhash.o: $(srcdir)/util/lruhash.c \ - config.h \ - $(srcdir)/util/auxiliary/util/storage/lruhash.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/fptr_wlist.h -rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c \ - config.h \ - $(srcdir)/util/auxiliary/log.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h \ - $(srcdir)/util/auxiliary/fptr_wlist.h $(srcdir)/util/auxiliary/util/fptr_wlist.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h -val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \ - config.h \ +gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c config.h +inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h +inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c config.h +sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h +strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.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 config.h +lookup3.lo lookup3.o: $(srcdir)/util/lookup3.c config.h $(srcdir)/util/auxiliary/util/storage/lookup3.h \ + $(srcdir)/util/lookup3.h $(srcdir)/util/orig-headers/lookup3.h +lruhash.lo lruhash.o: $(srcdir)/util/lruhash.c config.h $(srcdir)/util/auxiliary/util/storage/lruhash.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 config.h \ + $(srcdir)/util/auxiliary/util/fptr_wlist.h +rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/auxiliary/log.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h $(srcdir)/util/auxiliary/fptr_wlist.h \ + $(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h +val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c config.h \ $(srcdir)/util/auxiliary/util/data/packed_rrset.h \ $(srcdir)/util/auxiliary/validator/val_secalgo.h $(srcdir)/util/val_secalgo.h \ $(srcdir)/util/orig-headers/val_secalgo.h $(srcdir)/util/auxiliary/validator/val_nsec3.h \ - $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util/auxiliary/sldns/rrdef.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h $(srcdir)/util/auxiliary/sldns/rrdef.h \ $(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 -libev.lo libev.o: $(srcdir)/extension/libev.c \ - config.h \ - $(srcdir)/types-internal.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h -libevent.lo libevent.o: $(srcdir)/extension/libevent.c \ - config.h \ - $(srcdir)/types-internal.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h -libuv.lo libuv.o: $(srcdir)/extension/libuv.c \ - config.h \ - $(srcdir)/debug.h $(srcdir)/types-internal.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h -poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \ - config.h \ - $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns.h \ - getdns/getdns_extra.h \ - $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h -select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \ - config.h \ - $(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 +libev.lo libev.o: $(srcdir)/extension/libev.c config.h $(srcdir)/types-internal.h getdns/getdns.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h \ + getdns/getdns_extra.h +libevent.lo libevent.o: $(srcdir)/extension/libevent.c config.h $(srcdir)/types-internal.h \ + getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h \ + getdns/getdns_extra.h +libuv.lo libuv.o: $(srcdir)/extension/libuv.c config.h $(srcdir)/debug.h config.h $(srcdir)/types-internal.h \ + getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h \ + getdns/getdns_extra.h +poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c config.h \ + $(srcdir)/extension/poll_eventloop.h getdns/getdns.h getdns/getdns_extra.h \ + $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h config.h +select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c config.h \ + $(srcdir)/extension/select_eventloop.h getdns/getdns.h getdns/getdns_extra.h \ + $(srcdir)/debug.h config.h $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h diff --git a/src/anchor.c b/src/anchor.c new file mode 100644 index 00000000..4db8cef5 --- /dev/null +++ b/src/anchor.c @@ -0,0 +1,305 @@ +/** + * + * /brief functions for DNSSEC trust anchor management + */ +/* + * Copyright (c) 2017, NLnet Labs, Inc. + * 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. + */ + +#include "config.h" +#include "debug.h" +#include "anchor.h" +#include +#include +#include +#include +#include + +#define P7SIGNER "dnssec@iana.org" + +static const char* +get_builtin_cert(void) +{ + return +/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */ +"-----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"; +} + +/* get key usage out of its extension, returns 0 if no key_usage extension */ +static unsigned long +get_usage_of_ex(X509* cert) +{ + unsigned long val = 0; + ASN1_BIT_STRING* s; + if((s=X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL))) { + if(s->length > 0) { + val = s->data[0]; + if(s->length > 1) + val |= s->data[1] << 8; + } + ASN1_BIT_STRING_free(s); + } + return val; +} + +/** get valid signers from the list of signers in the signature */ +static STACK_OF(X509)* +get_valid_signers(PKCS7* p7, const char* p7signer) +{ + const int verb = 5; + int i; + STACK_OF(X509)* validsigners = sk_X509_new_null(); + STACK_OF(X509)* signers = PKCS7_get0_signers(p7, NULL, 0); + unsigned long usage = 0; + if(!validsigners) { + if(verb) printf("out of memory\n"); + sk_X509_free(signers); + return NULL; + } + if(!signers) { + if(verb) printf("no signers in pkcs7 signature\n"); + sk_X509_free(validsigners); + return NULL; + } + for(i=0; i= 3 && X509_NAME_get_text_by_NID(nm, + NID_commonName, buf, (int)sizeof(buf))) + printf("commonName: %s\n", buf); + if(verb >= 3 && X509_NAME_get_text_by_NID(nm, + NID_pkcs9_emailAddress, buf, (int)sizeof(buf))) + printf("emailAddress: %s\n", buf); + } + if(verb) { + int ku_loc = X509_get_ext_by_NID( + sk_X509_value(signers, i), NID_key_usage, -1); + if(verb >= 3 && ku_loc >= 0) { + X509_EXTENSION *ex = X509_get_ext( + sk_X509_value(signers, i), ku_loc); + if(ex) { + printf("keyUsage: "); + X509V3_EXT_print_fp(stdout, ex, 0, 0); + printf("\n"); + } + } + } + if(!p7signer || strcmp(p7signer, "")==0) { + /* there is no name to check, return all records */ + if(verb) printf("did not check commonName of signer\n"); + } else { + if(!X509_NAME_get_text_by_NID(nm, + NID_pkcs9_emailAddress, + buf, (int)sizeof(buf))) { + if(verb) printf("removed cert with no name\n"); + continue; /* no name, no use */ + } + if(strcmp(buf, p7signer) != 0) { + if(verb) printf("removed cert with wrong name\n"); + continue; /* wrong name, skip it */ + } + } + + /* check that the key usage allows digital signatures + * (the p7s) */ + usage = get_usage_of_ex(sk_X509_value(signers, i)); + if(!(usage & KU_DIGITAL_SIGNATURE)) { + if(verb) printf("removed cert with no key usage Digital Signature allowed\n"); + continue; + } + + /* we like this cert, add it to our list of valid + * signers certificates */ + sk_X509_push(validsigners, sk_X509_value(signers, i)); + } + sk_X509_free(signers); + return validsigners; +} + +static int +verify_p7sig(BIO* data, BIO* p7s, X509_STORE *store, const char* p7signer) +{ + const int verb = 5; + PKCS7* p7; + STACK_OF(X509)* validsigners; + int secure = 0; +#ifdef X509_V_FLAG_CHECK_SS_SIGNATURE + X509_VERIFY_PARAM* param = X509_VERIFY_PARAM_new(); + if(!param) { + if(verb) printf("out of memory\n"); + X509_STORE_free(store); + return 0; + } + /* do the selfcheck on the root certificate; it checks that the + * input is valid */ + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CHECK_SS_SIGNATURE); + if(store) X509_STORE_set1_param(store, param); +#endif + if(!store) { + if(verb) printf("out of memory\n"); +#ifdef X509_V_FLAG_CHECK_SS_SIGNATURE + X509_VERIFY_PARAM_free(param); +#endif + return 0; + } +#ifdef X509_V_FLAG_CHECK_SS_SIGNATURE + X509_VERIFY_PARAM_free(param); +#endif + + (void)BIO_reset(p7s); + (void)BIO_reset(data); + + /* convert p7s to p7 (the signature) */ + p7 = d2i_PKCS7_bio(p7s, NULL); + if(!p7) { + if(verb) printf("could not parse p7s signature file\n"); + X509_STORE_free(store); + return 0; + } + if(verb >= 2) printf("parsed the PKCS7 signature\n"); + + /* check what is in the Subject name of the certificates, + * and build a stack that contains only the right certificates */ + validsigners = get_valid_signers(p7, p7signer); + if(!validsigners) { + PKCS7_free(p7); + return 0; + } + BIO *out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE); + BIO_printf(out, "Hello World\n"); + if(PKCS7_verify(p7, validsigners, store, data, out, PKCS7_NOINTERN) == 1) { + secure = 1; + if(verb) printf("the PKCS7 signature verified\n"); + } else { + if(verb) printf("the PKCS7 signature did not verify\n"); + if(verb) { + ERR_print_errors_fp(stdout); + } + } + BIO_free(out); + + sk_X509_free(validsigners); + PKCS7_free(p7); + return secure; +} + +void _getdns_context_equip_with_anchor(getdns_context *context) +{ + char fn[1024]; + int xml_fd, p7s_fd; + int n; + BIO *xml, *p7s, *crt; + X509 *x; + X509_STORE *store; + char *crt_str; + + DEBUG_ANCHOR("entering %s\n", __FUNC__); + + n = snprintf( fn, sizeof(fn) + , "%s/.getdns/root-anchors.xml", getenv("HOME")); + + if (n < 0 || n >= (int)sizeof(fn)) + return; + + if ((xml_fd = open(fn, O_RDONLY)) < 0) + return; + + (void) snprintf( fn, sizeof(fn) + , "%s/.getdns/root-anchors.p7s", getenv("HOME")); + + if ((p7s_fd = open(fn, O_RDONLY)) < 0) { + close(xml_fd); + return; + } + if (!(xml = BIO_new_fd(xml_fd, 1))) { + close(xml_fd); + close(p7s_fd); + return; + } + if (!(p7s = BIO_new_fd(p7s_fd, 1))) { + BIO_free(xml); + close(p7s_fd); + return; + } + if (!(crt_str = strdup(get_builtin_cert()))) + goto error_free_xml; + if (!(crt = BIO_new_mem_buf(crt_str, (int)strlen(crt_str)))) + goto error_free_str; + if (!(store = X509_STORE_new())) + goto error_free_crt; + if (!(x = PEM_read_bio_X509(crt, NULL, 0, NULL))) + goto error_free_store; + if (!X509_STORE_add_cert(store, x)) + goto error_free_store; + if (verify_p7sig(xml, p7s, store, "dnssec@iana.org")) { + DEBUG_ANCHOR("Verifying trust-anchors SUCCEEDED, Yay!\n"); + ; + } else { + DEBUG_ANCHOR("Verifying trust-anchors failed!\n"); + ; + } +error_free_store: + X509_STORE_free(store); +error_free_crt: + BIO_free(crt); +error_free_str: + free(crt_str); +error_free_xml: + BIO_free(xml); + BIO_free(p7s); +} + +/* anchor.c */ diff --git a/src/anchor.h b/src/anchor.h new file mode 100644 index 00000000..db63a452 --- /dev/null +++ b/src/anchor.h @@ -0,0 +1,42 @@ +/** + * + * /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" + +void _getdns_context_equip_with_anchor(getdns_context *context); + +#endif +/* anchor.h */ diff --git a/src/context.c b/src/context.c index c52f770b..14b46721 100644 --- a/src/context.c +++ b/src/context.c @@ -35,6 +35,7 @@ */ #include "config.h" +#include "anchor.h" #ifndef USE_WINSOCK #include @@ -67,7 +68,6 @@ typedef unsigned short in_port_t; #endif #include -#include "config.h" #ifdef HAVE_LIBUNBOUND #include #endif @@ -1429,6 +1429,8 @@ getdns_context_create_with_extended_memory_functions( } else result->trust_anchors = result->trust_anchors_spc; + _getdns_context_equip_with_anchor(result); + result->upstreams = NULL; result->edns_extended_rcode = 0; diff --git a/src/test/Makefile.in b/src/test/Makefile.in index 758435c1..c481fdab 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -216,13 +216,10 @@ depend: .PHONY: clean test # Dependencies for the unit tests -check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c \ - ../getdns/getdns.h \ - $(srcdir)/check_getdns_common.h \ - ../getdns/getdns_extra.h \ - $(srcdir)/check_getdns_address.h $(srcdir)/check_getdns_address_sync.h \ - $(srcdir)/check_getdns_cancel_callback.h $(srcdir)/check_getdns_context_create.h \ - $(srcdir)/check_getdns_context_destroy.h \ +check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c ../getdns/getdns.h $(srcdir)/check_getdns_common.h \ + ../getdns/getdns_extra.h $(srcdir)/check_getdns_address.h \ + $(srcdir)/check_getdns_address_sync.h $(srcdir)/check_getdns_cancel_callback.h \ + $(srcdir)/check_getdns_context_create.h $(srcdir)/check_getdns_context_destroy.h \ $(srcdir)/check_getdns_context_set_context_update_callback.h \ $(srcdir)/check_getdns_context_set_dns_transport.h \ $(srcdir)/check_getdns_context_set_timeout.h \ @@ -242,58 +239,34 @@ check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c \ $(srcdir)/check_getdns_list_get_list.h $(srcdir)/check_getdns_pretty_print_dict.h \ $(srcdir)/check_getdns_service.h $(srcdir)/check_getdns_service_sync.h \ $(srcdir)/check_getdns_transport.h -check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c \ - ../getdns/getdns.h \ - ../config.h \ - $(srcdir)/check_getdns_common.h \ - ../getdns/getdns_extra.h \ +check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c ../getdns/getdns.h \ + ../config.h $(srcdir)/check_getdns_common.h ../getdns/getdns_extra.h \ $(srcdir)/check_getdns_eventloop.h check_getdns_context_set_timeout.lo check_getdns_context_set_timeout.o: $(srcdir)/check_getdns_context_set_timeout.c \ $(srcdir)/check_getdns_context_set_timeout.h $(srcdir)/check_getdns_common.h \ - ../getdns/getdns.h \ - ../getdns/getdns_extra.h + ../getdns/getdns.h ../getdns/getdns_extra.h check_getdns_libev.lo check_getdns_libev.o: $(srcdir)/check_getdns_libev.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h \ - ../getdns/getdns.h \ - $(srcdir)/../getdns/getdns_ext_libev.h \ - ../getdns/getdns_extra.h \ - $(srcdir)/check_getdns_common.h + ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libev.h \ + ../getdns/getdns_extra.h $(srcdir)/check_getdns_common.h check_getdns_libevent.lo check_getdns_libevent.o: $(srcdir)/check_getdns_libevent.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h \ - ../getdns/getdns.h \ - $(srcdir)/../getdns/getdns_ext_libevent.h \ - ../getdns/getdns_extra.h \ - $(srcdir)/check_getdns_libevent.h $(srcdir)/check_getdns_common.h + ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libevent.h \ + ../getdns/getdns_extra.h $(srcdir)/check_getdns_libevent.h $(srcdir)/check_getdns_common.h check_getdns_libuv.lo check_getdns_libuv.o: $(srcdir)/check_getdns_libuv.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h \ - ../getdns/getdns.h \ - $(srcdir)/../getdns/getdns_ext_libuv.h \ - ../getdns/getdns_extra.h \ - $(srcdir)/check_getdns_common.h + ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libuv.h \ + ../getdns/getdns_extra.h $(srcdir)/check_getdns_common.h check_getdns_selectloop.lo check_getdns_selectloop.o: $(srcdir)/check_getdns_selectloop.c \ - $(srcdir)/check_getdns_eventloop.h \ - ../config.h \ - ../getdns/getdns.h \ + $(srcdir)/check_getdns_eventloop.h ../config.h ../getdns/getdns.h \ ../getdns/getdns_extra.h check_getdns_transport.lo check_getdns_transport.o: $(srcdir)/check_getdns_transport.c \ - $(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h \ - ../getdns/getdns.h \ + $(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h ../getdns/getdns.h \ ../getdns/getdns_extra.h -scratchpad.template.lo scratchpad.template.o: scratchpad.template.c \ - ../getdns/getdns.h \ +scratchpad.template.lo scratchpad.template.o: scratchpad.template.c ../getdns/getdns.h \ ../getdns/getdns_extra.h testmessages.lo testmessages.o: $(srcdir)/testmessages.c $(srcdir)/testmessages.h -tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h \ - ../getdns/getdns.h -tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h \ - ../getdns/getdns.h -tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h \ - ../getdns/getdns.h -tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c \ - ../config.h \ - $(srcdir)/testmessages.h \ - ../getdns/getdns.h \ - ../getdns/getdns_extra.h -tests_stub_sync.lo tests_stub_sync.o: $(srcdir)/tests_stub_sync.c $(srcdir)/testmessages.h \ - ../getdns/getdns.h \ +tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h ../getdns/getdns.h +tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h ../getdns/getdns.h +tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h ../getdns/getdns.h +tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c ../config.h $(srcdir)/testmessages.h \ + ../getdns/getdns.h ../getdns/getdns_extra.h +tests_stub_sync.lo tests_stub_sync.o: $(srcdir)/tests_stub_sync.c $(srcdir)/testmessages.h ../getdns/getdns.h \ ../getdns/getdns_extra.h diff --git a/src/tools/Makefile.in b/src/tools/Makefile.in index d066e824..d98cf437 100644 --- a/src/tools/Makefile.in +++ b/src/tools/Makefile.in @@ -113,8 +113,5 @@ depend: .PHONY: clean test # Dependencies for getdns_query -getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c \ - ../config.h \ - $(srcdir)/../debug.h \ - ../getdns/getdns.h \ - ../getdns/getdns_extra.h +getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h $(srcdir)/../debug.h ../config.h \ + ../getdns/getdns.h ../getdns/getdns_extra.h From b0af051809645e1e8bbff79d9569c5cf3d494f55 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 20 Jun 2017 12:20:11 +0200 Subject: [PATCH 03/41] Initialize in correct order --- src/context.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/context.c b/src/context.c index 10a7c56f..4bfc8a24 100644 --- a/src/context.c +++ b/src/context.c @@ -1430,8 +1430,6 @@ getdns_context_create_with_extended_memory_functions( } else result->trust_anchors = result->trust_anchors_spc; - _getdns_context_equip_with_anchor(result); - result->upstreams = NULL; result->edns_extended_rcode = 0; @@ -1500,7 +1498,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 @@ -1508,6 +1514,7 @@ getdns_context_create_with_extended_memory_functions( #else /* XXX implement Windows-style unlock here */ #endif + _getdns_context_equip_with_anchor(result); #ifdef HAVE_LIBUNBOUND result->unbound_ctx = NULL; From e496d13777976c926a9a1532524a1abfa33d9654 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 20 Jun 2017 15:38:32 +0200 Subject: [PATCH 04/41] Start with getting files from user area --- src/anchor.c | 203 ++++++++++++++++++++------------------------------ src/context.c | 33 ++++++++ src/context.h | 3 + src/debug.h | 3 + 4 files changed, 119 insertions(+), 123 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 4db8cef5..9a2f76d1 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -37,14 +37,13 @@ #include #include #include +#include "types-internal.h" +#include "context.h" #define P7SIGNER "dnssec@iana.org" -static const char* -get_builtin_cert(void) -{ - return /* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */ +static const char* _getdns_builtin_cert = "-----BEGIN CERTIFICATE-----\n" "MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n" "TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n" @@ -66,14 +65,14 @@ get_builtin_cert(void) "0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n" "j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n" "-----END CERTIFICATE-----\n"; -} /* get key usage out of its extension, returns 0 if no key_usage extension */ static unsigned long -get_usage_of_ex(X509* cert) +_getdns_get_usage_of_ex(X509* cert) { unsigned long val = 0; ASN1_BIT_STRING* s; + if((s=X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL))) { if(s->length > 0) { val = s->data[0]; @@ -89,75 +88,57 @@ get_usage_of_ex(X509* cert) static STACK_OF(X509)* get_valid_signers(PKCS7* p7, const char* p7signer) { - const int verb = 5; int i; STACK_OF(X509)* validsigners = sk_X509_new_null(); STACK_OF(X509)* signers = PKCS7_get0_signers(p7, NULL, 0); unsigned long usage = 0; if(!validsigners) { - if(verb) printf("out of memory\n"); + DEBUG_ANCHOR("ERROR %s(): Failed to allocated validsigners\n" + , __FUNC__); sk_X509_free(signers); return NULL; } if(!signers) { - if(verb) printf("no signers in pkcs7 signature\n"); + DEBUG_ANCHOR("ERROR %s(): Failed to allocated signers\n" + , __FUNC__); sk_X509_free(validsigners); return NULL; } for(i=0; i= 3 && X509_NAME_get_text_by_NID(nm, - NID_commonName, buf, (int)sizeof(buf))) - printf("commonName: %s\n", buf); - if(verb >= 3 && X509_NAME_get_text_by_NID(nm, - NID_pkcs9_emailAddress, buf, (int)sizeof(buf))) - printf("emailAddress: %s\n", buf); - } - if(verb) { - int ku_loc = X509_get_ext_by_NID( - sk_X509_value(signers, i), NID_key_usage, -1); - if(verb >= 3 && ku_loc >= 0) { - X509_EXTENSION *ex = X509_get_ext( - sk_X509_value(signers, i), ku_loc); - if(ex) { - printf("keyUsage: "); - X509V3_EXT_print_fp(stdout, ex, 0, 0); - printf("\n"); - } - } - } if(!p7signer || strcmp(p7signer, "")==0) { /* there is no name to check, return all records */ - if(verb) printf("did not check commonName of signer\n"); + DEBUG_ANCHOR("%s(): did not check commonName of signer\n" + , __FUNC__); } else { if(!X509_NAME_get_text_by_NID(nm, NID_pkcs9_emailAddress, buf, (int)sizeof(buf))) { - if(verb) printf("removed cert with no name\n"); + DEBUG_ANCHOR("%s(): removed cert with no name\n" + , __FUNC__); continue; /* no name, no use */ } if(strcmp(buf, p7signer) != 0) { - if(verb) printf("removed cert with wrong name\n"); + DEBUG_ANCHOR("%s(): removed cert with wrong name\n" + , __FUNC__); continue; /* wrong name, skip it */ } } /* check that the key usage allows digital signatures * (the p7s) */ - usage = get_usage_of_ex(sk_X509_value(signers, i)); + usage = _getdns_get_usage_of_ex(sk_X509_value(signers, i)); if(!(usage & KU_DIGITAL_SIGNATURE)) { - if(verb) printf("removed cert with no key usage Digital Signature allowed\n"); + DEBUG_ANCHOR("%s(): removed cert with no key usage " + "Digital Signature allowed\n" + , __FUNC__); continue; } @@ -170,47 +151,34 @@ get_valid_signers(PKCS7* p7, const char* p7signer) } static int -verify_p7sig(BIO* data, BIO* p7s, X509_STORE *store, const char* p7signer) +_getdns_verify_p7sig(BIO* data, BIO* p7s, X509_STORE *store, const char* p7signer) { - const int verb = 5; PKCS7* p7; STACK_OF(X509)* validsigners; int secure = 0; #ifdef X509_V_FLAG_CHECK_SS_SIGNATURE X509_VERIFY_PARAM* param = X509_VERIFY_PARAM_new(); if(!param) { - if(verb) printf("out of memory\n"); - X509_STORE_free(store); + DEBUG_ANCHOR("ERROR %s(): Failed to allocated param\n" + , __FUNC__); return 0; } /* do the selfcheck on the root certificate; it checks that the * input is valid */ X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CHECK_SS_SIGNATURE); - if(store) X509_STORE_set1_param(store, param); -#endif - if(!store) { - if(verb) printf("out of memory\n"); -#ifdef X509_V_FLAG_CHECK_SS_SIGNATURE - X509_VERIFY_PARAM_free(param); -#endif - return 0; - } -#ifdef X509_V_FLAG_CHECK_SS_SIGNATURE + X509_STORE_set1_param(store, param); X509_VERIFY_PARAM_free(param); #endif - (void)BIO_reset(p7s); (void)BIO_reset(data); /* convert p7s to p7 (the signature) */ p7 = d2i_PKCS7_bio(p7s, NULL); if(!p7) { - if(verb) printf("could not parse p7s signature file\n"); - X509_STORE_free(store); + DEBUG_ANCHOR("ERROR %s(): could not parse p7s signature file\n" + , __FUNC__); return 0; } - if(verb >= 2) printf("parsed the PKCS7 signature\n"); - /* check what is in the Subject name of the certificates, * and build a stack that contains only the right certificates */ validsigners = get_valid_signers(p7, p7signer); @@ -218,19 +186,16 @@ verify_p7sig(BIO* data, BIO* p7s, X509_STORE *store, const char* p7signer) PKCS7_free(p7); return 0; } - BIO *out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE); - BIO_printf(out, "Hello World\n"); - if(PKCS7_verify(p7, validsigners, store, data, out, PKCS7_NOINTERN) == 1) { + if(PKCS7_verify(p7, validsigners, store, data, NULL, PKCS7_NOINTERN) == 1) { secure = 1; - if(verb) printf("the PKCS7 signature verified\n"); - } else { - if(verb) printf("the PKCS7 signature did not verify\n"); - if(verb) { - ERR_print_errors_fp(stdout); - } } - BIO_free(out); - +#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG + else { + DEBUG_ANCHOR("ERROR %s(): the PKCS7 signature did not verify\n" + , __FUNC__); + ERR_print_errors_cb(_getdns_ERR_print_errors_cb_f, NULL); + } +#endif sk_X509_free(validsigners); PKCS7_free(p7); return secure; @@ -238,68 +203,60 @@ verify_p7sig(BIO* data, BIO* p7s, X509_STORE *store, const char* p7signer) void _getdns_context_equip_with_anchor(getdns_context *context) { - char fn[1024]; - int xml_fd, p7s_fd; - int n; - BIO *xml, *p7s, *crt; - X509 *x; - X509_STORE *store; - char *crt_str; + uint8_t xml_spc[16384], *xml_data = xml_spc; + uint8_t p7s_spc[16384], *p7s_data = p7s_spc; + size_t xml_len, p7s_len; - DEBUG_ANCHOR("entering %s\n", __FUNC__); + BIO *xml = NULL, *p7s = NULL, *crt = NULL; + X509 *x = NULL; + X509_STORE *store = NULL; + + if (!(xml_data = _getdns_context_get_priv_file(context, + "root-anchors.xml", xml_spc, sizeof(xml_spc), &xml_len))) + ; /* pass */ + + else if (!(p7s_data = _getdns_context_get_priv_file(context, + "root-anchors.p7s", p7s_spc, sizeof(p7s_spc), &p7s_len))) + ; /* pass */ + + else if (!(xml = BIO_new_mem_buf(xml_data, xml_len))) + DEBUG_ANCHOR("ERROR %s(): Failed allocating xml BIO\n" + , __FUNC__); + + else if (!(p7s = BIO_new_mem_buf(p7s_data, p7s_len))) + DEBUG_ANCHOR("ERROR %s(): Failed allocating p7s BIO\n" + , __FUNC__); - n = snprintf( fn, sizeof(fn) - , "%s/.getdns/root-anchors.xml", getenv("HOME")); + else if (!(crt = BIO_new_mem_buf(_getdns_builtin_cert, -1))) + DEBUG_ANCHOR("ERROR %s(): Failed allocating crt BIO\n" + , __FUNC__); - if (n < 0 || n >= (int)sizeof(fn)) - return; + else if (!(x = PEM_read_bio_X509(crt, NULL, 0, NULL))) + DEBUG_ANCHOR("ERROR %s(): Parsing builtin certificate\n" + , __FUNC__); - if ((xml_fd = open(fn, O_RDONLY)) < 0) - return; + else if (!(store = X509_STORE_new())) + DEBUG_ANCHOR("ERROR %s(): Failed allocating store\n" + , __FUNC__); - (void) snprintf( fn, sizeof(fn) - , "%s/.getdns/root-anchors.p7s", getenv("HOME")); + else if (!X509_STORE_add_cert(store, x)) + DEBUG_ANCHOR("ERROR %s(): Adding certificate to store\n" + , __FUNC__); - if ((p7s_fd = open(fn, O_RDONLY)) < 0) { - close(xml_fd); - return; - } - if (!(xml = BIO_new_fd(xml_fd, 1))) { - close(xml_fd); - close(p7s_fd); - return; - } - if (!(p7s = BIO_new_fd(p7s_fd, 1))) { - BIO_free(xml); - close(p7s_fd); - return; - } - if (!(crt_str = strdup(get_builtin_cert()))) - goto error_free_xml; - if (!(crt = BIO_new_mem_buf(crt_str, (int)strlen(crt_str)))) - goto error_free_str; - if (!(store = X509_STORE_new())) - goto error_free_crt; - if (!(x = PEM_read_bio_X509(crt, NULL, 0, NULL))) - goto error_free_store; - if (!X509_STORE_add_cert(store, x)) - goto error_free_store; - if (verify_p7sig(xml, p7s, store, "dnssec@iana.org")) { + else if (_getdns_verify_p7sig(xml, p7s, store, "dnssec@iana.org")) { DEBUG_ANCHOR("Verifying trust-anchors SUCCEEDED, Yay!\n"); - ; } else { DEBUG_ANCHOR("Verifying trust-anchors failed!\n"); - ; } -error_free_store: - X509_STORE_free(store); -error_free_crt: - BIO_free(crt); -error_free_str: - free(crt_str); -error_free_xml: - BIO_free(xml); - BIO_free(p7s); + if (store) X509_STORE_free(store); + if (x) X509_free(x); + if (crt) BIO_free(crt); + if (xml) BIO_free(xml); + if (p7s) BIO_free(p7s); + if (xml_data && xml_data != xml_spc) + GETDNS_FREE(context->mf, xml_data); + if (p7s_data && p7s_data != p7s_spc) + GETDNS_FREE(context->mf, p7s_data); } /* anchor.c */ diff --git a/src/context.c b/src/context.c index 4bfc8a24..3d6144b6 100644 --- a/src/context.c +++ b/src/context.c @@ -4456,4 +4456,37 @@ getdns_context_config(getdns_context *context, const getdns_dict *config_dict) return r; } +uint8_t *_getdns_context_get_priv_file(getdns_context *context, + const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz) +{ + char path[FILENAME_MAX]; + int n; + FILE *f; + + n = snprintf(path, sizeof(path), "%s/.getdns/%s", getenv("HOME"), fn); + if (n < 0 || n > FILENAME_MAX) + return NULL; + + if (!(f = fopen(path, "r"))) + return NULL; + + if ((*file_sz = fread(buf, 1, buf_len, f)) < buf_len && feof(f)) + ; /* pass */ + + else if (fseek(f, 0, SEEK_END) < 0) + buf = NULL; + + else if ((buf = GETDNS_XMALLOC( + context->mf, uint8_t, (buf_len = ftell(f) + 1)))) { + + rewind(f); + if ((*file_sz = fread(buf, 1, buf_len, f)) >= buf_len || !feof(f)) { + GETDNS_FREE(context->mf, buf); + buf = NULL; + } + } + (void) fclose(f); + return buf; +} + /* context.c */ diff --git a/src/context.h b/src/context.h index 21090da1..862460b5 100644 --- a/src/context.h +++ b/src/context.h @@ -455,4 +455,7 @@ void _getdns_upstreams_dereference(getdns_upstreams *upstreams); void _getdns_upstream_shutdown(getdns_upstream *upstream); +uint8_t *_getdns_context_get_priv_file(getdns_context *context, + const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz); + #endif /* _GETDNS_CONTEXT_H_ */ diff --git a/src/debug.h b/src/debug.h index 7f1766af..647d712f 100644 --- a/src/debug.h +++ b/src/debug.h @@ -179,6 +179,9 @@ static inline void debug_req(const char *msg, getdns_network_req *netreq) (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 From a7ed88fbed70fd71e06f5cee8902c454cf0469d7 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 20 Jun 2017 16:00:37 +0200 Subject: [PATCH 05/41] Add yxml as submodule --- .gitmodules | 3 +++ src/Makefile.in | 24 +++++++++++++++++------- src/yxml | 1 + 3 files changed, 21 insertions(+), 7 deletions(-) create mode 160000 src/yxml diff --git a/.gitmodules b/.gitmodules index a79d3846..dacb1c18 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ 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 diff --git a/src/Makefile.in b/src/Makefile.in index b0a3b0eb..b8168487 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -82,6 +82,7 @@ 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 EXTENSION_OBJ=$(DEFAULT_EVENTLOOP_OBJ) libevent.lo libev.lo @@ -114,6 +115,9 @@ $(UTIL_OBJ): $(JSMN_OBJ): $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -DJSMN_GETDNS -c $(srcdir)/jsmn/$(@:.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 $@ @@ -154,8 +158,8 @@ 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) - $(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols +libgetdns.la: $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YXML_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) $(YXML_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols test: default cd test && $(MAKE) $@ @@ -191,13 +195,14 @@ 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 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 extension/*.c| \ sed -e "s? $$blddir/? ?g" \ -e 's? gldns/? $$(srcdir)/gldns/?g' \ -e 's? compat/? $$(srcdir)/compat/?g' \ -e 's? util/auxiliary/util/? $$(srcdir)/util/auxiliary/util/?g' \ -e 's? util/? $$(srcdir)/util/?g' \ -e 's? jsmn/? $$(srcdir)/jsmn/?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' \ @@ -216,12 +221,16 @@ 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 +anchor.lo anchor.o: $(srcdir)/anchor.c config.h $(srcdir)/debug.h $(srcdir)/anchor.h getdns/getdns.h \ + $(srcdir)/types-internal.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \ + config.h $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h getdns/getdns_extra.h \ getdns/getdns.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 getdns/getdns.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ +context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/anchor.h getdns/getdns.h $(srcdir)/debug.h \ + $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ @@ -363,6 +372,7 @@ val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c config.h \ $(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 getdns/getdns.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h \ diff --git a/src/yxml b/src/yxml new file mode 160000 index 00000000..10f968b0 --- /dev/null +++ b/src/yxml @@ -0,0 +1 @@ +Subproject commit 10f968b0e78b9aeee357d0de81a46b445c3fb27b From 631bf3fffcc943387ee4c4c2f910a8ea60f2abaa Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 20 Jun 2017 16:07:25 +0200 Subject: [PATCH 06/41] Copy yxml in distributions too --- Makefile.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 22350b55..2ea9bdfc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -190,13 +190,13 @@ $(distdir): mkdir -p $(distdir)/src mkdir -p $(distdir)/src/getdns mkdir -p $(distdir)/src/test - mkdir -p $(distdir)/src/test/jsmn mkdir -p $(distdir)/src/extension mkdir -p $(distdir)/src/compat mkdir -p $(distdir)/src/util 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)/systemd mkdir -p $(distdir)/spec @@ -250,6 +250,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 From a2cf568190deac2d4fb2aa5e4a94eaab39475f7f Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 22 Jun 2017 00:36:26 +0200 Subject: [PATCH 07/41] RFC7958 root-anchors.xml parsing --- configure.ac | 2 +- src/anchor.c | 398 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 393 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 434df5c7..0b5d2bc9 100644 --- a/configure.ac +++ b/configure.ac @@ -114,7 +114,7 @@ AC_SUBST(WPEDANTICFLAG) AC_SUBST(WNOERRORFLAG) case "$host_os" in - linux* ) CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE" + linux* ) CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_XOPEN_SOURCE" ;; solaris* ) CFLAGS="$CFLAGS -D__EXTENSIONS__" # for strdup() from ;; diff --git a/src/anchor.c b/src/anchor.c index 9a2f76d1..1fff63fb 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -32,18 +32,21 @@ #include "config.h" #include "debug.h" #include "anchor.h" -#include #include #include #include #include +#include +#include #include "types-internal.h" #include "context.h" +#include "yxml/yxml.h" +#include "gldns/parseutil.h" #define P7SIGNER "dnssec@iana.org" /* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */ -static const char* _getdns_builtin_cert = +static char* _getdns_builtin_cert = "-----BEGIN CERTIFICATE-----\n" "MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n" "TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n" @@ -201,10 +204,381 @@ _getdns_verify_p7sig(BIO* data, BIO* p7s, X509_STORE *store, const char* p7signe return secure; } +typedef struct ta_iter { + uint8_t yxml_buf[4096]; + yxml_t x; + + const char *start; + const char *ptr; + const char *end; + + char zone[1024]; + + time_t validFrom; + time_t validUntil; + + char keytag[6]; + char algorithm[4]; + char digesttype[4]; + char digest[2048]; +} ta_iter; + +/** + * XML convert DateTime element to time_t. + * [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm] + * (with optional .ssssss fractional seconds) + * @param str: the string + * @return a time_t representation or 0 on failure. + */ +static time_t +xml_convertdate(const char* str) +{ + time_t t = 0; + struct tm tm; + const char* s; + /* for this application, ignore minus in front; + * only positive dates are expected */ + s = str; + if(s[0] == '-') s++; + memset(&tm, 0, sizeof(tm)); + /* parse initial content of the string (lots of whitespace allowed) */ + s = strptime(s, "%t%Y%t-%t%m%t-%t%d%tT%t%H%t:%t%M%t:%t%S%t", &tm); + if(!s) { + DEBUG_ANCHOR("xml_convertdate parse failure %s\n", str); + return 0; + } + /* parse remainder of date string */ + if(*s == '.') { + /* optional '.' and fractional seconds */ + int frac = 0, n = 0; + if(sscanf(s+1, "%d%n", &frac, &n) < 1) { + DEBUG_ANCHOR("xml_convertdate f failure %s\n", str); + return 0; + } + /* fraction is not used, time_t has second accuracy */ + s++; + s+=n; + } + if(*s == 'Z' || *s == 'z') { + /* nothing to do for this */ + s++; + } else if(*s == '+' || *s == '-') { + /* optional timezone spec: Z or +hh:mm or -hh:mm */ + int hr = 0, mn = 0, n = 0; + if(sscanf(s+1, "%d:%d%n", &hr, &mn, &n) < 2) { + DEBUG_ANCHOR("xml_convertdate tz failure %s\n", str); + return 0; + } + if(*s == '+') { + tm.tm_hour += hr; + tm.tm_min += mn; + } else { + tm.tm_hour -= hr; + tm.tm_min -= mn; + } + s++; + s += n; + } + if(*s != 0) { + /* not ended properly */ + /* but ignore, (lenient) */ + } + + t = gldns_mktime_from_utc(&tm); + if(t == (time_t)-1) { + DEBUG_ANCHOR("xml_convertdate mktime failure\n"); + return 0; + } + return t; +} + + +static inline int ta_iter_done(ta_iter *ta) +{ return *ta->ptr == 0 || ta->ptr >= ta->end; } + +static ta_iter *ta_iter_next(ta_iter *ta) +{ + yxml_ret_t r; + yxml_t ta_x; + const char *ta_start; + int level; + char value[2048]; + char *cur, *tmp; + enum { VALIDFROM, VALIDUNTIL } attr_type; + enum { KEYTAG, ALGORITHM, DIGESTTYPE, DIGEST } elem_type; + + cur = value; + value[0] = 0; + + if (!ta->zone[0]) { + DEBUG_ANCHOR("Determine start of \n"); + /* Determine start of */ + while (!ta_iter_done(ta) && + ( yxml_parse(&ta->x, *ta->ptr) != YXML_ELEMSTART + || strcasecmp(ta->x.elem, "trustanchor"))) + ta->ptr++; + if (ta_iter_done(ta)) return NULL; + ta_start = ta->ptr; + ta_x = ta->x; + + DEBUG_ANCHOR("Find \n"); + /* Find */ + level = 0; + while (!ta_iter_done(ta) && !ta->zone[0]) { + switch ((r = yxml_parse(&ta->x, *ta->ptr))) { + case YXML_ELEMSTART: + level += 1; + if (level == 1 && + strcasecmp(ta->x.elem, "zone") == 0) { + cur = value; + *cur = 0; + } + break; + + case YXML_ELEMEND: + level -= 1; + if (level < 0) + /* End of section, + * try the next section + */ + return ta_iter_next(ta); + + else if (level == 0 && cur) { + /* content ready */ + (void) strncpy( ta->zone, value + , sizeof(ta->zone)); + + /* Reset to start of */ + cur = NULL; + ta->ptr = ta_start; + ta->x = ta_x; + } + break; + + case YXML_CONTENT: + if (!cur || level != 1) + break; + tmp = ta->x.data; + while (*tmp && cur < value + sizeof(value)) + *cur++ = *tmp++; + if (cur >= value + sizeof(value)) + cur = NULL; + else + *cur = 0; + break; + default: + break; + } + ta->ptr++; + } + if (ta_iter_done(ta)) + return NULL; + } + assert(ta->zone[0]); + + DEBUG_ANCHOR("Zone: %s, Find \n", ta->zone); + level = 0; + while (!ta_iter_done(ta)) { + r = yxml_parse(&ta->x, *ta->ptr); + + if (r == YXML_ELEMSTART) { + level += 1; + DEBUG_ANCHOR("elem start: %s, level: %d\n", ta->x.elem, level); + if (level == 1 && + strcasecmp(ta->x.elem, "keydigest") == 0) + break; + + } else if (r == YXML_ELEMEND) { + level -= 1; + if (level < 0) { + /* End of section */ + ta->zone[0] = 0; + return ta_iter_next(ta); + } + } + ta->ptr++; + } + if (ta_iter_done(ta)) + return NULL; + + DEBUG_ANCHOR("Found , Parse attributes\n"); + + ta->validFrom = ta->validUntil = 0; + *ta->keytag = *ta->algorithm = *ta->digesttype = *ta->digest = 0; + + cur = NULL; + value[0] = 0; + attr_type = -1; + + while (!ta_iter_done(ta)) { + switch ((r = yxml_parse(&ta->x, *ta->ptr))) { + case YXML_ELEMSTART: + break; + + case YXML_ELEMEND: + /* End of section, try next */ + return ta_iter_next(ta); + + case YXML_ATTRSTART: + DEBUG_ANCHOR("attrstart: %s\n", ta->x.attr); + if (strcasecmp(ta->x.attr, "validfrom") == 0) + attr_type = VALIDFROM; + + else if (strcasecmp(ta->x.attr, "validuntil") == 0) + attr_type = VALIDUNTIL; + else + break; + + cur = value; + *cur = 0; + break; + + case YXML_ATTREND: + if (!cur) + break; + cur = NULL; + DEBUG_ANCHOR("attrval: %s\n", value); + switch (attr_type) { + case VALIDFROM: + ta->validFrom = xml_convertdate(value); + break; + case VALIDUNTIL: + ta->validUntil = xml_convertdate(value); + break; + } + break; + + case YXML_ATTRVAL: + if (!cur) + break; + tmp = ta->x.data; + while (*tmp && cur < value + sizeof(value)) + *cur++ = *tmp++; + if (cur >= value + sizeof(value)) + cur = NULL; + else + *cur = 0; + break; + case YXML_OK: + case YXML_CONTENT: + break; + default: + DEBUG_ANCHOR("r: %d\n", (int)r); + return NULL; + break; + } + if (r == YXML_ELEMSTART) + break; + ta->ptr++; + } + if (ta_iter_done(ta)) + return NULL; + + assert(r == YXML_ELEMSTART); + DEBUG_ANCHOR("Within , Parse child elements\n"); + + cur = NULL; + value[0] = 0; + elem_type = -1; + + for (;;) { + switch (r) { + case YXML_ELEMSTART: + level += 1; + DEBUG_ANCHOR("elem start: %s, level: %d\n", ta->x.elem, level); + if (level != 2) + break; + + else if (strcasecmp(ta->x.elem, "keytag") == 0) + elem_type = KEYTAG; + + else if (strcasecmp(ta->x.elem, "algorithm") == 0) + elem_type = ALGORITHM; + + else if (strcasecmp(ta->x.elem, "digesttype") == 0) + elem_type = DIGESTTYPE; + + else if (strcasecmp(ta->x.elem, "digest") == 0) + elem_type = DIGEST; + else + break; + + cur = value; + *cur = 0; + break; + + case YXML_ELEMEND: + level -= 1; + if (level < 0) { + /* End of section */ + ta->zone[0] = 0; + return ta_iter_next(ta); + + } else if (level != 1 || !cur) + break; + + cur = NULL; + DEBUG_ANCHOR("elem end: %s\n", value); + switch (elem_type) { + case KEYTAG: + (void) strncpy( ta->keytag, value + , sizeof(ta->keytag)); + break; + case ALGORITHM: + (void) strncpy( ta->algorithm, value + , sizeof(ta->algorithm)); + break; + case DIGESTTYPE: + (void) strncpy( ta->digesttype, value + , sizeof(ta->digesttype)); + break; + case DIGEST: + (void) strncpy( ta->digest, value + , sizeof(ta->digest)); + break; + } + break; + + case YXML_CONTENT: + if (!cur) + break; + tmp = ta->x.data; + while (*tmp && cur < value + sizeof(value)) + *cur++ = *tmp++; + if (cur >= value + sizeof(value)) + cur = NULL; + else + *cur = 0; + break; + + default: + break; + } + if (level == 0) + break; + ta->ptr++; + if (ta_iter_done(ta)) + return NULL; + r = yxml_parse(&ta->x, *ta->ptr); + } + return ta->validFrom + && *ta->keytag && *ta->algorithm + && *ta->digesttype && *ta->digest ? ta : ta_iter_next(ta); +} + +static ta_iter *ta_iter_init(ta_iter *ta, const char *doc, size_t doc_len) +{ + ta->ptr = ta->start = doc; + ta->end = ta->start + doc_len; + yxml_init(&ta->x, ta->yxml_buf, sizeof(ta->yxml_buf)); + ta->zone[0] = 0; + return ta_iter_next(ta); +} + void _getdns_context_equip_with_anchor(getdns_context *context) { - uint8_t xml_spc[16384], *xml_data = xml_spc; - uint8_t p7s_spc[16384], *p7s_data = p7s_spc; + uint8_t xml_spc[4096], *xml_data = xml_spc; + uint8_t p7s_spc[4096], *p7s_data = p7s_spc; size_t xml_len, p7s_len; BIO *xml = NULL, *p7s = NULL, *crt = NULL; @@ -227,7 +601,7 @@ void _getdns_context_equip_with_anchor(getdns_context *context) DEBUG_ANCHOR("ERROR %s(): Failed allocating p7s BIO\n" , __FUNC__); - else if (!(crt = BIO_new_mem_buf(_getdns_builtin_cert, -1))) + else if (!(crt = BIO_new_mem_buf((void *)_getdns_builtin_cert, -1))) DEBUG_ANCHOR("ERROR %s(): Failed allocating crt BIO\n" , __FUNC__); @@ -244,7 +618,19 @@ void _getdns_context_equip_with_anchor(getdns_context *context) , __FUNC__); else if (_getdns_verify_p7sig(xml, p7s, store, "dnssec@iana.org")) { - DEBUG_ANCHOR("Verifying trust-anchors SUCCEEDED, Yay!\n"); + ta_iter ta_spc, *ta; + + for ( ta = ta_iter_init(&ta_spc, (char *)xml_data, xml_len) + ; ta; ta = ta_iter_next(ta)) { + + DEBUG_ANCHOR( "%s IN DS %s %s %s %s\n" + , ta->zone + , ta->keytag + , ta->algorithm + , ta->digesttype + , ta->digest + ); + } } else { DEBUG_ANCHOR("Verifying trust-anchors failed!\n"); } From 6b70160659cf1e1c276dc6d8530372429ac6fc0a Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 22 Jun 2017 10:30:13 +0200 Subject: [PATCH 08/41] getdnsify function names, even though they're static --- src/anchor.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 1fff63fb..c096f471 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -89,7 +89,7 @@ _getdns_get_usage_of_ex(X509* cert) /** get valid signers from the list of signers in the signature */ static STACK_OF(X509)* -get_valid_signers(PKCS7* p7, const char* p7signer) +_getdns_get_valid_signers(PKCS7* p7, const char* p7signer) { int i; STACK_OF(X509)* validsigners = sk_X509_new_null(); @@ -184,7 +184,7 @@ _getdns_verify_p7sig(BIO* data, BIO* p7s, X509_STORE *store, const char* p7signe } /* check what is in the Subject name of the certificates, * and build a stack that contains only the right certificates */ - validsigners = get_valid_signers(p7, p7signer); + validsigners = _getdns_get_valid_signers(p7, p7signer); if(!validsigners) { PKCS7_free(p7); return 0; @@ -231,7 +231,7 @@ typedef struct ta_iter { * @return a time_t representation or 0 on failure. */ static time_t -xml_convertdate(const char* str) +_getdns_xml_convertdate(const char* str) { time_t t = 0; struct tm tm; @@ -440,10 +440,10 @@ static ta_iter *ta_iter_next(ta_iter *ta) DEBUG_ANCHOR("attrval: %s\n", value); switch (attr_type) { case VALIDFROM: - ta->validFrom = xml_convertdate(value); + ta->validFrom = _getdns_xml_convertdate(value); break; case VALIDUNTIL: - ta->validUntil = xml_convertdate(value); + ta->validUntil = _getdns_xml_convertdate(value); break; } break; From 7ea3beaa6a40c689010b19a29d2404522473c456 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 22 Jun 2017 12:27:20 +0200 Subject: [PATCH 09/41] Equip context with xml read trust anchors --- configure.ac | 2 +- src/Makefile.in | 11 ++-- src/anchor.c | 134 ++++++++++++++++++++++++++++++++++++++++++++---- src/anchor.h | 3 +- src/context.c | 12 +++-- src/context.h | 7 +++ 6 files changed, 149 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index 0b5d2bc9..434df5c7 100644 --- a/configure.ac +++ b/configure.ac @@ -114,7 +114,7 @@ AC_SUBST(WPEDANTICFLAG) AC_SUBST(WNOERRORFLAG) case "$host_os" in - linux* ) CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_XOPEN_SOURCE" + linux* ) CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE" ;; solaris* ) CFLAGS="$CFLAGS -D__EXTENSIONS__" # for strdup() from ;; diff --git a/src/Makefile.in b/src/Makefile.in index b8168487..bbe58805 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -67,7 +67,7 @@ C99COMPATFLAGS=@C99COMPATFLAGS@ DEFAULT_EVENTLOOP_OBJ=@DEFAULT_EVENTLOOP@.lo -GETDNS_OBJ=anchor.lo const-info.lo convert.lo dict.lo dnssec.lo general.lo \ +GETDNS_OBJ=const-info.lo convert.lo dict.lo dnssec.lo general.lo \ list.lo request-internal.lo pubkey-pinning.lo rr-dict.lo \ rr-iter.lo server.lo stub.lo sync.lo ub_loop.lo util-internal.lo \ mdns.lo @@ -86,7 +86,7 @@ YXML_OBJ=yxml.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 @@ -121,6 +121,9 @@ $(YXML_OBJ): $(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 @@ -158,8 +161,8 @@ 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) $(YXML_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) $(YXML_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) + $(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) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols test: default cd test && $(MAKE) $@ diff --git a/src/anchor.c b/src/anchor.c index c096f471..bb63c200 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -42,6 +42,9 @@ #include "context.h" #include "yxml/yxml.h" #include "gldns/parseutil.h" +#include "gldns/gbuffer.h" +#include "gldns/str2wire.h" +#include "gldns/pkthdr.h" #define P7SIGNER "dnssec@iana.org" @@ -575,7 +578,94 @@ static ta_iter *ta_iter_init(ta_iter *ta, const char *doc, size_t doc_len) return ta_iter_next(ta); } -void _getdns_context_equip_with_anchor(getdns_context *context) +uint16_t _getdns_parse_xml_trust_anchors_buf( + gldns_buffer *gbuf, time_t now, char *xml_data, size_t xml_len) +{ + ta_iter ta_spc, *ta; + uint16_t ta_count = 0; + size_t pkt_start = gldns_buffer_position(gbuf); + + /* Empty header */ + gldns_buffer_write_u32(gbuf, 0); + gldns_buffer_write_u32(gbuf, 0); + gldns_buffer_write_u32(gbuf, 0); + + for ( ta = ta_iter_init(&ta_spc, (char *)xml_data, xml_len) + ; ta; ta = ta_iter_next(ta)) { + + if (now < ta->validFrom) + DEBUG_ANCHOR("Disregarding trust anchor " + "%s for %s which is not yet valid", + ta->keytag, ta->zone); + + else if (ta->validUntil != 0 && now > ta->validUntil) + DEBUG_ANCHOR("Disregarding trust anchor " + "%s for %s which is not valid anymore", + ta->keytag, ta->zone); + + else { + uint8_t zone[256]; + size_t zone_len = sizeof(zone); + uint8_t digest[sizeof(ta->digest)/2]; + size_t digest_len = sizeof(digest); + uint16_t keytag; + uint8_t algorithm; + uint8_t digesttype; + char *endptr; + + DEBUG_ANCHOR( "Installing trust anchor: " + "%s IN DS %s %s %s %s\n" + , ta->zone + , ta->keytag + , ta->algorithm + , ta->digesttype + , ta->digest + ); + if (gldns_str2wire_dname_buf(ta->zone, zone, &zone_len)) { + DEBUG_ANCHOR("Not installing trust anchor because " + "of unparsable zone: \"%s\"", ta->zone); + continue; + } + keytag = (uint16_t)strtol(ta->keytag, &endptr, 10); + if (endptr == ta->keytag || *endptr != 0) { + DEBUG_ANCHOR("Not installing trust anchor because " + "of unparsable keytag: \"%s\"", ta->keytag); + continue; + } + algorithm = (uint16_t)strtol(ta->algorithm, &endptr, 10); + if (endptr == ta->algorithm || *endptr != 0) { + DEBUG_ANCHOR("Not installing trust anchor because " + "of unparsable algorithm: \"%s\"", ta->algorithm); + continue; + } + digesttype = (uint16_t)strtol(ta->digesttype, &endptr, 10); + if (endptr == ta->digesttype || *endptr != 0) { + DEBUG_ANCHOR("Not installing trust anchor because " + "of unparsable digesttype: \"%s\"", ta->digesttype); + continue; + } + if (gldns_str2wire_hex_buf(ta->digest, digest, &digest_len)) { + DEBUG_ANCHOR("Not installing trust anchor because " + "of unparsable digest: \"%s\"", ta->digest); + continue; + } + gldns_buffer_write(gbuf, zone, zone_len); + gldns_buffer_write_u16(gbuf, GETDNS_RRTYPE_DS); + gldns_buffer_write_u16(gbuf, GETDNS_RRCLASS_IN); + gldns_buffer_write_u32(gbuf, 3600); + gldns_buffer_write_u16(gbuf, digest_len + 4); /* rdata_len */ + gldns_buffer_write_u16(gbuf, keytag); + gldns_buffer_write_u8(gbuf, algorithm); + gldns_buffer_write_u8(gbuf, digesttype); + gldns_buffer_write(gbuf, digest, digest_len); + ta_count += 1; + } + } + gldns_buffer_write_u16_at(gbuf, pkt_start+GLDNS_ANCOUNT_OFF, ta_count); + return ta_count; +} + +void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) { uint8_t xml_spc[4096], *xml_data = xml_spc; uint8_t p7s_spc[4096], *p7s_data = p7s_spc; @@ -618,19 +708,41 @@ void _getdns_context_equip_with_anchor(getdns_context *context) , __FUNC__); else if (_getdns_verify_p7sig(xml, p7s, store, "dnssec@iana.org")) { - ta_iter ta_spc, *ta; + uint8_t ta_spc[sizeof(context->trust_anchors_spc)]; + size_t ta_len; + uint8_t *ta = NULL; + gldns_buffer gbuf; - for ( ta = ta_iter_init(&ta_spc, (char *)xml_data, xml_len) - ; ta; ta = ta_iter_next(ta)) { + gldns_buffer_init_vfixed_frm_data( + &gbuf, ta_spc, sizeof(ta_spc)); - DEBUG_ANCHOR( "%s IN DS %s %s %s %s\n" - , ta->zone - , ta->keytag - , ta->algorithm - , ta->digesttype - , ta->digest - ); + if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, now, + (char *)xml_data, xml_len)) + DEBUG_ANCHOR("Failed to parse trust anchor XML data"); + else if ((ta_len = gldns_buffer_position(&gbuf)) > sizeof(ta_spc)) { + if ((ta = GETDNS_XMALLOC(context->mf, uint8_t, ta_len))) { + gldns_buffer_init_frm_data(&gbuf, ta, + gldns_buffer_position(&gbuf)); + if (!_getdns_parse_xml_trust_anchors_buf( + &gbuf, now, (char *)xml_data, xml_len)) { + DEBUG_ANCHOR("Failed to re-parse trust" + " anchor XML data"); + GETDNS_FREE(context->mf, ta); + } else { + context->trust_anchors = ta; + context->trust_anchors_len = ta_len; + context->trust_anchors_source = GETDNS_TASRC_XML; + } + } else + DEBUG_ANCHOR("Could not allocate space for XML file"); + } else { + (void)memcpy(context->trust_anchors_spc, ta_spc, ta_len); + context->trust_anchors = context->trust_anchors_spc; + context->trust_anchors_len = ta_len; + context->trust_anchors_source = GETDNS_TASRC_XML; } + DEBUG_ANCHOR("ta: %p, ta_len: %d\n", context->trust_anchors, (int)context->trust_anchors_len); + } else { DEBUG_ANCHOR("Verifying trust-anchors failed!\n"); } diff --git a/src/anchor.h b/src/anchor.h index db63a452..b619781c 100644 --- a/src/anchor.h +++ b/src/anchor.h @@ -35,8 +35,9 @@ #define ANCHOR_H_ #include "getdns/getdns.h" +#include -void _getdns_context_equip_with_anchor(getdns_context *context); +void _getdns_context_equip_with_anchor(getdns_context *context, time_t now); #endif /* anchor.h */ diff --git a/src/context.c b/src/context.c index 3d6144b6..87f309de 100644 --- a/src/context.c +++ b/src/context.c @@ -1406,6 +1406,7 @@ getdns_context_create_with_extended_memory_functions( result->suffixes = no_suffixes; result->suffixes_len = sizeof(no_suffixes); + result->trust_anchors_source = GETDNS_TASRC_NONE; gldns_buffer_init_vfixed_frm_data(&gbuf, result->trust_anchors_spc , sizeof(result->trust_anchors_spc)); @@ -1423,12 +1424,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; @@ -1514,7 +1519,8 @@ getdns_context_create_with_extended_memory_functions( #else /* XXX implement Windows-style unlock here */ #endif - _getdns_context_equip_with_anchor(result); + if (result->trust_anchors_source == GETDNS_TASRC_NONE) + _getdns_context_equip_with_anchor(result, time(NULL)); #ifdef HAVE_LIBUNBOUND result->unbound_ctx = NULL; diff --git a/src/context.h b/src/context.h index 862460b5..ae2315f1 100644 --- a/src/context.h +++ b/src/context.h @@ -92,6 +92,12 @@ typedef enum getdns_conn_state { GETDNS_CONN_BACKOFF } getdns_conn_state_t; +typedef enum getdns_tasrc { + GETDNS_TASRC_NONE, + GETDNS_TASRC_ZONE, + GETDNS_TASRC_XML +} getdns_tasrc; + typedef enum getdns_tsig_algo { GETDNS_NO_TSIG = 0, /* Do not use tsig */ GETDNS_HMAC_MD5 = 1, /* 128 bits */ @@ -272,6 +278,7 @@ struct getdns_context { size_t suffixes_len; uint8_t *trust_anchors; size_t trust_anchors_len; + getdns_tasrc trust_anchors_source; getdns_upstreams *upstreams; uint16_t limit_outstanding_queries; uint32_t dnssec_allowed_skew; From 4a1008e02ca7b554625739ffdc94cb4e0463a45e Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 22 Jun 2017 12:28:07 +0200 Subject: [PATCH 10/41] New deps for anchor.lo --- src/Makefile.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Makefile.in b/src/Makefile.in index bbe58805..3ee8e1bd 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -228,7 +228,8 @@ anchor.lo anchor.o: $(srcdir)/anchor.c config.h $(srcdir)/debug.h $(srcdir)/anch $(srcdir)/types-internal.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \ config.h $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h \ - $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/yxml/yxml.h $(srcdir)/gldns/parseutil.h \ + $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h getdns/getdns_extra.h \ getdns/getdns.h $(srcdir)/const-info.h context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/anchor.h getdns/getdns.h $(srcdir)/debug.h \ From e2f1d3badb3eb31d7a8eaf34d8e295a94e6fadfe Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 22 Jun 2017 12:41:01 +0200 Subject: [PATCH 11/41] Dependencies --- spec/example/Makefile.in | 24 ++- src/Makefile.in | 451 +++++++++++++++++++++++++-------------- src/test/Makefile.in | 71 ++++-- src/tools/Makefile.in | 7 +- 4 files changed, 358 insertions(+), 195 deletions(-) diff --git a/spec/example/Makefile.in b/spec/example/Makefile.in index 7bf5e016..8ff7f2d1 100644 --- a/spec/example/Makefile.in +++ b/spec/example/Makefile.in @@ -149,16 +149,24 @@ depend: # Dependencies for the examples example-all-functions.lo example-all-functions.o: $(srcdir)/example-all-functions.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h ../../src/getdns/getdns_extra.h -example-reverse.lo example-reverse.o: $(srcdir)/example-reverse.c $(srcdir)/getdns_libevent.h ../../src/config.h \ - ../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ + ../../src/config.h \ + ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ + ../../src/getdns/getdns_extra.h +example-reverse.lo example-reverse.o: $(srcdir)/example-reverse.c $(srcdir)/getdns_libevent.h \ + ../../src/config.h \ + ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ ../../src/getdns/getdns_extra.h example-simple-answers.lo example-simple-answers.o: $(srcdir)/example-simple-answers.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h ../../src/getdns/getdns_extra.h + ../../src/config.h \ + ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ + ../../src/getdns/getdns_extra.h example-synchronous.lo example-synchronous.o: $(srcdir)/example-synchronous.c $(srcdir)/getdns_core_only.h \ ../../src/getdns/getdns.h -example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h ../../src/config.h \ - ../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ +example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h \ + ../../src/config.h \ + ../../src/getdns/getdns.h \ + $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ ../../src/getdns/getdns_extra.h diff --git a/src/Makefile.in b/src/Makefile.in index 3ee8e1bd..fed842ed 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -224,176 +224,301 @@ 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 \ - $(srcdir)/types-internal.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \ - config.h $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h \ - $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/yxml/yxml.h $(srcdir)/gldns/parseutil.h \ +anchor.lo anchor.o: $(srcdir)/anchor.c \ + config.h \ + $(srcdir)/debug.h $(srcdir)/anchor.h \ + getdns/getdns.h \ + $(srcdir)/types-internal.h \ + getdns/getdns_extra.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)/yxml/yxml.h $(srcdir)/gldns/parseutil.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h -const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/const-info.h -context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/anchor.h getdns/getdns.h $(srcdir)/debug.h \ - $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/server.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)/dict.h \ - $(srcdir)/pubkey-pinning.h -convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ - $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h -dict.lo dict.o: $(srcdir)/dict.c config.h $(srcdir)/types-internal.h getdns/getdns.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ - $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h \ - $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/parseutil.h -dnssec.lo dnssec.o: $(srcdir)/dnssec.c config.h $(srcdir)/debug.h getdns/getdns.h $(srcdir)/context.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/server.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)/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 -general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/general.h getdns/getdns.h $(srcdir)/types-internal.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/server.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 -list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h \ - config.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h -mdns.lo mdns.o: $(srcdir)/mdns.c config.h $(srcdir)/debug.h $(srcdir)/context.h getdns/getdns.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/server.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 -pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c config.h $(srcdir)/debug.h getdns/getdns.h \ - $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h \ - config.h $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h \ - $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h -request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \ - getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ - $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \ - $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/convert.h $(srcdir)/general.h -rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h config.h getdns/getdns.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/util-internal.h $(srcdir)/context.h getdns/getdns_extra.h getdns/getdns.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)/anchor.h \ + getdns/getdns.h \ + $(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ + getdns/getdns_extra.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ - $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h -rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h config.h getdns/getdns.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h -server.lo server.o: $(srcdir)/server.c config.h getdns/getdns_extra.h getdns/getdns.h \ - $(srcdir)/context.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h -stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/debug.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \ - $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ - $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h -sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h getdns/getdns_extra.h \ - getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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)/gldns/wire2str.h -ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h config.h getdns/getdns.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h -util-internal.lo util-internal.o: $(srcdir)/util-internal.c config.h getdns/getdns.h $(srcdir)/dict.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/types-internal.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h \ - $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \ - getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ - $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h \ - $(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h -version.lo version.o: version.c -gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c config.h $(srcdir)/gldns/gbuffer.h -keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c config.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h -parse.lo parse.o: $(srcdir)/gldns/parse.c config.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h \ - $(srcdir)/gldns/gbuffer.h -parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c config.h $(srcdir)/gldns/parseutil.h -rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h -str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c config.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ - $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h -wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c config.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \ - $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/keyraw.h -arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h -arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h -arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c config.h -explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h -getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h -getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h -getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h -getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c -gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c config.h -inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h -inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c config.h -sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h -strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.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 config.h -lookup3.lo lookup3.o: $(srcdir)/util/lookup3.c config.h $(srcdir)/util/auxiliary/util/storage/lookup3.h \ - $(srcdir)/util/lookup3.h $(srcdir)/util/orig-headers/lookup3.h -lruhash.lo lruhash.o: $(srcdir)/util/lruhash.c config.h $(srcdir)/util/auxiliary/util/storage/lruhash.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)/dict.h $(srcdir)/pubkey-pinning.h +convert.lo convert.o: $(srcdir)/convert.c \ + config.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util-internal.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)/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 config.h \ - $(srcdir)/util/auxiliary/util/fptr_wlist.h -rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/auxiliary/log.h \ - $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h $(srcdir)/util/auxiliary/fptr_wlist.h \ - $(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h -val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c config.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)/gldns/wire2str.h \ + $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h \ + $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h +dict.lo dict.o: $(srcdir)/dict.c \ + config.h \ + $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h \ + $(srcdir)/gldns/parseutil.h +dnssec.lo dnssec.o: $(srcdir)/dnssec.c \ + config.h \ + $(srcdir)/debug.h \ + getdns/getdns.h \ + $(srcdir)/context.h \ + getdns/getdns_extra.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)/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 +general.lo general.o: $(srcdir)/general.c \ + config.h \ + $(srcdir)/general.h \ + getdns/getdns.h \ + $(srcdir)/types-internal.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h \ + $(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 +list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h \ + config.h \ + $(srcdir)/context.h $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h +mdns.lo mdns.o: $(srcdir)/mdns.c \ + config.h \ + $(srcdir)/debug.h $(srcdir)/context.h \ + getdns/getdns.h \ + getdns/getdns_extra.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)/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/fptr_wlist.h $(srcdir)/util/lookup3.h \ + $(srcdir)/util/orig-headers/lookup3.h +pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \ + config.h \ + $(srcdir)/debug.h \ + getdns/getdns.h \ + $(srcdir)/context.h \ + getdns/getdns_extra.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 +request-internal.lo request-internal.o: $(srcdir)/request-internal.c \ + config.h \ + $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h \ + $(srcdir)/convert.h $(srcdir)/general.h +rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \ + config.h \ + getdns/getdns.h \ + $(srcdir)/gldns/gbuffer.h $(srcdir)/util-internal.h $(srcdir)/context.h \ + getdns/getdns_extra.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)/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)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h +rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ + config.h \ + getdns/getdns.h \ + $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h +server.lo server.o: $(srcdir)/server.c \ + config.h \ + getdns/getdns_extra.h \ + getdns/getdns.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)/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 +stub.lo stub.o: $(srcdir)/stub.c \ + config.h \ + $(srcdir)/debug.h $(srcdir)/stub.h \ + getdns/getdns.h \ + $(srcdir)/types-internal.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ + $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h \ + $(srcdir)/rr-dict.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)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h +sync.lo sync.o: $(srcdir)/sync.c \ + getdns/getdns.h \ + config.h \ + $(srcdir)/context.h \ + getdns/getdns_extra.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)/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)/gldns/wire2str.h +ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \ + config.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h +util-internal.lo util-internal.o: $(srcdir)/util-internal.c \ + config.h \ + getdns/getdns.h \ + $(srcdir)/dict.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/types-internal.h \ + getdns/getdns_extra.h \ + $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(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)/rr-iter.h \ + $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h +gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \ + config.h \ + $(srcdir)/gldns/gbuffer.h +keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c \ + config.h \ + $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h +parse.lo parse.o: $(srcdir)/gldns/parse.c \ + config.h \ + $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h +parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c \ + config.h \ + $(srcdir)/gldns/parseutil.h +rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c \ + config.h \ + $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h +str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c \ + config.h \ + $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h +wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c \ + config.h \ + $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h \ + $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/keyraw.h +arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c \ + config.h +arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c \ + config.h \ + $(srcdir)/compat/chacha_private.h +arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c \ + config.h +explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c \ + config.h +getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c \ + config.h +getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c \ + config.h +getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c \ + config.h +getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c +gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c \ + config.h +inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c \ + config.h +inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c \ + config.h +sha512.lo sha512.o: $(srcdir)/compat/sha512.c \ + config.h +strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.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 +lookup3.lo lookup3.o: $(srcdir)/util/lookup3.c \ + config.h \ + $(srcdir)/util/auxiliary/util/storage/lookup3.h $(srcdir)/util/lookup3.h \ + $(srcdir)/util/orig-headers/lookup3.h +lruhash.lo lruhash.o: $(srcdir)/util/lruhash.c \ + config.h \ + $(srcdir)/util/auxiliary/util/storage/lruhash.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/fptr_wlist.h +rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c \ + config.h \ + $(srcdir)/util/auxiliary/log.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h \ + $(srcdir)/util/auxiliary/fptr_wlist.h $(srcdir)/util/auxiliary/util/fptr_wlist.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h +val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \ + config.h \ $(srcdir)/util/auxiliary/util/data/packed_rrset.h \ $(srcdir)/util/auxiliary/validator/val_secalgo.h $(srcdir)/util/val_secalgo.h \ $(srcdir)/util/orig-headers/val_secalgo.h $(srcdir)/util/auxiliary/validator/val_nsec3.h \ - $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h $(srcdir)/util/auxiliary/sldns/rrdef.h \ + $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util/auxiliary/sldns/rrdef.h \ $(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 getdns/getdns.h \ - getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h \ - getdns/getdns_extra.h -libevent.lo libevent.o: $(srcdir)/extension/libevent.c config.h $(srcdir)/types-internal.h \ - getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h \ - getdns/getdns_extra.h -libuv.lo libuv.o: $(srcdir)/extension/libuv.c config.h $(srcdir)/debug.h config.h $(srcdir)/types-internal.h \ - getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h \ - getdns/getdns_extra.h -poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c config.h \ - $(srcdir)/extension/poll_eventloop.h getdns/getdns.h getdns/getdns_extra.h \ - $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h config.h -select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c config.h \ - $(srcdir)/extension/select_eventloop.h getdns/getdns.h getdns/getdns_extra.h \ - $(srcdir)/debug.h config.h $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h +libev.lo libev.o: $(srcdir)/extension/libev.c \ + config.h \ + $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h +libevent.lo libevent.o: $(srcdir)/extension/libevent.c \ + config.h \ + $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h +libuv.lo libuv.o: $(srcdir)/extension/libuv.c \ + config.h \ + $(srcdir)/debug.h $(srcdir)/types-internal.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h +poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \ + config.h \ + $(srcdir)/extension/poll_eventloop.h \ + getdns/getdns.h \ + getdns/getdns_extra.h \ + $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h +select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \ + config.h \ + $(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 diff --git a/src/test/Makefile.in b/src/test/Makefile.in index 00211237..9d4dad00 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -231,10 +231,13 @@ depend: .PHONY: clean test # Dependencies for the unit tests -check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c ../getdns/getdns.h $(srcdir)/check_getdns_common.h \ - ../getdns/getdns_extra.h $(srcdir)/check_getdns_address.h \ - $(srcdir)/check_getdns_address_sync.h $(srcdir)/check_getdns_cancel_callback.h \ - $(srcdir)/check_getdns_context_create.h $(srcdir)/check_getdns_context_destroy.h \ +check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c \ + ../getdns/getdns.h \ + $(srcdir)/check_getdns_common.h \ + ../getdns/getdns_extra.h \ + $(srcdir)/check_getdns_address.h $(srcdir)/check_getdns_address_sync.h \ + $(srcdir)/check_getdns_cancel_callback.h $(srcdir)/check_getdns_context_create.h \ + $(srcdir)/check_getdns_context_destroy.h \ $(srcdir)/check_getdns_context_set_context_update_callback.h \ $(srcdir)/check_getdns_context_set_dns_transport.h \ $(srcdir)/check_getdns_context_set_timeout.h \ @@ -254,34 +257,58 @@ check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c ../getdns/getdns.h $(sr $(srcdir)/check_getdns_list_get_list.h $(srcdir)/check_getdns_pretty_print_dict.h \ $(srcdir)/check_getdns_service.h $(srcdir)/check_getdns_service_sync.h \ $(srcdir)/check_getdns_transport.h -check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c ../getdns/getdns.h \ - ../config.h $(srcdir)/check_getdns_common.h ../getdns/getdns_extra.h \ +check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c \ + ../getdns/getdns.h \ + ../config.h \ + $(srcdir)/check_getdns_common.h \ + ../getdns/getdns_extra.h \ $(srcdir)/check_getdns_eventloop.h check_getdns_context_set_timeout.lo check_getdns_context_set_timeout.o: $(srcdir)/check_getdns_context_set_timeout.c \ $(srcdir)/check_getdns_context_set_timeout.h $(srcdir)/check_getdns_common.h \ - ../getdns/getdns.h ../getdns/getdns_extra.h + ../getdns/getdns.h \ + ../getdns/getdns_extra.h check_getdns_libev.lo check_getdns_libev.o: $(srcdir)/check_getdns_libev.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libev.h \ - ../getdns/getdns_extra.h $(srcdir)/check_getdns_common.h + ../config.h \ + ../getdns/getdns.h \ + $(srcdir)/../getdns/getdns_ext_libev.h \ + ../getdns/getdns_extra.h \ + $(srcdir)/check_getdns_common.h check_getdns_libevent.lo check_getdns_libevent.o: $(srcdir)/check_getdns_libevent.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libevent.h \ - ../getdns/getdns_extra.h $(srcdir)/check_getdns_libevent.h $(srcdir)/check_getdns_common.h + ../config.h \ + ../getdns/getdns.h \ + $(srcdir)/../getdns/getdns_ext_libevent.h \ + ../getdns/getdns_extra.h \ + $(srcdir)/check_getdns_libevent.h $(srcdir)/check_getdns_common.h check_getdns_libuv.lo check_getdns_libuv.o: $(srcdir)/check_getdns_libuv.c $(srcdir)/check_getdns_eventloop.h \ - ../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libuv.h \ - ../getdns/getdns_extra.h $(srcdir)/check_getdns_common.h + ../config.h \ + ../getdns/getdns.h \ + $(srcdir)/../getdns/getdns_ext_libuv.h \ + ../getdns/getdns_extra.h \ + $(srcdir)/check_getdns_common.h check_getdns_selectloop.lo check_getdns_selectloop.o: $(srcdir)/check_getdns_selectloop.c \ - $(srcdir)/check_getdns_eventloop.h ../config.h ../getdns/getdns.h \ + $(srcdir)/check_getdns_eventloop.h \ + ../config.h \ + ../getdns/getdns.h \ ../getdns/getdns_extra.h check_getdns_transport.lo check_getdns_transport.o: $(srcdir)/check_getdns_transport.c \ - $(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h ../getdns/getdns.h \ + $(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h \ + ../getdns/getdns.h \ ../getdns/getdns_extra.h -scratchpad.template.lo scratchpad.template.o: scratchpad.template.c ../getdns/getdns.h \ +scratchpad.template.lo scratchpad.template.o: scratchpad.template.c \ + ../getdns/getdns.h \ ../getdns/getdns_extra.h testmessages.lo testmessages.o: $(srcdir)/testmessages.c $(srcdir)/testmessages.h -tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h ../getdns/getdns.h -tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h ../getdns/getdns.h -tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h ../getdns/getdns.h -tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c ../config.h $(srcdir)/testmessages.h \ - ../getdns/getdns.h ../getdns/getdns_extra.h -tests_stub_sync.lo tests_stub_sync.o: $(srcdir)/tests_stub_sync.c $(srcdir)/testmessages.h ../getdns/getdns.h \ +tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h \ + ../getdns/getdns.h +tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h \ + ../getdns/getdns.h +tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h \ + ../getdns/getdns.h +tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c \ + ../config.h \ + $(srcdir)/testmessages.h \ + ../getdns/getdns.h \ + ../getdns/getdns_extra.h +tests_stub_sync.lo tests_stub_sync.o: $(srcdir)/tests_stub_sync.c $(srcdir)/testmessages.h \ + ../getdns/getdns.h \ ../getdns/getdns_extra.h diff --git a/src/tools/Makefile.in b/src/tools/Makefile.in index e36bea08..7e291603 100644 --- a/src/tools/Makefile.in +++ b/src/tools/Makefile.in @@ -113,5 +113,8 @@ depend: .PHONY: clean test # Dependencies for getdns_query -getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h $(srcdir)/../debug.h ../config.h \ - ../getdns/getdns.h ../getdns/getdns_extra.h +getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c \ + ../config.h \ + $(srcdir)/../debug.h \ + ../getdns/getdns.h \ + ../getdns/getdns_extra.h From 69b3f6f55818254250c5e3be613d95297be09bc6 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 22 Jun 2017 12:43:33 +0200 Subject: [PATCH 12/41] Remove unnecessary initialization (scan-build) --- src/anchor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index bb63c200..34597719 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -667,8 +667,8 @@ uint16_t _getdns_parse_xml_trust_anchors_buf( void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) { - uint8_t xml_spc[4096], *xml_data = xml_spc; - uint8_t p7s_spc[4096], *p7s_data = p7s_spc; + uint8_t xml_spc[4096], *xml_data; + uint8_t p7s_spc[4096], *p7s_data; size_t xml_len, p7s_len; BIO *xml = NULL, *p7s = NULL, *crt = NULL; From 2962baa050a40a8f7443da3615ea7aaf165b330b Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 22 Jun 2017 12:48:22 +0200 Subject: [PATCH 13/41] Old (not so smart) compiler warns for uninitialized variable --- src/anchor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anchor.c b/src/anchor.c index 34597719..4ddbb142 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -301,7 +301,7 @@ static inline int ta_iter_done(ta_iter *ta) static ta_iter *ta_iter_next(ta_iter *ta) { - yxml_ret_t r; + yxml_ret_t r = YXML_OK; yxml_t ta_x; const char *ta_start; int level; From ff1ebbf6719fb5aad64ccf7e076704e2c592b08f Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 22 Jun 2017 13:09:45 +0200 Subject: [PATCH 14/41] Hmmm... this time the warning does make sense --- src/anchor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anchor.c b/src/anchor.c index 4ddbb142..bacd7334 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -668,7 +668,7 @@ uint16_t _getdns_parse_xml_trust_anchors_buf( void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) { uint8_t xml_spc[4096], *xml_data; - uint8_t p7s_spc[4096], *p7s_data; + uint8_t p7s_spc[4096], *p7s_data = NULL; size_t xml_len, p7s_len; BIO *xml = NULL, *p7s = NULL, *crt = NULL; From fb267938c3a42657d9e2b4e0c69bec3b58399e79 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 28 Jun 2017 20:35:30 +0200 Subject: [PATCH 15/41] Start with fetching root-anchors remotely Also lays the foundation for looking up upstreams by name and DANE authentication of upstreams. --- src/context.c | 7 ++++ src/context.h | 15 ++++++++- src/dnssec.c | 72 ++++++++++++++++++++++++++++++++++++++++++ src/request-internal.c | 2 ++ src/types-internal.h | 6 ++++ 5 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/context.c b/src/context.c index 87f309de..a62020cd 100644 --- a/src/context.c +++ b/src/context.c @@ -1467,6 +1467,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; @@ -1596,6 +1599,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); diff --git a/src/context.h b/src/context.h index ae2315f1..fc95a21d 100644 --- a/src/context.h +++ b/src/context.h @@ -95,7 +95,8 @@ typedef enum getdns_conn_state { typedef enum getdns_tasrc { GETDNS_TASRC_NONE, GETDNS_TASRC_ZONE, - GETDNS_TASRC_XML + GETDNS_TASRC_XML, + GETDNS_TASRC_FAILED } getdns_tasrc; typedef enum getdns_tsig_algo { @@ -371,6 +372,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 */ diff --git a/src/dnssec.c b/src/dnssec.c index fbbc966d..4b60fbc5 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -2980,6 +2980,14 @@ static void append_empty_ds2val_chain_list( getdns_dict_destroy(rr_dict); } +static void data_iana_org_a(getdns_dns_req *dnsreq) +{ + getdns_dns_req *orig_dnsreq = (getdns_dns_req *)dnsreq->user_pointer; + DEBUG_SEC("Address for data.iana.org. found\n"); + _getdns_context_cancel_request(dnsreq); + check_chain_complete(orig_dnsreq->chain); +} + static void check_chain_complete(chain_head *chain) { getdns_dns_req *dnsreq; @@ -2999,6 +3007,70 @@ 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; + dnsreq->waiting_for_ta = 0; + break; + } + } + + } else if (context->trust_anchors_source == GETDNS_TASRC_NONE) { + DEBUG_SEC("Need to fetch a trust anchor\n"); + + dnsreq->waiting_for_ta = 1; + dnsreq->ta_notify = context->ta_notify; + context->ta_notify = dnsreq; + + if (dnsreq->ta_notify) + return; /* Wait for the notify callback */ + + else if (!context->sys_ctxt) { + if (getdns_context_create_with_extended_memory_functions( + &context->sys_ctxt, 1, + context->mf.mf_arg, + context->mf.mf.ext.malloc, + context->mf.mf.ext.realloc, + context->mf.mf.ext.free)) { + DEBUG_SEC("TA fetch: Error creating system context\n"); + + } else if (getdns_context_set_eventloop( + context->sys_ctxt, context->extension) || + getdns_context_set_resolution_type( + context->sys_ctxt, GETDNS_RESOLUTION_STUB) + ) { + DEBUG_SEC("TA fetch: Error configuring system context\n"); + + getdns_context_destroy(context->sys_ctxt); + context->sys_ctxt = NULL; + } + } + if (context->sys_ctxt) { + DEBUG_SEC("Start of fetching of root-anchors.xml\n"); + if (!_getdns_general_loop(context->sys_ctxt, + dnsreq->loop, "data.iana.org.", GETDNS_RRTYPE_A, + NULL, dnsreq, NULL, NULL, data_iana_org_a) +#if 0 + || !_getdns_general_loop(context->sys_ctxt, + dnsreq->loop, "data.iana.org.", GETDNS_RRTYPE_AAAA, + NULL, context, NULL, data_iana_org_aaaa) +#endif + ) + return; + + DEBUG_SEC("Scheduling of lookup for \"data.iana.org.\" failed\n"); + + getdns_context_destroy(context->sys_ctxt); + context->sys_ctxt = NULL; + } + dnsreq->waiting_for_ta = 0; + context->ta_notify = dnsreq->ta_notify; + dnsreq->ta_notify = NULL; + } #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 diff --git a/src/request-internal.c b/src/request-internal.c index 15f97179..32f6611a 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -940,8 +940,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; diff --git a/src/types-internal.h b/src/types-internal.h index 7834fc32..9b50fc91 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -324,6 +324,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 +366,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. * From 3e6c5775ff6de173600b7cacc2c231abc4e57814 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 30 Jun 2017 10:18:07 +0200 Subject: [PATCH 16/41] Fetch and equip context with trust-anchors --- src/anchor.c | 563 ++++++++++++++++++++++++++++++++++++++++++- src/anchor.h | 3 + src/context.c | 4 + src/context.h | 33 +++ src/dnssec.c | 89 +++---- src/dnssec.h | 1 + src/general.c | 5 + src/stub.c | 12 - src/types-internal.h | 2 +- src/util-internal.h | 13 + 10 files changed, 654 insertions(+), 71 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index bacd7334..8ce1cead 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -40,16 +40,20 @@ #include #include "types-internal.h" #include "context.h" +#include "dnssec.h" #include "yxml/yxml.h" #include "gldns/parseutil.h" #include "gldns/gbuffer.h" #include "gldns/str2wire.h" #include "gldns/pkthdr.h" +#include "general.h" +#include "rr-iter.h" +#include "util-internal.h" #define P7SIGNER "dnssec@iana.org" /* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */ -static char* _getdns_builtin_cert = +static char _getdns_builtin_cert[] = "-----BEGIN CERTIFICATE-----\n" "MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n" "TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n" @@ -72,6 +76,9 @@ static char* _getdns_builtin_cert = "j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n" "-----END CERTIFICATE-----\n"; +static getdns_bindata _getdns_builtin_cert_bd = + { sizeof(_getdns_builtin_cert) - 1, (void *)_getdns_builtin_cert}; + /* get key usage out of its extension, returns 0 if no key_usage extension */ static unsigned long _getdns_get_usage_of_ex(X509* cert) @@ -665,6 +672,79 @@ uint16_t _getdns_parse_xml_trust_anchors_buf( return ta_count; } +static uint8_t *tas_validate(struct mem_funcs *mf, + const getdns_bindata *xml_bd, const getdns_bindata *p7s_bd, + const getdns_bindata *crt_bd, const char *p7signer, + time_t now, uint8_t *tas, size_t *tas_len) +{ + BIO *xml = NULL, *p7s = NULL, *crt = NULL; + X509 *x = NULL; + X509_STORE *store = NULL; + uint8_t *success = NULL; + + if (!(xml = BIO_new_mem_buf(xml_bd->data, xml_bd->size))) + DEBUG_ANCHOR("ERROR %s(): Failed allocating xml BIO\n" + , __FUNC__); + + else if (!(p7s = BIO_new_mem_buf(p7s_bd->data, p7s_bd->size))) + DEBUG_ANCHOR("ERROR %s(): Failed allocating p7s BIO\n" + , __FUNC__); + + else if (!(crt = BIO_new_mem_buf(crt_bd->data, crt_bd->size))) + DEBUG_ANCHOR("ERROR %s(): Failed allocating crt BIO\n" + , __FUNC__); + + else if (!(x = PEM_read_bio_X509(crt, NULL, 0, NULL))) + DEBUG_ANCHOR("ERROR %s(): Parsing builtin certificate\n" + , __FUNC__); + + else if (!(store = X509_STORE_new())) + DEBUG_ANCHOR("ERROR %s(): Failed allocating store\n" + , __FUNC__); + + else if (!X509_STORE_add_cert(store, x)) + DEBUG_ANCHOR("ERROR %s(): Adding certificate to store\n" + , __FUNC__); + + else if (_getdns_verify_p7sig(xml, p7s, store, p7signer)) { + gldns_buffer gbuf; + + gldns_buffer_init_vfixed_frm_data(&gbuf, tas, *tas_len); + + if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, now, + (char *)xml_bd->data, xml_bd->size)) + DEBUG_ANCHOR("Failed to parse trust anchor XML data"); + + else if (gldns_buffer_position(&gbuf) > *tas_len) { + *tas_len = gldns_buffer_position(&gbuf); + if ((success = GETDNS_XMALLOC(*mf, uint8_t, *tas_len))) { + gldns_buffer_init_frm_data(&gbuf, success, *tas_len); + if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, + now, (char *)xml_bd->data, xml_bd->size)) { + + DEBUG_ANCHOR("Failed to re-parse trust" + " anchor XML data\n"); + GETDNS_FREE(*mf, success); + success = NULL; + } + } else + DEBUG_ANCHOR("Could not allocate space for " + "trust anchors\n"); + } else { + success = tas; + *tas_len = gldns_buffer_position(&gbuf); + } + } else { + DEBUG_ANCHOR("Verifying trust-anchors failed!\n"); + } + if (store) X509_STORE_free(store); + if (x) X509_free(x); + if (crt) BIO_free(crt); + if (xml) BIO_free(xml); + if (p7s) BIO_free(p7s); + return success; +} + void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) { uint8_t xml_spc[4096], *xml_data; @@ -757,4 +837,485 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) GETDNS_FREE(context->mf, p7s_data); } +static const uint8_t tas_write_xml_buf[] = +"GET /root-anchors/root-anchors.xml HTTP/1.1\r\n" +"Host: data.iana.org\r\n" +"\r\n"; + +static const uint8_t tas_write_p7s_buf[] = +"GET /root-anchors/root-anchors.p7s HTTP/1.1\r\n" +"Host: data.iana.org\r\n" +"\r\n"; + +static const uint8_t tas_write_xml_p7s_buf[] = +"GET /root-anchors/root-anchors.xml HTTP/1.1\r\n" +"Host: data.iana.org\r\n" +"\r\n" +"GET /root-anchors/root-anchors.p7s HTTP/1.1\r\n" +"Host: data.iana.org\r\n" +"\r\n"; + + +static inline const char * rt_str(uint16_t rt) +{ return rt == GETDNS_RRTYPE_A ? "A" : rt == GETDNS_RRTYPE_AAAA ? "AAAA" : "?"; } + +static int tas_busy(tas_connection *a) +{ + return a->req != NULL; +} + +static void tas_cleanup(getdns_context *context, tas_connection *a) +{ + if (a->req) + _getdns_context_cancel_request(a->req->owner); + if (a->event.ev) + GETDNS_CLEAR_EVENT(a->loop, &a->event); + if (a->fd >= 0) + close(a->fd); + if (a->xml.data) + GETDNS_FREE(context->mf, a->xml.data); + if (a->tcp.read_buf && a->tcp.read_buf != context->tas_hdr_spc) + GETDNS_FREE(context->mf, a->tcp.read_buf); + (void) memset(a, 0, sizeof(*a)); +} + +static void tas_success(getdns_context *context, tas_connection *a) +{ + tas_connection *other = &context->a == a ? &context->aaaa : &context->a; + + tas_cleanup(context, a); + tas_cleanup(context, other); + + DEBUG_ANCHOR("Successfully fetched new trust anchors\n"); + context->trust_anchors_source = GETDNS_TASRC_XML; + _getdns_ta_notify_dnsreqs(context); +} + +static void tas_fail(getdns_context *context, tas_connection *a) +{ + tas_connection *other = &context->a == a ? &context->aaaa : &context->a; + uint16_t rt = &context->a == a ? GETDNS_RRTYPE_A : GETDNS_RRTYPE_AAAA; + uint16_t ort = rt == GETDNS_RRTYPE_A ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A; + tas_cleanup(context, a); + + if (!tas_busy(other)) { + DEBUG_ANCHOR("Fatal error fetching trust anchor: " + "%s connection failed too\n", rt_str(rt)); + context->trust_anchors_source = GETDNS_TASRC_FAILED; + _getdns_ta_notify_dnsreqs(context); + } else + DEBUG_ANCHOR("%s connection failed, waiting for %s\n" + , rt_str(rt), rt_str(ort)); +} + +static void tas_connect(getdns_context *context, tas_connection *a); +static void tas_next(getdns_context *context, tas_connection *a) +{ + DEBUG_ANCHOR("Try next address\n"); + if (!(a->rr = _getdns_rrtype_iter_next(a->rr))) + tas_fail(context, a); + else tas_connect(context, a); +} + +static void tas_timeout_cb(void *userarg) +{ + getdns_dns_req *dnsreq = (getdns_dns_req *)userarg; + getdns_context *context = (getdns_context *)dnsreq->user_pointer; + tas_connection *a; + + if (dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A) + a = &context->a; + else a = &context->aaaa; + + DEBUG_ANCHOR("Trust anchor fetch timeout\n"); + GETDNS_CLEAR_EVENT(a->loop, &a->event); + tas_next(context, a); +} + +static void tas_read_cb(void *userarg); +static void tas_write_cb(void *userarg); +static void tas_doc_read(getdns_context *context, tas_connection *a) +{ + DEBUG_ANCHOR("doc (size: %d): \"%.*s\"\n", + (int)a->tcp.read_buf_len, + (int)a->tcp.read_buf_len, (char *)a->tcp.read_buf); + if (a->state == TAS_READ_XML_DOC) { + if (a->xml.data) + GETDNS_FREE(context->mf, a->xml.data); + a->xml.data = a->tcp.read_buf; + a->xml.size = a->tcp.read_buf_len; + } + a->state += 1; + GETDNS_CLEAR_EVENT(a->loop, &a->event); + if (a->state == TAS_DONE) { + getdns_bindata p7s_bd; + uint8_t *tas = context->trust_anchors_spc; + size_t tas_len = sizeof(context->trust_anchors_spc); + + p7s_bd.data = a->tcp.read_buf; + p7s_bd.size = a->tcp.read_buf_len; + tas = tas_validate(&context->mf, &a->xml, &p7s_bd, + &_getdns_builtin_cert_bd, "dnssec@iana.org", + time(NULL), tas, &tas_len); + + if (tas) { + context->trust_anchors = tas; + context->trust_anchors_len = tas_len; + /* TODO: Try to write xml & p7s */ + tas_success(context, a); + } else + tas_fail(context, a); + return; + } + assert(a->state == TAS_WRITE_GET_PS7); + a->tcp.write_buf = tas_write_p7s_buf; + a->tcp.write_buf_len = sizeof(tas_write_p7s_buf) - 1; + a->tcp.written = 0; + + /* First try to read signatures immediately */ + a->state += 1; + assert(a->state == TAS_READ_PS7_HDR); + a->tcp.read_buf = context->tas_hdr_spc; + a->tcp.read_buf_len = sizeof(context->tas_hdr_spc); + a->tcp.read_pos = a->tcp.read_buf; + a->tcp.to_read = sizeof(context->tas_hdr_spc); + + GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 50, + getdns_eventloop_event_init(&a->event, a->req->owner, + tas_read_cb, NULL, tas_timeout_cb)); +#if 0 + GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 2000, + getdns_eventloop_event_init(&a->event, a->req->owner, + NULL, tas_write_cb, tas_timeout_cb)); +#endif + return; +} + +static void tas_read_cb(void *userarg) +{ + getdns_dns_req *dnsreq = (getdns_dns_req *)userarg; + getdns_context *context = (getdns_context *)dnsreq->user_pointer; + tas_connection *a; + ssize_t n, i; + + if (dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A) + a = &context->a; + else a = &context->aaaa; + + DEBUG_ANCHOR( "state: %d, to_read: %d\n" + , (int)a->state, (int)a->tcp.to_read); + + n = read(a->fd, a->tcp.read_pos, a->tcp.to_read); + if (n >= 0 && ( a->state == TAS_READ_XML_DOC + || a->state == TAS_READ_PS7_DOC)) { + + assert(n <= (ssize_t)a->tcp.to_read); + + DEBUG_ANCHOR("read: %d bytes at %p, for doc %p of size %d\n", + (int)n, a->tcp.read_pos, a->tcp.read_buf, (int)a->tcp.read_buf_len); + a->tcp.read_pos += n; + a->tcp.to_read -= n; + if (a->tcp.to_read == 0) + tas_doc_read(context, a); + return; + + } else if (n >= 0) { + ssize_t p = 0; + int doc_len = -1; + int len; + char *ln; + char *endptr; + + n += a->tcp.read_pos - a->tcp.read_buf; + for (i = 0; i < (n - 1); i++) { + if (a->tcp.read_buf[i] != '\r' || + a->tcp.read_buf[i+1] != '\n') + continue; + + len = (int)(i - p); + ln = (char *)&a->tcp.read_buf[p]; + + DEBUG_ANCHOR("line: \"%.*s\"\n", len, ln); + if (len >= 16 && + !strncasecmp(ln, "Content-Length: ", 16)) { + ln[len] = 0; + doc_len = (int)strtol(ln + 16, &endptr , 10); + if (endptr == ln || *endptr != 0) + doc_len = -1; + } + if (i - p == 0) { + i += 2; + break; + } + p = i + 2; + i++; + } + if (doc_len > 0) { + uint8_t *doc = GETDNS_XMALLOC( + context->mf, uint8_t, doc_len); + + DEBUG_ANCHOR("i: %d, n: %d, doc_len: %d\n" + , (int)i, (int)n, doc_len); + if (!doc) + DEBUG_ANCHOR("Memory error"); + else { + a->state += 1; + /* TODO: With pipelined read, the buffer might + * contain the full document, plus a piece + * of the headers of the next document! + * Currently context->tas_hdr_spc is kept + * small enough to anticipate this. + */ + if (n - i > 0) { + if ((n - i) > doc_len) + n -= (doc_len - i); + (void) memcpy( + doc, a->tcp.read_buf + i, (n - i)); + a->tcp.read_pos = doc + (n - i); + a->tcp.to_read = doc_len - (n - i); + } else { + a->tcp.read_pos = doc; + a->tcp.to_read = doc_len; + } + a->tcp.read_buf = doc; + a->tcp.read_buf_len = doc_len; + + if (a->tcp.to_read == 0) + tas_doc_read(context, a); + return; + } + } + } else if (_getdns_EWOULDBLOCK) + return; + + DEBUG_ANCHOR("Read error: %s\n", strerror(errno)); + GETDNS_CLEAR_EVENT(a->loop, &a->event); + tas_next(context, a); +} + +static void tas_write_cb(void *userarg) +{ + getdns_dns_req *dnsreq = (getdns_dns_req *)userarg; + getdns_context *context = (getdns_context *)dnsreq->user_pointer; + tas_connection *a; + ssize_t written; + + if (dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A) + a = &context->a; + else a = &context->aaaa; + + DEBUG_ANCHOR( "state: %d, to_write: %d\n" + , (int)a->state, (int)a->tcp.write_buf_len); + + written = write(a->fd, a->tcp.write_buf, a->tcp.write_buf_len); + if (written >= 0) { + assert(written <= (ssize_t)a->tcp.write_buf_len); + + a->tcp.write_buf += written; + a->tcp.write_buf_len -= written; + if (a->tcp.write_buf_len > 0) + /* Write remainder */ + return; + + a->state += 1; + a->tcp.read_buf = context->tas_hdr_spc; + a->tcp.read_buf_len = sizeof(context->tas_hdr_spc); + a->tcp.read_pos = a->tcp.read_buf; + a->tcp.to_read = sizeof(context->tas_hdr_spc); + GETDNS_CLEAR_EVENT(a->loop, &a->event); + DEBUG_ANCHOR("All written, schedule read\n"); + GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 2000, + getdns_eventloop_event_init(&a->event, a->req->owner, + tas_read_cb, NULL, tas_timeout_cb)); + return; + + } else if (_getdns_EWOULDBLOCK) + return; + + DEBUG_ANCHOR("Write error: %s\n", strerror(errno)); + GETDNS_CLEAR_EVENT(a->loop, &a->event); + tas_next(context, a); +} + +static void tas_connect(getdns_context *context, tas_connection *a) +{ + char a_buf[40]; + int r; + +#ifdef HAVE_FCNTL + int flag; +#elif defined(HAVE_IOCTLSOCKET) + unsigned long on = 1; +#endif + + if (a->rr->rr_i.nxt - (a->rr->rr_i.rr_type + 10) != + ( a->req->request_type == GETDNS_RRTYPE_A ? 4 + : a->req->request_type == GETDNS_RRTYPE_AAAA ? 16 : -1)) { + + tas_next(context, a); + return; + } + DEBUG_ANCHOR("Initiating connection to %s\n" + , inet_ntop(( a->req->request_type == GETDNS_RRTYPE_A + ? AF_INET : AF_INET6) + , a->rr->rr_i.rr_type + 10, a_buf, sizeof(a_buf))); + + if ((a->fd = socket(( a->req->request_type == GETDNS_RRTYPE_A + ? AF_INET : AF_INET6), SOCK_STREAM, IPPROTO_TCP)) == -1) { + DEBUG_ANCHOR("Error creating socket: %s\n", strerror(errno)); + tas_next(context, a); + return; + } +#ifdef HAVE_FCNTL + if((flag = fcntl(a->fd, F_GETFL)) != -1) { + flag |= O_NONBLOCK; + if(fcntl(a->fd, F_SETFL, flag) == -1) { + /* ignore error, continue blockingly */ + } + } +#elif defined(HAVE_IOCTLSOCKET) + if(ioctlsocket(a->fd, FIONBIO, &on) != 0) { + /* ignore error, continue blockingly */ + } +#endif + if (a->req->request_type == GETDNS_RRTYPE_A) { + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_port = htons(80); + (void) memcpy(&addr.sin_addr, a->rr->rr_i.rr_type + 10, 4); + r = connect(a->fd, (struct sockaddr *)&addr, sizeof(addr)); + } else { + struct sockaddr_in6 addr; + + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(80); + addr.sin6_flowinfo = 0; + (void) memcpy(&addr.sin6_addr, a->rr->rr_i.rr_type + 10, 16); + addr.sin6_scope_id = 0; + r = connect(a->fd, (struct sockaddr *)&addr, sizeof(addr)); + } + if (r == 0 || (r == -1 && (_getdns_EINPROGRESS || + _getdns_EWOULDBLOCK))) { + + a->state += 1; + a->tcp.write_buf = tas_write_xml_p7s_buf; + a->tcp.write_buf_len = sizeof(tas_write_xml_p7s_buf) - 1; + a->tcp.written = 0; + + GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 2000, + getdns_eventloop_event_init(&a->event, a->req->owner, + NULL, tas_write_cb, tas_timeout_cb)); + DEBUG_ANCHOR("Scheduled write\n"); + return; + } else + DEBUG_ANCHOR("Connect error: %s\n", strerror(errno)); + + tas_next(context, a); +} + +static void data_iana_org(getdns_dns_req *dnsreq) +{ + getdns_context *context = (getdns_context *)dnsreq->user_pointer; + tas_connection *a; + + if (dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A) + a = &context->a; + else a = &context->aaaa; + + a->rrset = _getdns_rrset_answer( + &a->rrset_spc, a->req->response, a->req->response_len); + + if (!a->rrset) + DEBUG_ANCHOR("%s lookup for data.iana.org. returned no " + "response\n", rt_str(a->req->request_type)); + + else if (a->req->response_len < dnsreq->name_len + 12 || + !_getdns_dname_equal(a->req->response + 12, dnsreq->name) || + a->rrset->rr_type != a->req->request_type) + DEBUG_ANCHOR("%s lookup for data.iana.org. returned wrong " + "response\n", rt_str(a->req->request_type)); + else if (!(a->rr = _getdns_rrtype_iter_init(&a->rr_spc, a->rrset))) + DEBUG_ANCHOR("%s lookup for data.iana.org. returned no " + "addresses\n", rt_str(a->req->request_type)); + else { + a->loop = dnsreq->loop; + tas_connect(context, a); + return; + } + tas_fail(context, a); +} + +void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) +{ + getdns_return_t r; + size_t scheduled; + + DEBUG_ANCHOR("%s on the %ssynchronous loop\n", __FUNC__, + loop == &context->sync_eventloop.loop ? "" : "a"); + + while (!context->sys_ctxt) { + if ((r = getdns_context_create_with_extended_memory_functions( + &context->sys_ctxt, 1, context->mf.mf_arg, + context->mf.mf.ext.malloc, context->mf.mf.ext.realloc, + context->mf.mf.ext.free))) + DEBUG_ANCHOR("Could not create system context: %s\n" + , getdns_get_errorstr_by_id(r)); + + else if ((r = getdns_context_set_eventloop( + context->sys_ctxt, loop))) + DEBUG_ANCHOR("Could not configure %ssynchronous loop " + "with system context: %s\n" + , ( loop == &context->sync_eventloop.loop + ? "" : "a" ) + , getdns_get_errorstr_by_id(r)); + + else if ((r = getdns_context_set_resolution_type( + context->sys_ctxt, GETDNS_RESOLUTION_STUB))) + DEBUG_ANCHOR("Could not configure system context for " + "stub resolver: %s\n" + , getdns_get_errorstr_by_id(r)); + else + break; + + getdns_context_destroy(context->sys_ctxt); + context->sys_ctxt = NULL; + DEBUG_ANCHOR("Fatal error fetching trust anchor: " + "missing system context\n"); + context->trust_anchors_source = GETDNS_TASRC_FAILED; + _getdns_ta_notify_dnsreqs(context); + return; + } + scheduled = 0; +#if 1 + context->a.state = TAS_LOOKUP_ADDRESSES; + if ((r = _getdns_general_loop(context->sys_ctxt, loop, + "data.iana.org.", GETDNS_RRTYPE_A, NULL, context, + &context->a.req, NULL, data_iana_org))) { + DEBUG_ANCHOR("Error scheduling A lookup for data.iana.org: " + "%s\n", getdns_get_errorstr_by_id(r)); + } else + scheduled += 1; +#endif + +#if 0 + context->aaaa.state = TAS_LOOKUP_ADDRESSES; + if ((r = _getdns_general_loop(context->sys_ctxt, loop, + "data.iana.org.", GETDNS_RRTYPE_AAAA, NULL, context, + &context->aaaa.req, NULL, data_iana_org))) { + DEBUG_ANCHOR("Error scheduling AAAA lookup for data.iana.org: " + "%s\n", getdns_get_errorstr_by_id(r)); + } else + scheduled += 1; +#endif + + if (!scheduled) { + DEBUG_ANCHOR("Fatal error fetching trust anchor: Unable to " + "schedule address requests for data.iana.org\n"); + context->trust_anchors_source = GETDNS_TASRC_FAILED; + _getdns_ta_notify_dnsreqs(context); + } else + context->trust_anchors_source = GETDNS_TASRC_FETCHING; +} + /* anchor.c */ diff --git a/src/anchor.h b/src/anchor.h index b619781c..56a6cbfe 100644 --- a/src/anchor.h +++ b/src/anchor.h @@ -35,9 +35,12 @@ #define ANCHOR_H_ #include "getdns/getdns.h" +#include "getdns/getdns_extra.h" #include void _getdns_context_equip_with_anchor(getdns_context *context, time_t now); +void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop); + #endif /* anchor.h */ diff --git a/src/context.c b/src/context.c index bf17436b..cbc51a8a 100644 --- a/src/context.c +++ b/src/context.c @@ -1426,6 +1426,10 @@ getdns_context_create_with_extended_memory_functions( result->suffixes_len = sizeof(no_suffixes); result->trust_anchors_source = GETDNS_TASRC_NONE; + + (void) memset(&result->a, 0, sizeof(result->a)); + (void) memset(&result->aaaa, 0, sizeof(result->aaaa)); + gldns_buffer_init_vfixed_frm_data(&gbuf, result->trust_anchors_spc , sizeof(result->trust_anchors_spc)); diff --git a/src/context.h b/src/context.h index 252bcd61..bdb9afa6 100644 --- a/src/context.h +++ b/src/context.h @@ -48,6 +48,7 @@ #ifdef HAVE_MDNS_SUPPORT #include "util/lruhash.h" #endif +#include "rr-iter.h" struct getdns_dns_req; struct ub_ctx; @@ -95,6 +96,7 @@ typedef enum getdns_conn_state { typedef enum getdns_tasrc { GETDNS_TASRC_NONE, GETDNS_TASRC_ZONE, + GETDNS_TASRC_FETCHING, GETDNS_TASRC_XML, GETDNS_TASRC_FAILED } getdns_tasrc; @@ -262,6 +264,31 @@ 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_state; + +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; + getdns_bindata xml; +} tas_connection; + struct getdns_context { /* Context values */ getdns_resolution_t resolution_type; @@ -283,9 +310,15 @@ 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_upstreams *upstreams; uint16_t limit_outstanding_queries; uint32_t dnssec_allowed_skew; diff --git a/src/dnssec.c b/src/dnssec.c index 4b60fbc5..9cbde394 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -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 @@ -2980,14 +2981,6 @@ static void append_empty_ds2val_chain_list( getdns_dict_destroy(rr_dict); } -static void data_iana_org_a(getdns_dns_req *dnsreq) -{ - getdns_dns_req *orig_dnsreq = (getdns_dns_req *)dnsreq->user_pointer; - DEBUG_SEC("Address for data.iana.org. found\n"); - _getdns_context_cancel_request(dnsreq); - check_chain_complete(orig_dnsreq->chain); -} - static void check_chain_complete(chain_head *chain) { getdns_dns_req *dnsreq; @@ -3019,57 +3012,16 @@ static void check_chain_complete(chain_head *chain) } } - } else if (context->trust_anchors_source == GETDNS_TASRC_NONE) { - DEBUG_SEC("Need to fetch a trust anchor\n"); + } else { + if (context->trust_anchors_source == GETDNS_TASRC_NONE) + _getdns_start_fetching_ta(context, dnsreq->loop); - dnsreq->waiting_for_ta = 1; - dnsreq->ta_notify = context->ta_notify; - context->ta_notify = dnsreq; - - if (dnsreq->ta_notify) - return; /* Wait for the notify callback */ - - else if (!context->sys_ctxt) { - if (getdns_context_create_with_extended_memory_functions( - &context->sys_ctxt, 1, - context->mf.mf_arg, - context->mf.mf.ext.malloc, - context->mf.mf.ext.realloc, - context->mf.mf.ext.free)) { - DEBUG_SEC("TA fetch: Error creating system context\n"); - - } else if (getdns_context_set_eventloop( - context->sys_ctxt, context->extension) || - getdns_context_set_resolution_type( - context->sys_ctxt, GETDNS_RESOLUTION_STUB) - ) { - DEBUG_SEC("TA fetch: Error configuring system context\n"); - - getdns_context_destroy(context->sys_ctxt); - context->sys_ctxt = NULL; - } + if (context->trust_anchors_source == GETDNS_TASRC_FETCHING) { + dnsreq->waiting_for_ta = 1; + dnsreq->ta_notify = context->ta_notify; + context->ta_notify = dnsreq; + return; } - if (context->sys_ctxt) { - DEBUG_SEC("Start of fetching of root-anchors.xml\n"); - if (!_getdns_general_loop(context->sys_ctxt, - dnsreq->loop, "data.iana.org.", GETDNS_RRTYPE_A, - NULL, dnsreq, NULL, NULL, data_iana_org_a) -#if 0 - || !_getdns_general_loop(context->sys_ctxt, - dnsreq->loop, "data.iana.org.", GETDNS_RRTYPE_AAAA, - NULL, context, NULL, data_iana_org_aaaa) -#endif - ) - return; - - DEBUG_SEC("Scheduling of lookup for \"data.iana.org.\" failed\n"); - - getdns_context_destroy(context->sys_ctxt); - context->sys_ctxt = NULL; - } - dnsreq->waiting_for_ta = 0; - context->ta_notify = dnsreq->ta_notify; - dnsreq->ta_notify = NULL; } #ifdef STUB_NATIVE_DNSSEC /* Perform validation only on GETDNS_RESOLUTION_STUB (unbound_id == -1) @@ -3184,6 +3136,29 @@ 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; + + 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 && dnsreq->chain); + + check_chain_complete(dnsreq->chain); + + assert(*dnsreq_p != dnsreq); + /* if (*dnsreq_p == dnsreq) + dnsreq_p = &dnsreq->ta_notify; */ + } +} + void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq) { chain_head *head = dnsreq->chain, *next; diff --git a/src/dnssec.h b/src/dnssec.h index b0334d52..3ffa96ee 100644 --- a/src/dnssec.h +++ b/src/dnssec.h @@ -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); diff --git a/src/general.c b/src/general.c index 280df08d..4374350e 100644 --- a/src/general.c +++ b/src/general.c @@ -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) { @@ -578,6 +579,10 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, req->internal_cb = internal_cb; req->is_sync_request = loop == &context->sync_eventloop.loop; + if (req->dnssec_return_status && + context->trust_anchors_source == GETDNS_TASRC_NONE) + _getdns_start_fetching_ta(context, loop); + if (return_netreq_p) *return_netreq_p = req->netreqs[0]; diff --git a/src/stub.c b/src/stub.c index c6f25c79..df2465ca 100644 --- a/src/stub.c +++ b/src/stub.c @@ -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... diff --git a/src/types-internal.h b/src/types-internal.h index 9b50fc91..a827456a 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -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; diff --git a/src/util-internal.h b/src/util-internal.h index 6f8de235..3f4b9959 100644 --- a/src/util-internal.h +++ b/src/util-internal.h @@ -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 */ From 61561dd52700128e721098a331de2a3895fc93aa Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 30 Jun 2017 10:45:51 +0200 Subject: [PATCH 17/41] Fix warnings & dependencies --- src/Makefile.in | 41 +++++++++++++++++++++-------------------- src/anchor.c | 6 ++++++ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/Makefile.in b/src/Makefile.in index fed842ed..02a93a0d 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -228,14 +228,14 @@ anchor.lo anchor.o: $(srcdir)/anchor.c \ config.h \ $(srcdir)/debug.h $(srcdir)/anchor.h \ getdns/getdns.h \ - $(srcdir)/types-internal.h \ getdns/getdns_extra.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/context.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)/yxml/yxml.h $(srcdir)/gldns/parseutil.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.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)/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 \ @@ -244,14 +244,14 @@ context.lo context.o: $(srcdir)/context.c \ config.h \ $(srcdir)/anchor.h \ getdns/getdns.h \ - $(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.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 \ @@ -287,11 +287,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 \ @@ -302,9 +302,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 \ @@ -324,8 +324,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 \ @@ -338,8 +338,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 \ @@ -374,7 +374,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 \ @@ -397,8 +398,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 \ diff --git a/src/anchor.c b/src/anchor.c index 8ce1cead..08ff3aa1 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -837,10 +837,12 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) GETDNS_FREE(context->mf, p7s_data); } +#if 0 static const uint8_t tas_write_xml_buf[] = "GET /root-anchors/root-anchors.xml HTTP/1.1\r\n" "Host: data.iana.org\r\n" "\r\n"; +#endif static const uint8_t tas_write_p7s_buf[] = "GET /root-anchors/root-anchors.p7s HTTP/1.1\r\n" @@ -894,8 +896,10 @@ static void tas_success(getdns_context *context, tas_connection *a) static void tas_fail(getdns_context *context, tas_connection *a) { tas_connection *other = &context->a == a ? &context->aaaa : &context->a; +#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG uint16_t rt = &context->a == a ? GETDNS_RRTYPE_A : GETDNS_RRTYPE_AAAA; uint16_t ort = rt == GETDNS_RRTYPE_A ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A; +#endif tas_cleanup(context, a); if (!tas_busy(other)) { @@ -1139,7 +1143,9 @@ static void tas_write_cb(void *userarg) static void tas_connect(getdns_context *context, tas_connection *a) { +#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG char a_buf[40]; +#endif int r; #ifdef HAVE_FCNTL From 77d13f885e96609501eda7d3eba282f294119fe4 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 30 Jun 2017 11:08:20 +0200 Subject: [PATCH 18/41] unused function warning --- src/anchor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/anchor.c b/src/anchor.c index 08ff3aa1..bc39c65d 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -858,8 +858,10 @@ static const uint8_t tas_write_xml_p7s_buf[] = "\r\n"; +#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG static inline const char * rt_str(uint16_t rt) { return rt == GETDNS_RRTYPE_A ? "A" : rt == GETDNS_RRTYPE_AAAA ? "AAAA" : "?"; } +#endif static int tas_busy(tas_connection *a) { From 4a5f03ebbe10634a33816253247a734c01508362 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 30 Jun 2017 21:14:02 +0200 Subject: [PATCH 19/41] Anticipate surplus reads --- src/anchor.c | 55 +++++++++++++++++++++++++++++++++++++++------------ src/context.c | 2 ++ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index bc39c65d..a0ef411d 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -881,6 +881,7 @@ static void tas_cleanup(getdns_context *context, tas_connection *a) if (a->tcp.read_buf && a->tcp.read_buf != context->tas_hdr_spc) GETDNS_FREE(context->mf, a->tcp.read_buf); (void) memset(a, 0, sizeof(*a)); + a->fd = -1; } static void tas_success(getdns_context *context, tas_connection *a) @@ -945,12 +946,17 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) DEBUG_ANCHOR("doc (size: %d): \"%.*s\"\n", (int)a->tcp.read_buf_len, (int)a->tcp.read_buf_len, (char *)a->tcp.read_buf); + + assert(a->tcp.read_pos == a->tcp.read_buf + a->tcp.read_buf_len); + if (a->state == TAS_READ_XML_DOC) { if (a->xml.data) GETDNS_FREE(context->mf, a->xml.data); a->xml.data = a->tcp.read_buf; a->xml.size = a->tcp.read_buf_len; - } + } else + assert(a->state == TAS_READ_PS7_DOC); + a->state += 1; GETDNS_CLEAR_EVENT(a->loop, &a->event); if (a->state == TAS_DONE) { @@ -983,9 +989,16 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) assert(a->state == TAS_READ_PS7_HDR); a->tcp.read_buf = context->tas_hdr_spc; a->tcp.read_buf_len = sizeof(context->tas_hdr_spc); - a->tcp.read_pos = a->tcp.read_buf; - a->tcp.to_read = sizeof(context->tas_hdr_spc); + /* Check for surplus read bytes, for the P7S headers */ + if (a->tcp.to_read > 0) { + a->tcp.read_pos = a->tcp.read_buf + a->tcp.to_read; + a->tcp.to_read = sizeof(context->tas_hdr_spc) + - a->tcp.to_read; + } else { + a->tcp.read_pos = a->tcp.read_buf; + a->tcp.to_read = sizeof(context->tas_hdr_spc); + } GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 50, getdns_eventloop_event_init(&a->event, a->req->owner, tas_read_cb, NULL, tas_timeout_cb)); @@ -1065,28 +1078,44 @@ static void tas_read_cb(void *userarg) if (!doc) DEBUG_ANCHOR("Memory error"); else { + ssize_t surplus = n - i; + a->state += 1; - /* TODO: With pipelined read, the buffer might + /* With pipelined read, the buffer might * contain the full document, plus a piece * of the headers of the next document! * Currently context->tas_hdr_spc is kept * small enough to anticipate this. */ - if (n - i > 0) { - if ((n - i) > doc_len) - n -= (doc_len - i); - (void) memcpy( - doc, a->tcp.read_buf + i, (n - i)); - a->tcp.read_pos = doc + (n - i); - a->tcp.to_read = doc_len - (n - i); - } else { + if (surplus <= 0) { a->tcp.read_pos = doc; a->tcp.to_read = doc_len; + } else if (surplus > doc_len) { + (void) memcpy( + doc, a->tcp.read_buf + i, doc_len); + a->tcp.read_pos = doc + doc_len; + + /* Special value to indicate a begin + * of the next reply is already + * present. Detectable by: + * (read_pos == read_buf + read_buf_len) + * && to_read > 0; + */ + a->tcp.to_read = surplus - doc_len; + (void) memmove(a->tcp.read_buf, + a->tcp.read_buf + i + doc_len, + surplus - doc_len); + } else { + assert(surplus <= doc_len); + (void) memcpy( + doc, a->tcp.read_buf + i, surplus); + a->tcp.read_pos = doc + surplus; + a->tcp.to_read = doc_len - surplus; } a->tcp.read_buf = doc; a->tcp.read_buf_len = doc_len; - if (a->tcp.to_read == 0) + if (a->tcp.read_pos == doc + doc_len) tas_doc_read(context, a); return; } diff --git a/src/context.c b/src/context.c index cbc51a8a..67977d63 100644 --- a/src/context.c +++ b/src/context.c @@ -1429,6 +1429,8 @@ getdns_context_create_with_extended_memory_functions( (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)); From f9bdedbf84e718116821fd3e08b6cd4f22c77b8b Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 30 Jun 2017 22:00:14 +0200 Subject: [PATCH 20/41] Reconnect on pipelining failure --- src/anchor.c | 76 +++++++++++++++++++++++++++++++++------------------ src/context.h | 7 ++++- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index a0ef411d..538bd49f 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -837,13 +837,6 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) GETDNS_FREE(context->mf, p7s_data); } -#if 0 -static const uint8_t tas_write_xml_buf[] = -"GET /root-anchors/root-anchors.xml HTTP/1.1\r\n" -"Host: data.iana.org\r\n" -"\r\n"; -#endif - static const uint8_t tas_write_p7s_buf[] = "GET /root-anchors/root-anchors.p7s HTTP/1.1\r\n" "Host: data.iana.org\r\n" @@ -939,6 +932,28 @@ static void tas_timeout_cb(void *userarg) tas_next(context, a); } + +static void tas_reconnect_cb(void *userarg) +{ + getdns_dns_req *dnsreq = (getdns_dns_req *)userarg; + getdns_context *context = (getdns_context *)dnsreq->user_pointer; + tas_connection *a; + + if (dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A) + a = &context->a; + else a = &context->aaaa; + + DEBUG_ANCHOR("Waiting for second document timeout. Reconnecting...\n"); + GETDNS_CLEAR_EVENT(a->loop, &a->event); + close(a->fd); + a->fd = -1; + if (a->state == TAS_READ_PS7_HDR) { + a->state = TAS_RETRY; + tas_connect(context, a); + } else + tas_next(context, a); +} + static void tas_read_cb(void *userarg); static void tas_write_cb(void *userarg); static void tas_doc_read(getdns_context *context, tas_connection *a) @@ -955,11 +970,12 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) a->xml.data = a->tcp.read_buf; a->xml.size = a->tcp.read_buf_len; } else - assert(a->state == TAS_READ_PS7_DOC); + assert(a->state == TAS_READ_PS7_DOC || + a->state == TAS_RETRY_PS7_DOC); a->state += 1; GETDNS_CLEAR_EVENT(a->loop, &a->event); - if (a->state == TAS_DONE) { + if (a->state == TAS_DONE || a->state == TAS_RETRY_DONE) { getdns_bindata p7s_bd; uint8_t *tas = context->trust_anchors_spc; size_t tas_len = sizeof(context->trust_anchors_spc); @@ -979,11 +995,6 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) tas_fail(context, a); return; } - assert(a->state == TAS_WRITE_GET_PS7); - a->tcp.write_buf = tas_write_p7s_buf; - a->tcp.write_buf_len = sizeof(tas_write_p7s_buf) - 1; - a->tcp.written = 0; - /* First try to read signatures immediately */ a->state += 1; assert(a->state == TAS_READ_PS7_HDR); @@ -1001,12 +1012,7 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) } GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 50, getdns_eventloop_event_init(&a->event, a->req->owner, - tas_read_cb, NULL, tas_timeout_cb)); -#if 0 - GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 2000, - getdns_eventloop_event_init(&a->event, a->req->owner, - NULL, tas_write_cb, tas_timeout_cb)); -#endif + tas_read_cb, NULL, tas_reconnect_cb)); return; } @@ -1025,8 +1031,21 @@ static void tas_read_cb(void *userarg) , (int)a->state, (int)a->tcp.to_read); n = read(a->fd, a->tcp.read_pos, a->tcp.to_read); - if (n >= 0 && ( a->state == TAS_READ_XML_DOC - || a->state == TAS_READ_PS7_DOC)) { + if (n == 0) { + DEBUG_ANCHOR("Connection closed\n"); + GETDNS_CLEAR_EVENT(a->loop, &a->event); + close(a->fd); + a->fd = -1; + if (a->state == TAS_READ_PS7_HDR) { + a->state = TAS_RETRY; + tas_connect(context, a); + } else + tas_next(context, a); + return; + + } else if (n > 0 && ( a->state == TAS_READ_XML_DOC + || a->state == TAS_READ_PS7_DOC + || a->state == TAS_RETRY_PS7_DOC)) { assert(n <= (ssize_t)a->tcp.to_read); @@ -1038,7 +1057,7 @@ static void tas_read_cb(void *userarg) tas_doc_read(context, a); return; - } else if (n >= 0) { + } else if (n > 0) { ssize_t p = 0; int doc_len = -1; int len; @@ -1123,7 +1142,7 @@ static void tas_read_cb(void *userarg) } else if (_getdns_EWOULDBLOCK) return; - DEBUG_ANCHOR("Read error: %s\n", strerror(errno)); + DEBUG_ANCHOR("Read error: %d %s\n", (int)n, strerror(errno)); GETDNS_CLEAR_EVENT(a->loop, &a->event); tas_next(context, a); } @@ -1236,8 +1255,13 @@ static void tas_connect(getdns_context *context, tas_connection *a) _getdns_EWOULDBLOCK))) { a->state += 1; - a->tcp.write_buf = tas_write_xml_p7s_buf; - a->tcp.write_buf_len = sizeof(tas_write_xml_p7s_buf) - 1; + if (a->state == TAS_RETRY_GET_PS7) { + a->tcp.write_buf = tas_write_p7s_buf; + a->tcp.write_buf_len = sizeof(tas_write_p7s_buf) - 1; + } else { + a->tcp.write_buf = tas_write_xml_p7s_buf; + a->tcp.write_buf_len = sizeof(tas_write_xml_p7s_buf) - 1; + } a->tcp.written = 0; GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 2000, diff --git a/src/context.h b/src/context.h index bdb9afa6..9d70282f 100644 --- a/src/context.h +++ b/src/context.h @@ -272,7 +272,12 @@ typedef enum tas_state { TAS_WRITE_GET_PS7, TAS_READ_PS7_HDR, TAS_READ_PS7_DOC, - TAS_DONE + TAS_DONE, + TAS_RETRY, + TAS_RETRY_GET_PS7, + TAS_RETRY_PS7_HDR, + TAS_RETRY_PS7_DOC, + TAS_RETRY_DONE } tas_state; typedef struct tas_connection { From 8ec1f8eae927f665d3eac6234dddbba51399f20d Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 30 Jun 2017 22:51:03 +0200 Subject: [PATCH 21/41] Happy Eyeballs --- src/anchor.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 538bd49f..53696935 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -861,18 +861,33 @@ static int tas_busy(tas_connection *a) return a->req != NULL; } -static void tas_cleanup(getdns_context *context, tas_connection *a) +static int tas_fetching(tas_connection *a) +{ + return a->fd >= 0; +} + +static void tas_rinse(getdns_context *context, tas_connection *a) { - if (a->req) - _getdns_context_cancel_request(a->req->owner); if (a->event.ev) GETDNS_CLEAR_EVENT(a->loop, &a->event); + a->event.ev = NULL; if (a->fd >= 0) close(a->fd); + a->fd = -1; if (a->xml.data) GETDNS_FREE(context->mf, a->xml.data); + a->xml.data = NULL; + a->xml.size = 0; if (a->tcp.read_buf && a->tcp.read_buf != context->tas_hdr_spc) GETDNS_FREE(context->mf, a->tcp.read_buf); + a->tcp.read_buf = NULL; +} + +static void tas_cleanup(getdns_context *context, tas_connection *a) +{ + tas_rinse(context, a); + if (a->req) + _getdns_context_cancel_request(a->req->owner); (void) memset(a, 0, sizeof(*a)); a->fd = -1; } @@ -911,10 +926,20 @@ static void tas_fail(getdns_context *context, tas_connection *a) static void tas_connect(getdns_context *context, tas_connection *a); static void tas_next(getdns_context *context, tas_connection *a) { + tas_connection *other = a == &context->a ? &context->aaaa : &context->a; + DEBUG_ANCHOR("Try next address\n"); - if (!(a->rr = _getdns_rrtype_iter_next(a->rr))) - tas_fail(context, a); - else tas_connect(context, a); + + if (a->rr) { + if (!(a->rr = _getdns_rrtype_iter_next(a->rr))) + tas_fail(context, a); + else tas_rinse(context, a); + } + if (other->rr) + tas_connect(context, other); + + else if (a->rr) + tas_connect(context, a); } static void tas_timeout_cb(void *userarg) @@ -1275,6 +1300,18 @@ static void tas_connect(getdns_context *context, tas_connection *a) tas_next(context, a); } +static void tas_happy_eyeballs_cb(void *userarg) +{ + getdns_dns_req *dnsreq = (getdns_dns_req *)userarg; + getdns_context *context = (getdns_context *)dnsreq->user_pointer; + + assert(dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A); + if (tas_fetching(&context->aaaa)) + return; + else + tas_connect(context, &context->a); +} + static void data_iana_org(getdns_dns_req *dnsreq) { getdns_context *context = (getdns_context *)dnsreq->user_pointer; @@ -1300,8 +1337,27 @@ static void data_iana_org(getdns_dns_req *dnsreq) DEBUG_ANCHOR("%s lookup for data.iana.org. returned no " "addresses\n", rt_str(a->req->request_type)); else { + tas_connection *other = a == &context->a ? &context->aaaa + : &context->a; a->loop = dnsreq->loop; - tas_connect(context, a); + + if (tas_fetching(other)) + ; /* pass */ + + else if (a == &context->a && tas_busy(other)) { + DEBUG_ANCHOR("Postponing connection initiation: " + "Happy Eyeballs\n"); + GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 25, + getdns_eventloop_event_init(&a->event, + a->req->owner, NULL, NULL, tas_happy_eyeballs_cb)); + } else { + if (other->event.ev && + other->event.timeout_cb == tas_happy_eyeballs_cb) { + DEBUG_ANCHOR("Clearing Happy Eyeballs timer\n"); + GETDNS_CLEAR_EVENT(other->loop, &other->event); + } + tas_connect(context, a); + } return; } tas_fail(context, a); @@ -1359,7 +1415,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) scheduled += 1; #endif -#if 0 +#if 1 context->aaaa.state = TAS_LOOKUP_ADDRESSES; if ((r = _getdns_general_loop(context->sys_ctxt, loop, "data.iana.org.", GETDNS_RRTYPE_AAAA, NULL, context, From 2b20f35e0ec8b1f3f0e7803f33ff0e6ef340d310 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sat, 1 Jul 2017 00:05:20 +0200 Subject: [PATCH 22/41] Write fetched trust anchor --- src/anchor.c | 5 ++++- src/context.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- src/context.h | 3 +++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 53696935..17a17138 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -1014,7 +1014,10 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) if (tas) { context->trust_anchors = tas; context->trust_anchors_len = tas_len; - /* TODO: Try to write xml & p7s */ + _getdns_context_write_priv_file( + context, "root-anchors.xml", &a->xml); + _getdns_context_write_priv_file( + context, "root-anchors.p7s", &p7s_bd); tas_success(context, a); } else tas_fail(context, a); diff --git a/src/context.c b/src/context.c index 67977d63..668cf6b5 100644 --- a/src/context.c +++ b/src/context.c @@ -4528,12 +4528,12 @@ getdns_context_config(getdns_context *context, const getdns_dict *config_dict) uint8_t *_getdns_context_get_priv_file(getdns_context *context, const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz) { - char path[FILENAME_MAX]; + char path[PATH_MAX]; int n; FILE *f; n = snprintf(path, sizeof(path), "%s/.getdns/%s", getenv("HOME"), fn); - if (n < 0 || n > FILENAME_MAX) + if (n < 0 || n > PATH_MAX) return NULL; if (!(f = fopen(path, "r"))) @@ -4558,4 +4558,48 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context, return buf; } +void _getdns_context_write_priv_file(getdns_context *context, + const char *fn, getdns_bindata *content) +{ + char path[PATH_MAX], tmpfn[PATH_MAX]; + int n, fd; + FILE *f; + + (void)context; + + DEBUG_ANCHOR("%s\n", __FUNC__); + + n = snprintf( path, sizeof( path), "%s/.getdns/%s" , getenv("HOME"), fn); + if (n < 0 || n > PATH_MAX) { + DEBUG_ANCHOR("Could not create filename for writing\n"); + return; + } + + n = snprintf(tmpfn, sizeof(tmpfn), "%s/.getdns/XXXXXX", getenv("HOME")); + if (n < 0 || n > PATH_MAX) { + DEBUG_ANCHOR("Could not create tmpfn for writing\n"); + return; + } + + if ((fd = mkstemp(tmpfn)) < 0) { + DEBUG_ANCHOR("Could not create temporary file from \"%s\": %s\n", + tmpfn, strerror(errno)); + return; + } + + if (!(f = fdopen(fd, "w"))) { + close(fd); + return; + } + if (fwrite(content->data, 1, content->size, f) != content->size) + fclose(f); + else { + fclose(f); + if (rename(tmpfn, path) == -1) + DEBUG_ANCHOR("Could not mv \"%s\" \"%s\": %s\n", + tmpfn, path, strerror(errno)); + } +} + + /* context.c */ diff --git a/src/context.h b/src/context.h index 9d70282f..165dd2a4 100644 --- a/src/context.h +++ b/src/context.h @@ -531,4 +531,7 @@ void _getdns_upstream_shutdown(getdns_upstream *upstream); uint8_t *_getdns_context_get_priv_file(getdns_context *context, const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz); +void _getdns_context_write_priv_file(getdns_context *context, + const char *fn, getdns_bindata *content); + #endif /* _GETDNS_CONTEXT_H_ */ From 59ff5e8178974c2f280c5ab56500ac1f622644f4 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sat, 1 Jul 2017 00:45:09 +0200 Subject: [PATCH 23/41] 0 terminate xml files --- src/anchor.c | 3 ++- src/context.c | 5 +++-- src/test/tpkg/100-compile.tpkg/100-compile.pre | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 17a17138..1a9b640a 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -1118,7 +1118,8 @@ static void tas_read_cb(void *userarg) } if (doc_len > 0) { uint8_t *doc = GETDNS_XMALLOC( - context->mf, uint8_t, doc_len); + context->mf, uint8_t, doc_len + 1); + doc[doc_len] = 0; DEBUG_ANCHOR("i: %d, n: %d, doc_len: %d\n" , (int)i, (int)n, doc_len); diff --git a/src/context.c b/src/context.c index 668cf6b5..4c78368b 100644 --- a/src/context.c +++ b/src/context.c @@ -4539,8 +4539,8 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context, if (!(f = fopen(path, "r"))) return NULL; - if ((*file_sz = fread(buf, 1, buf_len, f)) < buf_len && feof(f)) - ; /* pass */ + if ((*file_sz = fread(buf, 1, buf_len, f)) < (buf_len - 1) && feof(f)) + buf[*file_sz] = 0; else if (fseek(f, 0, SEEK_END) < 0) buf = NULL; @@ -4553,6 +4553,7 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context, GETDNS_FREE(context->mf, buf); buf = NULL; } + buf[*file_sz] = 0; } (void) fclose(f); return buf; diff --git a/src/test/tpkg/100-compile.tpkg/100-compile.pre b/src/test/tpkg/100-compile.tpkg/100-compile.pre index 6b76edba..ea1cacee 100644 --- a/src/test/tpkg/100-compile.tpkg/100-compile.pre +++ b/src/test/tpkg/100-compile.tpkg/100-compile.pre @@ -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 From 11138ff6788a42c42cba38e780dc2f10ce139237 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sat, 1 Jul 2017 01:00:40 +0200 Subject: [PATCH 24/41] Also register application set trust anchors --- src/context.c | 2 ++ src/context.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/context.c b/src/context.c index 4c78368b..efe30bed 100644 --- a/src/context.c +++ b/src/context.c @@ -2637,9 +2637,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; diff --git a/src/context.h b/src/context.h index 165dd2a4..b31c079d 100644 --- a/src/context.h +++ b/src/context.h @@ -96,6 +96,7 @@ typedef enum getdns_conn_state { typedef enum getdns_tasrc { GETDNS_TASRC_NONE, GETDNS_TASRC_ZONE, + GETDNS_TASRC_APP, GETDNS_TASRC_FETCHING, GETDNS_TASRC_XML, GETDNS_TASRC_FAILED From 7151e6fd4485d55e28ce2cbea67f15544c4dc783 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sat, 1 Jul 2017 01:01:17 +0200 Subject: [PATCH 25/41] Deal with leaking timeouts (between sync and async loop) --- src/extension/poll_eventloop.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/extension/poll_eventloop.c b/src/extension/poll_eventloop.c index e796de10..b4f204b1 100644 --- a/src/extension/poll_eventloop.c +++ b/src/extension/poll_eventloop.c @@ -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 From 44065bead8303b5c058104adad033f0866209bf0 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 6 Jul 2017 00:26:21 +0200 Subject: [PATCH 26/41] Initial windows work --- configure.ac | 37 +++- src/compat/strptime.c | 345 +++++++++++++++++++++++++++++++ src/extension/select_eventloop.h | 1 + src/util/val_secalgo.h | 2 + 4 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 src/compat/strptime.c diff --git a/configure.ac b/configure.ac index c39bec81..3efbe5f7 100644 --- a/configure.ac +++ b/configure.ac @@ -288,6 +288,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 +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]) @@ -1294,9 +1321,11 @@ const char *inet_ntop(int af, const void *src, char *dst, size_t size); #endif #ifdef USE_WINSOCK +# ifndef vsnprintf static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *format, va_list ap) { int r = vsnprintf(str, size, format, ap); return r == -1 ? _vscprintf(format, ap) : r; } -# define vsnprintf _gldns_custom_vsnprintf +# define vsnprintf _gldns_custom_vsnprintf +# endif #endif #ifdef __cplusplus @@ -1371,6 +1400,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 # ifdef HAVE_UNBOUND_EVENT_H diff --git a/src/compat/strptime.c b/src/compat/strptime.c new file mode 100644 index 00000000..10ec3157 --- /dev/null +++ b/src/compat/strptime.c @@ -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 +#endif + +#ifndef STRPTIME_WORKS + +#define TM_YEAR_BASE 1900 + +#include +#include + +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]) && counttm_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 */ diff --git a/src/extension/select_eventloop.h b/src/extension/select_eventloop.h index e830a2ac..88f82a14 100644 --- a/src/extension/select_eventloop.h +++ b/src/extension/select_eventloop.h @@ -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 diff --git a/src/util/val_secalgo.h b/src/util/val_secalgo.h index 55bf423e..08f40e83 100644 --- a/src/util/val_secalgo.h +++ b/src/util/val_secalgo.h @@ -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 From 8f3ce9af358d33b8390521a7b9164416d639549b Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 13 Sep 2017 14:00:54 +0200 Subject: [PATCH 27/41] Configurable zero configuration DNSSEC parameters --- src/anchor.c | 306 ++++++++++++++++++++++++++--------- src/context.c | 147 +++++++++++++++++ src/context.h | 15 ++ src/getdns/getdns_extra.h.in | 51 ++++++ 4 files changed, 439 insertions(+), 80 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 1a9b640a..ed594059 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -50,35 +50,6 @@ #include "rr-iter.h" #include "util-internal.h" -#define P7SIGNER "dnssec@iana.org" - -/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */ -static char _getdns_builtin_cert[] = -"-----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 getdns_bindata _getdns_builtin_cert_bd = - { sizeof(_getdns_builtin_cert) - 1, (void *)_getdns_builtin_cert}; - /* get key usage out of its extension, returns 0 if no key_usage extension */ static unsigned long _getdns_get_usage_of_ex(X509* cert) @@ -585,7 +556,7 @@ static ta_iter *ta_iter_init(ta_iter *ta, const char *doc, size_t doc_len) return ta_iter_next(ta); } -uint16_t _getdns_parse_xml_trust_anchors_buf( +static uint16_t _getdns_parse_xml_trust_anchors_buf( gldns_buffer *gbuf, time_t now, char *xml_data, size_t xml_len) { ta_iter ta_spc, *ta; @@ -750,18 +721,35 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) uint8_t xml_spc[4096], *xml_data; uint8_t p7s_spc[4096], *p7s_data = NULL; size_t xml_len, p7s_len; + const char *verify_email = NULL; + const char *verify_CA = NULL; + getdns_return_t r; BIO *xml = NULL, *p7s = NULL, *crt = NULL; X509 *x = NULL; X509_STORE *store = NULL; - if (!(xml_data = _getdns_context_get_priv_file(context, + if ((r = getdns_context_get_trust_anchor_verify_CA( + context, ".", &verify_CA))) + DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify" + " CA: \"%s\"\n", __FUNC__ + , getdns_get_errorstr_by_id(r)); + + else if ((r = getdns_context_get_trust_anchor_verify_email( + context, ".", &verify_email))) + DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify email " + "address: \"%s\"\n", __FUNC__ + , getdns_get_errorstr_by_id(r)); + + else if (!(xml_data = _getdns_context_get_priv_file(context, "root-anchors.xml", xml_spc, sizeof(xml_spc), &xml_len))) - ; /* pass */ + DEBUG_ANCHOR("DEBUG %s(): root-anchors.xml not present\n" + , __FUNC__); else if (!(p7s_data = _getdns_context_get_priv_file(context, "root-anchors.p7s", p7s_spc, sizeof(p7s_spc), &p7s_len))) - ; /* pass */ + DEBUG_ANCHOR("DEBUG %s(): root-anchors.p7s not present\n" + , __FUNC__); else if (!(xml = BIO_new_mem_buf(xml_data, xml_len))) DEBUG_ANCHOR("ERROR %s(): Failed allocating xml BIO\n" @@ -770,8 +758,8 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) else if (!(p7s = BIO_new_mem_buf(p7s_data, p7s_len))) DEBUG_ANCHOR("ERROR %s(): Failed allocating p7s BIO\n" , __FUNC__); - - else if (!(crt = BIO_new_mem_buf((void *)_getdns_builtin_cert, -1))) + + else if (!(crt = BIO_new_mem_buf((void *)verify_CA, -1))) DEBUG_ANCHOR("ERROR %s(): Failed allocating crt BIO\n" , __FUNC__); @@ -787,7 +775,7 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) DEBUG_ANCHOR("ERROR %s(): Adding certificate to store\n" , __FUNC__); - else if (_getdns_verify_p7sig(xml, p7s, store, "dnssec@iana.org")) { + else if (_getdns_verify_p7sig(xml, p7s, store, verify_email)) { uint8_t ta_spc[sizeof(context->trust_anchors_spc)]; size_t ta_len; uint8_t *ta = NULL; @@ -837,17 +825,17 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) GETDNS_FREE(context->mf, p7s_data); } -static const uint8_t tas_write_p7s_buf[] = -"GET /root-anchors/root-anchors.p7s HTTP/1.1\r\n" -"Host: data.iana.org\r\n" +static const char tas_write_p7s_buf[] = +"GET %s HTTP/1.1\r\n" +"Host: %s\r\n" "\r\n"; -static const uint8_t tas_write_xml_p7s_buf[] = -"GET /root-anchors/root-anchors.xml HTTP/1.1\r\n" -"Host: data.iana.org\r\n" +static const char tas_write_xml_p7s_buf[] = +"GET %s HTTP/1.1\r\n" +"Host: %s\r\n" "\r\n" -"GET /root-anchors/root-anchors.p7s HTTP/1.1\r\n" -"Host: data.iana.org\r\n" +"GET %s HTTP/1.1\r\n" +"Host: %s\r\n" "\r\n"; @@ -888,6 +876,8 @@ static void tas_cleanup(getdns_context *context, tas_connection *a) tas_rinse(context, a); if (a->req) _getdns_context_cancel_request(a->req->owner); + if (a->http) + GETDNS_FREE(context->mf, (void *)a->http); (void) memset(a, 0, sizeof(*a)); a->fd = -1; } @@ -1004,14 +994,33 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) getdns_bindata p7s_bd; uint8_t *tas = context->trust_anchors_spc; size_t tas_len = sizeof(context->trust_anchors_spc); + const char *verify_email = NULL; + getdns_bindata verify_CA; + getdns_return_t r; p7s_bd.data = a->tcp.read_buf; p7s_bd.size = a->tcp.read_buf_len; - tas = tas_validate(&context->mf, &a->xml, &p7s_bd, - &_getdns_builtin_cert_bd, "dnssec@iana.org", - time(NULL), tas, &tas_len); - if (tas) { + if ((r = getdns_context_get_trust_anchor_verify_CA( + context, ".", (const char **)&verify_CA.data))) + DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify" + " CA: \"%s\"\n", __FUNC__ + , getdns_get_errorstr_by_id(r)); + + else if (!(verify_CA.size = strlen((const char *)verify_CA.data))) + ; /* pass */ + + else if ((r = getdns_context_get_trust_anchor_verify_email( + context, ".", &verify_email))) + DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify" + " email address: \"%s\"\n", __FUNC__ + , getdns_get_errorstr_by_id(r)); + + else if (!(tas = tas_validate(&context->mf, &a->xml, &p7s_bd, + &verify_CA, verify_email, time(NULL), tas, &tas_len))) + ; /* pass */ + + else { context->trust_anchors = tas; context->trust_anchors_len = tas_len; _getdns_context_write_priv_file( @@ -1019,8 +1028,9 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) _getdns_context_write_priv_file( context, "root-anchors.p7s", &p7s_bd); tas_success(context, a); - } else - tas_fail(context, a); + return; + } + tas_fail(context, a); return; } /* First try to read signatures immediately */ @@ -1220,6 +1230,38 @@ static void tas_write_cb(void *userarg) tas_next(context, a); } +static getdns_return_t _getdns_get_tas_url_hostname( + getdns_context *context, char *hostname, const char **path) +{ + getdns_return_t r; + const char *url; + char *next_slash; + size_t s; + + if ((r = getdns_context_get_trust_anchor_url(context, ".", &url))) + return r; + + if ((next_slash = strchr(url + 7 /* "http://" */, '/'))) { + if (next_slash - url - 7 > 254) + return GETDNS_RETURN_NO_SUCH_LIST_ITEM; + if (path) + *path = next_slash; + strncpy(hostname, url + 7, next_slash - url - 7); + hostname[next_slash - url - 7] = 0; + } else { + if (path) + *path = url + strlen(url); + strncpy(hostname, url + 7, 254); + hostname[254] = 0; + } + s = strlen(hostname); + if (s && s < 255 && hostname[s - 1] != '.') { + hostname[s] = '.'; + hostname[s+1] = '\0'; + } + return GETDNS_RETURN_GOOD; +} + static void tas_connect(getdns_context *context, tas_connection *a) { #if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG @@ -1281,16 +1323,74 @@ static void tas_connect(getdns_context *context, tas_connection *a) r = connect(a->fd, (struct sockaddr *)&addr, sizeof(addr)); } if (r == 0 || (r == -1 && (_getdns_EINPROGRESS || - _getdns_EWOULDBLOCK))) { + _getdns_EWOULDBLOCK))) { + char tas_hostname[256]; + const char *path = "", *fmt; + getdns_return_t R; + char *write_buf; + size_t buf_sz, path_len, hostname_len; a->state += 1; - if (a->state == TAS_RETRY_GET_PS7) { - a->tcp.write_buf = tas_write_p7s_buf; - a->tcp.write_buf_len = sizeof(tas_write_p7s_buf) - 1; - } else { - a->tcp.write_buf = tas_write_xml_p7s_buf; - a->tcp.write_buf_len = sizeof(tas_write_xml_p7s_buf) - 1; + if (a->http) { + GETDNS_FREE(context->mf, (void *)a->http); + a->http = NULL; + a->tcp.write_buf = NULL; + a->tcp.write_buf_len = 0; + a->tcp.written = 0; } + if ((R = _getdns_get_tas_url_hostname( + context, tas_hostname, &path))) { + DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname" + ": \"%s\"", __FUNC__ + , getdns_get_errorstr_by_id(r)); + goto error; + } + hostname_len = strlen(tas_hostname); + if (hostname_len > 0 && tas_hostname[hostname_len - 1] == '.') + tas_hostname[--hostname_len] = '\0'; + path_len = strlen(path); + if (path_len < 4) { + DEBUG_ANCHOR("ERROR %s(): path of tas_url \"%s\" too " + "small\n", __FUNC__, path); + goto error; + } + if (a->state == TAS_RETRY_GET_PS7) { + buf_sz = sizeof(tas_write_p7s_buf) + + 1 * (hostname_len - 2) + 1 * (path_len - 2) + 1; + fmt = tas_write_p7s_buf; + } else { + buf_sz = sizeof(tas_write_xml_p7s_buf) + + 2 * (hostname_len - 2) + 2 * (path_len - 2) + 1; + fmt = tas_write_xml_p7s_buf; + } + if (!(write_buf = GETDNS_XMALLOC(context->mf, char, buf_sz))) { + DEBUG_ANCHOR("ERROR %s(): Could not allocate write " + "buffer\n", __FUNC__); + goto error; + } + if (a->state == TAS_RETRY_GET_PS7) { + (void) snprintf( write_buf, buf_sz, fmt + , path, tas_hostname); + write_buf[4 + path_len - 3] = + write_buf[4 + path_len - 3] == 'X' ? 'P' : 'p'; + write_buf[4 + path_len - 2] = '7'; + write_buf[4 + path_len - 1] = + write_buf[4 + path_len - 1] == 'L' ? 'S' : 's'; + } else { + (void) snprintf( write_buf, buf_sz, fmt + , path, tas_hostname + , path, tas_hostname); + write_buf[29 + hostname_len + 2 * path_len - 3] = + write_buf[29 + hostname_len + 2 * path_len - 3] == 'X' + ? 'P' : 'p'; + write_buf[29 + hostname_len + 2 * path_len - 2] = '7'; + write_buf[29 + hostname_len + 2 * path_len - 1] = + write_buf[29 + hostname_len + 2 * path_len - 1] == 'L' + ? 'S' : 's'; + } + DEBUG_ANCHOR("Write buffer: \"%s\"\n", write_buf); + a->tcp.write_buf = (uint8_t *)(a->http = write_buf); + a->tcp.write_buf_len = buf_sz - 1; a->tcp.written = 0; GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 2000, @@ -1301,6 +1401,7 @@ static void tas_connect(getdns_context *context, tas_connection *a) } else DEBUG_ANCHOR("Connect error: %s\n", strerror(errno)); +error: tas_next(context, a); } @@ -1316,7 +1417,7 @@ static void tas_happy_eyeballs_cb(void *userarg) tas_connect(context, &context->a); } -static void data_iana_org(getdns_dns_req *dnsreq) +static void _tas_hostname_lookup_cb(getdns_dns_req *dnsreq) { getdns_context *context = (getdns_context *)dnsreq->user_pointer; tas_connection *a; @@ -1328,19 +1429,30 @@ static void data_iana_org(getdns_dns_req *dnsreq) a->rrset = _getdns_rrset_answer( &a->rrset_spc, a->req->response, a->req->response_len); - if (!a->rrset) - DEBUG_ANCHOR("%s lookup for data.iana.org. returned no " - "response\n", rt_str(a->req->request_type)); - - else if (a->req->response_len < dnsreq->name_len + 12 || + if (!a->rrset) { +#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG + char tas_hostname[256] = ""; + (void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL); + DEBUG_ANCHOR("%s lookup for %s returned no response\n" + , rt_str(a->req->request_type), tas_hostname); +#endif + } else if (a->req->response_len < dnsreq->name_len + 12 || !_getdns_dname_equal(a->req->response + 12, dnsreq->name) || - a->rrset->rr_type != a->req->request_type) - DEBUG_ANCHOR("%s lookup for data.iana.org. returned wrong " - "response\n", rt_str(a->req->request_type)); - else if (!(a->rr = _getdns_rrtype_iter_init(&a->rr_spc, a->rrset))) - DEBUG_ANCHOR("%s lookup for data.iana.org. returned no " - "addresses\n", rt_str(a->req->request_type)); - else { + a->rrset->rr_type != a->req->request_type) { +#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG + char tas_hostname[256] = ""; + (void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL); + DEBUG_ANCHOR("%s lookup for %s returned wrong response\n" + , rt_str(a->req->request_type), tas_hostname); +#endif + } else if (!(a->rr = _getdns_rrtype_iter_init(&a->rr_spc, a->rrset))) { +#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG + char tas_hostname[256] = ""; + (void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL); + DEBUG_ANCHOR("%s lookup for %s returned no addresses\n" + , rt_str(a->req->request_type), tas_hostname); +#endif + } else { tas_connection *other = a == &context->a ? &context->aaaa : &context->a; a->loop = dnsreq->loop; @@ -1371,11 +1483,44 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) { getdns_return_t r; size_t scheduled; + char tas_hostname[256]; + const char *verify_CA; + const char *verify_email; + if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) { + DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname" + ": \"%s\"", __FUNC__ + , getdns_get_errorstr_by_id(r)); + return; + + } else if ((r = getdns_context_get_trust_anchor_verify_CA( + context, ".", &verify_CA))) { + DEBUG_ANCHOR("ERROR %s(): Could not get verify CA" + ": \"%s\"", __FUNC__ + , getdns_get_errorstr_by_id(r)); + return; + + } else if (!*verify_CA) { + DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely " + "disabled by empty verify CA\n"); + return; + } else if ((r = getdns_context_get_trust_anchor_verify_email( + context, ".", &verify_email))) { + DEBUG_ANCHOR("ERROR %s(): Could not get verify email address" + ": \"%s\"", __FUNC__ + , getdns_get_errorstr_by_id(r)); + return; + + } else if (!*verify_email) { + DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely " + "disabled by empty verify email address\n"); + return; + } + DEBUG_ANCHOR("Hostname: %s\n", tas_hostname); DEBUG_ANCHOR("%s on the %ssynchronous loop\n", __FUNC__, loop == &context->sync_eventloop.loop ? "" : "a"); - while (!context->sys_ctxt) { + while (!context->sys_ctxt) { /* Used as breakable if. Never repeats. */ if ((r = getdns_context_create_with_extended_memory_functions( &context->sys_ctxt, 1, context->mf.mf_arg, context->mf.mf.ext.malloc, context->mf.mf.ext.realloc, @@ -1411,10 +1556,10 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) #if 1 context->a.state = TAS_LOOKUP_ADDRESSES; if ((r = _getdns_general_loop(context->sys_ctxt, loop, - "data.iana.org.", GETDNS_RRTYPE_A, NULL, context, - &context->a.req, NULL, data_iana_org))) { - DEBUG_ANCHOR("Error scheduling A lookup for data.iana.org: " - "%s\n", getdns_get_errorstr_by_id(r)); + tas_hostname, GETDNS_RRTYPE_A, NULL, context, + &context->a.req, NULL, _tas_hostname_lookup_cb))) { + DEBUG_ANCHOR("Error scheduling A lookup for %s: %s\n" + , tas_hostname, getdns_get_errorstr_by_id(r)); } else scheduled += 1; #endif @@ -1422,17 +1567,18 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) #if 1 context->aaaa.state = TAS_LOOKUP_ADDRESSES; if ((r = _getdns_general_loop(context->sys_ctxt, loop, - "data.iana.org.", GETDNS_RRTYPE_AAAA, NULL, context, - &context->aaaa.req, NULL, data_iana_org))) { - DEBUG_ANCHOR("Error scheduling AAAA lookup for data.iana.org: " - "%s\n", getdns_get_errorstr_by_id(r)); + tas_hostname, GETDNS_RRTYPE_AAAA, NULL, context, + &context->aaaa.req, NULL, _tas_hostname_lookup_cb))) { + DEBUG_ANCHOR("Error scheduling AAAA lookup for %s: %s\n" + , tas_hostname, getdns_get_errorstr_by_id(r)); } else scheduled += 1; #endif if (!scheduled) { DEBUG_ANCHOR("Fatal error fetching trust anchor: Unable to " - "schedule address requests for data.iana.org\n"); + "schedule address requests for %s\n" + , tas_hostname); context->trust_anchors_source = GETDNS_TASRC_FAILED; _getdns_ta_notify_dnsreqs(context); } else diff --git a/src/context.c b/src/context.c index 49879228..71bbc4ba 100644 --- a/src/context.c +++ b/src/context.c @@ -1343,6 +1343,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 * @@ -1443,6 +1474,11 @@ getdns_context_create_with_extended_memory_functions( 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->a, 0, sizeof(result->a)); (void) memset(&result->aaaa, 0, sizeof(result->aaaa)); @@ -4626,5 +4662,116 @@ void _getdns_context_write_priv_file(getdns_context *context, } } +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 >= 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 */ diff --git a/src/context.h b/src/context.h index 24b47e8a..e7c39fa5 100644 --- a/src/context.h +++ b/src/context.h @@ -113,6 +113,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; @@ -281,6 +282,13 @@ typedef enum tas_state { 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; @@ -292,6 +300,7 @@ typedef struct tas_connection { getdns_eventloop_event event; tas_state state; getdns_tcp_state tcp; + char *http; getdns_bindata xml; } tas_connection; @@ -325,6 +334,12 @@ struct getdns_context { tas_connection aaaa; uint8_t tas_hdr_spc[512]; + _getdns_property can_write_appdata : 2; + + const char *root_anchor_url; + const char *root_anchor_verify_CA; + const char *root_anchor_verify_email; + getdns_upstreams *upstreams; uint16_t limit_outstanding_queries; uint32_t dnssec_allowed_skew; diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index dbb8eab4..a6f68d9a 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -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); + + /** @} */ From f31eb517e0a20dd17b35737234d9a07e477b02e3 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Sep 2017 11:47:02 +0200 Subject: [PATCH 28/41] Lazy TA and time checking --- src/anchor.c | 24 ++++++++++++++---------- src/anchor.h | 2 +- src/context.c | 3 --- src/dnssec.c | 3 --- src/general.c | 8 +++++--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index ed594059..68300984 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -557,7 +557,7 @@ static ta_iter *ta_iter_init(ta_iter *ta, const char *doc, size_t doc_len) } static uint16_t _getdns_parse_xml_trust_anchors_buf( - gldns_buffer *gbuf, time_t now, char *xml_data, size_t xml_len) + gldns_buffer *gbuf, uint64_t *now_ms, char *xml_data, size_t xml_len) { ta_iter ta_spc, *ta; uint16_t ta_count = 0; @@ -571,12 +571,14 @@ static uint16_t _getdns_parse_xml_trust_anchors_buf( for ( ta = ta_iter_init(&ta_spc, (char *)xml_data, xml_len) ; ta; ta = ta_iter_next(ta)) { - if (now < ta->validFrom) + if (*now_ms == 0) *now_ms = _getdns_get_now_ms(); + if ((time_t)(*now_ms / 1000) < ta->validFrom) DEBUG_ANCHOR("Disregarding trust anchor " "%s for %s which is not yet valid", ta->keytag, ta->zone); - else if (ta->validUntil != 0 && now > ta->validUntil) + else if (ta->validUntil != 0 + && (time_t)(*now_ms / 1000) > ta->validUntil) DEBUG_ANCHOR("Disregarding trust anchor " "%s for %s which is not valid anymore", ta->keytag, ta->zone); @@ -646,7 +648,7 @@ static uint16_t _getdns_parse_xml_trust_anchors_buf( static uint8_t *tas_validate(struct mem_funcs *mf, const getdns_bindata *xml_bd, const getdns_bindata *p7s_bd, const getdns_bindata *crt_bd, const char *p7signer, - time_t now, uint8_t *tas, size_t *tas_len) + uint64_t *now_ms, uint8_t *tas, size_t *tas_len) { BIO *xml = NULL, *p7s = NULL, *crt = NULL; X509 *x = NULL; @@ -682,7 +684,7 @@ static uint8_t *tas_validate(struct mem_funcs *mf, gldns_buffer_init_vfixed_frm_data(&gbuf, tas, *tas_len); - if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, now, + if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, now_ms, (char *)xml_bd->data, xml_bd->size)) DEBUG_ANCHOR("Failed to parse trust anchor XML data"); @@ -691,7 +693,7 @@ static uint8_t *tas_validate(struct mem_funcs *mf, if ((success = GETDNS_XMALLOC(*mf, uint8_t, *tas_len))) { gldns_buffer_init_frm_data(&gbuf, success, *tas_len); if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, - now, (char *)xml_bd->data, xml_bd->size)) { + now_ms, (char *)xml_bd->data, xml_bd->size)) { DEBUG_ANCHOR("Failed to re-parse trust" " anchor XML data\n"); @@ -716,7 +718,8 @@ static uint8_t *tas_validate(struct mem_funcs *mf, return success; } -void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) +void _getdns_context_equip_with_anchor( + getdns_context *context, uint64_t *now_ms) { uint8_t xml_spc[4096], *xml_data; uint8_t p7s_spc[4096], *p7s_data = NULL; @@ -784,7 +787,7 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) gldns_buffer_init_vfixed_frm_data( &gbuf, ta_spc, sizeof(ta_spc)); - if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, now, + if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, now_ms, (char *)xml_data, xml_len)) DEBUG_ANCHOR("Failed to parse trust anchor XML data"); else if ((ta_len = gldns_buffer_position(&gbuf)) > sizeof(ta_spc)) { @@ -792,7 +795,7 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now) gldns_buffer_init_frm_data(&gbuf, ta, gldns_buffer_position(&gbuf)); if (!_getdns_parse_xml_trust_anchors_buf( - &gbuf, now, (char *)xml_data, xml_len)) { + &gbuf, now_ms, (char *)xml_data, xml_len)) { DEBUG_ANCHOR("Failed to re-parse trust" " anchor XML data"); GETDNS_FREE(context->mf, ta); @@ -997,6 +1000,7 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) const char *verify_email = NULL; getdns_bindata verify_CA; getdns_return_t r; + uint64_t now_ms = 0; p7s_bd.data = a->tcp.read_buf; p7s_bd.size = a->tcp.read_buf_len; @@ -1017,7 +1021,7 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) , getdns_get_errorstr_by_id(r)); else if (!(tas = tas_validate(&context->mf, &a->xml, &p7s_bd, - &verify_CA, verify_email, time(NULL), tas, &tas_len))) + &verify_CA, verify_email, &now_ms, tas, &tas_len))) ; /* pass */ else { diff --git a/src/anchor.h b/src/anchor.h index 56a6cbfe..fda7433b 100644 --- a/src/anchor.h +++ b/src/anchor.h @@ -38,7 +38,7 @@ #include "getdns/getdns_extra.h" #include -void _getdns_context_equip_with_anchor(getdns_context *context, time_t now); +void _getdns_context_equip_with_anchor(getdns_context *context, uint64_t *now_ms); void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop); diff --git a/src/context.c b/src/context.c index 71bbc4ba..1c303f61 100644 --- a/src/context.c +++ b/src/context.c @@ -1600,9 +1600,6 @@ getdns_context_create_with_extended_memory_functions( #else /* XXX implement Windows-style unlock here */ #endif - if (result->trust_anchors_source == GETDNS_TASRC_NONE) - _getdns_context_equip_with_anchor(result, time(NULL)); - #ifdef HAVE_LIBUNBOUND result->unbound_ctx = NULL; if ((r = rebuild_ub_ctx(result))) diff --git a/src/dnssec.c b/src/dnssec.c index 2a137d7d..d166e91f 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -3031,9 +3031,6 @@ static void check_chain_complete(chain_head *chain) } } else { - if (context->trust_anchors_source == GETDNS_TASRC_NONE) - _getdns_start_fetching_ta(context, dnsreq->loop); - if (context->trust_anchors_source == GETDNS_TASRC_FETCHING) { dnsreq->waiting_for_ta = 1; dnsreq->ta_notify = context->ta_notify; diff --git a/src/general.c b/src/general.c index 13fc4190..21448641 100644 --- a/src/general.c +++ b/src/general.c @@ -587,9 +587,11 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, req->is_sync_request = loop == &context->sync_eventloop.loop; if (req->dnssec_return_status && - context->trust_anchors_source == GETDNS_TASRC_NONE) - _getdns_start_fetching_ta(context, loop); - + 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 (return_netreq_p) *return_netreq_p = req->netreqs[0]; From 6d29f7fb650ec2aabddf5f8d194afbb01f1490a8 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Sep 2017 15:14:00 +0200 Subject: [PATCH 29/41] Fix issues accumulated when tpkg didn't work --- src/Makefile.in | 4 +- src/anchor.c | 2 +- src/const-info.c | 6 +++ src/context.c | 3 +- src/debug.h | 46 +++++++++---------- src/libgetdns.symbols | 6 +++ .../330-event-loops-unit-tests.test | 2 + src/test/tpkg/run-all-lcov.sh | 2 +- src/test/tpkg/run-all.sh | 2 +- src/test/tpkg/run-parallel.sh | 2 +- src/test/tpkg/tpkg | 11 +++-- 11 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/Makefile.in b/src/Makefile.in index ded0c635..fedc0921 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -501,6 +501,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 @@ -557,4 +559,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 diff --git a/src/anchor.c b/src/anchor.c index 68300984..8dc31d0a 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -721,7 +721,7 @@ static uint8_t *tas_validate(struct mem_funcs *mf, void _getdns_context_equip_with_anchor( getdns_context *context, uint64_t *now_ms) { - uint8_t xml_spc[4096], *xml_data; + uint8_t xml_spc[4096], *xml_data = NULL; uint8_t p7s_spc[4096], *p7s_data = NULL; size_t xml_len, p7s_len; const char *verify_email = NULL; diff --git a/src/const-info.c b/src/const-info.c index 776e6795..9caf93cd 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -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 }, diff --git a/src/context.c b/src/context.c index e44ce842..6f57143e 100644 --- a/src/context.c +++ b/src/context.c @@ -4629,7 +4629,8 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context, GETDNS_FREE(context->mf, buf); buf = NULL; } - buf[*file_sz] = 0; + else + buf[*file_sz] = 0; } (void) fclose(f); return buf; diff --git a/src/debug.h b/src/debug.h index 0ddc9400..9d181140 100644 --- a/src/debug.h +++ b/src/debug.h @@ -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) diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 00b26848..6ef6a820 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -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 diff --git a/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test b/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test index 31a7dd1f..d34f8e8a 100644 --- a/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test +++ b/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test @@ -11,4 +11,6 @@ then then exit 1 fi +else + exit 1 fi diff --git a/src/test/tpkg/run-all-lcov.sh b/src/test/tpkg/run-all-lcov.sh index 8a083980..38f4b51a 100755 --- a/src/test/tpkg/run-all-lcov.sh +++ b/src/test/tpkg/run-all-lcov.sh @@ -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 diff --git a/src/test/tpkg/run-all.sh b/src/test/tpkg/run-all.sh index 2c1a23f8..94a5623a 100755 --- a/src/test/tpkg/run-all.sh +++ b/src/test/tpkg/run-all.sh @@ -17,4 +17,4 @@ do # trap keyboard interrupt (control-c) trap control_c 2 done -"${TPKG}" r +"${TPKG}" -n -1 r diff --git a/src/test/tpkg/run-parallel.sh b/src/test/tpkg/run-parallel.sh index a3ef22e0..1bde085a 100755 --- a/src/test/tpkg/run-parallel.sh +++ b/src/test/tpkg/run-parallel.sh @@ -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 diff --git a/src/test/tpkg/tpkg b/src/test/tpkg/tpkg index 0eddaedb..3701b723 100755 --- a/src/test/tpkg/tpkg +++ b/src/test/tpkg/tpkg @@ -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 From 57e6487d76f95e6e08ca45e792e16c8923e631b1 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Sep 2017 16:02:37 +0200 Subject: [PATCH 30/41] Some more fixes specific to travis --- .travis.yml | 1 + src/anchor.c | 6 ++- src/context.h | 2 +- .../330-event-loops-unit-tests.test | 39 +++++++++++++++++-- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index d46dd307..a2f8b3b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ addons: - check - libevent-dev - libev-dev + - libuv-dev - valgrind - clang - wget diff --git a/src/anchor.c b/src/anchor.c index 8dc31d0a..498ab7ca 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -812,7 +812,8 @@ void _getdns_context_equip_with_anchor( context->trust_anchors_len = ta_len; context->trust_anchors_source = GETDNS_TASRC_XML; } - DEBUG_ANCHOR("ta: %p, ta_len: %d\n", context->trust_anchors, (int)context->trust_anchors_len); + DEBUG_ANCHOR("ta: %p, ta_len: %d\n", + (void *)context->trust_anchors, (int)context->trust_anchors_len); } else { DEBUG_ANCHOR("Verifying trust-anchors failed!\n"); @@ -1092,7 +1093,8 @@ static void tas_read_cb(void *userarg) assert(n <= (ssize_t)a->tcp.to_read); DEBUG_ANCHOR("read: %d bytes at %p, for doc %p of size %d\n", - (int)n, a->tcp.read_pos, a->tcp.read_buf, (int)a->tcp.read_buf_len); + (int)n, (void *)a->tcp.read_pos + , (void *)a->tcp.read_buf, (int)a->tcp.read_buf_len); a->tcp.read_pos += n; a->tcp.to_read -= n; if (a->tcp.to_read == 0) diff --git a/src/context.h b/src/context.h index 9d25e382..9bab5199 100644 --- a/src/context.h +++ b/src/context.h @@ -335,7 +335,7 @@ struct getdns_context { tas_connection aaaa; uint8_t tas_hdr_spc[512]; - _getdns_property can_write_appdata : 2; + _getdns_property can_write_appdata; const char *root_anchor_url; const char *root_anchor_verify_CA; diff --git a/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test b/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test index d34f8e8a..10ab6ded 100644 --- a/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test +++ b/src/test/tpkg/330-event-loops-unit-tests.tpkg/330-event-loops-unit-tests.test @@ -5,12 +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 -else exit 1 +else + exit 0 fi + From e6051976dd85f88e819c79612232f011896b3707 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Sep 2017 16:32:53 +0200 Subject: [PATCH 31/41] travis specific fixed --- src/anchor.c | 3 ++- src/test/tpkg/310-dependencies.tpkg/310-dependencies.test | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/anchor.c b/src/anchor.c index 498ab7ca..ab48cb6a 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -850,7 +850,7 @@ static inline const char * rt_str(uint16_t rt) static int tas_busy(tas_connection *a) { - return a->req != NULL; + return a && a->req != NULL; } static int tas_fetching(tas_connection *a) @@ -982,6 +982,7 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) (int)a->tcp.read_buf_len, (char *)a->tcp.read_buf); assert(a->tcp.read_pos == a->tcp.read_buf + a->tcp.read_buf_len); + assert(context); if (a->state == TAS_READ_XML_DOC) { if (a->xml.data) diff --git a/src/test/tpkg/310-dependencies.tpkg/310-dependencies.test b/src/test/tpkg/310-dependencies.tpkg/310-dependencies.test index 985c420d..ef88d699 100644 --- a/src/test/tpkg/310-dependencies.tpkg/310-dependencies.test +++ b/src/test/tpkg/310-dependencies.tpkg/310-dependencies.test @@ -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 From aa74c0a3d5596178e07729f7359842e59913535a Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Sep 2017 16:43:10 +0200 Subject: [PATCH 32/41] One more pleasing travis fix --- src/extension/libuv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/extension/libuv.c b/src/extension/libuv.c index ec9257be..f1b7114e 100644 --- a/src/extension/libuv.c +++ b/src/extension/libuv.c @@ -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); From 463855d274293a7d9bd202dea5d76731a226eb57 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sat, 16 Sep 2017 18:16:21 +0200 Subject: [PATCH 33/41] Writability test for application data --- src/anchor.c | 18 +++-- src/context.c | 213 +++++++++++++++++++++++++++++++++++++++----------- src/context.h | 4 +- 3 files changed, 183 insertions(+), 52 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index ab48cb6a..8a615657 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -1029,9 +1029,9 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) else { context->trust_anchors = tas; context->trust_anchors_len = tas_len; - _getdns_context_write_priv_file( + (void) _getdns_context_write_priv_file( context, "root-anchors.xml", &a->xml); - _getdns_context_write_priv_file( + (void) _getdns_context_write_priv_file( context, "root-anchors.p7s", &p7s_bd); tas_success(context, a); return; @@ -1403,7 +1403,7 @@ static void tas_connect(getdns_context *context, tas_connection *a) GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 2000, getdns_eventloop_event_init(&a->event, a->req->owner, NULL, tas_write_cb, tas_timeout_cb)); - DEBUG_ANCHOR("Scheduled write\n"); + DEBUG_ANCHOR("Scheduled write with event\n"); return; } else DEBUG_ANCHOR("Connect error: %s\n", strerror(errno)); @@ -1420,8 +1420,11 @@ static void tas_happy_eyeballs_cb(void *userarg) assert(dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A); if (tas_fetching(&context->aaaa)) return; - else + else { + DEBUG_ANCHOR("AAAA came too late, clearing Happy Eyeballs timer\n"); + GETDNS_CLEAR_EVENT(context->a.loop, &context->a.event); tas_connect(context, &context->a); + } } static void _tas_hostname_lookup_cb(getdns_dns_req *dnsreq) @@ -1494,7 +1497,12 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) const char *verify_CA; const char *verify_email; - if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) { + if (!_getdns_context_can_write_appdata(context)) { + DEBUG_ANCHOR("NOTICE %s(): Not fetching TA, because " + "non writeable appdata directory\n", __FUNC__); + return; + + } else if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) { DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname" ": \"%s\"", __FUNC__ , getdns_get_errorstr_by_id(r)); diff --git a/src/context.c b/src/context.c index 6f57143e..89a86005 100644 --- a/src/context.c +++ b/src/context.c @@ -41,6 +41,7 @@ #include #include #include +#include #else #include #include @@ -4601,82 +4602,202 @@ 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; +} + uint8_t *_getdns_context_get_priv_file(getdns_context *context, const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz) { char path[PATH_MAX]; - int n; - FILE *f; + FILE *f = NULL; + size_t len; - n = snprintf(path, sizeof(path), "%s/.getdns/%s", getenv("HOME"), fn); - if (n < 0 || n > PATH_MAX) - return NULL; + if (!(len = _getdns_get_appdata(path))) + DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n" + , __FUNC__); - if (!(f = fopen(path, "r"))) - return NULL; + else if (len + strlen(fn) >= sizeof(path)) + DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__); - if ((*file_sz = fread(buf, 1, buf_len, f)) < (buf_len - 1) && feof(f)) + 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)); + + 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) - buf = NULL; + DEBUG_ANCHOR("ERROR %s(): Determining size of \"%s\": %s\n" + , __FUNC__, path, strerror(errno)); - else if ((buf = GETDNS_XMALLOC( - context->mf, uint8_t, (buf_len = ftell(f) + 1)))) { + 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, path); + else { rewind(f); if ((*file_sz = fread(buf, 1, buf_len, f)) >= buf_len || !feof(f)) { GETDNS_FREE(context->mf, buf); - buf = NULL; + DEBUG_ANCHOR("ERROR %s(): Reading \"%s\": %s\n" + , __FUNC__, path, strerror(errno)); } - else + else { buf[*file_sz] = 0; + (void) fclose(f); + return buf; + } } - (void) fclose(f); - return buf; + if (f) + (void) fclose(f); + return NULL; } -void _getdns_context_write_priv_file(getdns_context *context, + +int _getdns_context_write_priv_file(getdns_context *context, const char *fn, getdns_bindata *content) { char path[PATH_MAX], tmpfn[PATH_MAX]; - int n, fd; - FILE *f; + int fd = -1; + 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__); - DEBUG_ANCHOR("%s\n", __FUNC__); + else if (len + 6 >= sizeof(tmpfn) + || len + strlen(fn) >= sizeof(path)) + DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__); - n = snprintf( path, sizeof( path), "%s/.getdns/%s" , getenv("HOME"), fn); - if (n < 0 || n > PATH_MAX) { - DEBUG_ANCHOR("Could not create filename for writing\n"); - return; - } - n = snprintf(tmpfn, sizeof(tmpfn), "%s/.getdns/XXXXXX", getenv("HOME")); - if (n < 0 || n > PATH_MAX) { - DEBUG_ANCHOR("Could not create tmpfn for writing\n"); - return; - } + else if (snprintf(tmpfn, sizeof(tmpfn), "%sXXXXXX", path) < 0) + DEBUG_ANCHOR("ERROR %s(): Creating temporary filename template\n" + , __FUNC__); - if ((fd = mkstemp(tmpfn)) < 0) { - DEBUG_ANCHOR("Could not create temporary file from \"%s\": %s\n", - tmpfn, strerror(errno)); - return; - } + else if (!strcpy(path + len, fn)) + ; /* strcpy returns path + len always */ - if (!(f = fdopen(fd, "w"))) { - close(fd); - return; - } - if (fwrite(content->data, 1, content->size, f) != content->size) - fclose(f); + 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 { - fclose(f); - if (rename(tmpfn, path) == -1) - DEBUG_ANCHOR("Could not mv \"%s\" \"%s\": %s\n", - tmpfn, path, strerror(errno)); + 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 diff --git a/src/context.h b/src/context.h index 9bab5199..8acc8466 100644 --- a/src/context.h +++ b/src/context.h @@ -548,9 +548,11 @@ void _getdns_upstream_shutdown(getdns_upstream *upstream); uint8_t *_getdns_context_get_priv_file(getdns_context *context, const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz); -void _getdns_context_write_priv_file(getdns_context *context, +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_ */ From 737f49d2cc297f0aebcb90ef5a2a4c8c766fd856 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 18 Sep 2017 09:59:22 +0200 Subject: [PATCH 34/41] Setup libunbound ta's after processing XML --- src/anchor.c | 2 ++ src/general.c | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 8a615657..62a7786f 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -803,6 +803,7 @@ void _getdns_context_equip_with_anchor( context->trust_anchors = ta; context->trust_anchors_len = ta_len; context->trust_anchors_source = GETDNS_TASRC_XML; + _getdns_ta_notify_dnsreqs(context); } } else DEBUG_ANCHOR("Could not allocate space for XML file"); @@ -811,6 +812,7 @@ void _getdns_context_equip_with_anchor( context->trust_anchors = context->trust_anchors_spc; context->trust_anchors_len = ta_len; context->trust_anchors_source = GETDNS_TASRC_XML; + _getdns_ta_notify_dnsreqs(context); } DEBUG_ANCHOR("ta: %p, ta_len: %d\n", (void *)context->trust_anchors, (int)context->trust_anchors_len); diff --git a/src/general.c b/src/general.c index 21448641..8ca253b9 100644 --- a/src/general.c +++ b/src/general.c @@ -571,11 +571,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))) @@ -592,6 +587,11 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, if (context->trust_anchors_source == GETDNS_TASRC_NONE) _getdns_start_fetching_ta(context, loop); } + /* 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; + if (return_netreq_p) *return_netreq_p = req->netreqs[0]; From e2ffaf3e07270d1889bee860f83f0a277bb5ab47 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 18 Sep 2017 11:49:43 +0200 Subject: [PATCH 35/41] Less activity to detect XML verify failure --- src/anchor.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 62a7786f..a2903b96 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -738,12 +738,21 @@ void _getdns_context_equip_with_anchor( " CA: \"%s\"\n", __FUNC__ , getdns_get_errorstr_by_id(r)); + else if (!verify_CA || !*verify_CA) + DEBUG_ANCHOR("NOTICE: Trust anchor verification explicitely " + "disabled by empty verify CA\n"); + return; + else if ((r = getdns_context_get_trust_anchor_verify_email( context, ".", &verify_email))) DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify email " "address: \"%s\"\n", __FUNC__ , getdns_get_errorstr_by_id(r)); + else if (!verify_email || !*verify_email) + DEBUG_ANCHOR("NOTICE: Trust anchor verification explicitely " + "disabled by empty verify email\n"); + else if (!(xml_data = _getdns_context_get_priv_file(context, "root-anchors.xml", xml_spc, sizeof(xml_spc), &xml_len))) DEBUG_ANCHOR("DEBUG %s(): root-anchors.xml not present\n" @@ -1499,12 +1508,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) const char *verify_CA; const char *verify_email; - if (!_getdns_context_can_write_appdata(context)) { - DEBUG_ANCHOR("NOTICE %s(): Not fetching TA, because " - "non writeable appdata directory\n", __FUNC__); - return; - - } else if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) { + if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) { DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname" ": \"%s\"", __FUNC__ , getdns_get_errorstr_by_id(r)); @@ -1517,10 +1521,11 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) , getdns_get_errorstr_by_id(r)); return; - } else if (!*verify_CA) { + } else if (!verify_CA || !*verify_CA) { DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely " "disabled by empty verify CA\n"); return; + } else if ((r = getdns_context_get_trust_anchor_verify_email( context, ".", &verify_email))) { DEBUG_ANCHOR("ERROR %s(): Could not get verify email address" @@ -1528,11 +1533,16 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) , getdns_get_errorstr_by_id(r)); return; - } else if (!*verify_email) { + } else if (!verify_email || !*verify_email) { DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely " "disabled by empty verify email address\n"); return; - } + + } else if (!_getdns_context_can_write_appdata(context)) { + DEBUG_ANCHOR("NOTICE %s(): Not fetching TA, because " + "non writeable appdata directory\n", __FUNC__); + return; + } DEBUG_ANCHOR("Hostname: %s\n", tas_hostname); DEBUG_ANCHOR("%s on the %ssynchronous loop\n", __FUNC__, loop == &context->sync_eventloop.loop ? "" : "a"); From 34d35f9e7935a2edaa16674e2db04fa801a23675 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 20 Sep 2017 10:30:13 +0200 Subject: [PATCH 36/41] Track updating TA's with root DNSKEY rrset --- src/anchor.c | 305 ++++++++++++++++++++++++++++++++++++++++++++- src/anchor.h | 13 ++ src/context.c | 23 +++- src/context.h | 5 + src/dnssec.c | 15 +++ src/general.c | 12 +- src/gldns/keyraw.c | 2 +- src/gldns/keyraw.h | 2 +- 8 files changed, 364 insertions(+), 13 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index a2903b96..86338d4f 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -45,9 +45,10 @@ #include "gldns/parseutil.h" #include "gldns/gbuffer.h" #include "gldns/str2wire.h" +#include "gldns/wire2str.h" #include "gldns/pkthdr.h" +#include "gldns/keyraw.h" #include "general.h" -#include "rr-iter.h" #include "util-internal.h" /* get key usage out of its extension, returns 0 if no key_usage extension */ @@ -741,7 +742,6 @@ void _getdns_context_equip_with_anchor( else if (!verify_CA || !*verify_CA) DEBUG_ANCHOR("NOTICE: Trust anchor verification explicitely " "disabled by empty verify CA\n"); - return; else if ((r = getdns_context_get_trust_anchor_verify_email( context, ".", &verify_email))) @@ -1612,4 +1612,305 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop) context->trust_anchors_source = GETDNS_TASRC_FETCHING; } + +static int _uint16_cmp(const void *a, const void *b) +{ return (int)*(uint16_t *)a - (int)*(uint16_t *)b; } + +static int _uint8x16_cmp(const void *a, const void *b) +{ return memcmp(a, b, RRSIG_RDATA_LEN); } + +static void +_getdns_init_ksks(_getdns_ksks *ksks, _getdns_rrset *dnskey_set) +{ + _getdns_rrtype_iter *rr, rr_space; + _getdns_rrsig_iter *rrsig, rrsig_space; + + assert(ksks); + assert(dnskey_set); + assert(dnskey_set->rr_type == GETDNS_RRTYPE_DNSKEY); + + ksks->n = 0; + for ( rr = _getdns_rrtype_iter_init(&rr_space, dnskey_set) + ; rr && ksks->n < MAX_KSKS + ; rr = _getdns_rrtype_iter_next(rr)) { + + if (rr->rr_i.nxt - rr->rr_i.rr_type < 12 + || !(rr->rr_i.rr_type[11] & 1)) + continue; /* Not a KSK */ + + ksks->ids[ksks->n++] = gldns_calc_keytag_raw( + rr->rr_i.rr_type + 10, + rr->rr_i.nxt - rr->rr_i.rr_type - 10); + } + qsort(ksks->ids, ksks->n, sizeof(uint16_t), _uint16_cmp); + + ksks->n_rrsigs = 0; + for ( rrsig = _getdns_rrsig_iter_init(&rrsig_space, dnskey_set) + ; rrsig && ksks->n_rrsigs < MAX_KSKS + ; rrsig = _getdns_rrsig_iter_next(rrsig)) { + + if (rrsig->rr_i.nxt - rrsig->rr_i.rr_type < 28) + continue; + + (void) memcpy(ksks->rrsigs[ksks->n_rrsigs++], + rrsig->rr_i.rr_type + 12, RRSIG_RDATA_LEN); + } + qsort(ksks->rrsigs, ksks->n_rrsigs, RRSIG_RDATA_LEN, _uint8x16_cmp); +} + + +static int +_getdns_ksks_equal(_getdns_ksks *a, _getdns_ksks *b) +{ + return a == b + || ( a != NULL && b != NULL + && a->n == b->n + && memcmp(a->ids, b->ids, a->n * sizeof(uint16_t)) == 0 + && a->n_rrsigs == b->n_rrsigs + && memcmp(a->rrsigs, b->rrsigs, a->n_rrsigs * RRSIG_RDATA_LEN) == 0); +} + +static void _getdns_context_read_root_ksk(getdns_context *context) +{ + FILE *fp; + struct gldns_file_parse_state pst; + size_t len, dname_len; + uint8_t buf_spc[4096], *buf = buf_spc, *ptr = buf_spc; + size_t buf_sz = sizeof(buf_spc); + _getdns_rrset root_dnskey; + uint8_t *root_dname = (uint8_t *)"\00"; + + + if (!(fp = _getdns_context_get_priv_fp(context, "root.key"))) + return; + + for (;;) { + size_t n_rrs = 0; + + *pst.origin = 0; + pst.origin_len = 1; + *pst.prev_rr = 0; + pst.prev_rr_len = 1; + pst.default_ttl = 0; + pst.lineno = 1; + + (void) memset(buf, 0, 12); + ptr += 12; + + while (!feof(fp)) { + len = buf + buf_sz - ptr; + dname_len = 0; + if (gldns_fp2wire_rr_buf(fp, ptr, &len, &dname_len, &pst)) + break; + if ((ptr += len) > buf + buf_sz) + break; + if (len) + n_rrs += 1; + if (dname_len && dname_len < sizeof(pst.prev_rr)) { + memcpy(pst.prev_rr, ptr, dname_len); + pst.prev_rr_len = dname_len; + } + } + if (ptr <= buf + buf_sz) { + gldns_write_uint16(buf + GLDNS_ANCOUNT_OFF, n_rrs); + break; + } + rewind(fp); + if (buf == buf_spc) + buf_sz = 65536; + else { + GETDNS_FREE(context->mf, buf); + buf_sz *= 2; + } + if (!(buf = GETDNS_XMALLOC(context->mf, uint8_t, buf_sz))) { + DEBUG_ANCHOR("ERROR %s(): Memory error\n", __FUNC__); + break;; + } + ptr = buf; + }; + fclose(fp); + if (!buf) + return; + + root_dnskey.name = root_dname; + root_dnskey.rr_class = GETDNS_RRCLASS_IN; + root_dnskey.rr_type = GETDNS_RRTYPE_DNSKEY; + root_dnskey.pkt = buf; + root_dnskey.pkt_len = ptr - buf; + root_dnskey.sections = SECTION_ANSWER; + + _getdns_init_ksks(&context->root_ksk, &root_dnskey); + + if (buf && buf != buf_spc) + GETDNS_FREE(context->mf, buf); +} + +void +_getdns_context_update_root_ksk( + getdns_context *context, _getdns_rrset *dnskey_set) +{ + _getdns_ksks root_ksk_seen; + _getdns_rrtype_iter *rr, rr_space; + _getdns_rrsig_iter *rrsig, rrsig_space; + char str_spc[4096], *str_buf, *str_pos; + int sz_needed; + int remaining; + size_t str_sz = 0; + getdns_bindata root_key_bd; + + _getdns_init_ksks(&root_ksk_seen, dnskey_set); + if (_getdns_ksks_equal(&context->root_ksk, &root_ksk_seen)) + return; /* root DNSKEY rrset already known */ + + /* Try to read root DNSKEY rrset from root.key */ + _getdns_context_read_root_ksk(context); + if (_getdns_ksks_equal(&context->root_ksk, &root_ksk_seen)) + return; /* root DNSKEY rrset same as the safed one */ + + /* Different root DNSKEY rrset. Perhaps because of failure to read + * from disk. If we cannot write to our appdata directory, bail out + */ + if (context->can_write_appdata == PROP_UNABLE) + return; + + /* We might be able to write or we do not know whether we can write + * to the appdata directory. In the latter we'll try to write to + * find out. The section below converts the wireformat DNSKEY rrset + * to presentationformat. + */ + str_pos = str_buf = str_spc; + remaining = sizeof(str_spc); + for (;;) { + for ( rr = _getdns_rrtype_iter_init(&rr_space, dnskey_set) + ; rr ; rr = _getdns_rrtype_iter_next(rr)) { + + sz_needed = gldns_wire2str_rr_buf((uint8_t *)rr->rr_i.pos, + rr->rr_i.nxt - rr->rr_i.pos, str_pos, + (size_t)(remaining > 0 ? remaining : 0)); + + str_pos += sz_needed; + remaining -= sz_needed; + } + for ( rrsig = _getdns_rrsig_iter_init(&rrsig_space, dnskey_set) + ; rrsig + ; rrsig = _getdns_rrsig_iter_next(rrsig)) { + sz_needed = gldns_wire2str_rr_buf((uint8_t *)rrsig->rr_i.pos, + rrsig->rr_i.nxt - rrsig->rr_i.pos, str_pos, + (size_t)(remaining > 0 ? remaining : 0)); + + str_pos += sz_needed; + remaining -= sz_needed; + } + if (remaining > 0) { + *str_pos = 0; + if (str_buf == str_spc) + str_sz = sizeof(str_spc) - remaining; + break; + } + if (str_buf != str_spc) { + DEBUG_ANCHOR("ERROR %s(): Buffer size determination " + "error\n", __FUNC__); + if (str_buf) + GETDNS_FREE(context->mf, str_buf); + + return; + } + if (!(str_pos = str_buf = GETDNS_XMALLOC( context->mf, char, + (str_sz = sizeof(str_spc) - remaining) + 1))) { + DEBUG_ANCHOR("ERROR %s(): Memory error\n", __FUNC__); + return; + } + remaining = str_sz + 1; + DEBUG_ANCHOR("Retrying with buf size: %d\n", remaining); + }; + + /* Write presentation format DNSKEY rrset to "root.key" file */ + root_key_bd.size = str_sz; + root_key_bd.data = (void *)str_buf; + if (_getdns_context_write_priv_file( + context, "root.key", &root_key_bd)) { + size_t i; + + /* A new "root.key" file was written. When they contain + * key_id's which are not in "root-anchors.xml", then update + * "root-anchors.xml". + */ + + for (i = 0; i < context->root_ksk.n; i++) { + _getdns_rrset_iter tas_iter_spc, *ta; + + for ( ta = _getdns_rrset_iter_init(&tas_iter_spc + , context->trust_anchors + , context->trust_anchors_len + , SECTION_ANSWER) + ; ta ; ta = _getdns_rrset_iter_next(ta)) { + _getdns_rrtype_iter *rr, rr_space; + _getdns_rrset *rrset; + + if (!(rrset = _getdns_rrset_iter_value(ta))) + continue; + + if (*rrset->name != '\0') + continue; /* Not a root anchor */ + + if (rrset->rr_type == GETDNS_RRTYPE_DS) { + for ( rr = _getdns_rrtype_iter_init( + &rr_space, rrset) + ; rr + ; rr = _getdns_rrtype_iter_next(rr) + ) { + if (rr->rr_i.nxt - + rr->rr_i.rr_type < 12) + continue; + + DEBUG_ANCHOR("DS with id: %d\n" + , (int)gldns_read_uint16(rr->rr_i.rr_type + 10)); + if (gldns_read_uint16( + rr->rr_i.rr_type + 10) == + context->root_ksk.ids[i]) + break; + } + if (rr) + break; + continue; + } + if (rrset->rr_type != GETDNS_RRTYPE_DNSKEY) + continue; + + for ( rr = _getdns_rrtype_iter_init(&rr_space + , rrset) + ; rr ; rr = _getdns_rrtype_iter_next(rr)) { + + + if (rr->rr_i.nxt-rr->rr_i.rr_type < 12 + || !(rr->rr_i.rr_type[11] & 1)) + continue; /* Not a KSK */ + + if (gldns_calc_keytag_raw( + rr->rr_i.rr_type + 10, + rr->rr_i.nxt-rr->rr_i.rr_type - 10) + == context->root_ksk.ids[i]) + break; + } + if (rr) + break; + } + if (!ta) { + DEBUG_ANCHOR("NOTICE %s(): Key with id %d " + "*not* found in TA.\n" + "\"root-anchors.xml\" need " + "updating.\n", __FUNC__ + , context->root_ksk.ids[i]); + context->trust_anchors_source = + GETDNS_TASRC_XML_UPDATE; + break; + } + DEBUG_ANCHOR("DEBUG %s(): Key with id %d found in TA\n" + , __FUNC__, context->root_ksk.ids[i]); + } + } + if (str_buf && str_buf != str_spc) + GETDNS_FREE(context->mf, str_buf); +} + /* anchor.c */ diff --git a/src/anchor.h b/src/anchor.h index fda7433b..3c826384 100644 --- a/src/anchor.h +++ b/src/anchor.h @@ -37,10 +37,23 @@ #include "getdns/getdns.h" #include "getdns/getdns_extra.h" #include +#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 */ diff --git a/src/context.c b/src/context.c index 89a86005..ae89a098 100644 --- a/src/context.c +++ b/src/context.c @@ -1500,6 +1500,8 @@ getdns_context_create_with_extended_memory_functions( = _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; @@ -4654,13 +4656,13 @@ static size_t _getdns_get_appdata(char *path) return 0; } -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 *_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__); @@ -4675,6 +4677,17 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context, 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); @@ -4682,19 +4695,19 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context, } else if (fseek(f, 0, SEEK_END) < 0) DEBUG_ANCHOR("ERROR %s(): Determining size of \"%s\": %s\n" - , __FUNC__, path, strerror(errno)); + , __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, path); + , __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__, path, strerror(errno)); + , __FUNC__, fn, strerror(errno)); } else { buf[*file_sz] = 0; diff --git a/src/context.h b/src/context.h index 8acc8466..8225d10b 100644 --- a/src/context.h +++ b/src/context.h @@ -49,6 +49,7 @@ #include "util/lruhash.h" #endif #include "rr-iter.h" +#include "anchor.h" struct getdns_dns_req; struct ub_ctx; @@ -99,6 +100,7 @@ typedef enum getdns_tasrc { GETDNS_TASRC_APP, GETDNS_TASRC_FETCHING, GETDNS_TASRC_XML, + GETDNS_TASRC_XML_UPDATE, GETDNS_TASRC_FAILED } getdns_tasrc; @@ -341,6 +343,8 @@ struct getdns_context { 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; @@ -545,6 +549,7 @@ 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); diff --git a/src/dnssec.c b/src/dnssec.c index d166e91f..4ea9fd97 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -2998,6 +2998,11 @@ 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; +} static void check_chain_complete(chain_head *chain) { @@ -3063,6 +3068,16 @@ static void check_chain_complete(chain_head *chain) , context->trust_anchors_len , SECTION_ANSWER)); #endif + if (context->trust_anchors_source != GETDNS_TASRC_XML) + ; /* pass */ + + /* Find root key or query for it in full recursion... */ + else if (!(head = chain) || !(node = _to_the_root(head->parent))) + ; /* pass */ + + else if (node->dnskey.name && *node->dnskey.name == 0) + _getdns_context_update_root_ksk(context, &node->dnskey); + #ifdef DNSSEC_ROADBLOCK_AVOIDANCE if ( dnsreq->dnssec_roadblock_avoidance && !dnsreq->avoid_dnssec_roadblocks diff --git a/src/general.c b/src/general.c index 8ca253b9..60644115 100644 --- a/src/general.c +++ b/src/general.c @@ -581,11 +581,15 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, req->internal_cb = internal_cb; req->is_sync_request = loop == &context->sync_eventloop.loop; - if (req->dnssec_return_status && - context->trust_anchors_source == GETDNS_TASRC_NONE) { - _getdns_context_equip_with_anchor(context, &now_ms); - if (context->trust_anchors_source == GETDNS_TASRC_NONE) + if (req->dnssec_return_status) { + 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); + } } /* Set up the context assuming we won't use the specified namespaces. This is (currently) identical to setting up a pure DNS namespace */ diff --git a/src/gldns/keyraw.c b/src/gldns/keyraw.c index 3f6f1a20..365d6a0e 100644 --- a/src/gldns/keyraw.c +++ b/src/gldns/keyraw.c @@ -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; diff --git a/src/gldns/keyraw.h b/src/gldns/keyraw.h index 60e2bfde..3d19e96f 100644 --- a/src/gldns/keyraw.h +++ b/src/gldns/keyraw.h @@ -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 /** From e2abb8aff4077253fda1ca430094aaa610a5c341 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 20 Sep 2017 11:44:21 +0200 Subject: [PATCH 37/41] Fetch TA when ZONE or APP TASRC and bogus answer --- src/dnssec.c | 85 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index 4ea9fd97..72800c9d 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -2545,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) */ @@ -2751,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_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 @@ -3030,7 +3062,6 @@ static void check_chain_complete(chain_head *chain) if (*d == dnsreq) { *d = dnsreq->ta_notify; dnsreq->ta_notify = NULL; - dnsreq->waiting_for_ta = 0; break; } } @@ -3068,15 +3099,46 @@ static void check_chain_complete(chain_head *chain) , context->trust_anchors_len , SECTION_ANSWER)); #endif - if (context->trust_anchors_source != GETDNS_TASRC_XML) - ; /* pass */ - - /* Find root key or query for it in full recursion... */ - else if (!(head = chain) || !(node = _to_the_root(head->parent))) - ; /* pass */ + 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 (node->dnskey.name && *node->dnskey.name == 0) - _getdns_context_update_root_ksk(context, &node->dnskey); + } else if (dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) { + 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 @@ -3131,6 +3193,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; From f0f2afbca7bfce88266de7156e746f853d37b051 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 20 Sep 2017 12:40:59 +0200 Subject: [PATCH 38/41] Fetch TA before resolve for full recursion too --- src/dnssec.c | 24 ++++++++++++++++++---- src/general.c | 45 ++++++++++++++++++++++++++---------------- src/request-internal.c | 1 + src/types-internal.h | 1 + 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index 72800c9d..4079ae4f 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -3263,6 +3263,7 @@ static void check_chain_complete(chain_head *chain) void _getdns_ta_notify_dnsreqs(getdns_context *context) { getdns_dns_req **dnsreq_p, *dnsreq = NULL; + uint64_t now_ms = 0; assert(context); @@ -3272,14 +3273,29 @@ void _getdns_ta_notify_dnsreqs(getdns_context *context) dnsreq_p = &context->ta_notify; while ((dnsreq = *dnsreq_p)) { + assert(dnsreq->waiting_for_ta); - assert(dnsreq->waiting_for_ta && dnsreq->chain); + if (dnsreq->chain) + check_chain_complete(dnsreq->chain); + else { + getdns_network_req *netreq, **netreq_p; + int r = GETDNS_RETURN_GOOD; - check_chain_complete(dnsreq->chain); + (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); - /* if (*dnsreq_p == dnsreq) - dnsreq_p = &dnsreq->ta_notify; */ } } diff --git a/src/general.c b/src/general.c index 60644115..72e7840a 100644 --- a/src/general.c +++ b/src/general.c @@ -581,27 +581,37 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, req->internal_cb = internal_cb; req->is_sync_request = loop == &context->sync_eventloop.loop; - if (req->dnssec_return_status) { - 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); - } - } - /* 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; - if (return_netreq_p) *return_netreq_p = req->netreqs[0]; _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 (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; + } + } + } + } + if (!usenamespaces) { + (void) _getdns_context_prepare_for_resolution(context, 0); + /* issue all network requests */ for ( netreq_p = req->netreqs ; !r && (netreq = *netreq_p) @@ -616,7 +626,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( @@ -650,6 +660,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, } #endif /* HAVE_MDNS_SUPPORT */ } else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) { + (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 diff --git a/src/request-internal.c b/src/request-internal.c index 32f6611a..c5a5b0a9 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -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; diff --git a/src/types-internal.h b/src/types-internal.h index a827456a..56b7a2f0 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -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; From 17d7ee79f23c26d23f77ce31e11485deaf247a31 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 20 Sep 2017 12:44:14 +0200 Subject: [PATCH 39/41] Fix NULL pointer dereference --- src/dnssec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnssec.c b/src/dnssec.c index 4079ae4f..da0f92b1 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -2770,7 +2770,7 @@ static void chain_clear_netreq_dnssec_status(chain_head *chain) head->netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE; for ( node_count = head->node_count, node = head->parent - ; node_count ; node_count--, node = node->parent ) { + ; node && node_count ; node_count--, node = node->parent ) { node->ds_signer = -1; node->dnskey_signer = -1; From 36943a438090a5229de06599a1950d495507a38e Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 20 Sep 2017 14:42:35 +0200 Subject: [PATCH 40/41] A dnsreq is bogus if any of its netreqs is --- src/dnssec.c | 37 ++++++++++++++++++++++--------------- src/dnssec.h | 2 ++ src/general.c | 33 ++++++++++++++++++++------------- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index da0f92b1..3a2fc866 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -3036,6 +3036,17 @@ static inline chain_node *_to_the_root(chain_node *node) 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) { getdns_dns_req *dnsreq; @@ -3075,22 +3086,13 @@ static void check_chain_complete(chain_head *chain) } } #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, @@ -3104,13 +3106,14 @@ static void check_chain_complete(chain_head *chain) node->dnskey.name && *node->dnskey.name == 0) _getdns_context_update_root_ksk(context,&node->dnskey); - } else if (dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) { + } 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"); + DEBUG_ANCHOR("root DNSKEY set was bogus!\n"); if (!dnsreq->waiting_for_ta) { uint64_t now = 0; @@ -3143,7 +3146,7 @@ static void check_chain_complete(chain_head *chain) #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; @@ -3381,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 @@ -3391,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 diff --git a/src/dnssec.h b/src/dnssec.h index 3ffa96ee..ef1b4747 100644 --- a/src/dnssec.h +++ b/src/dnssec.h @@ -67,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 */ diff --git a/src/general.c b/src/general.c index 72e7840a..d8a2bdf8 100644 --- a/src/general.c +++ b/src/general.c @@ -214,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 */ @@ -236,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( @@ -594,22 +597,18 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, _getdns_context_equip_with_anchor(context, &now_ms); if (context->trust_anchors_source == GETDNS_TASRC_NONE) { _getdns_start_fetching_ta(context, loop); - 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; - } } } } 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 */ @@ -660,6 +659,14 @@ 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 From e6536bb2ef52a43f24b6e28d78e593b67264e3c5 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 20 Sep 2017 15:18:43 +0200 Subject: [PATCH 41/41] Typo --- src/context.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/context.c b/src/context.c index ae89a098..d306ca9e 100644 --- a/src/context.c +++ b/src/context.c @@ -4835,10 +4835,11 @@ getdns_context_set_trust_anchor_url( return GETDNS_RETURN_NOT_IMPLEMENTED; path_len = strlen(path); - if (! ( path_len >= 4 + 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'))) + && (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;