From: Willem Toorop Date: Tue, 6 Mar 2012 13:32:39 +0000 (+0000) Subject: Most of the dnssexy features for ldns-verify-zone. X-Git-Tag: release-1.6.13rc1~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ade756ce0d8758601d8c0d61a3c9136b9d1ce5a7;p=thirdparty%2Fldns.git Most of the dnssexy features for ldns-verify-zone. --- diff --git a/Changelog b/Changelog index d57be50b..5a2f0642 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,10 @@ 1.6.13 + * New -S option for ldns-verify-zone to chase signatures online. + * New -k option for ldns-verify-zone to validate using a trusted key. + * New inception and expiration margin options (-i and -e) to + ldns-verify-zone. + * fix ldns-verify-zone to allow NSEC3 signatures to come before + the NSEC3 RR in all cases. Thanks Wolfgang Nagele. * Zero the correct flag (opt-out) when creating NSEC3PARAMS. Thanks Peter van Dijk. * Canonicalize RRSIG's Signer's name too when validating, because @@ -6,9 +12,9 @@ * bugfix #433: Allocate rdf using ldns_rdf_new in ldns_dname_label * bugfix #432: Use LDNS_MALLOC & LDNS_FREE i.s.o. malloc & free * bugfix #431: Added error message for LDNS_STATUS_INVALID_B32_EXT - * bugfix #427: Eplicitely link ssl with the programs that use it. + * bugfix #427: Explicitely link ssl with the programs that use it. * Fix reading \DDD: Error on values that are outside range (>255). - * bugfix #429: fix doxyparse.plfails on NetBSD because specified + * bugfix #429: fix doxyparse.pl fails on NetBSD because specified path to perl. 1.6.12 diff --git a/Makefile.in b/Makefile.in index 9d5689b0..c779e095 100644 --- a/Makefile.in +++ b/Makefile.in @@ -65,24 +65,26 @@ LDNS_LOBJS_EX = ^linktest\.c$$ LDNS_ALL_LOBJS = $(LDNS_LOBJS) $(LIBLOBJS) LIB = libldns.la -LDNS_HEADERS = buffer.h dname.h dnssec.h dnssec_sign.h dnssec_verify.h dnssec_zone.h error.h higher.h host2str.h host2wire.h keys.h ldns.h packet.h parse.h rbtree.h rdata.h resolver.h rr.h rr_functions.h sha1.h sha2.h str2host.h tsig.h update.h wire2host.h zone.h +LDNS_HEADERS = buffer.h dname.h dnssec.h dnssec_sign.h dnssec_verify.h dnssec_zone.h error.h higher.h host2str.h host2wire.h keys.h ldns.h packet.h parse.h rbtree.h rdata.h resolver.h rr_functions.h rr.h sha1.h sha2.h str2host.h tsig.h update.h wire2host.h zone.h LDNS_HEADERS_EX = ^config\.h|common\.h|util\.h|net\.h$$ LDNS_HEADERS_GEN= common.h util.h net.h -PYLDNS_I_FILES = $(pywrapdir)/file_py3.i $(pywrapdir)/ldns.i $(pywrapdir)/ldns_buffer.i $(pywrapdir)/ldns_dname.i $(pywrapdir)/ldns_dnssec.i $(pywrapdir)/ldns_key.i $(pywrapdir)/ldns_packet.i $(pywrapdir)/ldns_rdf.i $(pywrapdir)/ldns_resolver.i $(pywrapdir)/ldns_rr.i $(pywrapdir)/ldns_zone.i +PYLDNS_I_FILES = $(pywrapdir)/file_py3.i $(pywrapdir)/ldns_buffer.i $(pywrapdir)/ldns_dname.i $(pywrapdir)/ldns_dnssec.i $(pywrapdir)/ldns.i $(pywrapdir)/ldns_key.i $(pywrapdir)/ldns_packet.i $(pywrapdir)/ldns_rdf.i $(pywrapdir)/ldns_resolver.i $(pywrapdir)/ldns_rr.i $(pywrapdir)/ldns_zone.i DRILL_LOBJS = drill/chasetrace.lo drill/dnssec.lo drill/drill.lo drill/drill_util.lo drill/error.lo drill/root.lo drill/securetrace.lo drill/work.lo -EXAMPLE_LOBJS = examples/ldns-chaos.lo examples/ldns-compare-zones.lo examples/ldns-dpa.lo examples/ldns-gen-zone.lo examples/ldns-key2ds.lo examples/ldns-keyfetcher.lo examples/ldns-keygen.lo examples/ldns-mx.lo examples/ldns-notify.lo examples/ldns-nsec3-hash.lo examples/ldns-read-zone.lo examples/ldns-resolver.lo examples/ldns-revoke.lo examples/ldns-rrsig.lo examples/ldns-signzone.lo examples/ldns-test-edns.lo examples/ldns-testns.lo examples/ldns-testpkts.lo examples/ldns-update.lo examples/ldns-verify-zone.lo examples/ldns-version.lo examples/ldns-walk.lo examples/ldns-zcat.lo examples/ldns-zsplit.lo examples/ldnsd.lo -EXAMPLE_PROGS = examples/ldns-chaos examples/ldns-compare-zones examples/ldns-gen-zone examples/ldns-key2ds examples/ldns-keyfetcher examples/ldns-keygen examples/ldns-mx examples/ldns-notify examples/ldns-nsec3-hash examples/ldns-read-zone examples/ldns-resolver examples/ldns-revoke examples/ldns-rrsig examples/ldns-test-edns examples/ldns-update examples/ldns-version examples/ldns-walk examples/ldns-zcat examples/ldns-zsplit examples/ldnsd -EX_PROGS_BASENM = ldns-chaos ldns-compare-zones ldns-dpa ldns-gen-zone ldns-key2ds ldns-keyfetcher ldns-keygen ldns-mx ldns-notify ldns-nsec3-hash ldns-read-zone ldns-resolver ldns-revoke ldns-rrsig ldns-signzone ldns-test-edns ldns-testns ldns-update ldns-verify-zone ldns-version ldns-walk ldns-zcat ldns-zsplit ldnsd -EXAMPLE_PROGS_EX= ^examples/ldns-testpkts\.c|examples/ldns-testns\.c|examples/ldns-dpa\.c|examples/ldns-signzone\.c|examples/ldns-verify-zone\.c$$ +EXAMPLE_LOBJS = examples/ldns-chaos.lo examples/ldns-compare-zones.lo examples/ldnsd.lo examples/ldns-dpa.lo examples/ldns-duration.lo examples/ldns-gen-zone.lo examples/ldns-key2ds.lo examples/ldns-keyfetcher.lo examples/ldns-keygen.lo examples/ldns-mx.lo examples/ldns-notify.lo examples/ldns-nsec3-hash.lo examples/ldns-read-zone.lo examples/ldns-resolver.lo examples/ldns-revoke.lo examples/ldns-rrsig.lo examples/ldns-signzone.lo examples/ldns-test-edns.lo examples/ldns-testns.lo examples/ldns-testpkts.lo examples/ldns-update.lo examples/ldns-verify-zone.lo examples/ldns-version.lo examples/ldns-walk.lo examples/ldns-zcat.lo examples/ldns-zsplit.lo +EXAMPLE_PROGS = examples/ldns-chaos examples/ldns-compare-zones examples/ldnsd examples/ldns-gen-zone examples/ldns-key2ds examples/ldns-keyfetcher examples/ldns-keygen examples/ldns-mx examples/ldns-notify examples/ldns-nsec3-hash examples/ldns-read-zone examples/ldns-resolver examples/ldns-revoke examples/ldns-rrsig examples/ldns-test-edns examples/ldns-update examples/ldns-version examples/ldns-walk examples/ldns-zcat examples/ldns-zsplit +EX_PROGS_BASENM = ldns-chaos ldns-compare-zones ldnsd ldns-dpa ldns-duration ldns-gen-zone ldns-key2ds ldns-keyfetcher ldns-keygen ldns-mx ldns-notify ldns-nsec3-hash ldns-read-zone ldns-resolver ldns-revoke ldns-rrsig ldns-signzone ldns-test-edns ldns-testns ldns-testpkts ldns-update ldns-verify-zone ldns-version ldns-walk ldns-zcat ldns-zsplit +EXAMPLE_PROGS_EX= ^examples/ldns-duration\.c|examples/ldns-testpkts\.c|examples/ldns-testns\.c|examples/ldns-dpa\.c|examples/ldns-signzone\.c|examples/ldns-verify-zone\.c$$ TESTNS = examples/ldns-testns TESTNS_LOBJS = examples/ldns-testns.lo examples/ldns-testpkts.lo LDNS_DPA = examples/ldns-dpa LDNS_DPA_LOBJS = examples/ldns-dpa.lo -EX_SSL_PROGS = examples/ldns-signzone examples/ldns-verify-zone -EX_SSL_LOBJS = examples/ldns-signzone.lo examples/ldns-verify-zone.lo +LDNS_VFY = examples/ldns-verify-zone +LDNS_VFY_LOBJS = examples/ldns-verify-zone.lo examples/ldns-duration.lo +EX_SSL_PROGS = examples/ldns-signzone +EX_SSL_LOBJS = examples/ldns-signzone.lo COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) @@ -108,13 +110,13 @@ $(LDNS_LOBJS) $(LIBLOBJS) $(DRILL_LOBJS) $(EXAMPLE_LOBJS): $(COMP_LIB) $(LIBSSL_CPPFLAGS) -c $(srcdir)/$(@:.lo=.c) -o $@ setup-builddir: - if test ! -d compat ; then mkdir compat ; fi - if test ! -d drill ; then mkdir drill ; fi - if test ! -d examples ; then mkdir examples ; fi - if test ! -h config.h ; then ln -s ldns/config.h . ; fi - if test ! -h lib ; then ln -s .libs lib ; fi ; - if test ! -d include ; then $(INSTALL) -d include; fi - if test ! -h include/ldns ; then ln -s ../ldns include/ldns || echo "include/ldns exists"; fi + @if test ! -d compat ; then mkdir compat ; fi + @if test ! -d drill ; then mkdir drill ; fi + @if test ! -d examples ; then mkdir examples ; fi + @if test ! -h config.h ; then ln -s ldns/config.h . ; fi + @if test ! -h lib ; then ln -s .libs lib ; fi ; + @if test ! -d include ; then $(INSTALL) -d include; fi + @if test ! -h include/ldns ; then ln -s ../ldns include/ldns || echo "include/ldns exists"; fi putdown-builddir: rm -f include/ldns lib config.h @@ -125,12 +127,12 @@ putdown-builddir: drill: no-drill-config-h drill/drill no-drill-config-h: - if test -e $(srcdir)/drill/config.h -o -e drill/config.h ; then \ - echo "A config.h was detected in the drill subdirectory." ; \ - echo "This does not work when building drill from here." ; \ - echo "Either remove the config.h from the subdirectory" ; \ - echo "or build drill there." ; \ - exit -1 ; \ + @if test -e $(srcdir)/drill/config.h -o -e drill/config.h ; \ + then echo "A config.h was detected in the drill subdirectory." ; \ + echo "This does not work when building drill from here." ; \ + echo "Either remove the config.h from the subdirectory" ; \ + echo "or build drill there." ; \ + exit -1 ; \ fi drill/drill: $(DRILL_LOBJS) $(LIB) $(LINK_EXE) $(DRILL_LOBJS) $(LIBS) $(LIBSSL_LIBS) -lldns -o drill/drill @@ -150,14 +152,14 @@ uninstall-drill: clean-drill: $(LIBTOOL) --mode clean rm -f $(DRILL_LOBJS) drill/drill -examples: no-examples-config-h $(EXAMPLE_PROGS) $(TESTNS) $(LDNS_DPA) $(EX_SSL_PROGS) +examples: no-examples-config-h $(EXAMPLE_PROGS) $(TESTNS) $(LDNS_DPA) $(LDNS_VFY) $(EX_SSL_PROGS) no-examples-config-h: - if test -e $(srcdir)/examples/config.h -o -e examples/config.h ; then \ - echo "A config.h was detected in the examples subdirectory." ; \ - echo "This does not work when building examples from here." ; \ - echo "Either remove the config.h from the subdirectory" ; \ - echo "or build examples there." ; \ - exit -1 ; \ + @if test -e $(srcdir)/examples/config.h -o -e examples/config.h ; \ + then echo "A config.h was detected in the examples subdirectory." ; \ + echo "This does not work when building examples from here." ; \ + echo "Either remove the config.h from the subdirectory" ; \ + echo "or build examples there." ; \ + exit -1 ; \ fi $(EXAMPLE_PROGS): $(LINK_EXE) $@.lo $(LIBS) -lldns -o $@ @@ -169,14 +171,18 @@ $(LDNS_DPA): $(LINK_EXE) $(LDNS_DPA_LOBJS) $(LIBS) $(LIBPCAP_LIBS) -lldns \ -o $(LDNS_DPA) +$(LDNS_VFY): + $(LINK_EXE) $(LDNS_VFY_LOBJS) $(LIBS) $(LIBSSL_LIBS) -lldns \ + -o $(LDNS_VFY) + $(EX_SSL_PROGS): $(LINK_EXE) $@.lo $(LIBS) $(LIBSSL_LIBS) -lldns -o $@ -install-examples: $(EXAMPLE_PROGS) $(TESTNS) $(LDNS_DPA) $(EX_SSL_PROGS) +install-examples: $(EXAMPLE_PROGS) $(TESTNS) $(LDNS_DPA) $(LDNS_VFY) $(EX_SSL_PROGS) $(INSTALL) -m 755 -d $(DESTDIR)$(bindir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1 - for p in $(EXAMPLE_PROGS) $(TESTNS) $(LDNS_DPA) $(EX_SSL_PROGS) ; do \ + for p in $(EXAMPLE_PROGS) $(TESTNS) $(LDNS_DPA) $(LDNS_VFY) $(EX_SSL_PROGS) ; do \ $(LIBTOOL) --mode=install cp $$p $(DESTDIR)$(bindir) ; \ $(INSTALL) -m 644 $(srcdir)/$$p.1 $(DESTDIR)$(mandir)/man1 ; \ done @@ -190,7 +196,7 @@ uninstall-examples: clean-examples: $(LIBTOOL) --mode clean rm -f $(EXAMPLE_PROGS) - $(LIBTOOL) --mode clean rm -f $(TESTNS) $(LDNS_DPA) $(EX_SSL_PROGS) + $(LIBTOOL) --mode clean rm -f $(TESTNS) $(LDNS_DPA) $(LDNS_VFY) $(EX_SSL_PROGS) $(LIBTOOL) --mode clean rm -f $(EXAMPLE_LOBJS) linktest: $(srcdir)/linktest.c libldns.la @@ -216,12 +222,14 @@ doxygen: manpages $(doxygen) $(srcdir)/libdns.doxygen doc: manpages $(doxygen) - $(INSTALL) -d doc + @$(INSTALL) -d doc manpages: $(srcdir)/doc/function_manpages - $(INSTALL) -d doc - cat $(srcdir)/ldns/*.h | $(srcdir)/doc/doxyparse.pl -m $(srcdir)/doc/function_manpages 2>&1 | \ - grep -v ^doxygen | grep -v ^cat > doc/ldns_manpages + @$(INSTALL) -d doc + @cat $(srcdir)/ldns/*.h \ + | $(srcdir)/doc/doxyparse.pl \ + -m $(srcdir)/doc/function_manpages 2>&1 \ + | grep -v ^doxygen | grep -v ^cat > doc/ldns_manpages pyldns: _ldns.la @@ -449,6 +457,9 @@ depend: done for p in $(EXAMPLE_PROGS) $(LDNS_DPA) $(EX_SSL_PROGS); do \ echo "$$p: $$p.lo $$p.o \$$(LIB)" >> $(DEPEND_TMP) ; done + echo "$(LDNS_VFY): `for o in $(LDNS_VFY_LOBJS) ; do \ + echo -n "$$o $${o%lo}o " ; done` \$$(LIB)" \ + >> $(DEPEND_TMP) echo "$(TESTNS): `for o in $(TESTNS_LOBJS) ; do \ echo -n "$$o $${o%lo}o " ; done` \$$(LIB)" \ >> $(DEPEND_TMP) @@ -577,7 +588,7 @@ parse.lo parse.o: $(srcdir)/parse.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/uti $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h \ ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h $(srcdir)/ldns/wire2host.h \ $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h $(srcdir)/ldns/sha2.h -rbtree.lo rbtree.o: $(srcdir)/rbtree.c ldns/config.h $(srcdir)/ldns/rbtree.h +rbtree.lo rbtree.o: $(srcdir)/rbtree.c ldns/config.h $(srcdir)/ldns/rbtree.h ldns/util.h ldns/common.h rdata.lo rdata.o: $(srcdir)/rdata.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h ldns/common.h \ $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h \ $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h \ @@ -687,11 +698,18 @@ examples/ldns-chaos.lo examples/ldns-chaos.o: $(srcdir)/examples/ldns-chaos.c ld examples/ldns-compare-zones.lo examples/ldns-compare-zones.o: $(srcdir)/examples/ldns-compare-zones.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h +examples/ldnsd.lo examples/ldnsd.o: $(srcdir)/examples/ldnsd.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h ldns/common.h \ + $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h \ + $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h \ + $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h \ + $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h \ + ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h $(srcdir)/ldns/wire2host.h \ + $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h $(srcdir)/ldns/sha2.h examples/ldns-dpa.lo examples/ldns-dpa.o: $(srcdir)/examples/ldns-dpa.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h \ ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h $(srcdir)/ldns/rdata.h \ $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h $(srcdir)/ldns/zone.h \ @@ -700,12 +718,13 @@ examples/ldns-dpa.lo examples/ldns-dpa.o: $(srcdir)/examples/ldns-dpa.c ldns/con $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h $(srcdir)/examples/ldns-dpa.h +examples/ldns-duration.lo examples/ldns-duration.o: $(srcdir)/examples/ldns-duration.c $(srcdir)/examples/ldns-duration.h examples/ldns-gen-zone.lo examples/ldns-gen-zone.o: $(srcdir)/examples/ldns-gen-zone.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h examples/ldns-key2ds.lo examples/ldns-key2ds.o: $(srcdir)/examples/ldns-key2ds.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h \ @@ -719,9 +738,9 @@ examples/ldns-key2ds.lo examples/ldns-key2ds.o: $(srcdir)/examples/ldns-key2ds.c examples/ldns-keyfetcher.lo examples/ldns-keyfetcher.o: $(srcdir)/examples/ldns-keyfetcher.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h examples/ldns-keygen.lo examples/ldns-keygen.o: $(srcdir)/examples/ldns-keygen.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h \ @@ -751,25 +770,25 @@ examples/ldns-notify.lo examples/ldns-notify.o: $(srcdir)/examples/ldns-notify.c examples/ldns-nsec3-hash.lo examples/ldns-nsec3-hash.o: $(srcdir)/examples/ldns-nsec3-hash.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h examples/ldns-read-zone.lo examples/ldns-read-zone.o: $(srcdir)/examples/ldns-read-zone.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h examples/ldns-resolver.lo examples/ldns-resolver.o: $(srcdir)/examples/ldns-resolver.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h examples/ldns-revoke.lo examples/ldns-revoke.o: $(srcdir)/examples/ldns-revoke.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h \ @@ -791,17 +810,17 @@ examples/ldns-rrsig.lo examples/ldns-rrsig.o: $(srcdir)/examples/ldns-rrsig.c ld examples/ldns-signzone.lo examples/ldns-signzone.o: $(srcdir)/examples/ldns-signzone.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h examples/ldns-test-edns.lo examples/ldns-test-edns.o: $(srcdir)/examples/ldns-test-edns.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h examples/ldns-testns.lo examples/ldns-testns.o: $(srcdir)/examples/ldns-testns.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h \ @@ -815,9 +834,9 @@ examples/ldns-testns.lo examples/ldns-testns.o: $(srcdir)/examples/ldns-testns.c examples/ldns-testpkts.lo examples/ldns-testpkts.o: $(srcdir)/examples/ldns-testpkts.c ldns/config.h $(srcdir)/ldns/ldns.h \ ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ + $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h \ + $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h \ + $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h $(srcdir)/examples/ldns-testpkts.h examples/ldns-update.lo examples/ldns-update.o: $(srcdir)/examples/ldns-update.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h \ @@ -828,14 +847,14 @@ examples/ldns-update.lo examples/ldns-update.o: $(srcdir)/examples/ldns-update.c $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h -examples/ldns-verify-zone.lo examples/ldns-verify-zone.o: $(srcdir)/examples/ldns-verify-zone.c ldns/config.h $(srcdir)/ldns/ldns.h \ - ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h \ - $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h \ - $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h \ - $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h \ - $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ - $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ - $(srcdir)/ldns/sha2.h +examples/ldns-verify-zone.lo examples/ldns-verify-zone.o: $(srcdir)/examples/ldns-verify-zone.c ldns/config.h \ + $(srcdir)/examples/ldns-duration.h $(srcdir)/ldns/ldns.h ldns/util.h ldns/common.h \ + $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h \ + $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h \ + $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h \ + $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h \ + ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h $(srcdir)/ldns/wire2host.h \ + $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h $(srcdir)/ldns/sha2.h examples/ldns-version.lo examples/ldns-version.o: $(srcdir)/examples/ldns-version.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h \ ldns/common.h $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h $(srcdir)/ldns/rdata.h \ $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h $(srcdir)/ldns/zone.h \ @@ -868,13 +887,6 @@ examples/ldns-zsplit.lo examples/ldns-zsplit.o: $(srcdir)/examples/ldns-zsplit.c $(srcdir)/ldns/host2wire.h ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h \ $(srcdir)/ldns/wire2host.h $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h \ $(srcdir)/ldns/sha2.h -examples/ldnsd.lo examples/ldnsd.o: $(srcdir)/examples/ldnsd.c ldns/config.h $(srcdir)/ldns/ldns.h ldns/util.h ldns/common.h \ - $(srcdir)/ldns/buffer.h $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h \ - $(srcdir)/ldns/packet.h $(srcdir)/ldns/rr.h $(srcdir)/ldns/keys.h $(srcdir)/ldns/zone.h $(srcdir)/ldns/resolver.h \ - $(srcdir)/ldns/tsig.h $(srcdir)/ldns/dnssec_zone.h $(srcdir)/ldns/rbtree.h $(srcdir)/ldns/host2str.h \ - $(srcdir)/ldns/dnssec_verify.h $(srcdir)/ldns/dnssec_sign.h $(srcdir)/ldns/higher.h $(srcdir)/ldns/host2wire.h \ - ldns/net.h $(srcdir)/ldns/str2host.h $(srcdir)/ldns/update.h $(srcdir)/ldns/wire2host.h \ - $(srcdir)/ldns/rr_functions.h $(srcdir)/ldns/parse.h $(srcdir)/ldns/sha1.h $(srcdir)/ldns/sha2.h drill/chasetrace.lo drill/chasetrace.o: $(srcdir)/drill/chasetrace.c $(srcdir)/drill/drill.h ldns/config.h \ $(srcdir)/drill/drill_util.h $(srcdir)/ldns/ldns.h ldns/util.h ldns/common.h $(srcdir)/ldns/buffer.h \ $(srcdir)/ldns/error.h $(srcdir)/ldns/dname.h $(srcdir)/ldns/rdata.h $(srcdir)/ldns/dnssec.h $(srcdir)/ldns/packet.h \ @@ -941,6 +953,7 @@ drill/work.lo drill/work.o: $(srcdir)/drill/work.c $(srcdir)/drill/drill.h ldns/ $(srcdir)/ldns/sha2.h examples/ldns-chaos: examples/ldns-chaos.lo examples/ldns-chaos.o $(LIB) examples/ldns-compare-zones: examples/ldns-compare-zones.lo examples/ldns-compare-zones.o $(LIB) +examples/ldnsd: examples/ldnsd.lo examples/ldnsd.o $(LIB) examples/ldns-gen-zone: examples/ldns-gen-zone.lo examples/ldns-gen-zone.o $(LIB) examples/ldns-key2ds: examples/ldns-key2ds.lo examples/ldns-key2ds.o $(LIB) examples/ldns-keyfetcher: examples/ldns-keyfetcher.lo examples/ldns-keyfetcher.o $(LIB) @@ -958,8 +971,7 @@ examples/ldns-version: examples/ldns-version.lo examples/ldns-version.o $(LIB) examples/ldns-walk: examples/ldns-walk.lo examples/ldns-walk.o $(LIB) examples/ldns-zcat: examples/ldns-zcat.lo examples/ldns-zcat.o $(LIB) examples/ldns-zsplit: examples/ldns-zsplit.lo examples/ldns-zsplit.o $(LIB) -examples/ldnsd: examples/ldnsd.lo examples/ldnsd.o $(LIB) examples/ldns-dpa: examples/ldns-dpa.lo examples/ldns-dpa.o $(LIB) examples/ldns-signzone: examples/ldns-signzone.lo examples/ldns-signzone.o $(LIB) -examples/ldns-verify-zone: examples/ldns-verify-zone.lo examples/ldns-verify-zone.o $(LIB) +examples/ldns-verify-zone: examples/ldns-verify-zone.lo examples/ldns-verify-zone.o examples/ldns-duration.lo examples/ldns-duration.o $(LIB) examples/ldns-testns: examples/ldns-testns.lo examples/ldns-testns.o examples/ldns-testpkts.lo examples/ldns-testpkts.o $(LIB) diff --git a/examples/ldns-duration.c b/examples/ldns-duration.c new file mode 100644 index 00000000..b5086d84 --- /dev/null +++ b/examples/ldns-duration.c @@ -0,0 +1,547 @@ +/* + * $Id: duration.c 4518 2011-02-24 15:39:09Z matthijs $ + * + * Copyright (c) 2009 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + */ + +/** + * + * This file is copied from the OpenDNSSEC source repository + * and only slightly adapted to make it fit. + */ + +/** + * + * Durations. + */ + +#include "ldns-duration.h" + +#include +#include +#include +#include + + +/** + * Create a new 'instant' duration. + * + */ +ldns_duration_type* +ldns_duration_create(void) +{ + ldns_duration_type* duration; + + duration = malloc(sizeof(ldns_duration_type)); + if (!duration) { + return NULL; + } + duration->years = 0; + duration->months = 0; + duration->weeks = 0; + duration->days = 0; + duration->hours = 0; + duration->minutes = 0; + duration->seconds = 0; + return duration; +} + + +/** + * Compare durations. + * + */ +int +ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2) +{ + if (!d1 && !d2) { + return 0; + } + if (!d1 || !d2) { + return d1?-1:1; + } + + if (d1->years != d2->years) { + return d1->years - d2->years; + } + if (d1->months != d2->months) { + return d1->months - d2->months; + } + if (d1->weeks != d2->weeks) { + return d1->weeks - d2->weeks; + } + if (d1->days != d2->days) { + return d1->days - d2->days; + } + if (d1->hours != d2->hours) { + return d1->hours - d2->hours; + } + if (d1->minutes != d2->minutes) { + return d1->minutes - d2->minutes; + } + if (d1->seconds != d2->seconds) { + return d1->seconds - d2->seconds; + } + + return 0; +} + + +/** + * Create a duration from string. + * + */ +ldns_duration_type* +ldns_duration_create_from_string(const char* str) +{ + ldns_duration_type* duration = ldns_duration_create(); + char* P, *X, *T, *W; + int not_weeks = 0; + + if (!duration) { + return NULL; + } + if (!str) { + return duration; + } + + P = strchr(str, 'P'); + if (!P) { + ldns_duration_cleanup(duration); + return NULL; + } + + T = strchr(str, 'T'); + X = strchr(str, 'Y'); + if (X) { + duration->years = atoi(str+1); + str = X; + not_weeks = 1; + } + X = strchr(str, 'M'); + if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) { + duration->months = atoi(str+1); + str = X; + not_weeks = 1; + } + X = strchr(str, 'D'); + if (X) { + duration->days = atoi(str+1); + str = X; + not_weeks = 1; + } + if (T) { + str = T; + not_weeks = 1; + } + X = strchr(str, 'H'); + if (X && T) { + duration->hours = atoi(str+1); + str = X; + not_weeks = 1; + } + X = strrchr(str, 'M'); + if (X && T && (size_t) (X-P) > (size_t) (T-P)) { + duration->minutes = atoi(str+1); + str = X; + not_weeks = 1; + } + X = strchr(str, 'S'); + if (X && T) { + duration->seconds = atoi(str+1); + str = X; + not_weeks = 1; + } + + W = strchr(str, 'W'); + if (W) { + if (not_weeks) { + ldns_duration_cleanup(duration); + return NULL; + } else { + duration->weeks = atoi(str+1); + str = W; + } + } + return duration; +} + + +/** + * Get the number of digits in a number. + * + */ +static size_t +digits_in_number(time_t duration) +{ + uint32_t period = (uint32_t) duration; + size_t count = 0; + + while (period > 0) { + count++; + period /= 10; + } + return count; +} + + +/** + * Convert a duration to a string. + * + */ +char* +ldns_duration2string(ldns_duration_type* duration) +{ + char* str = NULL, *num = NULL; + size_t count = 2; + int T = 0; + + if (!duration) { + return NULL; + } + + if (duration->years > 0) { + count = count + 1 + digits_in_number(duration->years); + } + if (duration->months > 0) { + count = count + 1 + digits_in_number(duration->months); + } + if (duration->weeks > 0) { + count = count + 1 + digits_in_number(duration->weeks); + } + if (duration->days > 0) { + count = count + 1 + digits_in_number(duration->days); + } + if (duration->hours > 0) { + count = count + 1 + digits_in_number(duration->hours); + T = 1; + } + if (duration->minutes > 0) { + count = count + 1 + digits_in_number(duration->minutes); + T = 1; + } + if (duration->seconds > 0) { + count = count + 1 + digits_in_number(duration->seconds); + T = 1; + } + if (T) { + count++; + } + + str = (char*) calloc(count, sizeof(char)); + str[0] = 'P'; + str[1] = '\0'; + + if (duration->years > 0) { + count = digits_in_number(duration->years); + num = (char*) calloc(count+2, sizeof(char)); + snprintf(num, count+2, "%uY", (uint32_t) duration->years); + str = strncat(str, num, count+2); + free((void*) num); + } + if (duration->months > 0) { + count = digits_in_number(duration->months); + num = (char*) calloc(count+2, sizeof(char)); + snprintf(num, count+2, "%uM", (uint32_t) duration->months); + str = strncat(str, num, count+2); + free((void*) num); + } + if (duration->weeks > 0) { + count = digits_in_number(duration->weeks); + num = (char*) calloc(count+2, sizeof(char)); + snprintf(num, count+2, "%uW", (uint32_t) duration->weeks); + str = strncat(str, num, count+2); + free((void*) num); + } + if (duration->days > 0) { + count = digits_in_number(duration->days); + num = (char*) calloc(count+2, sizeof(char)); + snprintf(num, count+2, "%uD", (uint32_t) duration->days); + str = strncat(str, num, count+2); + free((void*) num); + } + if (T) { + str = strncat(str, "T", 1); + } + if (duration->hours > 0) { + count = digits_in_number(duration->hours); + num = (char*) calloc(count+2, sizeof(char)); + snprintf(num, count+2, "%uH", (uint32_t) duration->hours); + str = strncat(str, num, count+2); + free((void*) num); + } + if (duration->minutes > 0) { + count = digits_in_number(duration->minutes); + num = (char*) calloc(count+2, sizeof(char)); + snprintf(num, count+2, "%uM", (uint32_t) duration->minutes); + str = strncat(str, num, count+2); + free((void*) num); + } + if (duration->seconds > 0) { + count = digits_in_number(duration->seconds); + num = (char*) calloc(count+2, sizeof(char)); + snprintf(num, count+2, "%uS", (uint32_t) duration->seconds); + str = strncat(str, num, count+2); + free((void*) num); + } + return str; +} + + +/** + * Convert a duration to a time. + * + */ +time_t +ldns_duration2time(ldns_duration_type* duration) +{ + time_t period = 0; + char* dstr = NULL; + + if (duration) { + period += (duration->seconds); + period += (duration->minutes)*60; + period += (duration->hours)*3600; + period += (duration->days)*86400; + period += (duration->weeks)*86400*7; + period += (duration->months)*86400*31; + period += (duration->years)*86400*365; + + /* [TODO] calculate correct number of days in this month/year */ + /* + if (duration->months || duration->years) { + } + */ + } + return period; +} + +/** + * Return the shortest time. + * + */ +time_t +time_minimum(time_t a, time_t b) +{ + return (a < b ? a : b); +} + +/** + * Return the longest time. + * + */ +time_t +time_maximum(time_t a, time_t b) +{ + return (a > b ? a : b); +} + + +/** + * Return a random time. + * + */ +time_t +ods_rand(time_t mod) +{ +#ifdef HAVE_ARC4RANDOM_UNIFORM + return (time_t) (arc4random_uniform((uint32_t) mod+1)); +#elif HAVE_ARC4RANDOM + return (time_t) (arc4random() % (unsigned) mod+1); +#else + return (time_t) (random() % (unsigned) mod+1); +#endif +} + + +/* Number of days per month (except for February in leap years). */ +static const int mdays[] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + + +static int +is_leap_year(int year) +{ + return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); +} + + +static int +leap_days(int y1, int y2) +{ + --y1; + --y2; + return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400); +} + + +/* + * Code taken from NSD 3.2.5, which is + * code adapted from Python 2.4.1 sources (Lib/calendar.py). + */ +static time_t +mktime_from_utc(const struct tm *tm) +{ + int year = 1900 + tm->tm_year; + time_t days = 365 * (year - 1970) + leap_days(1970, year); + time_t hours; + time_t minutes; + time_t seconds; + int i; + + for (i = 0; i < tm->tm_mon; ++i) { + days += mdays[i]; + } + if (tm->tm_mon > 1 && is_leap_year(year)) { + ++days; + } + days += tm->tm_mday - 1; + + hours = days * 24 + tm->tm_hour; + minutes = hours * 60 + tm->tm_min; + seconds = minutes * 60 + tm->tm_sec; + + return seconds; +} + + +/** + * Convert time in string format into seconds. + * + */ +static time_t +timeshift2time(const char *time) +{ + /* convert a string in format YYMMDDHHMMSS to time_t */ + struct tm tm; + time_t timeshift = 0; + + /* Try to scan the time... */ + if (strptime(time, "%Y%m%d%H%M%S", &tm)) { + timeshift = mktime_from_utc(&tm); + } + return timeshift; +} + + +/** + * Return the time since Epoch, measured in seconds. + * + */ +time_t +time_now(void) +{ +#ifdef ENFORCER_TIMESHIFT + const char* env = getenv("ENFORCER_TIMESHIFT"); + if (env) { + return timeshift2time(env); + } else +#endif /* ENFORCER_TIMESHIFT */ + + return time(NULL); +} + + +/** + * copycode: This code is based on the EXAMPLE in the strftime manual. + * + */ +uint32_t +time_datestamp(time_t tt, const char* format, char** str) +{ + time_t t; + struct tm *tmp; + uint32_t ut = 0; + char outstr[32]; + + if (tt) { + t = tt; + } else { + t = time_now(); + } + + tmp = localtime(&t); + if (tmp == NULL) { + return 0; + } + + if (strftime(outstr, sizeof(outstr), format, tmp) == 0) { + return 0; + } + + ut = (uint32_t) strtoul(outstr, NULL, 10); + if (str) { + *str = strdup(outstr); + } + return ut; +} + +static void +time_itoa_reverse(char* s) +{ + int i, j; + char c; + + for (i = 0, j = strlen(s)-1; i 0); /* delete it */ + s[i] = '\0'; + time_itoa_reverse(s); + return; +} + + +/** + * Clean up duration. + * + */ +void +ldns_duration_cleanup(ldns_duration_type* duration) +{ + if (!duration) { + return; + } + free(duration); + return; +} diff --git a/examples/ldns-duration.h b/examples/ldns-duration.h new file mode 100644 index 00000000..24becd50 --- /dev/null +++ b/examples/ldns-duration.h @@ -0,0 +1,161 @@ +/* + * $Id: duration.h 4341 2011-01-31 15:21:09Z matthijs $ + * + * Copyright (c) 2009 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + */ + +/** + * + * This file is copied from the OpenDNSSEC source repository + * and only slightly adapted to make it fit. + */ + +/** + * + * Durations. + */ + +#ifndef LDNS_DURATION_H +#define LDNS_DURATION_H + +#include +#include + +/** + * Duration. + * + */ +typedef struct ldns_duration_struct ldns_duration_type; +struct ldns_duration_struct +{ + time_t years; + time_t months; + time_t weeks; + time_t days; + time_t hours; + time_t minutes; + time_t seconds; +}; + +/** + * Create a new 'instant' duration. + * \return ldns_duration_type* created duration + * + */ +ldns_duration_type* ldns_duration_create(void); + +/** + * Compare durations. + * \param[in] d1 one duration + * \param[in] d2 another duration + * \return int 0 if equal, -1 if d1 < d2, 1 if d2 < d1 + * + */ +int ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2); + +/** + * Create a duration from string. + * \param[in] str string-format duration + * \return ldns_duration_type* created duration + * + */ +ldns_duration_type* ldns_duration_create_from_string(const char* str); + +/** + * Convert a duration to a string. + * \param[in] duration duration to be converted + * \return char* string-format duration + * + */ +char* ldns_duration2string(ldns_duration_type* duration); + +/** + * Convert a duration to a time. + * \param[in] duration duration to be converted + * \return time_t time-format duration + * + */ +time_t ldns_duration2time(ldns_duration_type* duration); + +/** + * Return a random time. + * \param[in] mod modulo + * \return time_t random time + * + */ +time_t ods_rand(time_t mod); + +/** + * Return the shortest time. + * \param[in] a one time + * \param[in] b another time + * \return time_t the shortest time + * + */ +time_t time_minimum(time_t a, time_t b); + +/** + * Return the longest time. + * \param[in] a one time + * \param[in] b another time + * \return time_t the shortest time + * + */ +time_t time_maximum(time_t a, time_t b); + +/** + * Convert time into string. + * \param[in] n time + * \param[in] s string + * + */ +void time_itoa(time_t n, char* s); + +/** + * Return time in datestamp. + * \param[in] tt time + * \param[in] format stamp format + * \param[out] str store string + * \return uint32_t integer based datestamp. + * + */ +uint32_t time_datestamp(time_t tt, const char* format, char** str); + +/** + * Return the time since Epoch, measured in seconds. + * If the timeshift is enabled, return the environment variable. + * \return time_t now (or timeshift). + * + */ +time_t time_now(void); + +/** + * Clean up duration. + * \param[in] duration duration to be cleaned up + * + */ +void ldns_duration_cleanup(ldns_duration_type* duration); + +#endif /* LDNS_DURATION_H */ diff --git a/examples/ldns-verify-zone.1 b/examples/ldns-verify-zone.1 index f4555a79..cc93ce75 100644 --- a/examples/ldns-verify-zone.1 +++ b/examples/ldns-verify-zone.1 @@ -14,10 +14,27 @@ RRSIG resource records are checked against the DNSKEY set at the zone apex. Each name is checked for an NSEC(3), if appropriate. .SH OPTIONS +.TP +\fB-h\fR +Show usage and exit + .TP \fB-a\fR Apex only, check only the zone apex +.TP +\fB-e\fR \fIperiod\fR +Signatures may not expire within this period. + +.TP +\fB-i\fR \fIperiod\fR +Signatures must have been valid at least this long. + +.TP +\fB-k\fR \fIfile\fR +A file that contains a trusted DNSKEY or DS rr. +This option may be given more than once. + .TP \fB-p\fR \fI[0-100]\fR Only check this percentage of the zone. @@ -25,8 +42,9 @@ Which names to check is determined randomly. Defaults to 100. .TP -\fB-h\fR -Show usage and exit +\fB-S\fR +Chase signature(s) to a known key. +The network may be accessed to validate the zone's DNSKEYs. (implies -k) .TP \fB-t\fR \fIYYYYMMDDhhmmss | [+|-]offset\fR diff --git a/examples/ldns-verify-zone.c b/examples/ldns-verify-zone.c index 7b67c73b..5bb5ac9e 100644 --- a/examples/ldns-verify-zone.c +++ b/examples/ldns-verify-zone.c @@ -11,6 +11,7 @@ #include "config.h" #include #include +#include "ldns-duration.h" #include @@ -19,134 +20,343 @@ #ifdef HAVE_SSL #include +#define LDNS_VERIFY_ZONE_ERROR 0x8000 +#define LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN \ + LDNS_VERIFY_ZONE_ERROR | 0 +#define LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN \ + LDNS_VERIFY_ZONE_ERROR | 1 + int verbosity = 3; +time_t check_time = 0; +time_t inception_offset = 0; +time_t expiration_offset = 0; +bool do_sigchase = false; +bool no_nomatch_msg = false; +bool zone_is_nsec3_optout = false; + +FILE* myout; +FILE* myerr; -static int -zone_is_nsec3_optout(ldns_rbtree_t *zone_nodes) +static const char* +get_errorstr_by_id(int err) { - /* simply find the first NSEC3 RR and check its flags */ - /* TODO: maybe create a general function that uses the active - * NSEC3PARAM RR? */ - ldns_rbnode_t *cur_node; - ldns_dnssec_name *cur_name; - cur_node = ldns_rbtree_first(zone_nodes); - while (cur_node != LDNS_RBTREE_NULL) { - cur_name = (ldns_dnssec_name *) cur_node->data; - if (cur_name && cur_name->nsec && - ldns_rr_get_type(cur_name->nsec) == LDNS_RR_TYPE_NSEC3) { - if (ldns_nsec3_optout(cur_name->nsec)) { - return 1; - } else { - return 0; - } - } - cur_node = ldns_rbtree_next(cur_node); + switch (err) { + case LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN: + return "DNSSEC signature not incepted long enough"; + case LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN: + return "DNSSEC signature will expire to soon"; + default: + return ldns_get_errorstr_by_id(err); } - return 0; } static void -print_type(ldns_rr_type type) +print_type(FILE* stream, ldns_rr_type type) { - const ldns_rr_descriptor *descriptor; + const ldns_rr_descriptor *descriptor = ldns_rr_descript(type); - descriptor = ldns_rr_descript(type); if (descriptor && descriptor->_name) { - fprintf(stdout, "%s", descriptor->_name); + fprintf(stream, "%s", descriptor->_name); } else { - fprintf(stdout, "TYPE%u", - type); + fprintf(stream, "TYPE%u", type); + } +} + +ldns_status +read_key_file(const char *filename, ldns_rr_list *keys) +{ + ldns_status status = LDNS_STATUS_ERR; + ldns_rr *rr; + FILE *fp; + uint32_t my_ttl = 0; + ldns_rdf *my_origin = NULL; + ldns_rdf *my_prev = NULL; + int line_nr; + + if (! (fp = fopen(filename, "r"))) { + fprintf( myerr + , "Error opening %s: %s\n" + , filename + , strerror(errno) + ); + return LDNS_STATUS_ERR; } + while (!feof(fp)) { + status = ldns_rr_new_frm_fp_l( &rr + , fp + , &my_ttl + , &my_origin + , &my_prev + , &line_nr + ); + + if (status == LDNS_STATUS_OK) { + if ( ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS + || ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY ) + + ldns_rr_list_push_rr(keys, rr); + + } else if (status == LDNS_STATUS_SYNTAX_EMPTY + || status == LDNS_STATUS_SYNTAX_TTL + || status == LDNS_STATUS_SYNTAX_ORIGIN + || status == LDNS_STATUS_SYNTAX_INCLUDE ) + + status = LDNS_STATUS_OK; + else + break; + } + return status; } -static ldns_dnssec_zone * -create_dnssec_zone(ldns_zone *orig_zone) +static bool +rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t) { + return ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG + && ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t; +} + +static ldns_status +dnssec_zone_new_frm_fp_l( ldns_dnssec_zone** z + , FILE* fp + , ldns_rdf* origin + , uint32_t ttl + , ldns_rr_class ATTR_UNUSED(c) + , int* line_nr + ) +{ + ldns_rr* cur_rr; size_t i; - ldns_dnssec_zone *dnssec_zone; - ldns_rr *cur_rr; - ldns_status status; + uint32_t my_ttl = ttl; + ldns_rdf *my_origin = NULL; + ldns_rdf *my_prev = NULL; + + ldns_dnssec_zone *newzone = ldns_dnssec_zone_new(); /* when reading NSEC3s, there is a chance that we encounter nsecs for empty nonterminals, whose nonterminals we cannot derive yet because the needed information is to be read later. in that case we keep a list of those nsec3's and retry to add them later */ - ldns_rr_list *failed_nsec3s = ldns_rr_list_new(); - ldns_rr_list *failed_nsec3_rrsigs = ldns_rr_list_new(); + ldns_rr_list* todo_nsec3s = ldns_rr_list_new(); + ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new(); - dnssec_zone = ldns_dnssec_zone_new(); - if (ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(orig_zone)) - != LDNS_STATUS_OK) { - if (verbosity > 0) { - fprintf(stderr, "Error adding SOA to dnssec zone, " - "skipping record\n"); - } - } - - for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(orig_zone)); i++) { - cur_rr = ldns_rr_list_rr(ldns_zone_rrs(orig_zone), i); - status = ldns_dnssec_zone_add_rr(dnssec_zone, cur_rr); - if (status != LDNS_STATUS_OK) { - if (LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND - == status) { - if (ldns_rr_get_type(cur_rr) - == LDNS_RR_TYPE_RRSIG - && ldns_rdf2rr_type( - ldns_rr_rrsig_typecovered( - cur_rr - ) - ) == LDNS_RR_TYPE_NSEC3) { - ldns_rr_list_push_rr( - failed_nsec3_rrsigs, - cur_rr); + ldns_status status = LDNS_STATUS_MEM_ERR; + + if ( ! newzone || ! todo_nsec3s || ! todo_nsec3_rrsigs ) goto error; + + if (origin) { + if (! (my_origin = ldns_rdf_clone(origin))) goto error; + if (! (my_prev = ldns_rdf_clone(origin))) goto error; + } + + while (!feof(fp)) { + status = ldns_rr_new_frm_fp_l( &cur_rr + , fp + , &my_ttl + , &my_origin + , &my_prev + , line_nr + ); + switch (status) { + case LDNS_STATUS_OK: + + status = ldns_dnssec_zone_add_rr(newzone, cur_rr); + if (status + == LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) { + + if (rr_is_rrsig_covering( cur_rr + , LDNS_RR_TYPE_NSEC3)){ + ldns_rr_list_push_rr( todo_nsec3_rrsigs + , cur_rr + ); } else { - ldns_rr_list_push_rr(failed_nsec3s, - cur_rr); - } - } else { - if (verbosity > 0) { - fprintf(stderr, "Error adding RR to " - "dnssec zone" - ", skipping record:\n"); - ldns_rr_print(stderr, cur_rr); + ldns_rr_list_push_rr( todo_nsec3s + , cur_rr + ); } - } + } else if (status != LDNS_STATUS_OK) + goto error; + + if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC3) + zone_is_nsec3_optout + = zone_is_nsec3_optout + || ldns_nsec3_optout(cur_rr); + + break; + + + case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */ + case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/ + case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/ + break; + + case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */ + status = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL; + break; + + default: + goto error; } } - if (ldns_rr_list_rr_count(failed_nsec3s) > 0) { - (void) ldns_dnssec_zone_add_empty_nonterminals(dnssec_zone); - for (i = 0; i < ldns_rr_list_rr_count(failed_nsec3s); i++) { - cur_rr = ldns_rr_list_rr(failed_nsec3s, i); - status = ldns_dnssec_zone_add_rr(dnssec_zone, cur_rr); + if (ldns_rr_list_rr_count(todo_nsec3s) > 0) { + (void) ldns_dnssec_zone_add_empty_nonterminals(newzone); + for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3s); i++) { + cur_rr = ldns_rr_list_rr(todo_nsec3s, i); + status = ldns_dnssec_zone_add_rr(newzone, cur_rr); } - for (i = 0; i < ldns_rr_list_rr_count(failed_nsec3_rrsigs); - i++) { - cur_rr = ldns_rr_list_rr(failed_nsec3_rrsigs, i); - status = ldns_dnssec_zone_add_rr(dnssec_zone, cur_rr); + for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){ + cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i); + status = ldns_dnssec_zone_add_rr(newzone, cur_rr); + } + } else if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) { + for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){ + cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i); + status = ldns_dnssec_zone_add_rr(newzone, cur_rr); } } - ldns_rr_list_free(failed_nsec3_rrsigs); - ldns_rr_list_free(failed_nsec3s); - return dnssec_zone; + ldns_rr_list_free(todo_nsec3_rrsigs); + ldns_rr_list_free(todo_nsec3s); + + if (z) { + *z = newzone; + } else { + ldns_dnssec_zone_free(newzone); + } + + return LDNS_STATUS_OK; + +error: + if (my_origin) { + ldns_rdf_deep_free(my_origin); + } + if (my_prev) { + ldns_rdf_deep_free(my_prev); + } + if (newzone) { + ldns_dnssec_zone_free(newzone); + } + return status; +} + + + +static void +print_rr_error(FILE* stream, ldns_rr* rr, const char* msg) +{ + if (verbosity > 0) { + fprintf(stream, "Error: %s for ", msg); + ldns_rdf_print(stream, ldns_rr_owner(rr)); + fprintf(stream, "\t"); + print_type(stream, ldns_rr_get_type(rr)); + fprintf(stream, "\n"); + } +} + +static void +print_rr_status_error(FILE* stream, ldns_rr* rr, ldns_status status) +{ + if (status != LDNS_STATUS_OK) { + print_rr_error(stream, rr, get_errorstr_by_id(status)); + if (verbosity > 0 && status == LDNS_STATUS_SSL_ERR) { + ERR_load_crypto_strings(); + ERR_print_errors_fp(stream); + } + } +} + +static void +print_rrs_status_error( FILE* stream + , ldns_rr_list* rrs + , ldns_status status + , ldns_dnssec_rrs* cur_sig + ) +{ + if (status != LDNS_STATUS_OK) { + if (ldns_rr_list_rr_count(rrs) > 0) { + print_rr_status_error( stream + , ldns_rr_list_rr(rrs, 0) + , status + ); + } else { + fprintf( stream + , "Error: %s for \n" + , get_errorstr_by_id(status) + ); + } + if (verbosity >= 4) { + fprintf(stream, "RRSet:\n"); + ldns_rr_list_print(stream, rrs); + fprintf(stream, "Signature:\n"); + ldns_rr_print(stream, cur_sig->rr); + fprintf(stream, "\n"); + } + } +} + +static ldns_status +rrsig_check_time_margins(ldns_rr* rrsig) +{ + int32_t inception, expiration; + + inception = ldns_rdf2native_int32(ldns_rr_rrsig_inception (rrsig)); + expiration = ldns_rdf2native_int32(ldns_rr_rrsig_expiration(rrsig)); + + if (check_time - inception_offset - inception < 0) { + return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN; + } + if (expiration - expiration_offset - check_time < 0) { + return LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN; + } + return LDNS_STATUS_OK; +} + +static ldns_status +verify_rrs( ldns_rr_list* rrset_rrs + , ldns_dnssec_rrs* cur_sig + , ldns_rr_list* keys + ) +{ + ldns_rr_list* good_keys; + ldns_status status, result = LDNS_STATUS_OK; + + while (cur_sig) { + good_keys = ldns_rr_list_new(); + status = ldns_verify_rrsig_keylist_time( rrset_rrs + , cur_sig->rr + , keys + , check_time + , good_keys + ); + status = status ? status + : rrsig_check_time_margins(cur_sig->rr); + if ( status != LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY + || ! no_nomatch_msg ) { + print_rrs_status_error( myerr + , rrset_rrs + , status + , cur_sig + ); + } + result = result ? result : status; + ldns_rr_list_free(good_keys); + cur_sig = cur_sig->next; + } + + return result; } static ldns_status -verify_dnssec_rrset( - ldns_rdf *zone_name, - ldns_rdf *name, - ldns_dnssec_rrsets *rrset, - ldns_rr_list *keys, - time_t check_time - ) +verify_dnssec_rrset( ldns_rdf *zone_name + , ldns_rdf *name + , ldns_dnssec_rrsets *rrset + , ldns_rr_list *keys + ) { ldns_rr_list *rrset_rrs; ldns_dnssec_rrs *cur_rr, *cur_sig; ldns_status status; - ldns_rr_list *good_keys; - ldns_status result = LDNS_STATUS_OK; if (!rrset->rrs) return LDNS_STATUS_OK; @@ -158,115 +368,39 @@ verify_dnssec_rrset( } cur_sig = rrset->signatures; if (cur_sig) { - while (cur_sig) { - good_keys = ldns_rr_list_new(); - status = ldns_verify_rrsig_keylist_time( - rrset_rrs, cur_sig->rr, - keys, check_time, good_keys); - if (status != LDNS_STATUS_OK) { - if (verbosity > 0) { - printf("Error: %s", - ldns_get_errorstr_by_id( - status)); - printf(" for "); - ldns_rdf_print(stdout, - ldns_rr_owner(rrset->rrs->rr)); - printf("\t"); - print_type(rrset->type); - printf("\n"); - if (result == LDNS_STATUS_OK) { - result = status; - } - if (status == LDNS_STATUS_SSL_ERR) { - ERR_load_crypto_strings(); - ERR_print_errors_fp(stdout); - } - if (verbosity >= 4) { - printf("RRSet:\n"); - ldns_dnssec_rrs_print(stdout, - rrset->rrs); - printf("Signature:\n"); - ldns_rr_print(stdout, - cur_sig->rr); - printf("\n"); - } - } - } - ldns_rr_list_free(good_keys); + status = verify_rrs(rrset_rrs, cur_sig, keys); - cur_sig = cur_sig->next; - } + } else /* delegations may be unsigned (on opt out...) */ + if (rrset->type != LDNS_RR_TYPE_NS + || ldns_dname_compare(name, zone_name) == 0) { + + print_rr_error(myerr, rrset->rrs->rr, "no signatures"); + status = LDNS_STATUS_CRYPTO_NO_RRSIG; } else { - /* delegations are unsigned */ - if (rrset->type != LDNS_RR_TYPE_NS || - ldns_dname_compare(name, zone_name) == 0) { - if (verbosity > 0) { - printf("Error: no signatures for "); - ldns_rdf_print(stdout, - ldns_rr_owner(rrset->rrs->rr)); - printf("\t"); - print_type(rrset->type); - printf("\n"); - } - } + status = LDNS_STATUS_OK; } ldns_rr_list_free(rrset_rrs); - return result; + + return status; } static ldns_status -verify_single_rr( - ldns_rr *rr, - ldns_dnssec_rrs *signature_rrs, - ldns_rr_list *keys) +verify_single_rr( ldns_rr *rr + , ldns_dnssec_rrs *signature_rrs + , ldns_rr_list *keys + ) { ldns_rr_list *rrset_rrs; - ldns_rr_list *good_keys; - ldns_dnssec_rrs *cur_sig; ldns_status status; - ldns_status result = LDNS_STATUS_OK; rrset_rrs = ldns_rr_list_new(); ldns_rr_list_push_rr(rrset_rrs, rr); - cur_sig = signature_rrs; - while (cur_sig) { - good_keys = ldns_rr_list_new(); - status = ldns_verify_rrsig_keylist( - rrset_rrs, cur_sig->rr, keys, good_keys); - if (status != LDNS_STATUS_OK) { - if (verbosity >= 1) { - printf("Error: %s ", - ldns_get_errorstr_by_id(status)); - if (result == LDNS_STATUS_OK) { - result = status; - } - printf("for "); - ldns_rdf_print(stdout, ldns_rr_owner(rr)); - printf("\t"); - print_type(ldns_rr_get_type(rr)); - printf("\n"); - if (status == LDNS_STATUS_SSL_ERR) { - ERR_load_crypto_strings(); - ERR_print_errors_fp(stdout); - } - if (verbosity >= 4) { - printf("RRSet:\n"); - ldns_rr_list_print(stdout, rrset_rrs); - printf("Signature:\n"); - ldns_rr_print(stdout, cur_sig->rr); - printf("\n"); - } - } - result = status; - } - ldns_rr_list_free(good_keys); - cur_sig = cur_sig->next; - } + status = verify_rrs(rrset_rrs, signature_rrs, keys); ldns_rr_list_free(rrset_rrs); - return result; + return status; } static ldns_status @@ -295,22 +429,27 @@ verify_next_hashed_name(ldns_rbtree_t *zone_nodes, ldns_dnssec_name *name) continue; } if (!next_name->hashed_name) { - next_name->hashed_name = ldns_nsec3_hash_name_frm_nsec3( - name->nsec, next_name->name); + next_name->hashed_name = ldns_nsec3_hash_name_frm_nsec3 + ( name->nsec + , next_name->name + ); } /* we keep track of what 'so far' is the next hashed name; * it must of course be 'larger' than the current name * if we find one that is larger, but smaller than what we * previously thought was the next one, that one is the next */ - cmp = ldns_dname_compare( - name->hashed_name, next_name->hashed_name); + cmp = ldns_dname_compare( name->hashed_name + , next_name->hashed_name + ); if (cmp < 0) { if (!cur_next_name) { cur_next_name = next_name; } else { - cmp = ldns_dname_compare(next_name->hashed_name, - cur_next_name->hashed_name); + cmp = ldns_dname_compare + ( next_name->hashed_name + , cur_next_name->hashed_name + ); if (cmp < 0) { cur_next_name = next_name; } @@ -321,8 +460,9 @@ verify_next_hashed_name(ldns_rbtree_t *zone_nodes, ldns_dnssec_name *name) if (!cur_first_name) { cur_first_name = next_name; } else { - cmp = ldns_dname_compare(next_name->hashed_name, - cur_first_name->hashed_name); + cmp = ldns_dname_compare( next_name->hashed_name + , cur_first_name->hashed_name + ); if (cmp < 0) { cur_first_name = next_name; } @@ -335,19 +475,24 @@ verify_next_hashed_name(ldns_rbtree_t *zone_nodes, ldns_dnssec_name *name) next_owner_str = ldns_rdf2str(ldns_nsec3_next_owner(name->nsec)); next_owner_dname = ldns_dname_new_frm_str(next_owner_str); - cmp = ldns_dname_compare(next_owner_dname, - cur_next_name->hashed_name); + cmp = ldns_dname_compare( next_owner_dname + , cur_next_name->hashed_name + ); ldns_rdf_deep_free(next_owner_dname); LDNS_FREE(next_owner_str); if (cmp != 0) { - printf("Error: The NSEC3 record for "); - ldns_rdf_print(stdout, name->name); - printf(" points to the wrong next hashed owner name\n"); - printf("(should point to "); - ldns_rdf_print(stdout, cur_next_name->name); - printf("(whose hashed name is "); - ldns_rdf_print(stdout, cur_next_name->hashed_name); - printf(")\n"); + if (verbosity > 0) { + fprintf(myerr, "Error: The NSEC3 record for "); + ldns_rdf_print(stdout, name->name); + fprintf( myerr + , " points to the wrong next hashed owner" + " name\n\tshould point to " + ); + ldns_rdf_print(myerr, cur_next_name->name); + fprintf(myerr, ", whose hashed name is "); + ldns_rdf_print(myerr, cur_next_name->hashed_name); + fprintf(myerr, "\n"); + } return LDNS_STATUS_ERR; } else { return LDNS_STATUS_OK; @@ -355,10 +500,10 @@ verify_next_hashed_name(ldns_rbtree_t *zone_nodes, ldns_dnssec_name *name) } static ldns_status -verify_nsec( - ldns_rbtree_t *zone_nodes, - ldns_rbnode_t *cur_node, - ldns_rr_list *keys) +verify_nsec( ldns_rbtree_t *zone_nodes + , ldns_rbnode_t *cur_node + , ldns_rr_list *keys + ) { ldns_rbnode_t *next_node; ldns_dnssec_name *name, *next_name; @@ -368,20 +513,21 @@ verify_nsec( name = (ldns_dnssec_name *) cur_node->data; if (name->nsec) { if (name->nsec_signatures) { - status = verify_single_rr(name->nsec, - name->nsec_signatures, keys); - if (result == LDNS_STATUS_OK) { - result = status; - } + status = verify_single_rr( name->nsec + , name->nsec_signatures + , keys + ); + + result = result ? result : status; } else { - if (verbosity >= 1) { - printf("Error: the NSEC(3) record of "); - ldns_rdf_print(stdout, name->name); - printf(" has no signatures\n"); - } - if (result == LDNS_STATUS_OK) { - result = LDNS_STATUS_ERR; + if (verbosity >= 0) { + fprintf( myerr + , "Error: the NSEC(3) record of " + ); + ldns_rdf_print(myerr, name->name); + fprintf(myerr, " has no signatures\n"); } + result = result ? result : LDNS_STATUS_ERR; } /* check whether the NSEC record points to the right name */ switch (ldns_rr_get_type(name->nsec)) { @@ -395,81 +541,82 @@ verify_nsec( next_node = ldns_dnssec_name_node_next_nonglue( next_node); next_name = (ldns_dnssec_name *)next_node->data; - if (ldns_dname_compare( - next_name->name, - ldns_rr_rdf( - name->nsec, 0)) - != 0) { - printf("Error: the NSEC record for "); - ldns_rdf_print(stdout, name->name); - printf(" points to the wrong next " - "owner name\n"); + if (ldns_dname_compare( next_name->name + , ldns_rr_rdf( name->nsec + , 0 + ) + ) != 0) { + fprintf( myerr + , "Error: the NSEC record for " + ); + ldns_rdf_print(myerr, name->name); + fprintf( myerr + , " points to the wrong next" + " owner name\n" + ); if (verbosity >= 4) { - printf(" : "); - ldns_rdf_print(stdout, - ldns_rr_rdf(name->nsec, - 0)); - printf(" i.s.o. "); - ldns_rdf_print(stdout, - next_name->name); - printf(".\n"); - } - if (result == LDNS_STATUS_OK) { - result = LDNS_STATUS_ERR; + fprintf(myerr, "\t: "); + ldns_rdf_print( myerr + , ldns_rr_rdf( + name->nsec, 0) + ); + fprintf(myerr, " i.s.o. "); + ldns_rdf_print( myerr + , next_name->name + ); + fprintf(myerr, ".\n"); } + result = result ? result + : LDNS_STATUS_ERR; } break; case LDNS_RR_TYPE_NSEC3: /* find the hashed next name in the tree */ - /* this is expensive, do we need to add support - * for this in the structs? (ie. pointer to next - * hashed name?) + /* this is expensive, do we need to add + * support for this in the structs? + * (ie. pointer to next hashed name?) */ - status = verify_next_hashed_name( - zone_nodes, name); - if (result == LDNS_STATUS_OK) { - result = status; - } + status = verify_next_hashed_name( zone_nodes + , name + ); + result = result ? result : status; break; default: break; } } else { - /* todo; do this once and cache result? */ - if (zone_is_nsec3_optout(zone_nodes) && - ( ldns_dnssec_name_is_glue(name) - || ( - ldns_dnssec_rrsets_contains_type( - name->rrsets, LDNS_RR_TYPE_NS) - && !ldns_dnssec_rrsets_contains_type( - name->rrsets, LDNS_RR_TYPE_DS) - ) - )) { + if (zone_is_nsec3_optout + && (ldns_dnssec_name_is_glue(name) + || ( ldns_dnssec_rrsets_contains_type( name->rrsets + , LDNS_RR_TYPE_NS + ) + && !ldns_dnssec_rrsets_contains_type( name->rrsets + , LDNS_RR_TYPE_DS + )))) { + /* TODO */ /* ok, no problem, but we need to remember to check * whether the chain does not actually point to this * name later */ } else { if (verbosity >= 1) { - printf("Error: there is no NSEC(3) for "); - ldns_rdf_print(stdout, name->name); - printf("\n"); - } - if (result == LDNS_STATUS_OK) { - result = LDNS_STATUS_ERR; + fprintf( myerr + , "Error: there is no NSEC(3) for "); + ldns_rdf_print(myerr, name->name); + fprintf(myerr, "\n"); } + result = result ? result : LDNS_STATUS_ERR; } } return result; } static ldns_status -verify_dnssec_name(ldns_rdf *zone_name, - ldns_dnssec_zone* ATTR_UNUSED(zone), - ldns_rbtree_t *zone_nodes, - ldns_rbnode_t *cur_node, - ldns_rr_list *keys, - time_t check_time - ) +verify_dnssec_name( ldns_rdf *zone_name + , ldns_dnssec_zone* ATTR_UNUSED(zone) + , ldns_rbtree_t *zone_nodes + , ldns_rbnode_t *cur_node + , ldns_rr_list *keys + ) { ldns_status result = LDNS_STATUS_OK; ldns_status status; @@ -480,9 +627,9 @@ verify_dnssec_name(ldns_rdf *zone_name, name = (ldns_dnssec_name *) cur_node->data; if (verbosity >= 3) { - printf("Checking: "); - ldns_rdf_print(stdout, name->name); - printf("\n"); + fprintf(myout, "Checking: "); + ldns_rdf_print(myout, name->name); + fprintf(myout, "\n"); } if (ldns_dnssec_name_is_glue(name)) { @@ -490,105 +637,251 @@ verify_dnssec_name(ldns_rdf *zone_name, cur_rrset = name->rrsets; while (cur_rrset) { if (cur_rrset->signatures) { - if (verbosity >= 1) { - printf("Error: "); - ldns_rdf_print(stdout, name->name); - printf("\t"); - print_type(cur_rrset->type); - printf(" has signature(s), " - "but is glue\n"); + if (verbosity >= 0) { + fprintf(myerr, "Error: "); + ldns_rdf_print(myerr, name->name); + fprintf(myerr, "\t"); + print_type(myerr, cur_rrset->type); + fprintf( myerr + , " has signature(s)," + " but is glue\n" + ); } result = LDNS_STATUS_ERR; } cur_rrset = cur_rrset->next; } if (name->nsec) { - if (verbosity >= 1) { - printf("Error: "); - ldns_rdf_print(stdout, name->name); - printf("\thas an NSEC(3), but is glue\n"); + if (verbosity >= 0) { + fprintf(myerr, "Error: "); + ldns_rdf_print(myerr, name->name); + fprintf( myerr + , " has an NSEC(3)," + " but is glue\n" + ); } result = LDNS_STATUS_ERR; } } else { /* not glue, do real verify */ - on_delegation_point = ldns_dnssec_rrsets_contains_type( - name->rrsets, LDNS_RR_TYPE_NS) - && !ldns_dnssec_rrsets_contains_type( - name->rrsets, LDNS_RR_TYPE_SOA); - + on_delegation_point + = ldns_dnssec_rrsets_contains_type( name->rrsets + , LDNS_RR_TYPE_NS + ) + && !ldns_dnssec_rrsets_contains_type( name->rrsets + , LDNS_RR_TYPE_SOA + ); cur_rrset = name->rrsets; while(cur_rrset) { /* Do not check occluded rrsets * on the delegation point */ - if ( ( on_delegation_point && ( - cur_rrset->type == LDNS_RR_TYPE_NS - || cur_rrset->type == LDNS_RR_TYPE_DS)) - || (!on_delegation_point && - cur_rrset->type != LDNS_RR_TYPE_RRSIG - && cur_rrset->type != LDNS_RR_TYPE_NSEC)) { - - status = verify_dnssec_rrset( - zone_name, name->name, - cur_rrset, keys, check_time); - if (status != LDNS_STATUS_OK - && result == LDNS_STATUS_OK) { - result = status; - } + if (( on_delegation_point + && ( cur_rrset->type == LDNS_RR_TYPE_NS + || cur_rrset->type == LDNS_RR_TYPE_DS)) + || ( !on_delegation_point + && cur_rrset->type != LDNS_RR_TYPE_RRSIG + && cur_rrset->type != LDNS_RR_TYPE_NSEC)) { + + status = verify_dnssec_rrset( zone_name + , name->name + , cur_rrset + , keys + ); + result = result ? result : status; } cur_rrset = cur_rrset->next; } - status = verify_nsec(zone_nodes, cur_node, keys); - if (result == LDNS_STATUS_OK) { - result = status; - } + status = verify_nsec( zone_nodes + , cur_node + , keys + ); + result = result ? result : status; } return result; } +static void +add_keys_with_matching_ds( ldns_dnssec_rrsets* from_keys + , ldns_rr_list *dss + , ldns_rr_list *to_keys + ) +{ + size_t i; + ldns_rr* ds_rr; + ldns_dnssec_rrs *cur_key; + + for ( i = 0 + ; i < ldns_rr_list_rr_count(dss) + ; i++ ) { + + if ( ldns_rr_get_type(ds_rr = ldns_rr_list_rr(dss, i)) + == LDNS_RR_TYPE_DS) { + + for ( cur_key = from_keys->rrs + ; cur_key + ; cur_key = cur_key->next ) { + + if (ldns_rr_compare_ds(cur_key->rr, ds_rr)) { + ldns_rr_list_push_rr( to_keys + , cur_key->rr + ); + break; + } + } + } + } +} + +static ldns_status +sigchase( ldns_resolver* res + , ldns_rdf *zone_name + , ldns_dnssec_rrsets *zonekeys + , ldns_rr_list *keys + ) +{ + ldns_dnssec_rrs* cur_key; + ldns_status status; + bool free_resolver = false; + ldns_rdf* parent_name; + ldns_rr_list* parent_keys; + ldns_rr_list* ds_keys; + + add_keys_with_matching_ds(zonekeys, keys, keys); + + /* First try to authenticate the keys offline. + * When do_sigchase is given validation may continue lookup up + * keys online. Reporting the failure of the offline validation + * should then be suppressed. + */ + no_nomatch_msg = do_sigchase; + status = verify_dnssec_rrset( zone_name + , zone_name + , zonekeys + , keys + ); + no_nomatch_msg = false; + + /* Continue online on validation failure when the -S option was given. + */ + if ( do_sigchase + && status == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY + && ldns_dname_label_count(zone_name) > 0 ) { + + if (! res) { + if ((status = ldns_resolver_new_frm_file(&res, NULL))){ + ldns_resolver_free(res); + fprintf( myerr + , "Could not create resolver: %s\n" + , ldns_get_errorstr_by_id(status) + ); + return status; + } + free_resolver = true; + ldns_resolver_set_dnssec(res,1); + ldns_resolver_set_dnssec_cd(res, 1); + } + if ((parent_name = ldns_dname_left_chop(zone_name))) { + /* + * Use the (authenticated) keys of the parent zone ... + */ + parent_keys + = ldns_fetch_valid_domain_keys( res + , parent_name + , keys + , &status + ); + ldns_rdf_deep_free(parent_name); + + /* + * ... to validate the DS for the zone ... + */ + ds_keys = ldns_validate_domain_ds( res + , zone_name + , parent_keys + ); + ldns_rr_list_free(parent_keys); + + /* + * ... to use it to add the KSK to the trusted keys ... + */ + add_keys_with_matching_ds(zonekeys, ds_keys, keys); + ldns_rr_list_free(ds_keys); + + /* + * ... to validate all zonekeys ... + */ + status = verify_dnssec_rrset( zone_name + , zone_name + , zonekeys + , keys + ); + } else { + status = LDNS_STATUS_MEM_ERR; + } + if (free_resolver) { + ldns_resolver_deep_free(res); + } + + } + /* + * ... so they can all be added to our list of trusted keys. + */ + if (status == LDNS_STATUS_OK) + for ( cur_key = zonekeys->rrs + ; cur_key + ; cur_key = cur_key->next + ) + ldns_rr_list_push_rr(keys, cur_key->rr); + return status; +} + static ldns_status -verify_dnssec_zone( - ldns_dnssec_zone *dnssec_zone, - ldns_rdf *zone_name, - bool apexonly, - int percentage, - time_t check_time - ) +verify_dnssec_zone( ldns_dnssec_zone *dnssec_zone + , ldns_rdf *zone_name + , ldns_rr_list *keys + , bool apexonly + , int percentage + ) { - ldns_rr_list *keys; ldns_rbnode_t *cur_node; ldns_dnssec_rrsets *cur_key_rrset; ldns_dnssec_rrs *cur_key; ldns_status status; ldns_status result = LDNS_STATUS_OK; - keys = ldns_rr_list_new(); - cur_key_rrset = ldns_dnssec_zone_find_rrset( - dnssec_zone, zone_name, LDNS_RR_TYPE_DNSKEY); + cur_key_rrset = ldns_dnssec_zone_find_rrset( dnssec_zone, zone_name + , LDNS_RR_TYPE_DNSKEY + ); if (!cur_key_rrset || !cur_key_rrset->rrs) { - if (verbosity >= 1) { - printf("No DNSKEY records at zone apex\n"); + if (verbosity >= 0) { + fprintf( myerr + , "Error: No DNSKEY records at zone apex\n"); } result = LDNS_STATUS_ERR; } else { - cur_key = cur_key_rrset->rrs; - while (cur_key) { - if (verbosity >= 4) { - printf("DNSKEY: "); - ldns_rr_print(stdout, cur_key->rr); - } - ldns_rr_list_push_rr(keys, cur_key->rr); - cur_key = cur_key->next; - } + /* are keys given with -k to use for validation? */ + if (ldns_rr_list_rr_count(keys) > 0) { + if ((result = sigchase( NULL + , zone_name + , cur_key_rrset + , keys + ))) + goto error; + } else + for ( cur_key = cur_key_rrset->rrs + ; cur_key + ; cur_key = cur_key->next + ) + ldns_rr_list_push_rr(keys, cur_key->rr); cur_node = ldns_rbtree_first(dnssec_zone->names); if (cur_node == LDNS_RBTREE_NULL) { - if (verbosity >= 1) { - printf("Empty zone?\n"); + if (verbosity >= 0) { + fprintf(myerr, "Error: Empty zone?\n"); } result = LDNS_STATUS_ERR; } @@ -608,25 +901,21 @@ verify_dnssec_zone( while (cur_node != LDNS_RBTREE_NULL) { /* should we check this one? saves calls to random. */ if (percentage == 100 - || ((random() % 100) - >= 100 - percentage)) { - status = verify_dnssec_name( - zone_name, - dnssec_zone, - dnssec_zone->names, - cur_node, - keys, - check_time); - if (status != LDNS_STATUS_OK - && result == LDNS_STATUS_OK) { - result = status; - } + || ((random() % 100) >= 100 - percentage)) { + status = verify_dnssec_name( zone_name + , dnssec_zone + , dnssec_zone->names + , cur_node + , keys + ); + result = result ? result : status; if (apexonly) break; } cur_node = ldns_rbtree_next(cur_node); } } +error: ldns_rr_list_free(keys); return result; } @@ -636,68 +925,131 @@ main(int argc, char **argv) { char *filename; FILE *fp; - ldns_zone *z; int line_nr = 0; int c; ldns_status s; - ldns_dnssec_zone *dnssec_zone; + ldns_dnssec_zone *dnssec_zone = NULL; ldns_status result = LDNS_STATUS_ERR; bool apexonly = false; int percentage = 100; struct tm tm; - time_t check_time = ldns_time(NULL); + ldns_duration_type *duration; + ldns_rr_list *keys = ldns_rr_list_new(); - while ((c = getopt(argc, argv, "ahvV:p:t:")) != -1) { + check_time = ldns_time(NULL); + myout = stdout; + // myerr = stderr; + myerr = stdout; + + while ((c = getopt(argc, argv, "ae:hi:k:vV:p:St:")) != -1) { switch(c) { case 'a': apexonly = true; break; case 'h': - printf("Usage: %s [OPTIONS] \n", argv[0]); - printf("\tReads the zonefile and checks for DNSSEC " - "errors.\n"); - printf("\nIt checks whether NSEC(3)s are present,"); - printf(" and verifies all signatures\n"); - printf("It also checks the NSEC(3) chain, but it will " - "error on opted-out delegations\n"); - printf("\nOPTIONS:\n"); - printf("\t-a\t\tapex only, check only the zone apex\n"); - printf("\t-p [0-100]\tonly checks this percentage of " - "the zone.\n\t\t\tDefaults to 100\n"); - printf("\t-h\t\tshow this text\n"); - printf("\t-t YYYYMMDDhhmmss | [+|-]offset\n\t\t\t" - "Set the validation time either by an " - "absolute time\n\t\t\tvalue or as an offset " - "in seconds from .\n"); - printf("\t-v\t\tshows the version and exits\n"); - printf("\t-V [0-5]\tset verbosity level (default 3)\n"); - printf("\nif no file is given standard input is " - "read\n"); + printf( "Usage: %s [OPTIONS] \n", argv[0] ); + printf( "\tReads the zonefile and checks for DNSSEC " + "errors.\n" + ); + printf( "\nIt checks whether NSEC(3)s are present, " + "and verifies all signatures\n" + ); + printf( "It also checks the NSEC(3) chain, but it " + "will error on opted-out delegations\n" + ); + printf( "\nOPTIONS:\n"); + printf( "\t-h\t\tshow this text\n"); + printf( "\t-a\t\tapex only, " + "check only the zone apex\n" + ); + printf( "\t-e \tsignatures may not expire " + "within this period.\n" + ); + printf( "\t-i \tsignatures must have been " + "valid at least this long.\n" + ); + printf( "\t-k \tspecify a file that contains a " + "trusted DNSKEY or DS rr.\n\t\t\t" + "This option may be given more than " + "once.\n" + ); + printf( "\t-p [0-100]\tonly checks this percentage of " + "the zone.\n\t\t\tDefaults to 100\n" + ); + printf( "\t-S\t\tchase signature(s) to a known key. " + "The network may be\n\t\t\taccessed to " + "validate the zone's DNSKEYs. (implies -k)\n" + ); + printf( "\t-t YYYYMMDDhhmmss | [+|-]offset\n\t\t\t" + "set the validation time either by an " + "absolute time\n\t\t\tvalue or as an " + "offset in seconds from .\n\t\t\t" + "For data that came from the network (while " + "chasing),\n\t\t\tsystem time will be used " + "for validating it regardless.\n" + ); + printf( "\t-v\t\tshows the version and exits\n"); + printf( "\t-V [0-5]\tset verbosity level (default 3)\n" + ); + printf( "\ns are given " + "in ISO 8601 duration format: " + "P[n]Y[n]M[n]DT[n]H[n]M[n]S\n" + ); + printf( "\nif no file is given " + "standard input is read\n" + ); exit(EXIT_SUCCESS); break; - case 'v': - printf("verify-zone version %s (ldns version %s)\n", - LDNS_VERSION, ldns_version()); - exit(EXIT_SUCCESS); + case 'e': + case 'i': + duration = ldns_duration_create_from_string(optarg); + if (!duration) { + fprintf( myerr + , " should be in ISO 8601 " + "duration format: " + "P[n]Y[n]M[n]DT[n]H[n]M[n]S\n" + ); + exit(EXIT_FAILURE); + } + if (c == 'e') + expiration_offset + = ldns_duration2time(duration); + else + inception_offset + = ldns_duration2time(duration); break; - case 'V': - verbosity = atoi(optarg); + case 'k': + s = read_key_file(optarg, keys); + if (s != LDNS_STATUS_OK) { + fprintf( myerr + , "Could not parse key file %s: %s\n" + , optarg + , get_errorstr_by_id(s) + ); + exit(EXIT_FAILURE); + } break; case 'p': percentage = atoi(optarg); if (percentage < 0 || percentage > 100) { - fprintf(stderr, "percentage needs to fall " - "between 0..100\n"); + fprintf( myerr + , "percentage needs to fall " + "between 0..100\n" + ); exit(EXIT_FAILURE); } srandom(time(NULL) ^ getpid()); break; + case 'S': + do_sigchase = true; + /* may chase */ + break; case 't': - if (strlen(optarg) == 14 && sscanf(optarg, - "%4d%2d%2d%2d%2d%2d", - &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, - &tm.tm_min, &tm.tm_sec) == 6) { + if (strlen(optarg) == 14 + && sscanf(optarg, "%4d%2d%2d%2d%2d%2d" + , &tm.tm_year, &tm.tm_mon + , &tm.tm_mday, &tm.tm_hour + , &tm.tm_min , &tm.tm_sec ) == 6) { tm.tm_year -= 1900; tm.tm_mon--; check_time = mktime_from_utc(&tm); @@ -705,8 +1057,23 @@ main(int argc, char **argv) else { check_time += atoi(optarg); } + break; + case 'v': + printf( "verify-zone version %s (ldns version %s)\n" + , LDNS_VERSION + , ldns_version() + ); + exit(EXIT_SUCCESS); + break; + case 'V': + verbosity = atoi(optarg); + break; } } + if (do_sigchase && ldns_rr_list_rr_count(keys) == 0) { + fprintf(myerr, "Unable to chase signature without keys.\n"); + exit(EXIT_SUCCESS); + } argc -= optind; argv += optind; @@ -718,66 +1085,87 @@ main(int argc, char **argv) fp = fopen(filename, "r"); if (!fp) { - fprintf(stderr, - "Unable to open %s: %s\n", - filename, - strerror(errno)); + fprintf( myerr + , "Unable to open %s: %s\n" + , filename + , strerror(errno) + ); exit(EXIT_FAILURE); } } - s = ldns_zone_new_frm_fp_l(&z, fp, NULL, 0, LDNS_RR_CLASS_IN, &line_nr); + s = dnssec_zone_new_frm_fp_l( &dnssec_zone + , fp + , NULL + , 0 + , LDNS_RR_CLASS_IN + , &line_nr + ); if (s == LDNS_STATUS_OK) { - if (!ldns_zone_soa(z)) { - fprintf(stderr, "; Error: no SOA in the zone\n"); + if (! dnssec_zone->soa) { + fprintf(myerr, "; Error: no SOA in the zone\n"); exit(1); } - dnssec_zone = create_dnssec_zone(z); result = ldns_dnssec_zone_mark_glue(dnssec_zone); if (result != LDNS_STATUS_OK) { if (verbosity >= 1) { - printf("There were errors identifying the glue " - "in the zone\n"); + fprintf( myerr + , "There were errors identifying the " + "glue in the zone\n" + ); } } if (verbosity >= 5) { - ldns_dnssec_zone_print(stdout, dnssec_zone); + ldns_dnssec_zone_print(myout, dnssec_zone); } - result = verify_dnssec_zone(dnssec_zone, - ldns_rr_owner(ldns_zone_soa(z)), - apexonly, percentage, check_time); + result = verify_dnssec_zone( dnssec_zone + , dnssec_zone->soa->name + , keys + , apexonly + , percentage + ); if (result == LDNS_STATUS_OK) { - if (verbosity >= 1) { - printf("Zone is verified and complete\n"); + if (verbosity >= 3) { + fprintf( myout + , "Zone is verified and complete\n" + ); } } else { if (verbosity >= 1) { - printf("There were errors in the zone\n"); + fprintf( myerr + , "There were errors in the zone\n" + ); } } - ldns_zone_free(z); ldns_dnssec_zone_deep_free(dnssec_zone); } else { - fprintf(stderr, "%s at %d\n", - ldns_get_errorstr_by_id(s), - line_nr); + fprintf( myerr + , "%s at %d\n" + , get_errorstr_by_id(s) + , line_nr + ); exit(EXIT_FAILURE); } fclose(fp); exit(result); } + #else + int main(int argc, char **argv) { - fprintf(stderr, "ldns-verify-zone needs OpenSSL support, " - "which has not been compiled in\n"); + fprintf( stderr + , "ldns-verify-zone needs OpenSSL support, " + "which has not been compiled in\n" + ); return 1; } #endif /* HAVE_SSL */ +