diff options
Diffstat (limited to 'tests')
309 files changed, 30433 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..86f30f2 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,240 @@ +AM_CPPFLAGS = \ + -include $(top_builddir)/src/config.h \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/libdnssec \ + -I$(top_srcdir)/src/libdnssec/shared \ + $(gnutls_CFLAGS) + +LDADD = \ + libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la + +if HAVE_DAEMON +LDADD += \ + $(top_builddir)/src/libknotd.la +endif HAVE_DAEMON + +EXTRA_DIST = \ + tap/libtap.sh \ + libdnssec/sample_keys.h \ + knot/semantic_check_data \ + knot/test_semantic_check.in \ + libzscanner/data \ + libzscanner/test_zscanner.in \ + libzscanner/TESTS + +check_LTLIBRARIES = libtap.la + +libtap_la_SOURCES = \ + tap/basic.c \ + tap/basic.h \ + tap/files.c \ + tap/files.h \ + tap/float.c \ + tap/float.h \ + tap/macros.h + +EXTRA_PROGRAMS = tap/runtests + +tap_runtests_LDADD = + +check_PROGRAMS = \ + contrib/test_base32hex \ + contrib/test_base64 \ + contrib/test_dynarray \ + contrib/test_heap \ + contrib/test_net \ + contrib/test_net_shortwrite \ + contrib/test_qp-trie \ + contrib/test_siphash \ + contrib/test_sockaddr \ + contrib/test_string \ + contrib/test_strtonum \ + contrib/test_time \ + contrib/test_wire_ctx + +check_PROGRAMS += \ + libdnssec/test_binary \ + libdnssec/test_crypto \ + libdnssec/test_key \ + libdnssec/test_key_algorithm \ + libdnssec/test_key_ds \ + libdnssec/test_keyid \ + libdnssec/test_keystore_pkcs11 \ + libdnssec/test_keystore_pkcs8 \ + libdnssec/test_keystore_pkcs8_dir \ + libdnssec/test_keytag \ + libdnssec/test_list \ + libdnssec/test_nsec_bitmap \ + libdnssec/test_nsec_hash \ + libdnssec/test_random \ + libdnssec/test_sign \ + libdnssec/test_sign_der \ + libdnssec/test_shared_bignum \ + libdnssec/test_shared_dname \ + libdnssec/test_tsig + +if HAVE_DAEMON +check_PROGRAMS += \ + knot/test_acl \ + knot/test_changeset \ + knot/test_conf \ + knot/test_conf_tools \ + knot/test_confdb \ + knot/test_confio \ + knot/test_dthreads \ + knot/test_fdset \ + knot/test_journal \ + knot/test_kasp_db \ + knot/test_node \ + knot/test_process_query \ + knot/test_query_module \ + knot/test_requestor \ + knot/test_server \ + knot/test_worker_pool \ + knot/test_worker_queue \ + knot/test_zone-tree \ + knot/test_zone-update \ + knot/test_zone_events \ + knot/test_zone_serial \ + knot/test_zone_timers \ + knot/test_zonedb + +knot_test_acl_SOURCES = \ + knot/test_acl.c \ + knot/test_conf.h + +knot_test_conf_SOURCES = \ + knot/test_conf.c \ + knot/test_conf.h + +knot_test_confdb_SOURCES = \ + knot/test_confdb.c \ + knot/test_conf.h + +knot_test_confio_SOURCES = \ + knot/test_confio.c \ + knot/test_conf.h + +knot_test_process_query_SOURCES = \ + knot/test_process_query.c \ + knot/test_server.h \ + knot/test_conf.h +endif HAVE_DAEMON + +check_PROGRAMS += \ + libknot/test_control \ + libknot/test_cookies \ + libknot/test_db \ + libknot/test_descriptor \ + libknot/test_dname \ + libknot/test_edns \ + libknot/test_edns_ecs \ + libknot/test_endian \ + libknot/test_lookup \ + libknot/test_pkt \ + libknot/test_rdata \ + libknot/test_rdataset \ + libknot/test_rrset \ + libknot/test_rrset-wire \ + libknot/test_tsig \ + libknot/test_yparser \ + libknot/test_ypschema \ + libknot/test_yptrafo \ + libknot/test_wire + +if HAVE_LIBUTILS +check_PROGRAMS += \ + utils/test_cert \ + utils/test_lookup +endif HAVE_LIBUTILS + +if HAVE_DAEMON +if STATIC_MODULE_onlinesign +check_PROGRAMS += \ + modules/test_onlinesign +else +if SHARED_MODULE_onlinesign +check_PROGRAMS += \ + modules/test_onlinesign +endif +endif + +if STATIC_MODULE_rrl +check_PROGRAMS += \ + modules/test_rrl +else +if SHARED_MODULE_rrl +check_PROGRAMS += \ + modules/test_rrl +endif +endif +endif HAVE_DAEMON + +libdnssec_test_keystore_pkcs11_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -DLIBDIR='"$(libdir)"' + +if HAVE_LIBUTILS +utils_test_lookup_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(libedit_CFLAGS) + +utils_test_lookup_LDADD = \ + libtap.la \ + $(top_builddir)/src/libknotus.la \ + $(libedit_LIBS) + +utils_test_cert_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(libedit_CFLAGS) + +utils_test_cert_LDADD = \ + libtap.la \ + $(top_builddir)/src/libknotus.la \ + $(libedit_LIBS) +endif HAVE_LIBUTILS + +EXTRA_PROGRAMS += libzscanner/zscanner-tool + +libzscanner_zscanner_tool_SOURCES = \ + libzscanner/zscanner-tool.c \ + libzscanner/processing.h \ + libzscanner/processing.c + +check_SCRIPTS = \ + libzscanner/test_zscanner + +edit = $(SED) \ + -e 's|@top_srcdir[@]|$(abs_top_srcdir)|g' \ + -e 's|@top_builddir[@]|$(abs_top_builddir)|g' + +if HAVE_LIBUTILS +check_SCRIPTS += \ + knot/test_semantic_check + +knot/test_semantic_check: + @$(edit) < $(top_srcdir)/tests/$@.in > $(top_builddir)/tests/$@ + @chmod +x $(top_builddir)/tests/$@ +endif HAVE_LIBUTILS + +libzscanner/test_zscanner: libzscanner/zscanner-tool + @$(edit) < $(top_srcdir)/tests/$@.in > $(top_builddir)/tests/$@ + @chmod +x $(top_builddir)/tests/$@ + +CLEANFILES = $(check_SCRIPTS) $(EXTRA_PROGRAMS) runtests.log + +check-compile: $(check_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) $(check_SCRIPTS) + +AM_V_RUNTESTS = $(am__v_RUNTESTS_@AM_V@) +am__v_RUNTESTS_ = $(am__v_RUNTESTS_@AM_DEFAULT_V@) +am__v_RUNTESTS_0 = +am__v_RUNTESTS_1 = RET=$$?; if [ "$$RET" != "0" ]; then cat "$(builddir)/runtests.log"; exit $$RET; fi +check-local: $(check_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) $(check_SCRIPTS) + @$(top_builddir)/tests/tap/runtests -s $(srcdir) -b $(builddir) \ + -L $(builddir)/runtests.log $(check_PROGRAMS) $(check_SCRIPTS); \ + $(AM_V_RUNTESTS) diff --git a/tests/Makefile.in b/tests/Makefile.in new file mode 100644 index 0000000..3ec7322 --- /dev/null +++ b/tests/Makefile.in @@ -0,0 +1,2383 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@HAVE_DAEMON_TRUE@am__append_1 = \ +@HAVE_DAEMON_TRUE@ $(top_builddir)/src/libknotd.la + +EXTRA_PROGRAMS = tap/runtests$(EXEEXT) \ + libzscanner/zscanner-tool$(EXEEXT) +check_PROGRAMS = contrib/test_base32hex$(EXEEXT) \ + contrib/test_base64$(EXEEXT) contrib/test_dynarray$(EXEEXT) \ + contrib/test_heap$(EXEEXT) contrib/test_net$(EXEEXT) \ + contrib/test_net_shortwrite$(EXEEXT) \ + contrib/test_qp-trie$(EXEEXT) contrib/test_siphash$(EXEEXT) \ + contrib/test_sockaddr$(EXEEXT) contrib/test_string$(EXEEXT) \ + contrib/test_strtonum$(EXEEXT) contrib/test_time$(EXEEXT) \ + contrib/test_wire_ctx$(EXEEXT) libdnssec/test_binary$(EXEEXT) \ + libdnssec/test_crypto$(EXEEXT) libdnssec/test_key$(EXEEXT) \ + libdnssec/test_key_algorithm$(EXEEXT) \ + libdnssec/test_key_ds$(EXEEXT) libdnssec/test_keyid$(EXEEXT) \ + libdnssec/test_keystore_pkcs11$(EXEEXT) \ + libdnssec/test_keystore_pkcs8$(EXEEXT) \ + libdnssec/test_keystore_pkcs8_dir$(EXEEXT) \ + libdnssec/test_keytag$(EXEEXT) libdnssec/test_list$(EXEEXT) \ + libdnssec/test_nsec_bitmap$(EXEEXT) \ + libdnssec/test_nsec_hash$(EXEEXT) \ + libdnssec/test_random$(EXEEXT) libdnssec/test_sign$(EXEEXT) \ + libdnssec/test_sign_der$(EXEEXT) \ + libdnssec/test_shared_bignum$(EXEEXT) \ + libdnssec/test_shared_dname$(EXEEXT) \ + libdnssec/test_tsig$(EXEEXT) $(am__EXEEXT_1) \ + libknot/test_control$(EXEEXT) libknot/test_cookies$(EXEEXT) \ + libknot/test_db$(EXEEXT) libknot/test_descriptor$(EXEEXT) \ + libknot/test_dname$(EXEEXT) libknot/test_edns$(EXEEXT) \ + libknot/test_edns_ecs$(EXEEXT) libknot/test_endian$(EXEEXT) \ + libknot/test_lookup$(EXEEXT) libknot/test_pkt$(EXEEXT) \ + libknot/test_rdata$(EXEEXT) libknot/test_rdataset$(EXEEXT) \ + libknot/test_rrset$(EXEEXT) libknot/test_rrset-wire$(EXEEXT) \ + libknot/test_tsig$(EXEEXT) libknot/test_yparser$(EXEEXT) \ + libknot/test_ypschema$(EXEEXT) libknot/test_yptrafo$(EXEEXT) \ + libknot/test_wire$(EXEEXT) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) +@HAVE_DAEMON_TRUE@am__append_2 = \ +@HAVE_DAEMON_TRUE@ knot/test_acl \ +@HAVE_DAEMON_TRUE@ knot/test_changeset \ +@HAVE_DAEMON_TRUE@ knot/test_conf \ +@HAVE_DAEMON_TRUE@ knot/test_conf_tools \ +@HAVE_DAEMON_TRUE@ knot/test_confdb \ +@HAVE_DAEMON_TRUE@ knot/test_confio \ +@HAVE_DAEMON_TRUE@ knot/test_dthreads \ +@HAVE_DAEMON_TRUE@ knot/test_fdset \ +@HAVE_DAEMON_TRUE@ knot/test_journal \ +@HAVE_DAEMON_TRUE@ knot/test_kasp_db \ +@HAVE_DAEMON_TRUE@ knot/test_node \ +@HAVE_DAEMON_TRUE@ knot/test_process_query \ +@HAVE_DAEMON_TRUE@ knot/test_query_module \ +@HAVE_DAEMON_TRUE@ knot/test_requestor \ +@HAVE_DAEMON_TRUE@ knot/test_server \ +@HAVE_DAEMON_TRUE@ knot/test_worker_pool \ +@HAVE_DAEMON_TRUE@ knot/test_worker_queue \ +@HAVE_DAEMON_TRUE@ knot/test_zone-tree \ +@HAVE_DAEMON_TRUE@ knot/test_zone-update \ +@HAVE_DAEMON_TRUE@ knot/test_zone_events \ +@HAVE_DAEMON_TRUE@ knot/test_zone_serial \ +@HAVE_DAEMON_TRUE@ knot/test_zone_timers \ +@HAVE_DAEMON_TRUE@ knot/test_zonedb + +@HAVE_LIBUTILS_TRUE@am__append_3 = \ +@HAVE_LIBUTILS_TRUE@ utils/test_cert \ +@HAVE_LIBUTILS_TRUE@ utils/test_lookup + +@HAVE_DAEMON_TRUE@@STATIC_MODULE_onlinesign_TRUE@am__append_4 = \ +@HAVE_DAEMON_TRUE@@STATIC_MODULE_onlinesign_TRUE@ modules/test_onlinesign + +@HAVE_DAEMON_TRUE@@SHARED_MODULE_onlinesign_TRUE@@STATIC_MODULE_onlinesign_FALSE@am__append_5 = \ +@HAVE_DAEMON_TRUE@@SHARED_MODULE_onlinesign_TRUE@@STATIC_MODULE_onlinesign_FALSE@ modules/test_onlinesign + +@HAVE_DAEMON_TRUE@@STATIC_MODULE_rrl_TRUE@am__append_6 = \ +@HAVE_DAEMON_TRUE@@STATIC_MODULE_rrl_TRUE@ modules/test_rrl + +@HAVE_DAEMON_TRUE@@SHARED_MODULE_rrl_TRUE@@STATIC_MODULE_rrl_FALSE@am__append_7 = \ +@HAVE_DAEMON_TRUE@@SHARED_MODULE_rrl_TRUE@@STATIC_MODULE_rrl_FALSE@ modules/test_rrl + +@HAVE_LIBUTILS_TRUE@am__append_8 = \ +@HAVE_LIBUTILS_TRUE@ knot/test_semantic_check + +subdir = tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_clang.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_compare_version.m4 \ + $(top_srcdir)/m4/code-coverage.m4 \ + $(top_srcdir)/m4/knot-lib-version.m4 \ + $(top_srcdir)/m4/knot-module.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/sanitizer.m4 $(top_srcdir)/m4/visibility.m4 \ + $(top_srcdir)/m4/knot-version.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +libtap_la_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp +am_libtap_la_OBJECTS = tap/basic.lo tap/files.lo tap/float.lo +libtap_la_OBJECTS = $(am_libtap_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +@HAVE_DAEMON_TRUE@am__EXEEXT_1 = knot/test_acl$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_changeset$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_conf$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_conf_tools$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_confdb$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_confio$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_dthreads$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_fdset$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_journal$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_kasp_db$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_node$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_process_query$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_query_module$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_requestor$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_server$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_worker_pool$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_worker_queue$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone-tree$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone-update$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone_events$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone_serial$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone_timers$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zonedb$(EXEEXT) +@HAVE_LIBUTILS_TRUE@am__EXEEXT_2 = utils/test_cert$(EXEEXT) \ +@HAVE_LIBUTILS_TRUE@ utils/test_lookup$(EXEEXT) +@HAVE_DAEMON_TRUE@@STATIC_MODULE_onlinesign_TRUE@am__EXEEXT_3 = modules/test_onlinesign$(EXEEXT) +@HAVE_DAEMON_TRUE@@SHARED_MODULE_onlinesign_TRUE@@STATIC_MODULE_onlinesign_FALSE@am__EXEEXT_4 = modules/test_onlinesign$(EXEEXT) +@HAVE_DAEMON_TRUE@@STATIC_MODULE_rrl_TRUE@am__EXEEXT_5 = modules/test_rrl$(EXEEXT) +@HAVE_DAEMON_TRUE@@SHARED_MODULE_rrl_TRUE@@STATIC_MODULE_rrl_FALSE@am__EXEEXT_6 = modules/test_rrl$(EXEEXT) +contrib_test_base32hex_SOURCES = contrib/test_base32hex.c +contrib_test_base32hex_OBJECTS = contrib/test_base32hex.$(OBJEXT) +contrib_test_base32hex_LDADD = $(LDADD) +contrib_test_base32hex_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_base64_SOURCES = contrib/test_base64.c +contrib_test_base64_OBJECTS = contrib/test_base64.$(OBJEXT) +contrib_test_base64_LDADD = $(LDADD) +contrib_test_base64_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_dynarray_SOURCES = contrib/test_dynarray.c +contrib_test_dynarray_OBJECTS = contrib/test_dynarray.$(OBJEXT) +contrib_test_dynarray_LDADD = $(LDADD) +contrib_test_dynarray_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_heap_SOURCES = contrib/test_heap.c +contrib_test_heap_OBJECTS = contrib/test_heap.$(OBJEXT) +contrib_test_heap_LDADD = $(LDADD) +contrib_test_heap_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_net_SOURCES = contrib/test_net.c +contrib_test_net_OBJECTS = contrib/test_net.$(OBJEXT) +contrib_test_net_LDADD = $(LDADD) +contrib_test_net_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_net_shortwrite_SOURCES = contrib/test_net_shortwrite.c +contrib_test_net_shortwrite_OBJECTS = \ + contrib/test_net_shortwrite.$(OBJEXT) +contrib_test_net_shortwrite_LDADD = $(LDADD) +contrib_test_net_shortwrite_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_qp_trie_SOURCES = contrib/test_qp-trie.c +contrib_test_qp_trie_OBJECTS = contrib/test_qp-trie.$(OBJEXT) +contrib_test_qp_trie_LDADD = $(LDADD) +contrib_test_qp_trie_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_siphash_SOURCES = contrib/test_siphash.c +contrib_test_siphash_OBJECTS = contrib/test_siphash.$(OBJEXT) +contrib_test_siphash_LDADD = $(LDADD) +contrib_test_siphash_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_sockaddr_SOURCES = contrib/test_sockaddr.c +contrib_test_sockaddr_OBJECTS = contrib/test_sockaddr.$(OBJEXT) +contrib_test_sockaddr_LDADD = $(LDADD) +contrib_test_sockaddr_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_string_SOURCES = contrib/test_string.c +contrib_test_string_OBJECTS = contrib/test_string.$(OBJEXT) +contrib_test_string_LDADD = $(LDADD) +contrib_test_string_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_strtonum_SOURCES = contrib/test_strtonum.c +contrib_test_strtonum_OBJECTS = contrib/test_strtonum.$(OBJEXT) +contrib_test_strtonum_LDADD = $(LDADD) +contrib_test_strtonum_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_time_SOURCES = contrib/test_time.c +contrib_test_time_OBJECTS = contrib/test_time.$(OBJEXT) +contrib_test_time_LDADD = $(LDADD) +contrib_test_time_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +contrib_test_wire_ctx_SOURCES = contrib/test_wire_ctx.c +contrib_test_wire_ctx_OBJECTS = contrib/test_wire_ctx.$(OBJEXT) +contrib_test_wire_ctx_LDADD = $(LDADD) +contrib_test_wire_ctx_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +am__knot_test_acl_SOURCES_DIST = knot/test_acl.c knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_acl_OBJECTS = knot/test_acl.$(OBJEXT) +knot_test_acl_OBJECTS = $(am_knot_test_acl_OBJECTS) +knot_test_acl_LDADD = $(LDADD) +knot_test_acl_DEPENDENCIES = libtap.la $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_changeset_SOURCES = knot/test_changeset.c +knot_test_changeset_OBJECTS = knot/test_changeset.$(OBJEXT) +knot_test_changeset_LDADD = $(LDADD) +knot_test_changeset_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +am__knot_test_conf_SOURCES_DIST = knot/test_conf.c knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_conf_OBJECTS = \ +@HAVE_DAEMON_TRUE@ knot/test_conf.$(OBJEXT) +knot_test_conf_OBJECTS = $(am_knot_test_conf_OBJECTS) +knot_test_conf_LDADD = $(LDADD) +knot_test_conf_DEPENDENCIES = libtap.la $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_conf_tools_SOURCES = knot/test_conf_tools.c +knot_test_conf_tools_OBJECTS = knot/test_conf_tools.$(OBJEXT) +knot_test_conf_tools_LDADD = $(LDADD) +knot_test_conf_tools_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +am__knot_test_confdb_SOURCES_DIST = knot/test_confdb.c \ + knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_confdb_OBJECTS = \ +@HAVE_DAEMON_TRUE@ knot/test_confdb.$(OBJEXT) +knot_test_confdb_OBJECTS = $(am_knot_test_confdb_OBJECTS) +knot_test_confdb_LDADD = $(LDADD) +knot_test_confdb_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +am__knot_test_confio_SOURCES_DIST = knot/test_confio.c \ + knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_confio_OBJECTS = \ +@HAVE_DAEMON_TRUE@ knot/test_confio.$(OBJEXT) +knot_test_confio_OBJECTS = $(am_knot_test_confio_OBJECTS) +knot_test_confio_LDADD = $(LDADD) +knot_test_confio_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_dthreads_SOURCES = knot/test_dthreads.c +knot_test_dthreads_OBJECTS = knot/test_dthreads.$(OBJEXT) +knot_test_dthreads_LDADD = $(LDADD) +knot_test_dthreads_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_fdset_SOURCES = knot/test_fdset.c +knot_test_fdset_OBJECTS = knot/test_fdset.$(OBJEXT) +knot_test_fdset_LDADD = $(LDADD) +knot_test_fdset_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_journal_SOURCES = knot/test_journal.c +knot_test_journal_OBJECTS = knot/test_journal.$(OBJEXT) +knot_test_journal_LDADD = $(LDADD) +knot_test_journal_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_kasp_db_SOURCES = knot/test_kasp_db.c +knot_test_kasp_db_OBJECTS = knot/test_kasp_db.$(OBJEXT) +knot_test_kasp_db_LDADD = $(LDADD) +knot_test_kasp_db_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_node_SOURCES = knot/test_node.c +knot_test_node_OBJECTS = knot/test_node.$(OBJEXT) +knot_test_node_LDADD = $(LDADD) +knot_test_node_DEPENDENCIES = libtap.la $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +am__knot_test_process_query_SOURCES_DIST = knot/test_process_query.c \ + knot/test_server.h knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_process_query_OBJECTS = \ +@HAVE_DAEMON_TRUE@ knot/test_process_query.$(OBJEXT) +knot_test_process_query_OBJECTS = \ + $(am_knot_test_process_query_OBJECTS) +knot_test_process_query_LDADD = $(LDADD) +knot_test_process_query_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_query_module_SOURCES = knot/test_query_module.c +knot_test_query_module_OBJECTS = knot/test_query_module.$(OBJEXT) +knot_test_query_module_LDADD = $(LDADD) +knot_test_query_module_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_requestor_SOURCES = knot/test_requestor.c +knot_test_requestor_OBJECTS = knot/test_requestor.$(OBJEXT) +knot_test_requestor_LDADD = $(LDADD) +knot_test_requestor_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_server_SOURCES = knot/test_server.c +knot_test_server_OBJECTS = knot/test_server.$(OBJEXT) +knot_test_server_LDADD = $(LDADD) +knot_test_server_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_worker_pool_SOURCES = knot/test_worker_pool.c +knot_test_worker_pool_OBJECTS = knot/test_worker_pool.$(OBJEXT) +knot_test_worker_pool_LDADD = $(LDADD) +knot_test_worker_pool_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_worker_queue_SOURCES = knot/test_worker_queue.c +knot_test_worker_queue_OBJECTS = knot/test_worker_queue.$(OBJEXT) +knot_test_worker_queue_LDADD = $(LDADD) +knot_test_worker_queue_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_zone_tree_SOURCES = knot/test_zone-tree.c +knot_test_zone_tree_OBJECTS = knot/test_zone-tree.$(OBJEXT) +knot_test_zone_tree_LDADD = $(LDADD) +knot_test_zone_tree_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_zone_update_SOURCES = knot/test_zone-update.c +knot_test_zone_update_OBJECTS = knot/test_zone-update.$(OBJEXT) +knot_test_zone_update_LDADD = $(LDADD) +knot_test_zone_update_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_zone_events_SOURCES = knot/test_zone_events.c +knot_test_zone_events_OBJECTS = knot/test_zone_events.$(OBJEXT) +knot_test_zone_events_LDADD = $(LDADD) +knot_test_zone_events_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_zone_serial_SOURCES = knot/test_zone_serial.c +knot_test_zone_serial_OBJECTS = knot/test_zone_serial.$(OBJEXT) +knot_test_zone_serial_LDADD = $(LDADD) +knot_test_zone_serial_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_zone_timers_SOURCES = knot/test_zone_timers.c +knot_test_zone_timers_OBJECTS = knot/test_zone_timers.$(OBJEXT) +knot_test_zone_timers_LDADD = $(LDADD) +knot_test_zone_timers_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +knot_test_zonedb_SOURCES = knot/test_zonedb.c +knot_test_zonedb_OBJECTS = knot/test_zonedb.$(OBJEXT) +knot_test_zonedb_LDADD = $(LDADD) +knot_test_zonedb_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_binary_SOURCES = libdnssec/test_binary.c +libdnssec_test_binary_OBJECTS = libdnssec/test_binary.$(OBJEXT) +libdnssec_test_binary_LDADD = $(LDADD) +libdnssec_test_binary_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_crypto_SOURCES = libdnssec/test_crypto.c +libdnssec_test_crypto_OBJECTS = libdnssec/test_crypto.$(OBJEXT) +libdnssec_test_crypto_LDADD = $(LDADD) +libdnssec_test_crypto_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_key_SOURCES = libdnssec/test_key.c +libdnssec_test_key_OBJECTS = libdnssec/test_key.$(OBJEXT) +libdnssec_test_key_LDADD = $(LDADD) +libdnssec_test_key_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_key_algorithm_SOURCES = libdnssec/test_key_algorithm.c +libdnssec_test_key_algorithm_OBJECTS = \ + libdnssec/test_key_algorithm.$(OBJEXT) +libdnssec_test_key_algorithm_LDADD = $(LDADD) +libdnssec_test_key_algorithm_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_key_ds_SOURCES = libdnssec/test_key_ds.c +libdnssec_test_key_ds_OBJECTS = libdnssec/test_key_ds.$(OBJEXT) +libdnssec_test_key_ds_LDADD = $(LDADD) +libdnssec_test_key_ds_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_keyid_SOURCES = libdnssec/test_keyid.c +libdnssec_test_keyid_OBJECTS = libdnssec/test_keyid.$(OBJEXT) +libdnssec_test_keyid_LDADD = $(LDADD) +libdnssec_test_keyid_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_keystore_pkcs11_SOURCES = \ + libdnssec/test_keystore_pkcs11.c +libdnssec_test_keystore_pkcs11_OBJECTS = libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.$(OBJEXT) +libdnssec_test_keystore_pkcs11_LDADD = $(LDADD) +libdnssec_test_keystore_pkcs11_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_keystore_pkcs8_SOURCES = \ + libdnssec/test_keystore_pkcs8.c +libdnssec_test_keystore_pkcs8_OBJECTS = \ + libdnssec/test_keystore_pkcs8.$(OBJEXT) +libdnssec_test_keystore_pkcs8_LDADD = $(LDADD) +libdnssec_test_keystore_pkcs8_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_keystore_pkcs8_dir_SOURCES = \ + libdnssec/test_keystore_pkcs8_dir.c +libdnssec_test_keystore_pkcs8_dir_OBJECTS = \ + libdnssec/test_keystore_pkcs8_dir.$(OBJEXT) +libdnssec_test_keystore_pkcs8_dir_LDADD = $(LDADD) +libdnssec_test_keystore_pkcs8_dir_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_keytag_SOURCES = libdnssec/test_keytag.c +libdnssec_test_keytag_OBJECTS = libdnssec/test_keytag.$(OBJEXT) +libdnssec_test_keytag_LDADD = $(LDADD) +libdnssec_test_keytag_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_list_SOURCES = libdnssec/test_list.c +libdnssec_test_list_OBJECTS = libdnssec/test_list.$(OBJEXT) +libdnssec_test_list_LDADD = $(LDADD) +libdnssec_test_list_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_nsec_bitmap_SOURCES = libdnssec/test_nsec_bitmap.c +libdnssec_test_nsec_bitmap_OBJECTS = \ + libdnssec/test_nsec_bitmap.$(OBJEXT) +libdnssec_test_nsec_bitmap_LDADD = $(LDADD) +libdnssec_test_nsec_bitmap_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_nsec_hash_SOURCES = libdnssec/test_nsec_hash.c +libdnssec_test_nsec_hash_OBJECTS = libdnssec/test_nsec_hash.$(OBJEXT) +libdnssec_test_nsec_hash_LDADD = $(LDADD) +libdnssec_test_nsec_hash_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_random_SOURCES = libdnssec/test_random.c +libdnssec_test_random_OBJECTS = libdnssec/test_random.$(OBJEXT) +libdnssec_test_random_LDADD = $(LDADD) +libdnssec_test_random_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_shared_bignum_SOURCES = libdnssec/test_shared_bignum.c +libdnssec_test_shared_bignum_OBJECTS = \ + libdnssec/test_shared_bignum.$(OBJEXT) +libdnssec_test_shared_bignum_LDADD = $(LDADD) +libdnssec_test_shared_bignum_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_shared_dname_SOURCES = libdnssec/test_shared_dname.c +libdnssec_test_shared_dname_OBJECTS = \ + libdnssec/test_shared_dname.$(OBJEXT) +libdnssec_test_shared_dname_LDADD = $(LDADD) +libdnssec_test_shared_dname_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_sign_SOURCES = libdnssec/test_sign.c +libdnssec_test_sign_OBJECTS = libdnssec/test_sign.$(OBJEXT) +libdnssec_test_sign_LDADD = $(LDADD) +libdnssec_test_sign_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_sign_der_SOURCES = libdnssec/test_sign_der.c +libdnssec_test_sign_der_OBJECTS = libdnssec/test_sign_der.$(OBJEXT) +libdnssec_test_sign_der_LDADD = $(LDADD) +libdnssec_test_sign_der_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libdnssec_test_tsig_SOURCES = libdnssec/test_tsig.c +libdnssec_test_tsig_OBJECTS = libdnssec/test_tsig.$(OBJEXT) +libdnssec_test_tsig_LDADD = $(LDADD) +libdnssec_test_tsig_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_control_SOURCES = libknot/test_control.c +libknot_test_control_OBJECTS = libknot/test_control.$(OBJEXT) +libknot_test_control_LDADD = $(LDADD) +libknot_test_control_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_cookies_SOURCES = libknot/test_cookies.c +libknot_test_cookies_OBJECTS = libknot/test_cookies.$(OBJEXT) +libknot_test_cookies_LDADD = $(LDADD) +libknot_test_cookies_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_db_SOURCES = libknot/test_db.c +libknot_test_db_OBJECTS = libknot/test_db.$(OBJEXT) +libknot_test_db_LDADD = $(LDADD) +libknot_test_db_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_descriptor_SOURCES = libknot/test_descriptor.c +libknot_test_descriptor_OBJECTS = libknot/test_descriptor.$(OBJEXT) +libknot_test_descriptor_LDADD = $(LDADD) +libknot_test_descriptor_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_dname_SOURCES = libknot/test_dname.c +libknot_test_dname_OBJECTS = libknot/test_dname.$(OBJEXT) +libknot_test_dname_LDADD = $(LDADD) +libknot_test_dname_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_edns_SOURCES = libknot/test_edns.c +libknot_test_edns_OBJECTS = libknot/test_edns.$(OBJEXT) +libknot_test_edns_LDADD = $(LDADD) +libknot_test_edns_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_edns_ecs_SOURCES = libknot/test_edns_ecs.c +libknot_test_edns_ecs_OBJECTS = libknot/test_edns_ecs.$(OBJEXT) +libknot_test_edns_ecs_LDADD = $(LDADD) +libknot_test_edns_ecs_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_endian_SOURCES = libknot/test_endian.c +libknot_test_endian_OBJECTS = libknot/test_endian.$(OBJEXT) +libknot_test_endian_LDADD = $(LDADD) +libknot_test_endian_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_lookup_SOURCES = libknot/test_lookup.c +libknot_test_lookup_OBJECTS = libknot/test_lookup.$(OBJEXT) +libknot_test_lookup_LDADD = $(LDADD) +libknot_test_lookup_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_pkt_SOURCES = libknot/test_pkt.c +libknot_test_pkt_OBJECTS = libknot/test_pkt.$(OBJEXT) +libknot_test_pkt_LDADD = $(LDADD) +libknot_test_pkt_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_rdata_SOURCES = libknot/test_rdata.c +libknot_test_rdata_OBJECTS = libknot/test_rdata.$(OBJEXT) +libknot_test_rdata_LDADD = $(LDADD) +libknot_test_rdata_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_rdataset_SOURCES = libknot/test_rdataset.c +libknot_test_rdataset_OBJECTS = libknot/test_rdataset.$(OBJEXT) +libknot_test_rdataset_LDADD = $(LDADD) +libknot_test_rdataset_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_rrset_SOURCES = libknot/test_rrset.c +libknot_test_rrset_OBJECTS = libknot/test_rrset.$(OBJEXT) +libknot_test_rrset_LDADD = $(LDADD) +libknot_test_rrset_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_rrset_wire_SOURCES = libknot/test_rrset-wire.c +libknot_test_rrset_wire_OBJECTS = libknot/test_rrset-wire.$(OBJEXT) +libknot_test_rrset_wire_LDADD = $(LDADD) +libknot_test_rrset_wire_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_tsig_SOURCES = libknot/test_tsig.c +libknot_test_tsig_OBJECTS = libknot/test_tsig.$(OBJEXT) +libknot_test_tsig_LDADD = $(LDADD) +libknot_test_tsig_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_wire_SOURCES = libknot/test_wire.c +libknot_test_wire_OBJECTS = libknot/test_wire.$(OBJEXT) +libknot_test_wire_LDADD = $(LDADD) +libknot_test_wire_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_yparser_SOURCES = libknot/test_yparser.c +libknot_test_yparser_OBJECTS = libknot/test_yparser.$(OBJEXT) +libknot_test_yparser_LDADD = $(LDADD) +libknot_test_yparser_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_ypschema_SOURCES = libknot/test_ypschema.c +libknot_test_ypschema_OBJECTS = libknot/test_ypschema.$(OBJEXT) +libknot_test_ypschema_LDADD = $(LDADD) +libknot_test_ypschema_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +libknot_test_yptrafo_SOURCES = libknot/test_yptrafo.c +libknot_test_yptrafo_OBJECTS = libknot/test_yptrafo.$(OBJEXT) +libknot_test_yptrafo_LDADD = $(LDADD) +libknot_test_yptrafo_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +am_libzscanner_zscanner_tool_OBJECTS = \ + libzscanner/zscanner-tool.$(OBJEXT) \ + libzscanner/processing.$(OBJEXT) +libzscanner_zscanner_tool_OBJECTS = \ + $(am_libzscanner_zscanner_tool_OBJECTS) +libzscanner_zscanner_tool_LDADD = $(LDADD) +libzscanner_zscanner_tool_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +modules_test_onlinesign_SOURCES = modules/test_onlinesign.c +modules_test_onlinesign_OBJECTS = modules/test_onlinesign.$(OBJEXT) +modules_test_onlinesign_LDADD = $(LDADD) +modules_test_onlinesign_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +modules_test_rrl_SOURCES = modules/test_rrl.c +modules_test_rrl_OBJECTS = modules/test_rrl.$(OBJEXT) +modules_test_rrl_LDADD = $(LDADD) +modules_test_rrl_DEPENDENCIES = libtap.la \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +tap_runtests_SOURCES = tap/runtests.c +tap_runtests_OBJECTS = tap/runtests.$(OBJEXT) +tap_runtests_DEPENDENCIES = +utils_test_cert_SOURCES = utils/test_cert.c +utils_test_cert_OBJECTS = utils/utils_test_cert-test_cert.$(OBJEXT) +am__DEPENDENCIES_1 = +@HAVE_LIBUTILS_TRUE@utils_test_cert_DEPENDENCIES = libtap.la \ +@HAVE_LIBUTILS_TRUE@ $(top_builddir)/src/libknotus.la \ +@HAVE_LIBUTILS_TRUE@ $(am__DEPENDENCIES_1) +utils_test_lookup_SOURCES = utils/test_lookup.c +utils_test_lookup_OBJECTS = \ + utils/utils_test_lookup-test_lookup.$(OBJEXT) +@HAVE_LIBUTILS_TRUE@utils_test_lookup_DEPENDENCIES = libtap.la \ +@HAVE_LIBUTILS_TRUE@ $(top_builddir)/src/libknotus.la \ +@HAVE_LIBUTILS_TRUE@ $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libtap_la_SOURCES) contrib/test_base32hex.c \ + contrib/test_base64.c contrib/test_dynarray.c \ + contrib/test_heap.c contrib/test_net.c \ + contrib/test_net_shortwrite.c contrib/test_qp-trie.c \ + contrib/test_siphash.c contrib/test_sockaddr.c \ + contrib/test_string.c contrib/test_strtonum.c \ + contrib/test_time.c contrib/test_wire_ctx.c \ + $(knot_test_acl_SOURCES) knot/test_changeset.c \ + $(knot_test_conf_SOURCES) knot/test_conf_tools.c \ + $(knot_test_confdb_SOURCES) $(knot_test_confio_SOURCES) \ + knot/test_dthreads.c knot/test_fdset.c knot/test_journal.c \ + knot/test_kasp_db.c knot/test_node.c \ + $(knot_test_process_query_SOURCES) knot/test_query_module.c \ + knot/test_requestor.c knot/test_server.c \ + knot/test_worker_pool.c knot/test_worker_queue.c \ + knot/test_zone-tree.c knot/test_zone-update.c \ + knot/test_zone_events.c knot/test_zone_serial.c \ + knot/test_zone_timers.c knot/test_zonedb.c \ + libdnssec/test_binary.c libdnssec/test_crypto.c \ + libdnssec/test_key.c libdnssec/test_key_algorithm.c \ + libdnssec/test_key_ds.c libdnssec/test_keyid.c \ + libdnssec/test_keystore_pkcs11.c \ + libdnssec/test_keystore_pkcs8.c \ + libdnssec/test_keystore_pkcs8_dir.c libdnssec/test_keytag.c \ + libdnssec/test_list.c libdnssec/test_nsec_bitmap.c \ + libdnssec/test_nsec_hash.c libdnssec/test_random.c \ + libdnssec/test_shared_bignum.c libdnssec/test_shared_dname.c \ + libdnssec/test_sign.c libdnssec/test_sign_der.c \ + libdnssec/test_tsig.c libknot/test_control.c \ + libknot/test_cookies.c libknot/test_db.c \ + libknot/test_descriptor.c libknot/test_dname.c \ + libknot/test_edns.c libknot/test_edns_ecs.c \ + libknot/test_endian.c libknot/test_lookup.c libknot/test_pkt.c \ + libknot/test_rdata.c libknot/test_rdataset.c \ + libknot/test_rrset.c libknot/test_rrset-wire.c \ + libknot/test_tsig.c libknot/test_wire.c libknot/test_yparser.c \ + libknot/test_ypschema.c libknot/test_yptrafo.c \ + $(libzscanner_zscanner_tool_SOURCES) modules/test_onlinesign.c \ + modules/test_rrl.c tap/runtests.c utils/test_cert.c \ + utils/test_lookup.c +DIST_SOURCES = $(libtap_la_SOURCES) contrib/test_base32hex.c \ + contrib/test_base64.c contrib/test_dynarray.c \ + contrib/test_heap.c contrib/test_net.c \ + contrib/test_net_shortwrite.c contrib/test_qp-trie.c \ + contrib/test_siphash.c contrib/test_sockaddr.c \ + contrib/test_string.c contrib/test_strtonum.c \ + contrib/test_time.c contrib/test_wire_ctx.c \ + $(am__knot_test_acl_SOURCES_DIST) knot/test_changeset.c \ + $(am__knot_test_conf_SOURCES_DIST) knot/test_conf_tools.c \ + $(am__knot_test_confdb_SOURCES_DIST) \ + $(am__knot_test_confio_SOURCES_DIST) knot/test_dthreads.c \ + knot/test_fdset.c knot/test_journal.c knot/test_kasp_db.c \ + knot/test_node.c $(am__knot_test_process_query_SOURCES_DIST) \ + knot/test_query_module.c knot/test_requestor.c \ + knot/test_server.c knot/test_worker_pool.c \ + knot/test_worker_queue.c knot/test_zone-tree.c \ + knot/test_zone-update.c knot/test_zone_events.c \ + knot/test_zone_serial.c knot/test_zone_timers.c \ + knot/test_zonedb.c libdnssec/test_binary.c \ + libdnssec/test_crypto.c libdnssec/test_key.c \ + libdnssec/test_key_algorithm.c libdnssec/test_key_ds.c \ + libdnssec/test_keyid.c libdnssec/test_keystore_pkcs11.c \ + libdnssec/test_keystore_pkcs8.c \ + libdnssec/test_keystore_pkcs8_dir.c libdnssec/test_keytag.c \ + libdnssec/test_list.c libdnssec/test_nsec_bitmap.c \ + libdnssec/test_nsec_hash.c libdnssec/test_random.c \ + libdnssec/test_shared_bignum.c libdnssec/test_shared_dname.c \ + libdnssec/test_sign.c libdnssec/test_sign_der.c \ + libdnssec/test_tsig.c libknot/test_control.c \ + libknot/test_cookies.c libknot/test_db.c \ + libknot/test_descriptor.c libknot/test_dname.c \ + libknot/test_edns.c libknot/test_edns_ecs.c \ + libknot/test_endian.c libknot/test_lookup.c libknot/test_pkt.c \ + libknot/test_rdata.c libknot/test_rdataset.c \ + libknot/test_rrset.c libknot/test_rrset-wire.c \ + libknot/test_tsig.c libknot/test_wire.c libknot/test_yparser.c \ + libknot/test_ypschema.c libknot/test_yptrafo.c \ + $(libzscanner_zscanner_tool_SOURCES) modules/test_onlinesign.c \ + modules/test_rrl.c tap/runtests.c utils/test_cert.c \ + utils/test_lookup.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_CLANG_VERSION = @CC_CLANG_VERSION@ +CFLAGS = @CFLAGS@ +CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DNSTAP_CFLAGS = @DNSTAP_CFLAGS@ +DNSTAP_LIBS = @DNSTAP_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KNOT_VERSION_MAJOR = @KNOT_VERSION_MAJOR@ +KNOT_VERSION_MINOR = @KNOT_VERSION_MINOR@ +KNOT_VERSION_PATCH = @KNOT_VERSION_PATCH@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAG_EXCLUDE_LIBS = @LDFLAG_EXCLUDE_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTOC_C = @PROTOC_C@ +RANLIB = @RANLIB@ +RELEASE_DATE = @RELEASE_DATE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINXBUILD = @SPHINXBUILD@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +cap_ng_CFLAGS = @cap_ng_CFLAGS@ +cap_ng_LIBS = @cap_ng_LIBS@ +conf_mapsize = @conf_mapsize@ +config_dir = @config_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dlopen_LIBS = @dlopen_LIBS@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +external_lmdb_LIBS = @external_lmdb_LIBS@ +fuzzer_CFLAGS = @fuzzer_CFLAGS@ +fuzzer_LDFLAGS = @fuzzer_LDFLAGS@ +gnutls_CFLAGS = @gnutls_CFLAGS@ +gnutls_LIBS = @gnutls_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libdnssec_SONAME = @libdnssec_SONAME@ +libdnssec_SOVERSION = @libdnssec_SOVERSION@ +libdnssec_VERSION_INFO = @libdnssec_VERSION_INFO@ +libedit_CFLAGS = @libedit_CFLAGS@ +libedit_LIBS = @libedit_LIBS@ +libexecdir = @libexecdir@ +libfstrm_CFLAGS = @libfstrm_CFLAGS@ +libfstrm_LIBS = @libfstrm_LIBS@ +libidn2_CFLAGS = @libidn2_CFLAGS@ +libidn2_LIBS = @libidn2_LIBS@ +libidn_CFLAGS = @libidn_CFLAGS@ +libidn_LIBS = @libidn_LIBS@ +libknot_SONAME = @libknot_SONAME@ +libknot_SOVERSION = @libknot_SOVERSION@ +libknot_VERSION_INFO = @libknot_VERSION_INFO@ +libmaxminddb_CFLAGS = @libmaxminddb_CFLAGS@ +libmaxminddb_LIBS = @libmaxminddb_LIBS@ +libprotobuf_c_CFLAGS = @libprotobuf_c_CFLAGS@ +libprotobuf_c_LIBS = @libprotobuf_c_LIBS@ +liburcu_CFLAGS = @liburcu_CFLAGS@ +liburcu_LIBS = @liburcu_LIBS@ +liburcu_PKGCONFIG = @liburcu_PKGCONFIG@ +libzscanner_SONAME = @libzscanner_SONAME@ +libzscanner_SOVERSION = @libzscanner_SOVERSION@ +libzscanner_VERSION_INFO = @libzscanner_VERSION_INFO@ +lmdb_CFLAGS = @lmdb_CFLAGS@ +lmdb_LIBS = @lmdb_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +malloc_LIBS = @malloc_LIBS@ +mandir = @mandir@ +math_LIBS = @math_LIBS@ +mkdir_p = @mkdir_p@ +module_dir = @module_dir@ +module_instdir = @module_instdir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_LIBS = @pthread_LIBS@ +run_dir = @run_dir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +storage_dir = @storage_dir@ +sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = \ + -include $(top_builddir)/src/config.h \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/libdnssec \ + -I$(top_srcdir)/src/libdnssec/shared \ + $(gnutls_CFLAGS) + +LDADD = libtap.la $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libshared.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__append_1) +EXTRA_DIST = \ + tap/libtap.sh \ + libdnssec/sample_keys.h \ + knot/semantic_check_data \ + knot/test_semantic_check.in \ + libzscanner/data \ + libzscanner/test_zscanner.in \ + libzscanner/TESTS + +check_LTLIBRARIES = libtap.la +libtap_la_SOURCES = \ + tap/basic.c \ + tap/basic.h \ + tap/files.c \ + tap/files.h \ + tap/float.c \ + tap/float.h \ + tap/macros.h + +tap_runtests_LDADD = +@HAVE_DAEMON_TRUE@knot_test_acl_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_acl.c \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +@HAVE_DAEMON_TRUE@knot_test_conf_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_conf.c \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +@HAVE_DAEMON_TRUE@knot_test_confdb_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_confdb.c \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +@HAVE_DAEMON_TRUE@knot_test_confio_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_confio.c \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +@HAVE_DAEMON_TRUE@knot_test_process_query_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_process_query.c \ +@HAVE_DAEMON_TRUE@ knot/test_server.h \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +libdnssec_test_keystore_pkcs11_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -DLIBDIR='"$(libdir)"' + +@HAVE_LIBUTILS_TRUE@utils_test_lookup_CPPFLAGS = \ +@HAVE_LIBUTILS_TRUE@ $(AM_CPPFLAGS) \ +@HAVE_LIBUTILS_TRUE@ $(libedit_CFLAGS) + +@HAVE_LIBUTILS_TRUE@utils_test_lookup_LDADD = \ +@HAVE_LIBUTILS_TRUE@ libtap.la \ +@HAVE_LIBUTILS_TRUE@ $(top_builddir)/src/libknotus.la \ +@HAVE_LIBUTILS_TRUE@ $(libedit_LIBS) + +@HAVE_LIBUTILS_TRUE@utils_test_cert_CPPFLAGS = \ +@HAVE_LIBUTILS_TRUE@ $(AM_CPPFLAGS) \ +@HAVE_LIBUTILS_TRUE@ $(libedit_CFLAGS) + +@HAVE_LIBUTILS_TRUE@utils_test_cert_LDADD = \ +@HAVE_LIBUTILS_TRUE@ libtap.la \ +@HAVE_LIBUTILS_TRUE@ $(top_builddir)/src/libknotus.la \ +@HAVE_LIBUTILS_TRUE@ $(libedit_LIBS) + +libzscanner_zscanner_tool_SOURCES = \ + libzscanner/zscanner-tool.c \ + libzscanner/processing.h \ + libzscanner/processing.c + +check_SCRIPTS = libzscanner/test_zscanner $(am__append_8) +edit = $(SED) \ + -e 's|@top_srcdir[@]|$(abs_top_srcdir)|g' \ + -e 's|@top_builddir[@]|$(abs_top_builddir)|g' + +CLEANFILES = $(check_SCRIPTS) $(EXTRA_PROGRAMS) runtests.log +AM_V_RUNTESTS = $(am__v_RUNTESTS_@AM_V@) +am__v_RUNTESTS_ = $(am__v_RUNTESTS_@AM_DEFAULT_V@) +am__v_RUNTESTS_0 = +am__v_RUNTESTS_1 = RET=$$?; if [ "$$RET" != "0" ]; then cat "$(builddir)/runtests.log"; exit $$RET; fi +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +tap/$(am__dirstamp): + @$(MKDIR_P) tap + @: > tap/$(am__dirstamp) +tap/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tap/$(DEPDIR) + @: > tap/$(DEPDIR)/$(am__dirstamp) +tap/basic.lo: tap/$(am__dirstamp) tap/$(DEPDIR)/$(am__dirstamp) +tap/files.lo: tap/$(am__dirstamp) tap/$(DEPDIR)/$(am__dirstamp) +tap/float.lo: tap/$(am__dirstamp) tap/$(DEPDIR)/$(am__dirstamp) + +libtap.la: $(libtap_la_OBJECTS) $(libtap_la_DEPENDENCIES) $(EXTRA_libtap_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libtap_la_OBJECTS) $(libtap_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +contrib/$(am__dirstamp): + @$(MKDIR_P) contrib + @: > contrib/$(am__dirstamp) +contrib/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) contrib/$(DEPDIR) + @: > contrib/$(DEPDIR)/$(am__dirstamp) +contrib/test_base32hex.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_base32hex$(EXEEXT): $(contrib_test_base32hex_OBJECTS) $(contrib_test_base32hex_DEPENDENCIES) $(EXTRA_contrib_test_base32hex_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_base32hex$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_base32hex_OBJECTS) $(contrib_test_base32hex_LDADD) $(LIBS) +contrib/test_base64.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_base64$(EXEEXT): $(contrib_test_base64_OBJECTS) $(contrib_test_base64_DEPENDENCIES) $(EXTRA_contrib_test_base64_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_base64$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_base64_OBJECTS) $(contrib_test_base64_LDADD) $(LIBS) +contrib/test_dynarray.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_dynarray$(EXEEXT): $(contrib_test_dynarray_OBJECTS) $(contrib_test_dynarray_DEPENDENCIES) $(EXTRA_contrib_test_dynarray_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_dynarray$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_dynarray_OBJECTS) $(contrib_test_dynarray_LDADD) $(LIBS) +contrib/test_heap.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_heap$(EXEEXT): $(contrib_test_heap_OBJECTS) $(contrib_test_heap_DEPENDENCIES) $(EXTRA_contrib_test_heap_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_heap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_heap_OBJECTS) $(contrib_test_heap_LDADD) $(LIBS) +contrib/test_net.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_net$(EXEEXT): $(contrib_test_net_OBJECTS) $(contrib_test_net_DEPENDENCIES) $(EXTRA_contrib_test_net_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_net$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_net_OBJECTS) $(contrib_test_net_LDADD) $(LIBS) +contrib/test_net_shortwrite.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_net_shortwrite$(EXEEXT): $(contrib_test_net_shortwrite_OBJECTS) $(contrib_test_net_shortwrite_DEPENDENCIES) $(EXTRA_contrib_test_net_shortwrite_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_net_shortwrite$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_net_shortwrite_OBJECTS) $(contrib_test_net_shortwrite_LDADD) $(LIBS) +contrib/test_qp-trie.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_qp-trie$(EXEEXT): $(contrib_test_qp_trie_OBJECTS) $(contrib_test_qp_trie_DEPENDENCIES) $(EXTRA_contrib_test_qp_trie_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_qp-trie$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_qp_trie_OBJECTS) $(contrib_test_qp_trie_LDADD) $(LIBS) +contrib/test_siphash.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_siphash$(EXEEXT): $(contrib_test_siphash_OBJECTS) $(contrib_test_siphash_DEPENDENCIES) $(EXTRA_contrib_test_siphash_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_siphash$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_siphash_OBJECTS) $(contrib_test_siphash_LDADD) $(LIBS) +contrib/test_sockaddr.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_sockaddr$(EXEEXT): $(contrib_test_sockaddr_OBJECTS) $(contrib_test_sockaddr_DEPENDENCIES) $(EXTRA_contrib_test_sockaddr_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_sockaddr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_sockaddr_OBJECTS) $(contrib_test_sockaddr_LDADD) $(LIBS) +contrib/test_string.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_string$(EXEEXT): $(contrib_test_string_OBJECTS) $(contrib_test_string_DEPENDENCIES) $(EXTRA_contrib_test_string_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_string$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_string_OBJECTS) $(contrib_test_string_LDADD) $(LIBS) +contrib/test_strtonum.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_strtonum$(EXEEXT): $(contrib_test_strtonum_OBJECTS) $(contrib_test_strtonum_DEPENDENCIES) $(EXTRA_contrib_test_strtonum_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_strtonum$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_strtonum_OBJECTS) $(contrib_test_strtonum_LDADD) $(LIBS) +contrib/test_time.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_time$(EXEEXT): $(contrib_test_time_OBJECTS) $(contrib_test_time_DEPENDENCIES) $(EXTRA_contrib_test_time_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_time$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_time_OBJECTS) $(contrib_test_time_LDADD) $(LIBS) +contrib/test_wire_ctx.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_wire_ctx$(EXEEXT): $(contrib_test_wire_ctx_OBJECTS) $(contrib_test_wire_ctx_DEPENDENCIES) $(EXTRA_contrib_test_wire_ctx_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_wire_ctx$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_wire_ctx_OBJECTS) $(contrib_test_wire_ctx_LDADD) $(LIBS) +knot/$(am__dirstamp): + @$(MKDIR_P) knot + @: > knot/$(am__dirstamp) +knot/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) knot/$(DEPDIR) + @: > knot/$(DEPDIR)/$(am__dirstamp) +knot/test_acl.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_acl$(EXEEXT): $(knot_test_acl_OBJECTS) $(knot_test_acl_DEPENDENCIES) $(EXTRA_knot_test_acl_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_acl$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_acl_OBJECTS) $(knot_test_acl_LDADD) $(LIBS) +knot/test_changeset.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_changeset$(EXEEXT): $(knot_test_changeset_OBJECTS) $(knot_test_changeset_DEPENDENCIES) $(EXTRA_knot_test_changeset_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_changeset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_changeset_OBJECTS) $(knot_test_changeset_LDADD) $(LIBS) +knot/test_conf.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_conf$(EXEEXT): $(knot_test_conf_OBJECTS) $(knot_test_conf_DEPENDENCIES) $(EXTRA_knot_test_conf_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_conf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_conf_OBJECTS) $(knot_test_conf_LDADD) $(LIBS) +knot/test_conf_tools.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_conf_tools$(EXEEXT): $(knot_test_conf_tools_OBJECTS) $(knot_test_conf_tools_DEPENDENCIES) $(EXTRA_knot_test_conf_tools_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_conf_tools$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_conf_tools_OBJECTS) $(knot_test_conf_tools_LDADD) $(LIBS) +knot/test_confdb.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_confdb$(EXEEXT): $(knot_test_confdb_OBJECTS) $(knot_test_confdb_DEPENDENCIES) $(EXTRA_knot_test_confdb_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_confdb$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_confdb_OBJECTS) $(knot_test_confdb_LDADD) $(LIBS) +knot/test_confio.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_confio$(EXEEXT): $(knot_test_confio_OBJECTS) $(knot_test_confio_DEPENDENCIES) $(EXTRA_knot_test_confio_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_confio$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_confio_OBJECTS) $(knot_test_confio_LDADD) $(LIBS) +knot/test_dthreads.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_dthreads$(EXEEXT): $(knot_test_dthreads_OBJECTS) $(knot_test_dthreads_DEPENDENCIES) $(EXTRA_knot_test_dthreads_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_dthreads$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_dthreads_OBJECTS) $(knot_test_dthreads_LDADD) $(LIBS) +knot/test_fdset.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_fdset$(EXEEXT): $(knot_test_fdset_OBJECTS) $(knot_test_fdset_DEPENDENCIES) $(EXTRA_knot_test_fdset_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_fdset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_fdset_OBJECTS) $(knot_test_fdset_LDADD) $(LIBS) +knot/test_journal.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_journal$(EXEEXT): $(knot_test_journal_OBJECTS) $(knot_test_journal_DEPENDENCIES) $(EXTRA_knot_test_journal_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_journal$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_journal_OBJECTS) $(knot_test_journal_LDADD) $(LIBS) +knot/test_kasp_db.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_kasp_db$(EXEEXT): $(knot_test_kasp_db_OBJECTS) $(knot_test_kasp_db_DEPENDENCIES) $(EXTRA_knot_test_kasp_db_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_kasp_db$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_kasp_db_OBJECTS) $(knot_test_kasp_db_LDADD) $(LIBS) +knot/test_node.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_node$(EXEEXT): $(knot_test_node_OBJECTS) $(knot_test_node_DEPENDENCIES) $(EXTRA_knot_test_node_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_node$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_node_OBJECTS) $(knot_test_node_LDADD) $(LIBS) +knot/test_process_query.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_process_query$(EXEEXT): $(knot_test_process_query_OBJECTS) $(knot_test_process_query_DEPENDENCIES) $(EXTRA_knot_test_process_query_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_process_query$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_process_query_OBJECTS) $(knot_test_process_query_LDADD) $(LIBS) +knot/test_query_module.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_query_module$(EXEEXT): $(knot_test_query_module_OBJECTS) $(knot_test_query_module_DEPENDENCIES) $(EXTRA_knot_test_query_module_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_query_module$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_query_module_OBJECTS) $(knot_test_query_module_LDADD) $(LIBS) +knot/test_requestor.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_requestor$(EXEEXT): $(knot_test_requestor_OBJECTS) $(knot_test_requestor_DEPENDENCIES) $(EXTRA_knot_test_requestor_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_requestor$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_requestor_OBJECTS) $(knot_test_requestor_LDADD) $(LIBS) +knot/test_server.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_server$(EXEEXT): $(knot_test_server_OBJECTS) $(knot_test_server_DEPENDENCIES) $(EXTRA_knot_test_server_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_server$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_server_OBJECTS) $(knot_test_server_LDADD) $(LIBS) +knot/test_worker_pool.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_worker_pool$(EXEEXT): $(knot_test_worker_pool_OBJECTS) $(knot_test_worker_pool_DEPENDENCIES) $(EXTRA_knot_test_worker_pool_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_worker_pool$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_worker_pool_OBJECTS) $(knot_test_worker_pool_LDADD) $(LIBS) +knot/test_worker_queue.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_worker_queue$(EXEEXT): $(knot_test_worker_queue_OBJECTS) $(knot_test_worker_queue_DEPENDENCIES) $(EXTRA_knot_test_worker_queue_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_worker_queue$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_worker_queue_OBJECTS) $(knot_test_worker_queue_LDADD) $(LIBS) +knot/test_zone-tree.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone-tree$(EXEEXT): $(knot_test_zone_tree_OBJECTS) $(knot_test_zone_tree_DEPENDENCIES) $(EXTRA_knot_test_zone_tree_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone-tree$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_tree_OBJECTS) $(knot_test_zone_tree_LDADD) $(LIBS) +knot/test_zone-update.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone-update$(EXEEXT): $(knot_test_zone_update_OBJECTS) $(knot_test_zone_update_DEPENDENCIES) $(EXTRA_knot_test_zone_update_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone-update$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_update_OBJECTS) $(knot_test_zone_update_LDADD) $(LIBS) +knot/test_zone_events.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone_events$(EXEEXT): $(knot_test_zone_events_OBJECTS) $(knot_test_zone_events_DEPENDENCIES) $(EXTRA_knot_test_zone_events_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone_events$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_events_OBJECTS) $(knot_test_zone_events_LDADD) $(LIBS) +knot/test_zone_serial.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone_serial$(EXEEXT): $(knot_test_zone_serial_OBJECTS) $(knot_test_zone_serial_DEPENDENCIES) $(EXTRA_knot_test_zone_serial_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone_serial$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_serial_OBJECTS) $(knot_test_zone_serial_LDADD) $(LIBS) +knot/test_zone_timers.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone_timers$(EXEEXT): $(knot_test_zone_timers_OBJECTS) $(knot_test_zone_timers_DEPENDENCIES) $(EXTRA_knot_test_zone_timers_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone_timers$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_timers_OBJECTS) $(knot_test_zone_timers_LDADD) $(LIBS) +knot/test_zonedb.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zonedb$(EXEEXT): $(knot_test_zonedb_OBJECTS) $(knot_test_zonedb_DEPENDENCIES) $(EXTRA_knot_test_zonedb_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zonedb$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zonedb_OBJECTS) $(knot_test_zonedb_LDADD) $(LIBS) +libdnssec/$(am__dirstamp): + @$(MKDIR_P) libdnssec + @: > libdnssec/$(am__dirstamp) +libdnssec/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) libdnssec/$(DEPDIR) + @: > libdnssec/$(DEPDIR)/$(am__dirstamp) +libdnssec/test_binary.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_binary$(EXEEXT): $(libdnssec_test_binary_OBJECTS) $(libdnssec_test_binary_DEPENDENCIES) $(EXTRA_libdnssec_test_binary_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_binary$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_binary_OBJECTS) $(libdnssec_test_binary_LDADD) $(LIBS) +libdnssec/test_crypto.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_crypto$(EXEEXT): $(libdnssec_test_crypto_OBJECTS) $(libdnssec_test_crypto_DEPENDENCIES) $(EXTRA_libdnssec_test_crypto_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_crypto$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_crypto_OBJECTS) $(libdnssec_test_crypto_LDADD) $(LIBS) +libdnssec/test_key.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_key$(EXEEXT): $(libdnssec_test_key_OBJECTS) $(libdnssec_test_key_DEPENDENCIES) $(EXTRA_libdnssec_test_key_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_key$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_key_OBJECTS) $(libdnssec_test_key_LDADD) $(LIBS) +libdnssec/test_key_algorithm.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_key_algorithm$(EXEEXT): $(libdnssec_test_key_algorithm_OBJECTS) $(libdnssec_test_key_algorithm_DEPENDENCIES) $(EXTRA_libdnssec_test_key_algorithm_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_key_algorithm$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_key_algorithm_OBJECTS) $(libdnssec_test_key_algorithm_LDADD) $(LIBS) +libdnssec/test_key_ds.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_key_ds$(EXEEXT): $(libdnssec_test_key_ds_OBJECTS) $(libdnssec_test_key_ds_DEPENDENCIES) $(EXTRA_libdnssec_test_key_ds_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_key_ds$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_key_ds_OBJECTS) $(libdnssec_test_key_ds_LDADD) $(LIBS) +libdnssec/test_keyid.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keyid$(EXEEXT): $(libdnssec_test_keyid_OBJECTS) $(libdnssec_test_keyid_DEPENDENCIES) $(EXTRA_libdnssec_test_keyid_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keyid$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keyid_OBJECTS) $(libdnssec_test_keyid_LDADD) $(LIBS) +libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.$(OBJEXT): \ + libdnssec/$(am__dirstamp) libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keystore_pkcs11$(EXEEXT): $(libdnssec_test_keystore_pkcs11_OBJECTS) $(libdnssec_test_keystore_pkcs11_DEPENDENCIES) $(EXTRA_libdnssec_test_keystore_pkcs11_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keystore_pkcs11$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keystore_pkcs11_OBJECTS) $(libdnssec_test_keystore_pkcs11_LDADD) $(LIBS) +libdnssec/test_keystore_pkcs8.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keystore_pkcs8$(EXEEXT): $(libdnssec_test_keystore_pkcs8_OBJECTS) $(libdnssec_test_keystore_pkcs8_DEPENDENCIES) $(EXTRA_libdnssec_test_keystore_pkcs8_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keystore_pkcs8$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keystore_pkcs8_OBJECTS) $(libdnssec_test_keystore_pkcs8_LDADD) $(LIBS) +libdnssec/test_keystore_pkcs8_dir.$(OBJEXT): \ + libdnssec/$(am__dirstamp) libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keystore_pkcs8_dir$(EXEEXT): $(libdnssec_test_keystore_pkcs8_dir_OBJECTS) $(libdnssec_test_keystore_pkcs8_dir_DEPENDENCIES) $(EXTRA_libdnssec_test_keystore_pkcs8_dir_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keystore_pkcs8_dir$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keystore_pkcs8_dir_OBJECTS) $(libdnssec_test_keystore_pkcs8_dir_LDADD) $(LIBS) +libdnssec/test_keytag.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keytag$(EXEEXT): $(libdnssec_test_keytag_OBJECTS) $(libdnssec_test_keytag_DEPENDENCIES) $(EXTRA_libdnssec_test_keytag_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keytag$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keytag_OBJECTS) $(libdnssec_test_keytag_LDADD) $(LIBS) +libdnssec/test_list.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_list$(EXEEXT): $(libdnssec_test_list_OBJECTS) $(libdnssec_test_list_DEPENDENCIES) $(EXTRA_libdnssec_test_list_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_list$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_list_OBJECTS) $(libdnssec_test_list_LDADD) $(LIBS) +libdnssec/test_nsec_bitmap.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_nsec_bitmap$(EXEEXT): $(libdnssec_test_nsec_bitmap_OBJECTS) $(libdnssec_test_nsec_bitmap_DEPENDENCIES) $(EXTRA_libdnssec_test_nsec_bitmap_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_nsec_bitmap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_nsec_bitmap_OBJECTS) $(libdnssec_test_nsec_bitmap_LDADD) $(LIBS) +libdnssec/test_nsec_hash.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_nsec_hash$(EXEEXT): $(libdnssec_test_nsec_hash_OBJECTS) $(libdnssec_test_nsec_hash_DEPENDENCIES) $(EXTRA_libdnssec_test_nsec_hash_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_nsec_hash$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_nsec_hash_OBJECTS) $(libdnssec_test_nsec_hash_LDADD) $(LIBS) +libdnssec/test_random.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_random$(EXEEXT): $(libdnssec_test_random_OBJECTS) $(libdnssec_test_random_DEPENDENCIES) $(EXTRA_libdnssec_test_random_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_random$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_random_OBJECTS) $(libdnssec_test_random_LDADD) $(LIBS) +libdnssec/test_shared_bignum.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_shared_bignum$(EXEEXT): $(libdnssec_test_shared_bignum_OBJECTS) $(libdnssec_test_shared_bignum_DEPENDENCIES) $(EXTRA_libdnssec_test_shared_bignum_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_shared_bignum$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_shared_bignum_OBJECTS) $(libdnssec_test_shared_bignum_LDADD) $(LIBS) +libdnssec/test_shared_dname.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_shared_dname$(EXEEXT): $(libdnssec_test_shared_dname_OBJECTS) $(libdnssec_test_shared_dname_DEPENDENCIES) $(EXTRA_libdnssec_test_shared_dname_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_shared_dname$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_shared_dname_OBJECTS) $(libdnssec_test_shared_dname_LDADD) $(LIBS) +libdnssec/test_sign.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_sign$(EXEEXT): $(libdnssec_test_sign_OBJECTS) $(libdnssec_test_sign_DEPENDENCIES) $(EXTRA_libdnssec_test_sign_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_sign$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_sign_OBJECTS) $(libdnssec_test_sign_LDADD) $(LIBS) +libdnssec/test_sign_der.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_sign_der$(EXEEXT): $(libdnssec_test_sign_der_OBJECTS) $(libdnssec_test_sign_der_DEPENDENCIES) $(EXTRA_libdnssec_test_sign_der_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_sign_der$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_sign_der_OBJECTS) $(libdnssec_test_sign_der_LDADD) $(LIBS) +libdnssec/test_tsig.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_tsig$(EXEEXT): $(libdnssec_test_tsig_OBJECTS) $(libdnssec_test_tsig_DEPENDENCIES) $(EXTRA_libdnssec_test_tsig_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_tsig$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_tsig_OBJECTS) $(libdnssec_test_tsig_LDADD) $(LIBS) +libknot/$(am__dirstamp): + @$(MKDIR_P) libknot + @: > libknot/$(am__dirstamp) +libknot/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) libknot/$(DEPDIR) + @: > libknot/$(DEPDIR)/$(am__dirstamp) +libknot/test_control.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_control$(EXEEXT): $(libknot_test_control_OBJECTS) $(libknot_test_control_DEPENDENCIES) $(EXTRA_libknot_test_control_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_control$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_control_OBJECTS) $(libknot_test_control_LDADD) $(LIBS) +libknot/test_cookies.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_cookies$(EXEEXT): $(libknot_test_cookies_OBJECTS) $(libknot_test_cookies_DEPENDENCIES) $(EXTRA_libknot_test_cookies_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_cookies$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_cookies_OBJECTS) $(libknot_test_cookies_LDADD) $(LIBS) +libknot/test_db.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_db$(EXEEXT): $(libknot_test_db_OBJECTS) $(libknot_test_db_DEPENDENCIES) $(EXTRA_libknot_test_db_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_db$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_db_OBJECTS) $(libknot_test_db_LDADD) $(LIBS) +libknot/test_descriptor.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_descriptor$(EXEEXT): $(libknot_test_descriptor_OBJECTS) $(libknot_test_descriptor_DEPENDENCIES) $(EXTRA_libknot_test_descriptor_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_descriptor$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_descriptor_OBJECTS) $(libknot_test_descriptor_LDADD) $(LIBS) +libknot/test_dname.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_dname$(EXEEXT): $(libknot_test_dname_OBJECTS) $(libknot_test_dname_DEPENDENCIES) $(EXTRA_libknot_test_dname_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_dname$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_dname_OBJECTS) $(libknot_test_dname_LDADD) $(LIBS) +libknot/test_edns.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_edns$(EXEEXT): $(libknot_test_edns_OBJECTS) $(libknot_test_edns_DEPENDENCIES) $(EXTRA_libknot_test_edns_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_edns$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_edns_OBJECTS) $(libknot_test_edns_LDADD) $(LIBS) +libknot/test_edns_ecs.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_edns_ecs$(EXEEXT): $(libknot_test_edns_ecs_OBJECTS) $(libknot_test_edns_ecs_DEPENDENCIES) $(EXTRA_libknot_test_edns_ecs_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_edns_ecs$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_edns_ecs_OBJECTS) $(libknot_test_edns_ecs_LDADD) $(LIBS) +libknot/test_endian.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_endian$(EXEEXT): $(libknot_test_endian_OBJECTS) $(libknot_test_endian_DEPENDENCIES) $(EXTRA_libknot_test_endian_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_endian$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_endian_OBJECTS) $(libknot_test_endian_LDADD) $(LIBS) +libknot/test_lookup.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_lookup$(EXEEXT): $(libknot_test_lookup_OBJECTS) $(libknot_test_lookup_DEPENDENCIES) $(EXTRA_libknot_test_lookup_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_lookup_OBJECTS) $(libknot_test_lookup_LDADD) $(LIBS) +libknot/test_pkt.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_pkt$(EXEEXT): $(libknot_test_pkt_OBJECTS) $(libknot_test_pkt_DEPENDENCIES) $(EXTRA_libknot_test_pkt_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_pkt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_pkt_OBJECTS) $(libknot_test_pkt_LDADD) $(LIBS) +libknot/test_rdata.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_rdata$(EXEEXT): $(libknot_test_rdata_OBJECTS) $(libknot_test_rdata_DEPENDENCIES) $(EXTRA_libknot_test_rdata_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_rdata$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_rdata_OBJECTS) $(libknot_test_rdata_LDADD) $(LIBS) +libknot/test_rdataset.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_rdataset$(EXEEXT): $(libknot_test_rdataset_OBJECTS) $(libknot_test_rdataset_DEPENDENCIES) $(EXTRA_libknot_test_rdataset_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_rdataset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_rdataset_OBJECTS) $(libknot_test_rdataset_LDADD) $(LIBS) +libknot/test_rrset.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_rrset$(EXEEXT): $(libknot_test_rrset_OBJECTS) $(libknot_test_rrset_DEPENDENCIES) $(EXTRA_libknot_test_rrset_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_rrset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_rrset_OBJECTS) $(libknot_test_rrset_LDADD) $(LIBS) +libknot/test_rrset-wire.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_rrset-wire$(EXEEXT): $(libknot_test_rrset_wire_OBJECTS) $(libknot_test_rrset_wire_DEPENDENCIES) $(EXTRA_libknot_test_rrset_wire_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_rrset-wire$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_rrset_wire_OBJECTS) $(libknot_test_rrset_wire_LDADD) $(LIBS) +libknot/test_tsig.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_tsig$(EXEEXT): $(libknot_test_tsig_OBJECTS) $(libknot_test_tsig_DEPENDENCIES) $(EXTRA_libknot_test_tsig_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_tsig$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_tsig_OBJECTS) $(libknot_test_tsig_LDADD) $(LIBS) +libknot/test_wire.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_wire$(EXEEXT): $(libknot_test_wire_OBJECTS) $(libknot_test_wire_DEPENDENCIES) $(EXTRA_libknot_test_wire_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_wire$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_wire_OBJECTS) $(libknot_test_wire_LDADD) $(LIBS) +libknot/test_yparser.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_yparser$(EXEEXT): $(libknot_test_yparser_OBJECTS) $(libknot_test_yparser_DEPENDENCIES) $(EXTRA_libknot_test_yparser_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_yparser$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_yparser_OBJECTS) $(libknot_test_yparser_LDADD) $(LIBS) +libknot/test_ypschema.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_ypschema$(EXEEXT): $(libknot_test_ypschema_OBJECTS) $(libknot_test_ypschema_DEPENDENCIES) $(EXTRA_libknot_test_ypschema_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_ypschema$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_ypschema_OBJECTS) $(libknot_test_ypschema_LDADD) $(LIBS) +libknot/test_yptrafo.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_yptrafo$(EXEEXT): $(libknot_test_yptrafo_OBJECTS) $(libknot_test_yptrafo_DEPENDENCIES) $(EXTRA_libknot_test_yptrafo_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_yptrafo$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_yptrafo_OBJECTS) $(libknot_test_yptrafo_LDADD) $(LIBS) +libzscanner/$(am__dirstamp): + @$(MKDIR_P) libzscanner + @: > libzscanner/$(am__dirstamp) +libzscanner/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) libzscanner/$(DEPDIR) + @: > libzscanner/$(DEPDIR)/$(am__dirstamp) +libzscanner/zscanner-tool.$(OBJEXT): libzscanner/$(am__dirstamp) \ + libzscanner/$(DEPDIR)/$(am__dirstamp) +libzscanner/processing.$(OBJEXT): libzscanner/$(am__dirstamp) \ + libzscanner/$(DEPDIR)/$(am__dirstamp) + +libzscanner/zscanner-tool$(EXEEXT): $(libzscanner_zscanner_tool_OBJECTS) $(libzscanner_zscanner_tool_DEPENDENCIES) $(EXTRA_libzscanner_zscanner_tool_DEPENDENCIES) libzscanner/$(am__dirstamp) + @rm -f libzscanner/zscanner-tool$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libzscanner_zscanner_tool_OBJECTS) $(libzscanner_zscanner_tool_LDADD) $(LIBS) +modules/$(am__dirstamp): + @$(MKDIR_P) modules + @: > modules/$(am__dirstamp) +modules/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) modules/$(DEPDIR) + @: > modules/$(DEPDIR)/$(am__dirstamp) +modules/test_onlinesign.$(OBJEXT): modules/$(am__dirstamp) \ + modules/$(DEPDIR)/$(am__dirstamp) + +modules/test_onlinesign$(EXEEXT): $(modules_test_onlinesign_OBJECTS) $(modules_test_onlinesign_DEPENDENCIES) $(EXTRA_modules_test_onlinesign_DEPENDENCIES) modules/$(am__dirstamp) + @rm -f modules/test_onlinesign$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(modules_test_onlinesign_OBJECTS) $(modules_test_onlinesign_LDADD) $(LIBS) +modules/test_rrl.$(OBJEXT): modules/$(am__dirstamp) \ + modules/$(DEPDIR)/$(am__dirstamp) + +modules/test_rrl$(EXEEXT): $(modules_test_rrl_OBJECTS) $(modules_test_rrl_DEPENDENCIES) $(EXTRA_modules_test_rrl_DEPENDENCIES) modules/$(am__dirstamp) + @rm -f modules/test_rrl$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(modules_test_rrl_OBJECTS) $(modules_test_rrl_LDADD) $(LIBS) +tap/runtests.$(OBJEXT): tap/$(am__dirstamp) \ + tap/$(DEPDIR)/$(am__dirstamp) + +tap/runtests$(EXEEXT): $(tap_runtests_OBJECTS) $(tap_runtests_DEPENDENCIES) $(EXTRA_tap_runtests_DEPENDENCIES) tap/$(am__dirstamp) + @rm -f tap/runtests$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tap_runtests_OBJECTS) $(tap_runtests_LDADD) $(LIBS) +utils/$(am__dirstamp): + @$(MKDIR_P) utils + @: > utils/$(am__dirstamp) +utils/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) utils/$(DEPDIR) + @: > utils/$(DEPDIR)/$(am__dirstamp) +utils/utils_test_cert-test_cert.$(OBJEXT): utils/$(am__dirstamp) \ + utils/$(DEPDIR)/$(am__dirstamp) + +utils/test_cert$(EXEEXT): $(utils_test_cert_OBJECTS) $(utils_test_cert_DEPENDENCIES) $(EXTRA_utils_test_cert_DEPENDENCIES) utils/$(am__dirstamp) + @rm -f utils/test_cert$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(utils_test_cert_OBJECTS) $(utils_test_cert_LDADD) $(LIBS) +utils/utils_test_lookup-test_lookup.$(OBJEXT): utils/$(am__dirstamp) \ + utils/$(DEPDIR)/$(am__dirstamp) + +utils/test_lookup$(EXEEXT): $(utils_test_lookup_OBJECTS) $(utils_test_lookup_DEPENDENCIES) $(EXTRA_utils_test_lookup_DEPENDENCIES) utils/$(am__dirstamp) + @rm -f utils/test_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(utils_test_lookup_OBJECTS) $(utils_test_lookup_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f contrib/*.$(OBJEXT) + -rm -f knot/*.$(OBJEXT) + -rm -f libdnssec/*.$(OBJEXT) + -rm -f libknot/*.$(OBJEXT) + -rm -f libzscanner/*.$(OBJEXT) + -rm -f modules/*.$(OBJEXT) + -rm -f tap/*.$(OBJEXT) + -rm -f tap/*.lo + -rm -f utils/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_base32hex.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_base64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_dynarray.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_heap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_net.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_net_shortwrite.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_qp-trie.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_siphash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_sockaddr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_string.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_strtonum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_time.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_wire_ctx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_acl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_changeset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_conf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_conf_tools.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_confdb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_confio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_dthreads.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_fdset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_journal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_kasp_db.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_node.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_process_query.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_query_module.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_requestor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_server.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_worker_pool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_worker_queue.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone-tree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone-update.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone_events.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone_serial.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone_timers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zonedb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_binary.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_crypto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_key.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_key_algorithm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_key_ds.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_keyid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_keystore_pkcs8.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_keystore_pkcs8_dir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_keytag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_list.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_nsec_bitmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_nsec_hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_random.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_shared_bignum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_shared_dname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_sign.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_sign_der.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_tsig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_control.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_cookies.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_db.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_descriptor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_dname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_edns.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_edns_ecs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_endian.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_pkt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_rdata.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_rdataset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_rrset-wire.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_rrset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_tsig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_wire.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_yparser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_ypschema.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_yptrafo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libzscanner/$(DEPDIR)/processing.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libzscanner/$(DEPDIR)/zscanner-tool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@modules/$(DEPDIR)/test_onlinesign.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@modules/$(DEPDIR)/test_rrl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@tap/$(DEPDIR)/basic.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@tap/$(DEPDIR)/files.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@tap/$(DEPDIR)/float.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@tap/$(DEPDIR)/runtests.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/utils_test_cert-test_cert.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.o: libdnssec/test_keystore_pkcs11.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdnssec_test_keystore_pkcs11_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.o -MD -MP -MF libdnssec/$(DEPDIR)/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.Tpo -c -o libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.o `test -f 'libdnssec/test_keystore_pkcs11.c' || echo '$(srcdir)/'`libdnssec/test_keystore_pkcs11.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libdnssec/$(DEPDIR)/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.Tpo libdnssec/$(DEPDIR)/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libdnssec/test_keystore_pkcs11.c' object='libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdnssec_test_keystore_pkcs11_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.o `test -f 'libdnssec/test_keystore_pkcs11.c' || echo '$(srcdir)/'`libdnssec/test_keystore_pkcs11.c + +libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.obj: libdnssec/test_keystore_pkcs11.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdnssec_test_keystore_pkcs11_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.obj -MD -MP -MF libdnssec/$(DEPDIR)/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.Tpo -c -o libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.obj `if test -f 'libdnssec/test_keystore_pkcs11.c'; then $(CYGPATH_W) 'libdnssec/test_keystore_pkcs11.c'; else $(CYGPATH_W) '$(srcdir)/libdnssec/test_keystore_pkcs11.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libdnssec/$(DEPDIR)/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.Tpo libdnssec/$(DEPDIR)/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libdnssec/test_keystore_pkcs11.c' object='libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdnssec_test_keystore_pkcs11_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdnssec/libdnssec_test_keystore_pkcs11-test_keystore_pkcs11.obj `if test -f 'libdnssec/test_keystore_pkcs11.c'; then $(CYGPATH_W) 'libdnssec/test_keystore_pkcs11.c'; else $(CYGPATH_W) '$(srcdir)/libdnssec/test_keystore_pkcs11.c'; fi` + +utils/utils_test_cert-test_cert.o: utils/test_cert.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_cert_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils/utils_test_cert-test_cert.o -MD -MP -MF utils/$(DEPDIR)/utils_test_cert-test_cert.Tpo -c -o utils/utils_test_cert-test_cert.o `test -f 'utils/test_cert.c' || echo '$(srcdir)/'`utils/test_cert.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) utils/$(DEPDIR)/utils_test_cert-test_cert.Tpo utils/$(DEPDIR)/utils_test_cert-test_cert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/test_cert.c' object='utils/utils_test_cert-test_cert.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_cert_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utils/utils_test_cert-test_cert.o `test -f 'utils/test_cert.c' || echo '$(srcdir)/'`utils/test_cert.c + +utils/utils_test_cert-test_cert.obj: utils/test_cert.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_cert_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils/utils_test_cert-test_cert.obj -MD -MP -MF utils/$(DEPDIR)/utils_test_cert-test_cert.Tpo -c -o utils/utils_test_cert-test_cert.obj `if test -f 'utils/test_cert.c'; then $(CYGPATH_W) 'utils/test_cert.c'; else $(CYGPATH_W) '$(srcdir)/utils/test_cert.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) utils/$(DEPDIR)/utils_test_cert-test_cert.Tpo utils/$(DEPDIR)/utils_test_cert-test_cert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/test_cert.c' object='utils/utils_test_cert-test_cert.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_cert_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utils/utils_test_cert-test_cert.obj `if test -f 'utils/test_cert.c'; then $(CYGPATH_W) 'utils/test_cert.c'; else $(CYGPATH_W) '$(srcdir)/utils/test_cert.c'; fi` + +utils/utils_test_lookup-test_lookup.o: utils/test_lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_lookup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils/utils_test_lookup-test_lookup.o -MD -MP -MF utils/$(DEPDIR)/utils_test_lookup-test_lookup.Tpo -c -o utils/utils_test_lookup-test_lookup.o `test -f 'utils/test_lookup.c' || echo '$(srcdir)/'`utils/test_lookup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) utils/$(DEPDIR)/utils_test_lookup-test_lookup.Tpo utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/test_lookup.c' object='utils/utils_test_lookup-test_lookup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_lookup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utils/utils_test_lookup-test_lookup.o `test -f 'utils/test_lookup.c' || echo '$(srcdir)/'`utils/test_lookup.c + +utils/utils_test_lookup-test_lookup.obj: utils/test_lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_lookup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils/utils_test_lookup-test_lookup.obj -MD -MP -MF utils/$(DEPDIR)/utils_test_lookup-test_lookup.Tpo -c -o utils/utils_test_lookup-test_lookup.obj `if test -f 'utils/test_lookup.c'; then $(CYGPATH_W) 'utils/test_lookup.c'; else $(CYGPATH_W) '$(srcdir)/utils/test_lookup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) utils/$(DEPDIR)/utils_test_lookup-test_lookup.Tpo utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/test_lookup.c' object='utils/utils_test_lookup-test_lookup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_lookup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utils/utils_test_lookup-test_lookup.obj `if test -f 'utils/test_lookup.c'; then $(CYGPATH_W) 'utils/test_lookup.c'; else $(CYGPATH_W) '$(srcdir)/utils/test_lookup.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf contrib/.libs contrib/_libs + -rm -rf knot/.libs knot/_libs + -rm -rf libdnssec/.libs libdnssec/_libs + -rm -rf libknot/.libs libknot/_libs + -rm -rf libzscanner/.libs libzscanner/_libs + -rm -rf modules/.libs modules/_libs + -rm -rf tap/.libs tap/_libs + -rm -rf utils/.libs utils/_libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS) \ + $(check_SCRIPTS) + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f contrib/$(DEPDIR)/$(am__dirstamp) + -rm -f contrib/$(am__dirstamp) + -rm -f knot/$(DEPDIR)/$(am__dirstamp) + -rm -f knot/$(am__dirstamp) + -rm -f libdnssec/$(DEPDIR)/$(am__dirstamp) + -rm -f libdnssec/$(am__dirstamp) + -rm -f libknot/$(DEPDIR)/$(am__dirstamp) + -rm -f libknot/$(am__dirstamp) + -rm -f libzscanner/$(DEPDIR)/$(am__dirstamp) + -rm -f libzscanner/$(am__dirstamp) + -rm -f modules/$(DEPDIR)/$(am__dirstamp) + -rm -f modules/$(am__dirstamp) + -rm -f tap/$(DEPDIR)/$(am__dirstamp) + -rm -f tap/$(am__dirstamp) + -rm -f utils/$(DEPDIR)/$(am__dirstamp) + -rm -f utils/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ + clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf contrib/$(DEPDIR) knot/$(DEPDIR) libdnssec/$(DEPDIR) libknot/$(DEPDIR) libzscanner/$(DEPDIR) modules/$(DEPDIR) tap/$(DEPDIR) utils/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf contrib/$(DEPDIR) knot/$(DEPDIR) libdnssec/$(DEPDIR) libknot/$(DEPDIR) libzscanner/$(DEPDIR) modules/$(DEPDIR) tap/$(DEPDIR) utils/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-local clean \ + clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +@HAVE_LIBUTILS_TRUE@knot/test_semantic_check: +@HAVE_LIBUTILS_TRUE@ @$(edit) < $(top_srcdir)/tests/$@.in > $(top_builddir)/tests/$@ +@HAVE_LIBUTILS_TRUE@ @chmod +x $(top_builddir)/tests/$@ + +libzscanner/test_zscanner: libzscanner/zscanner-tool + @$(edit) < $(top_srcdir)/tests/$@.in > $(top_builddir)/tests/$@ + @chmod +x $(top_builddir)/tests/$@ + +check-compile: $(check_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) $(check_SCRIPTS) +check-local: $(check_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) $(check_SCRIPTS) + @$(top_builddir)/tests/tap/runtests -s $(srcdir) -b $(builddir) \ + -L $(builddir)/runtests.log $(check_PROGRAMS) $(check_SCRIPTS); \ + $(AM_V_RUNTESTS) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tests/contrib/test_base32hex.c b/tests/contrib/test_base32hex.c new file mode 100644 index 0000000..4c52fad --- /dev/null +++ b/tests/contrib/test_base32hex.c @@ -0,0 +1,267 @@ +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/libknot.h" +#include "contrib/base32hex.h" +#include "contrib/openbsd/strlcpy.h" + +#define BUF_LEN 256 +#define MAX_BIN_DATA_LEN ((INT32_MAX / 8) * 5) + +int main(int argc, char *argv[]) +{ + plan(67); + + int32_t ret; + uint8_t in[BUF_LEN], ref[BUF_LEN], out[BUF_LEN], out2[BUF_LEN], *out3; + uint32_t in_len, ref_len; + + // 0. test invalid input + ret = base32hex_encode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "base32hex_encode: NULL input buffer"); + ret = base32hex_encode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "base32hex_encode: NULL output buffer"); + ret = base32hex_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "base32hex_encode: input buffer too large"); + ret = base32hex_encode(in, BUF_LEN, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "base32hex_encode: output buffer too small"); + + ret = base32hex_encode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "base32hex_encode_alloc: NULL input buffer"); + ret = base32hex_encode_alloc(in, MAX_BIN_DATA_LEN + 1, &out3); + is_int(KNOT_ERANGE, ret, "base32hex_encode_alloc: input buffer too large"); + ret = base32hex_encode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "base32hex_encode_alloc: NULL output buffer"); + + ret = base32hex_decode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "base32hex_decode: NULL input buffer"); + ret = base32hex_decode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "base32hex_decode: NULL output buffer"); + ret = base32hex_decode(in, UINT32_MAX, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "base32hex_decode: input buffer too large"); + ret = base32hex_decode(in, BUF_LEN, out, 0); + is_int(KNOT_ERANGE, ret, "base32hex_decode: output buffer too small"); + + ret = base32hex_decode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "base32hex_decode_alloc: NULL input buffer"); + ret = base32hex_decode_alloc(in, UINT32_MAX, &out3); + is_int(KNOT_ERANGE, ret, "base32hex_decode_aloc: input buffer too large"); + ret = base32hex_decode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "base32hex_decode_alloc: NULL output buffer"); + + // 1. test vector -> ENC -> DEC + strlcpy((char *)in, "", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "1. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "1. test vector - ENC output content"); + } + ret = base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "1. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "1. test vector - DEC output content"); + } + + // 2. test vector -> ENC -> DEC + strlcpy((char *)in, "f", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "co======", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "2. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "2. test vector - ENC output content"); + } + ret = base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "2. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "2. test vector - DEC output content"); + } + + // 3. test vector -> ENC -> DEC + strlcpy((char *)in, "fo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpng====", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "3. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "3. test vector - ENC output content"); + } + ret = base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "3. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "3. test vector - DEC output content"); + } + + // 4. test vector -> ENC -> DEC + strlcpy((char *)in, "foo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpnmu===", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "4. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "4. test vector - ENC output content"); + } + ret = base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "4. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "4. test vector - DEC output content"); + } + + // 5. test vector -> ENC -> DEC + strlcpy((char *)in, "foob", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpnmuog=", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "5. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "5. test vector - ENC output content"); + } + ret = base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "5. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "5. test vector - DEC output content"); + } + + // 6. test vector -> ENC -> DEC + strlcpy((char *)in, "fooba", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpnmuoj1", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "6. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "6. test vector - ENC output content"); + } + ret = base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "6. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "6. test vector - DEC output content"); + } + + // 7. test vector -> ENC -> DEC + strlcpy((char *)in, "foobar", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpnmuoj1e8======", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "7. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "7. test vector - ENC output content"); + } + ret = base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "7. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "7. test vector - DEC output content"); + } + + // Bad paddings + ret = base32hex_decode((uint8_t *)"AAAAAA==", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding length 2"); + ret = base32hex_decode((uint8_t *)"AAA=====", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding length 5"); + ret = base32hex_decode((uint8_t *)"A=======", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding length 7"); + ret = base32hex_decode((uint8_t *)"========", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding length 8"); + ret = base32hex_decode((uint8_t *)"AAAAA=A=", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding character on position 2"); + ret = base32hex_decode((uint8_t *)"AA=A====", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding character on position 5"); + ret = base32hex_decode((uint8_t *)"=A======", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding character on position 7"); + ret = base32hex_decode((uint8_t *)"CO======CO======", 16, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Two octects with padding"); + + // Bad data length + ret = base32hex_decode((uint8_t *)"A", 1, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 1"); + ret = base32hex_decode((uint8_t *)"AA", 2, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 2"); + ret = base32hex_decode((uint8_t *)"AAA", 3, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 3"); + ret = base32hex_decode((uint8_t *)"AAAA", 4, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 4"); + ret = base32hex_decode((uint8_t *)"AAAAA", 5, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 5"); + ret = base32hex_decode((uint8_t *)"AAAAAA", 6, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 6"); + ret = base32hex_decode((uint8_t *)"AAAAAAA", 7, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 7"); + ret = base32hex_decode((uint8_t *)"AAAAAAAAA", 9, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 9"); + + // Bad data character + ret = base32hex_decode((uint8_t *)"AAAAAAA$", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar"); + ret = base32hex_decode((uint8_t *)"AAAAAAA ", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character space"); + ret = base32hex_decode((uint8_t *)"AAAAAA$A", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 7"); + ret = base32hex_decode((uint8_t *)"AAAAA$AA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 6"); + ret = base32hex_decode((uint8_t *)"AAAA$AAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 5"); + ret = base32hex_decode((uint8_t *)"AAA$AAAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 4"); + ret = base32hex_decode((uint8_t *)"AA$AAAAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 3"); + ret = base32hex_decode((uint8_t *)"A$AAAAAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 2"); + ret = base32hex_decode((uint8_t *)"$AAAAAAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 1"); + + return 0; +} diff --git a/tests/contrib/test_base64.c b/tests/contrib/test_base64.c new file mode 100644 index 0000000..45e4e55 --- /dev/null +++ b/tests/contrib/test_base64.c @@ -0,0 +1,237 @@ +/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/libknot.h" +#include "contrib/base64.h" +#include "contrib/openbsd/strlcpy.h" + +#define BUF_LEN 256 +#define MAX_BIN_DATA_LEN ((INT32_MAX / 4) * 3) + +int main(int argc, char *argv[]) +{ + plan(52); + + int32_t ret; + uint8_t in[BUF_LEN], ref[BUF_LEN], out[BUF_LEN], out2[BUF_LEN], *out3; + uint32_t in_len, ref_len; + + // 0. test invalid input + ret = base64_encode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "base64_encode: NULL input buffer"); + ret = base64_encode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "base64_encode: NULL output buffer"); + ret = base64_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "base64_encode: input buffer too large"); + ret = base64_encode(in, BUF_LEN, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "base64_encode: output buffer too small"); + + ret = base64_encode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "base64_encode_alloc: NULL input buffer"); + ret = base64_encode_alloc(in, MAX_BIN_DATA_LEN + 1, &out3); + is_int(KNOT_ERANGE, ret, "base64_encode_alloc: input buffer too large"); + ret = base64_encode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "base64_encode_alloc: NULL output buffer"); + + ret = base64_decode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "base64_decode: NULL input buffer"); + ret = base64_decode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "base64_decode: NULL output buffer"); + ret = base64_decode(in, UINT32_MAX, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "base64_decode: input buffer too large"); + ret = base64_decode(in, BUF_LEN, out, 0); + is_int(KNOT_ERANGE, ret, "base64_decode: output buffer too small"); + + ret = base64_decode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "base64_decode_alloc: NULL input buffer"); + ret = base64_decode_alloc(in, UINT32_MAX, &out3); + is_int(KNOT_ERANGE, ret, "base64_decode_aloc: input buffer too large"); + ret = base64_decode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "base64_decode_alloc: NULL output buffer"); + + // 1. test vector -> ENC -> DEC + strlcpy((char *)in, "", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "1. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "1. test vector - ENC output content"); + } + ret = base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "1. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "1. test vector - DEC output content"); + } + + // 2. test vector -> ENC -> DEC + strlcpy((char *)in, "f", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zg==", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "2. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "2. test vector - ENC output content"); + } + ret = base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "2. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "2. test vector - DEC output content"); + } + + // 3. test vector -> ENC -> DEC + strlcpy((char *)in, "fo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm8=", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "3. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "3. test vector - ENC output content"); + } + ret = base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "3. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "3. test vector - DEC output content"); + } + + // 4. test vector -> ENC -> DEC + strlcpy((char *)in, "foo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9v", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "4. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "4. test vector - ENC output content"); + } + ret = base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "4. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "4. test vector - DEC output content"); + } + + // 5. test vector -> ENC -> DEC + strlcpy((char *)in, "foob", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYg==", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "5. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "5. test vector - ENC output content"); + } + ret = base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "5. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "5. test vector - DEC output content"); + } + + // 6. test vector -> ENC -> DEC + strlcpy((char *)in, "fooba", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYmE=", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "6. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "6. test vector - ENC output content"); + } + ret = base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "6. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "6. test vector - DEC output content"); + } + + // 7. test vector -> ENC -> DEC + strlcpy((char *)in, "foobar", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYmFy", BUF_LEN); + ref_len = strlen((char *)ref); + ret = base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "7. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "7. test vector - ENC output content"); + } + ret = base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "7. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "7. test vector - DEC output content"); + } + + // Bad paddings + ret = base64_decode((uint8_t *)"A===", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding length 3"); + ret = base64_decode((uint8_t *)"====", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding length 4"); + ret = base64_decode((uint8_t *)"AA=A", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding character on position 2"); + ret = base64_decode((uint8_t *)"Zg==Zg==", 8, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Two quartets with padding"); + + // Bad data length + ret = base64_decode((uint8_t *)"A", 1, out, BUF_LEN); + ok(ret == KNOT_BASE64_ESIZE, "Bad data length 1"); + ret = base64_decode((uint8_t *)"AA", 2, out, BUF_LEN); + ok(ret == KNOT_BASE64_ESIZE, "Bad data length 2"); + ret = base64_decode((uint8_t *)"AAA", 3, out, BUF_LEN); + ok(ret == KNOT_BASE64_ESIZE, "Bad data length 3"); + ret = base64_decode((uint8_t *)"AAAAA", 5, out, BUF_LEN); + ok(ret == KNOT_BASE64_ESIZE, "Bad data length 5"); + + // Bad data character + ret = base64_decode((uint8_t *)"AAA$", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad data character dollar"); + ret = base64_decode((uint8_t *)"AAA ", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad data character space"); + + return 0; +} diff --git a/tests/contrib/test_dynarray.c b/tests/contrib/test_dynarray.c new file mode 100644 index 0000000..3e4c57f --- /dev/null +++ b/tests/contrib/test_dynarray.c @@ -0,0 +1,81 @@ +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <tap/basic.h> + +#include "contrib/dynarray.h" + +#define test_capacity 5 +// minimum 3 + +typedef struct { + int x; + int x2; +} quadrate_t; + +dynarray_declare(q, quadrate_t, DYNARRAY_VISIBILITY_STATIC, test_capacity); +dynarray_define(q, quadrate_t, DYNARRAY_VISIBILITY_STATIC); + +static q_dynarray_t q_fill(size_t howmany) +{ + quadrate_t q = { 0 }; + q_dynarray_t qd = { 0 }; + + for (size_t i = 0; i < howmany; i++) { + q.x2 = q.x * q.x; + q_dynarray_add(&qd, &q); + q.x++; + } + return qd; +} + +static void check_arr(q_dynarray_t *q, size_t count, size_t index, const char *msg) +{ + quadrate_t *arr = q->arr(q); + ok(arr[index].x == index && arr[index].x2 == index * index, + "%s check: index %zu", msg, index); + + size_t i = 0; + dynarray_foreach(q, quadrate_t, p, *q) { + ok(p->x == i && p->x2 == i * i, "%s foreach: index %zu", msg, i); + i++; + } + + ok(i == count, "%s foreach: whole array", msg); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // first fill + q_dynarray_t q = q_fill(test_capacity - 1); + check_arr(&q, test_capacity - 1, test_capacity - 3, "initial"); + q_dynarray_free(&q); + + // second fill + q = q_fill(test_capacity + 3); + check_arr(&q, test_capacity + 3, test_capacity + 1, "second"); + q_dynarray_free(&q); + + // third fill + q = q_fill(test_capacity * 5); + check_arr(&q, test_capacity * 5, test_capacity * 4, "third"); + q_dynarray_free(&q); + + return 0; +} diff --git a/tests/contrib/test_heap.c b/tests/contrib/test_heap.c new file mode 100644 index 0000000..e49204c --- /dev/null +++ b/tests/contrib/test_heap.c @@ -0,0 +1,166 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "contrib/ucw/heap.h" + +static void seed_random(void) +{ + unsigned short int seed[3] = { 0 }; + + FILE *f = fopen("/dev/urandom", "r"); + if (f) { + if (fread(seed, sizeof(seed), 1, f) != 1) { + diag("failed to seed random source"); + } + fclose(f); + } + + diag("seed %hu %hu %hu", seed[0], seed[1], seed[2]); + seed48(seed); +} + +struct value { + heap_val_t _heap; + int data; +}; + +static int value_cmp(void *_a, void *_b) +{ + const struct value *a = _a; + const struct value *b = _b; + return (a->data - b->data); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + seed_random(); + + static const int VALUE_COUNT = 1000; + static const int VALUE_RANGE = 950; + static const int VALUE_REPLACE = 300; + static const int VALUE_DELETE = 100; + + struct heap heap; + heap_init(&heap, value_cmp, 0); + + ok(EMPTY_HEAP(&heap), "heap is empty"); + + // fill the heap with random values (with duplicates) + + struct value *values = calloc(VALUE_COUNT, sizeof(struct value)); + assert(values); + assert(VALUE_RANGE < VALUE_COUNT); + + bool valid = true; + for (int i = 0; i < VALUE_COUNT; i++) { + values[i].data = lrand48() % VALUE_RANGE; + if (heap_insert(&heap, &values[i]._heap) == 0) { + valid = false; + } + } + ok(valid, "heap_insert"); + ok(!EMPTY_HEAP(&heap), "heap is non-empty"); + + // exercise heap_insert + + valid = true; + for (int i = 0; i < VALUE_COUNT; i++) { + int pos = heap_find(&heap, &values[i]._heap); + if (*HELEMENT(&heap, pos) != &values[i]._heap) { + valid = false; + } + } + ok(valid, "heap_find"); + + // exercise heap_replace + + assert(VALUE_REPLACE <= VALUE_COUNT); + struct value *replaced = calloc(VALUE_REPLACE, sizeof(struct value)); + assert(replaced); + + valid = true; + for (int i = 0; i < VALUE_REPLACE; i++) { + replaced[i].data = lrand48() % VALUE_RANGE; + int pos = heap_find(&heap, &values[i]._heap); + if (pos < 1) { + valid = false; + continue; + } + + heap_replace(&heap, pos, &replaced[i]._heap); + int newpos = heap_find(&heap, &replaced[i]._heap); + if (newpos < 1) { + valid = false; + } + } + ok(valid, "heap_replace"); + + // exercise heap_delete + + assert(VALUE_REPLACE + VALUE_DELETE < VALUE_COUNT); + + valid = true; + for (int i = 0; i < VALUE_DELETE; i++) { + heap_val_t *value = &values[i + VALUE_REPLACE]._heap; + int pos = heap_find(&heap, value); + if (pos < 1) { + valid = false; + continue; + + } + heap_delete(&heap, pos); + pos = heap_find(&heap, value); + if (pos != 0) { + valid = false; + } + } + ok(valid, "heap_delete"); + + // exercise item retrieval + + assert(VALUE_COUNT > VALUE_DELETE); + + valid = true; + int current = -1; + for (int i = 0; i < VALUE_COUNT - VALUE_DELETE; i++) { + struct value *val = (struct value *)*HHEAD(&heap); + heap_delmin(&heap); + if (current <= val->data) { + current = val->data; + } else { + valid = false; + } + } + + ok(valid, "heap ordering"); + ok(EMPTY_HEAP(&heap), "heap_delmin"); + + free(replaced); + free(values); + heap_deinit(&heap); + + return 0; +} diff --git a/tests/contrib/test_net.c b/tests/contrib/test_net.c new file mode 100644 index 0000000..9583362 --- /dev/null +++ b/tests/contrib/test_net.c @@ -0,0 +1,759 @@ +/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include <assert.h> +#include <fcntl.h> +#include <poll.h> +#include <pthread.h> +#include <signal.h> +#include <stdbool.h> +#include <string.h> + +#include "libknot/errcode.h" +#include "contrib/net.h" +#include "contrib/sockaddr.h" + +#undef ENABLE_NET_UNREACHABLE_TEST +//#define ENABLE_NET_UNREACHABLE_TEST + +const int TIMEOUT = 5000; +const int TIMEOUT_SHORT = 500; + +/*! + * \brief Get loopback socket address with unset port. + */ +static struct sockaddr_storage addr_local(void) +{ + struct sockaddr_storage addr = { 0 }; + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + + addr6->sin6_family = AF_INET6; + addr6->sin6_addr = in6addr_loopback; + + return addr; +} + +#ifdef ENABLE_NET_UNREACHABLE_TEST +/*! + * \brief Get unreachable IPv6 address. + * + * Allocated from 100::/64 (Discard-Only Address Block). + */ +static struct sockaddr_storage addr_unreachable(void) +{ + struct sockaddr_storage addr = { 0 }; + sockaddr_set(&addr, AF_INET6, "100::b1ac:h01e", 42); + + return addr; +} +#endif + +/*! + * \brief Get address of a socket. + */ +static struct sockaddr_storage addr_from_socket(int sock) +{ + struct sockaddr_storage addr = { 0 }; + socklen_t len = sizeof(addr); + getsockname(sock, (struct sockaddr *)&addr, &len); + + return addr; +} + +static const char *socktype_name(int type) +{ + switch (type) { + case SOCK_STREAM: return "TCP"; + case SOCK_DGRAM: return "UDP"; + default: return "unknown"; + } +} + +static bool socktype_is_stream(int type) +{ + return type == SOCK_STREAM; +} + +/* -- mock server ---------------------------------------------------------- */ + +#define LISTEN_BACKLOG 5 + +struct server_ctx; +typedef struct server_ctx server_ctx_t; + +typedef void (*server_cb)(int sock, void *data); + +/*! + * \brief Server context. + */ +struct server_ctx { + int sock; + int type; + bool terminate; + server_cb handler; + void *handler_data; + + pthread_t thr; + pthread_mutex_t mx; +}; + +static int poll_read(int sock) +{ + struct pollfd pfd = { .fd = sock, .events = POLLIN }; + return poll(&pfd, 1, TIMEOUT); +} + +static void server_handle(server_ctx_t *ctx) +{ + int remote = ctx->sock; + + assert(ctx->type == SOCK_STREAM || ctx->type == SOCK_DGRAM); + + if (socktype_is_stream(ctx->type)) { + remote = accept(ctx->sock, 0, 0); + if (remote < 0) { + return; + } + } + + pthread_mutex_lock(&ctx->mx); + server_cb handler = ctx->handler; + pthread_mutex_unlock(&ctx->mx); + handler(remote, ctx->handler_data); + + if (socktype_is_stream(ctx->type)) { + close(remote); + } +} + +/*! + * \brief Simple server. + * + * Terminated when a one-byte message is delivered. + */ +static void *server_main(void *_ctx) +{ + server_ctx_t *ctx = _ctx; + + for (;;) { + pthread_mutex_lock(&ctx->mx); + bool terminate = ctx->terminate; + pthread_mutex_unlock(&ctx->mx); + if (terminate) { + break; + } + + int r = poll_read(ctx->sock); + if (r == -1) { + if (errno == EINTR) { + continue; + } else { + break; + } + } else if (r == 0) { + continue; + } + + assert(r == 1); + server_handle(ctx); + } + + return NULL; +} + +static bool server_start(server_ctx_t *ctx, int sock, int type, + server_cb handler, void *handler_data) +{ + memset(ctx, 0, sizeof(*ctx)); + + ctx->sock = sock; + ctx->type = type; + ctx->handler = handler; + ctx->handler_data = handler_data; + + ctx->terminate = false; + + pthread_mutex_init(&ctx->mx, NULL); + return (pthread_create(&ctx->thr, NULL, server_main, ctx) == 0); +} + +static void server_stop(server_ctx_t *ctx) +{ + pthread_mutex_lock(&ctx->mx); + ctx->terminate = true; + pthread_mutex_unlock(&ctx->mx); + + pthread_kill(ctx->thr, SIGUSR1); + pthread_join(ctx->thr, NULL); +} + +/* -- tests ---------------------------------------------------------------- */ + +static void handler_echo(int sock, void *_server) +{ + server_ctx_t *server = _server; + uint8_t buffer[16] = { 0 }; + + struct sockaddr_storage remote = { 0 }; + struct sockaddr_storage *addr = NULL; + if (!socktype_is_stream(server->type)) { + addr = &remote; + } + + int in = net_recv(sock, buffer, sizeof(buffer), addr, TIMEOUT); + if (in <= 0) { + return; + } + + net_send(sock, buffer, in, (struct sockaddr *)addr, TIMEOUT); +} + +static void test_connected_one(const struct sockaddr_storage *server_addr, + const struct sockaddr_storage *source_addr, + int type, const char *name, const char *addr_name) +{ + int r; + + int client = net_connected_socket(type, (struct sockaddr *)server_addr, NULL); + ok(client >= 0, "%s, %s: client, create connected socket", name, addr_name); + + const uint8_t out[] = "test message"; + const size_t out_len = sizeof(out); + if (socktype_is_stream(type)) { + r = net_stream_send(client, out, out_len, TIMEOUT); + } else { + r = net_dgram_send(client, out, out_len, NULL); + } + ok(r == out_len, "%s, %s: client, send message", name, addr_name); + + r = net_is_connected(client); + ok(r, "%s, %s: client, is connected", name, addr_name); + + uint8_t in[128] = { 0 }; + if (socktype_is_stream(type)) { + r = net_stream_recv(client, in, sizeof(in), TIMEOUT); + } else { + r = net_dgram_recv(client, in, sizeof(in), TIMEOUT); + } + ok(r == out_len && memcmp(out, in, out_len) == 0, + "%s, %s: client, receive message", name, addr_name); + + close(client); +} + +static void test_connected(int type) +{ + const char *name = socktype_name(type); + const struct sockaddr_storage empty_addr = { 0 }; + const struct sockaddr_storage local_addr = addr_local(); + + int r; + + // setup server + + int server = net_bound_socket(type, (struct sockaddr *)&local_addr, 0); + ok(server >= 0, "%s: server, create bound socket", name); + + if (socktype_is_stream(type)) { + r = listen(server, LISTEN_BACKLOG); + ok(r == 0, "%s: server, start listening", name); + } + + server_ctx_t server_ctx = { 0 }; + r = server_start(&server_ctx, server, type, handler_echo, &server_ctx); + ok(r, "%s: server, start", name); + + const struct sockaddr_storage server_addr = addr_from_socket(server); + + // connected socket, send and receive + + test_connected_one(&server_addr, NULL, type, name, "NULL source"); + test_connected_one(&server_addr, &empty_addr, type, name, "zero source"); + test_connected_one(&server_addr, &local_addr, type, name, "valid source"); + + // cleanup + + server_stop(&server_ctx); + close(server); +} + +static void handler_noop(int sock, void *data) +{ +} + +static void test_unconnected(void) +{ + int r = 0; + int sock = -1; + const struct sockaddr_storage local = addr_local(); + + uint8_t buffer[] = { 'k', 'n', 'o', 't' }; + ssize_t buffer_len = sizeof(buffer); + + // server + + int server = net_bound_socket(SOCK_DGRAM, (struct sockaddr *)&local, 0); + ok(server >= 0, "UDP, create server socket"); + + server_ctx_t server_ctx = { 0 }; + r = server_start(&server_ctx, server, SOCK_DGRAM, handler_noop, NULL); + ok(r, "UDP, start server"); + + // UDP + + sock = net_unbound_socket(SOCK_DGRAM, (struct sockaddr *)&local); + ok(sock >= 0, "UDP, create unbound socket"); + + ok(!net_is_connected(sock), "UDP, is not connected"); + + r = net_dgram_send(sock, buffer, buffer_len, NULL); + ok(r == KNOT_ECONN, "UDP, send failure on unconnected socket"); + + r = net_dgram_recv(sock, buffer, buffer_len, TIMEOUT_SHORT); + ok(r == KNOT_ETIMEOUT, "UDP, receive timeout on unconnected socket"); + + struct sockaddr_storage server_addr = addr_from_socket(server); + r = net_dgram_send(sock, buffer, buffer_len, (struct sockaddr *)&server_addr); + ok(r == buffer_len, "UDP, send on defined address"); + + close(sock); + + // TCP + + sock = net_unbound_socket(SOCK_STREAM, (struct sockaddr *)&local); + ok(sock >= 0, "TCP, create unbound socket"); + + ok(!net_is_connected(sock), "TCP, is not connected"); + +#ifdef __linux__ + const int expected = KNOT_ECONN; + const char *expected_msg = "failure"; + const int expected_timeout = TIMEOUT; +#else + const int expected = KNOT_ETIMEOUT; + const char *expected_msg = "timeout"; + const int expected_timeout = TIMEOUT_SHORT; +#endif + + r = net_stream_send(sock, buffer, buffer_len, expected_timeout); + ok(r == expected, "TCP, send %s on unconnected socket", expected_msg); + + r = net_stream_recv(sock, buffer, sizeof(buffer), expected_timeout); + ok(r == expected, "TCP, receive %s on unconnected socket", expected_msg); + + close(sock); + + // server termination + + server_stop(&server_ctx); + close(server); +} + +static void test_refused(void) +{ + int r = -1; + + struct sockaddr_storage addr = { 0 }; + uint8_t buffer[1] = { 0 }; + int server, client; + + // unreachable remote + +#ifdef ENABLE_NET_UNREACHABLE_TEST + addr = addr_unreachable(); + + client = net_connected_socket(SOCK_STREAM, &addr, NULL); + ok(client >= 0, "client, connected"); + + tv = TIMEOUT_SHORT; + r = net_stream_send(client, (uint8_t *)"", 1, &tv); + ok(r == KNOT_ETIMEOUT, "client, timeout on write"); + close(client); + + client = net_connected_socket(SOCK_STREAM, &addr, NULL); + ok(client >= 0, "client, connected"); + + tv = TIMEOUT_SHORT; + r = net_stream_recv(client, buffer, sizeof(buffer), &tv); + ok(r == KNOT_ETIMEOUT, "client, timeout on read"); + close(client); +#else + skip("unreachable tests disabled"); +#endif + + // listening, not accepting + + addr = addr_local(); + server = net_bound_socket(SOCK_STREAM, (struct sockaddr *)&addr, 0); + ok(server >= 0, "server, create server"); + addr = addr_from_socket(server); + + r = listen(server, LISTEN_BACKLOG); + ok(r == 0, "server, start listening"); + + client = net_connected_socket(SOCK_STREAM, (struct sockaddr *)&addr, NULL); + ok(client >= 0, "client, connect"); + + r = net_stream_send(client, (uint8_t *)"", 1, TIMEOUT); + ok(r == 1, "client, successful write"); + + r = net_stream_recv(client, buffer, sizeof(buffer), TIMEOUT_SHORT); + ok(r == KNOT_ETIMEOUT, "client, timeout on read"); + + close(client); + + // listening, closed immediately + + client = net_connected_socket(SOCK_STREAM, (struct sockaddr *)&addr, NULL); + ok(client >= 0, "client, connect"); + + r = close(server); + ok(r == 0, "server, close socket"); + + r = net_stream_send(client, (uint8_t *)"", 1, TIMEOUT); + ok(r == KNOT_ECONN, "client, refused on write"); + + close(client); +} + +struct dns_handler_ctx { + const uint8_t *expected; + int len; + bool raw; + bool success; +}; + +static void _sync(int remote, int send) +{ + uint8_t buf[1] = { 0 }; + int r; + if (send) { + r = net_stream_send(remote, buf, sizeof(buf), TIMEOUT); + } else { + r = net_stream_recv(remote, buf, sizeof(buf), TIMEOUT); + + } + assert(r == sizeof(buf)); + (void)r; +} + +static void sync_signal(int remote) +{ + _sync(remote, true); +} + +static void sync_wait(int remote) +{ + _sync(remote, false); +} + +static void handler_dns(int sock, void *_ctx) +{ + struct dns_handler_ctx *ctx = _ctx; + + uint8_t in[16] = { 0 }; + int in_len = 0; + + sync_signal(sock); + + if (ctx->raw) { + in_len = net_stream_recv(sock, in, sizeof(in), TIMEOUT); + } else { + in_len = net_dns_tcp_recv(sock, in, sizeof(in), TIMEOUT); + } + + ctx->success = in_len == ctx->len && + (ctx->len < 0 || memcmp(in, ctx->expected, in_len) == 0); +} + +static void dns_send_hello(int sock) +{ + net_dns_tcp_send(sock, (uint8_t *)"wimbgunts", 9, TIMEOUT); +} + +static void dns_send_fragmented(int sock) +{ + struct fragment { const uint8_t *data; size_t len; }; + + const struct fragment fragments[] = { + { (uint8_t *)"\x00", 1 }, + { (uint8_t *)"\x08""qu", 3 }, + { (uint8_t *)"oopisk", 6 }, + { NULL } + }; + + for (const struct fragment *f = fragments; f->len > 0; f++) { + net_stream_send(sock, f->data, f->len, TIMEOUT); + } +} + +static void dns_send_incomplete(int sock) +{ + net_stream_send(sock, (uint8_t *)"\x00\x08""korm", 6, TIMEOUT); +} + +static void dns_send_trailing(int sock) +{ + net_stream_send(sock, (uint8_t *)"\x00\x05""bloitxx", 9, TIMEOUT); +} + +static void test_dns_tcp(void) +{ + struct testcase { + const char *name; + const uint8_t *expected; + size_t expected_len; + bool expected_raw; + void (*send_callback)(int sock); + }; + + const struct testcase testcases[] = { + { "single DNS", (uint8_t *)"wimbgunts", 9, false, dns_send_hello }, + { "single RAW", (uint8_t *)"\x00\x09""wimbgunts", 11, true, dns_send_hello }, + { "fragmented", (uint8_t *)"quoopisk", 8, false, dns_send_fragmented }, + { "incomplete", NULL, KNOT_ECONN, false, dns_send_incomplete }, + { "trailing garbage", (uint8_t *)"bloit", 5, false, dns_send_trailing }, + { NULL } + }; + + for (const struct testcase *t = testcases; t->name != NULL; t++) { + struct dns_handler_ctx handler_ctx = { + .expected = t->expected, + .len = t->expected_len, + .raw = t->expected_raw, + .success = false + }; + + struct sockaddr_storage addr = addr_local(); + int server = net_bound_socket(SOCK_STREAM, (struct sockaddr *)&addr, 0); + ok(server >= 0, "%s, server, create socket", t->name); + + int r = listen(server, LISTEN_BACKLOG); + ok(r == 0, "%s, server, start listening", t->name); + + server_ctx_t server_ctx = { 0 }; + r = server_start(&server_ctx, server, SOCK_STREAM, handler_dns, &handler_ctx); + ok(r, "%s, server, start handler", t->name); + + addr = addr_from_socket(server); + int client = net_connected_socket(SOCK_STREAM, (struct sockaddr *)&addr, NULL); + ok(client >= 0, "%s, client, create connected socket", t->name); + + sync_wait(client); + t->send_callback(client); + + close(client); + server_stop(&server_ctx); + close(server); + + ok(handler_ctx.success, "%s, expected result", t->name); + } +} + +static bool socket_is_blocking(int sock) +{ + return fcntl(sock, F_GETFL, O_NONBLOCK) == 0; +} + +static void test_nonblocking_mode(int type) +{ + const char *name = socktype_name(type); + const struct sockaddr_storage addr = addr_local(); + + int client = net_unbound_socket(type, (struct sockaddr *)&addr); + ok(client >= 0, "%s: unbound, create", name); + ok(!socket_is_blocking(client), "%s: unbound, nonblocking mode", name); + close(client); + + int server = net_bound_socket(type, (struct sockaddr *)&addr, 0); + ok(server >= 0, "%s: bound, create", name); + ok(!socket_is_blocking(server), "%s: bound, nonblocking mode", name); + + if (socktype_is_stream(type)) { + int r = listen(server, LISTEN_BACKLOG); + ok(r == 0, "%s: bound, start listening", name); + } + + struct sockaddr_storage server_addr = addr_from_socket(server); + client = net_connected_socket(type, (struct sockaddr *)&server_addr, NULL); + ok(client >= 0, "%s: connected, create", name); + ok(!socket_is_blocking(client), "%s: connected, nonblocking mode", name); + + close(client); + close(server); +} + +static void test_nonblocking_accept(void) +{ + int r; + + // create server + + struct sockaddr_storage addr_server = addr_local(); + + int server = net_bound_socket(SOCK_STREAM, (struct sockaddr *)&addr_server, 0); + ok(server >= 0, "server, create socket"); + + r = listen(server, LISTEN_BACKLOG); + ok(r == 0, "server, start listening"); + + addr_server = addr_from_socket(server); + + // create client + + int client = net_connected_socket(SOCK_STREAM, (struct sockaddr *)&addr_server, NULL); + ok(client >= 0, "client, create connected socket"); + + struct sockaddr_storage addr_client = addr_from_socket(client); + + // accept connection + + r = poll_read(server); + ok(r == 1, "server, pending connection"); + + struct sockaddr_storage addr_accepted = { 0 }; + int accepted = net_accept(server, &addr_accepted); + ok(accepted >= 0, "server, accept connection"); + + ok(!socket_is_blocking(accepted), "accepted, nonblocking mode"); + + ok(sockaddr_cmp((struct sockaddr *)&addr_client, + (struct sockaddr *)&addr_accepted) == 0, + "accepted, correct address"); + + close(client); + + // client reconnect + + close(client); + client = net_connected_socket(SOCK_STREAM, (struct sockaddr *)&addr_server, NULL); + ok(client >= 0, "client, reconnect"); + + r = poll_read(server); + ok(r == 1, "server, pending connection"); + + accepted = net_accept(server, NULL); + ok(accepted >= 0, "server, accept connection (no remote address)"); + + ok(!socket_is_blocking(accepted), "accepted, nonblocking mode"); + + // cleanup + + close(client); + close(server); +} + +static void test_socket_types(void) +{ + struct sockaddr_storage addr = addr_local(); + + struct testcase { + const char *name; + int type; + bool is_stream; + }; + + const struct testcase testcases[] = { + { "UDP", SOCK_DGRAM, false }, + { "TCP", SOCK_STREAM, true }, + { NULL } + }; + + for (const struct testcase *t = testcases; t->name != NULL; t++) { + int sock = net_unbound_socket(t->type, (struct sockaddr *)&addr); + ok(sock >= 0, "%s, create socket", t->name); + + is_int(t->type, net_socktype(sock), "%s, socket type", t->name); + + ok(net_is_stream(sock) == t->is_stream, "%s, is stream", t->name); + + close(sock); + } + + is_int(AF_UNSPEC, net_socktype(-1), "invalid, socket type"); + ok(!net_is_stream(-1), "invalid, is stream"); +} + +static void test_bind_multiple(void) +{ + const struct sockaddr_storage addr = addr_local(); + + // bind first socket + + int sock_one = net_bound_socket(SOCK_DGRAM, (struct sockaddr *)&addr, NET_BIND_MULTIPLE); + if (sock_one == KNOT_ENOTSUP) { + skip("not supported on this system"); + return; + } + ok(sock_one >= 0, "bind first socket"); + + // bind second socket to the same address + + const struct sockaddr_storage addr_one = addr_from_socket(sock_one); + int sock_two = net_bound_socket(SOCK_DGRAM, (struct sockaddr *)&addr_one, NET_BIND_MULTIPLE); + ok(sock_two >= 0, "bind second socket"); + + // compare sockets + + ok(sock_one != sock_two, "descriptors are different"); + + const struct sockaddr_storage addr_two = addr_from_socket(sock_two); + ok(sockaddr_cmp((struct sockaddr *)&addr_one, + (struct sockaddr *)&addr_two) == 0, + "addresses are the same"); + + close(sock_one); + close(sock_two); +} + +static void signal_noop(int sig) +{ +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + signal(SIGUSR1, signal_noop); + + diag("nonblocking mode"); + test_nonblocking_mode(SOCK_DGRAM); + test_nonblocking_mode(SOCK_STREAM); + test_nonblocking_accept(); + + diag("socket types"); + test_socket_types(); + + diag("connected sockets"); + test_connected(SOCK_DGRAM); + test_connected(SOCK_STREAM); + + diag("unconnected sockets"); + test_unconnected(); + + diag("refused connections"); + test_refused(); + + diag("DNS messages over TCP"); + test_dns_tcp(); + + diag("flag NET_BIND_MULTIPLE"); + test_bind_multiple(); + + return 0; +} diff --git a/tests/contrib/test_net_shortwrite.c b/tests/contrib/test_net_shortwrite.c new file mode 100644 index 0000000..37b80ac --- /dev/null +++ b/tests/contrib/test_net_shortwrite.c @@ -0,0 +1,151 @@ +/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include <fcntl.h> +#include <stdint.h> +#include <string.h> +#include <pthread.h> +#include <poll.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + +#include "libknot/errcode.h" +#include "contrib/net.h" +#include "contrib/sockaddr.h" + +const int TIMEOUT = 2000; + +static struct sockaddr_storage localhost(void) +{ + struct sockaddr_storage addr = { 0 }; + + struct addrinfo *res = NULL; + if (getaddrinfo(NULL, "0", NULL, &res) == 0) { + memcpy(&addr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + } + + return addr; +} + +struct data { + int server_fd; + uint8_t *buffer; + size_t size; + int result; +}; + +static void *thr_receive(void *data) +{ + struct data *d = data; + + struct pollfd pfd = { .fd = d->server_fd, .events = POLLIN }; + int r = poll(&pfd, 1, TIMEOUT); + if (r != 1) { + d->result = KNOT_ETIMEOUT; + return NULL; + } + + int client = accept(d->server_fd, NULL, NULL); + if (client < 0) { + d->result = KNOT_ECONN; + return NULL; + } + + d->result = net_dns_tcp_recv(client, d->buffer, d->size, TIMEOUT); + + close(client); + + return NULL; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + int r; + + // create TCP server + + struct sockaddr_storage addr = localhost(); + int server = net_bound_socket(SOCK_STREAM, (struct sockaddr *)&addr, 0); + ok(server >= 0, "server: bind socket"); + + r = listen(server, 0); + ok(r == 0, "server: start listening"); + + struct sockaddr *sa = (struct sockaddr *)&addr; + socklen_t salen = sockaddr_len(sa); + r = getsockname(server, sa, &salen); + ok(r == 0, "server: get bound address"); + + // create TCP client + + int client = net_connected_socket(SOCK_STREAM, (struct sockaddr *)&addr, NULL); + ok(client >= 0, "client: connect to server"); + + int optval = 8192; + socklen_t optlen = sizeof(optval); + r = setsockopt(client, SOL_SOCKET, SO_SNDBUF, &optval, optlen); + ok(r == 0, "client: configure small send buffer"); + + // accept TCP connection on the background + + uint8_t recvbuf[UINT16_MAX] = { 0 }; + struct data recv_data = { + .server_fd = server, + .buffer = recvbuf, + .size = sizeof(recvbuf) + }; + + pthread_t thr; + r = pthread_create(&thr, NULL, thr_receive, &recv_data); + ok(r == 0, "server: start receiver thread"); + + // send message (should handle partial-write correctly) + + uint8_t sndbuf[UINT16_MAX]; + for (size_t i = 0; i < sizeof(sndbuf); i++) { + sndbuf[i] = i; + } + r = net_dns_tcp_send(client, sndbuf, sizeof(sndbuf), TIMEOUT); + ok(r == sizeof(sndbuf), "client: net_dns_tcp_send() with short-write"); + + // receive message + + r = pthread_join(thr, NULL); + ok(r == 0, "server: wait for receiver thread to terminate"); + + ok(recv_data.result == sizeof(recvbuf) && + memcmp(sndbuf, recvbuf, sizeof(recvbuf)) == 0, + "server: net_dns_tcp_recv() complete and valid data"); + + // clean up + + if (server >= 0) { + close(server); + } + + if (client >= 0) { + close(client); + } + + return 0; +} diff --git a/tests/contrib/test_qp-trie.c b/tests/contrib/test_qp-trie.c new file mode 100644 index 0000000..f1440f2 --- /dev/null +++ b/tests/contrib/test_qp-trie.c @@ -0,0 +1,202 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <tap/basic.h> + +#include "contrib/qp-trie/trie.h" +#include "contrib/macros.h" +#include "contrib/string.h" +#include "libknot/errcode.h" + +/* UCW array sorting defines. */ +#define ASORT_PREFIX(X) str_key_##X +#define ASORT_KEY_TYPE char* +#define ASORT_LT(x, y) (strcmp((x), (y)) < 0) +#include "contrib/ucw/array-sort.h" + +/* Constants. */ +#define KEY_MAXLEN 64 + +/*! \brief Generate random key. */ +static const char *alphabet = "abcdefghijklmn0123456789"; +static char *str_key_rand(size_t len) +{ + char *s = malloc(len); + memset(s, 0, len); + for (unsigned i = 0; i < len - 1; ++i) { + s[i] = alphabet[rand() % strlen(alphabet)]; + } + return s; +} + +/* \brief Check lesser or equal result. */ +static bool str_key_get_leq(trie_t *trie, char **keys, size_t i, size_t size) +{ + static char key_buf[KEY_MAXLEN]; + + int ret = 0; + trie_val_t *val = NULL; + const char *key = keys[i]; + size_t key_len = strlen(key) + 1; + memcpy(key_buf, key, key_len); + + /* Count equal first keys. */ + size_t first_key_count = 1; + for (size_t k = 1; k < size; ++k) { + if (strcmp(keys[0], keys[k]) == 0) { + first_key_count += 1; + } else { + break; + } + } + + /* Before current key. */ + key_buf[key_len - 2] -= 1; + if (i < first_key_count) { + ret = trie_get_leq(trie, key_buf, key_len, &val); + if (ret != KNOT_ENOENT) { + diag("%s: leq for key BEFORE %zu/'%s' ret = %d", __func__, i, keys[i], ret); + return false; /* No key before first. */ + } + } else { + ret = trie_get_leq(trie, key_buf, key_len, &val); + if (ret < KNOT_EOK || strcmp(*val, key_buf) > 0) { + diag("%s: '%s' is not before the key %zu/'%s'", __func__, (char*)*val, i, keys[i]); + return false; /* Found key must be LEQ than searched. */ + } + } + + /* Current key. */ + key_buf[key_len - 2] += 1; + ret = trie_get_leq(trie, key_buf, key_len, &val); + if (! (ret == KNOT_EOK && val && strcmp(*val, key_buf) == 0)) { + diag("%s: leq for key %zu/'%s' ret = %d", __func__, i, keys[i], ret); + return false; /* Must find equal match. */ + } + + /* After the current key. */ + key_buf[key_len - 2] += 1; + ret = trie_get_leq(trie, key_buf, key_len, &val); + if (! (ret >= KNOT_EOK && strcmp(*val, key_buf) <= 0)) { + diag("%s: leq for key AFTER %zu/'%s' ret = %d %s", __func__, i, keys[i], ret, (char*)*val); + return false; /* Every key must have its LEQ match. */ + } + + return true; + +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Random keys. */ + srand(time(NULL)); + unsigned key_count = 100000; + char **keys = malloc(sizeof(char*) * key_count); + for (unsigned i = 0; i < key_count; ++i) { + keys[i] = str_key_rand(KEY_MAXLEN); + } + + /* Sort random keys. */ + str_key_sort(keys, key_count); + + /* Create trie */ + trie_val_t *val = NULL; + trie_t *trie = trie_create(NULL); + ok(trie != NULL, "trie: create"); + + /* Insert keys */ + bool passed = true; + size_t inserted = 0; + for (unsigned i = 0; i < key_count; ++i) { + val = trie_get_ins(trie, keys[i], strlen(keys[i]) + 1); + if (!val) { + passed = false; + break; + } + if (*val == NULL) { + *val = keys[i]; + ++inserted; + } + } + ok(passed, "trie: insert"); + + /* Check total insertions against trie weight. */ + is_int(trie_weight(trie), inserted, "trie: trie weight matches insertions"); + + /* Lookup all keys */ + passed = true; + for (unsigned i = 0; i < key_count; ++i) { + val = trie_get_try(trie, keys[i], strlen(keys[i]) + 1); + if (val && (*val == keys[i] || strcmp(*val, keys[i]) == 0)) { + continue; + } else { + diag("trie: mismatch on element '%u'", i); + passed = false; + break; + } + } + ok(passed, "trie: lookup all keys"); + + /* Lesser or equal lookup. */ + passed = true; + for (unsigned i = 0; i < key_count; ++i) { + if (!str_key_get_leq(trie, keys, i, key_count)) { + passed = false; + for (int off = -10; off < 10; ++off) { + int k = (int)i + off; + if (k < 0 || k >= key_count) { + continue; + } + diag("[%u/%d]: %s%s", i, off, off == 0?">":"",keys[k]); + } + break; + } + } + ok(passed, "trie: find lesser or equal for all keys"); + + /* Sorted iteration. */ + char key_buf[KEY_MAXLEN] = {'\0'}; + size_t iterated = 0; + trie_it_t *it = trie_it_begin(trie); + while (!trie_it_finished(it)) { + size_t cur_key_len = 0; + const char *cur_key = trie_it_key(it, &cur_key_len); + if (iterated > 0) { /* Only if previous exists. */ + if (strcmp(key_buf, cur_key) > 0) { + diag("'%s' <= '%s' FAIL\n", key_buf, cur_key); + break; + } + } + ++iterated; + memcpy(key_buf, cur_key, cur_key_len); + trie_it_next(it); + } + is_int(inserted, iterated, "trie: sorted iteration"); + trie_it_free(it); + + /* Cleanup */ + for (unsigned i = 0; i < key_count; ++i) { + free(keys[i]); + } + free(keys); + trie_free(trie); + return 0; +} diff --git a/tests/contrib/test_siphash.c b/tests/contrib/test_siphash.c new file mode 100644 index 0000000..b7e2739 --- /dev/null +++ b/tests/contrib/test_siphash.c @@ -0,0 +1,135 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <tap/basic.h> + +// Prevent possible linking with a system SiphHash (OpenBSD). +#include "contrib/openbsd/siphash.c" + +// https://github.com/veorq/SipHash +const uint8_t vectors24[64][8] = { + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72 }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74 }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85 }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18 }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93 }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4 }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75 }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14 }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7 }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1 }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69 }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0 }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93 }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8 }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8 }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17 }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6 }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32 }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71 }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7 }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12 }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15 }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31 }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02 }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18 }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4 }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9 }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9 }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0 }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6 }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7 }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1 }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81 }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24 }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7 }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60 }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66 }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5 }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95 }, +}; + +static void block_test(SIPHASH_KEY *key, uint8_t *data, int data_len, int block_len) +{ + int count = data_len / block_len; + int rest = data_len % block_len; + + SIPHASH_CTX ctx; + SipHash24_Init(&ctx, key); + + for (int i = 0; i < count; i++) { + SipHash24_Update(&ctx, data + i * block_len, block_len); + } + SipHash24_Update(&ctx, data + count * block_len, rest); + + uint64_t hash = SipHash24_End(&ctx); + ok(memcmp(&hash, vectors24[data_len], sizeof(uint64_t)) == 0, + "siphash24: %i-byte block updates", block_len); +} + +int main(void) +{ + plan_lazy(); + + SIPHASH_KEY key; + memcpy(&key.k0, "\x00\x01\x02\x03\x04\x05\x06\x07", sizeof(uint64_t)); + memcpy(&key.k1, "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", sizeof(uint64_t)); + + uint8_t data[64]; + for (int i = 0; i < sizeof(data); i++) { + data[i] = i; + } + + for (int data_len = 0; data_len < sizeof(data); data_len++) { + diag("data length %i", data_len); + + uint64_t hash = SipHash24(&key, data, data_len); + ok(memcmp(&hash, vectors24[data_len], sizeof(uint64_t)) == 0, + "siphash24: 1-block update"); + + for (int block_len = 1; block_len <= 8; block_len++) { + block_test(&key, data, data_len, block_len); + } + } + + return 0; +} diff --git a/tests/contrib/test_sockaddr.c b/tests/contrib/test_sockaddr.c new file mode 100644 index 0000000..5f80507 --- /dev/null +++ b/tests/contrib/test_sockaddr.c @@ -0,0 +1,234 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "contrib/sockaddr.h" +#include "libknot/errcode.h" + +struct sockaddr *SA(struct sockaddr_storage *ss) +{ + return (struct sockaddr *)ss; +} + +static void test_sockaddr_is_any(void) +{ + struct sockaddr_storage invalid = { 0 }; + ok(!sockaddr_is_any(SA(&invalid)), "sockaddr_is_any: invalid"); + + struct sockaddr_storage path = { 0 }; + path.ss_family = AF_UNIX; + ok(!sockaddr_is_any(SA(&path)), "sockaddr_is_any: unix"); + + struct sockaddr_storage ipv4_local = { 0 }; + sockaddr_set(&ipv4_local, AF_INET, "127.0.0.1", 0); + ok(!sockaddr_is_any(SA(&ipv4_local)), "sockaddr_is_any: IPv4 local"); + + struct sockaddr_storage ipv4_any = { 0 }; + sockaddr_set(&ipv4_any, AF_INET, "0.0.0.0", 0); + ok(sockaddr_is_any(SA(&ipv4_any)), "sockaddr_is_any: IPv4 any"); + + struct sockaddr_storage ipv6_local = { 0 }; + sockaddr_set(&ipv6_local, AF_INET6, "::1", 0); + ok(!sockaddr_is_any(SA(&ipv6_local)), "sockaddr_is_any: IPv6 local"); + + struct sockaddr_storage ipv6_any = { 0 }; + sockaddr_set(&ipv6_any, AF_INET6, "::", 0); + ok(sockaddr_is_any(SA(&ipv6_any)), "sockaddr_is_any: IPv6 any"); +} + +static void check_sockaddr_set(struct sockaddr_storage *ss, int family, + const char *straddr, int port) +{ + int ret = sockaddr_set(ss, family, straddr, port); + is_int(KNOT_EOK, ret, "set address '%s'", straddr); +} + +static void test_net_match(void) +{ + int ret; + struct sockaddr_storage t = { 0 }; + + // 127 dec ~ 01111111 bin + // 170 dec ~ 10101010 bin + struct sockaddr_storage ref4 = { 0 }; + check_sockaddr_set(&ref4, AF_INET, "127.170.170.127", 0); + + // 7F hex ~ 01111111 bin + // AA hex ~ 10101010 bin + struct sockaddr_storage ref6 = { 0 }; + check_sockaddr_set(&ref6, AF_INET6, "7FAA::AA7F", 0); + + ret = sockaddr_net_match(SA(&ref4), SA(&ref6), 32); + ok(ret == false, "match: family mismatch"); + + ret = sockaddr_net_match(NULL, SA(&ref4), 32); + ok(ret == false, "match: NULL first parameter"); + ret = sockaddr_net_match(SA(&ref4), NULL, 32); + ok(ret == false, "match: NULL second parameter"); + + ret = sockaddr_net_match(SA(&ref4), SA(&ref4), -1); + ok(ret == true, "match: ipv4 - identity, auto full prefix"); + ret = sockaddr_net_match(SA(&ref4), SA(&ref4), 31); + ok(ret == true, "match: ipv4 - identity, subnet"); + ret = sockaddr_net_match(SA(&ref4), SA(&ref4), 32); + ok(ret == true, "match: ipv4 - identity, full prefix"); + ret = sockaddr_net_match(SA(&ref4), SA(&ref4), 33); + ok(ret == true, "match: ipv4 - identity, prefix overflow"); + + ret = sockaddr_net_match(SA(&ref6), SA(&ref6), -1); + ok(ret == true, "match: ipv6 - identity, auto full prefix"); + ret = sockaddr_net_match(SA(&ref6), SA(&ref6), 127); + ok(ret == true, "match: ipv6 - identity, subnet"); + ret = sockaddr_net_match(SA(&ref6), SA(&ref6), 128); + ok(ret == true, "match: ipv6 - identity, full prefix"); + ret = sockaddr_net_match(SA(&ref6), SA(&ref6), 129); + ok(ret == true, "match: ipv6 - identity, prefix overflow"); + + // 124 dec ~ 01111100 bin + check_sockaddr_set(&t, AF_INET, "124.0.0.0", 0); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 5); + ok(ret == true, "match: ipv4 - first byte, shorter prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 6); + ok(ret == true, "match: ipv4 - first byte, precise prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 7); + ok(ret == false, "match: ipv4 - first byte, not match"); + + check_sockaddr_set(&t, AF_INET, "127.170.170.124", 0); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 29); + ok(ret == true, "match: ipv4 - last byte, shorter prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 30); + ok(ret == true, "match: ipv4 - last byte, precise prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 31); + ok(ret == false, "match: ipv4 - last byte, not match"); + + // 7C hex ~ 01111100 bin + check_sockaddr_set(&t, AF_INET6, "7CAA::", 0); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 5); + ok(ret == true, "match: ipv6 - first byte, shorter prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 6); + ok(ret == true, "match: ipv6 - first byte, precise prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 7); + ok(ret == false, "match: ipv6 - first byte, not match"); + + check_sockaddr_set(&t, AF_INET6, "7FAA::AA7C", 0); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 125); + ok(ret == true, "match: ipv6 - last byte, shorter prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 126); + ok(ret == true, "match: ipv6 - last byte, precise prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 127); + ok(ret == false, "match: ipv6 - last byte, not match"); +} + +static void test_range_match(void) +{ + bool ret; + struct sockaddr_storage t = { 0 }; + struct sockaddr_storage min = { 0 }; + struct sockaddr_storage max = { 0 }; + + // IPv4 tests. + + check_sockaddr_set(&min, AF_INET, "0.0.0.0", 0); + check_sockaddr_set(&max, AF_INET, "255.255.255.255", 0); + + check_sockaddr_set(&t, AF_INET, "0.0.0.0", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 max range - minimum"); + check_sockaddr_set(&t, AF_INET, "255.255.255.255", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 max range - maximum"); + + check_sockaddr_set(&min, AF_INET, "1.13.113.213", 0); + check_sockaddr_set(&max, AF_INET, "2.24.124.224", 0); + + check_sockaddr_set(&t, AF_INET, "1.12.113.213", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv4 middle range - negative far min"); + check_sockaddr_set(&t, AF_INET, "1.13.113.212", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv4 middle range - negative close min"); + check_sockaddr_set(&t, AF_INET, "1.13.113.213", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 middle range - minimum"); + check_sockaddr_set(&t, AF_INET, "1.13.213.213", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 middle range - middle"); + check_sockaddr_set(&t, AF_INET, "2.24.124.224", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 middle range - max"); + check_sockaddr_set(&t, AF_INET, "2.24.124.225", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv4 middle range - negative close max"); + check_sockaddr_set(&t, AF_INET, "2.25.124.225", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv4 middle range - negative far max"); + + // IPv6 tests. + + check_sockaddr_set(&min, AF_INET6, "::0", 0); + check_sockaddr_set(&max, AF_INET6, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 0); + + check_sockaddr_set(&t, AF_INET6, "::0", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 max range - minimum"); + check_sockaddr_set(&t, AF_INET6, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 max range - maximum"); + + check_sockaddr_set(&min, AF_INET6, "1:13::ABCD:200B", 0); + check_sockaddr_set(&max, AF_INET6, "2:A24::124:224", 0); + + check_sockaddr_set(&t, AF_INET6, "1:12::BCD:2000", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv6 middle range - negative far min"); + check_sockaddr_set(&t, AF_INET6, "1:13::ABCD:200A", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv6 middle range - negative close min"); + check_sockaddr_set(&t, AF_INET6, "1:13::ABCD:200B", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 middle range - minimum"); + check_sockaddr_set(&t, AF_INET6, "1:13:0:12:34:0:ABCD:200B", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 middle range - middle"); + check_sockaddr_set(&t, AF_INET6, "2:A24::124:224", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 middle range - max"); + check_sockaddr_set(&t, AF_INET6, "2:A24::124:225", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv6 middle range - negative close max"); + check_sockaddr_set(&t, AF_INET6, "2:FA24::4:24", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv6 middle range - negative far max"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("sockaddr_is_any"); + test_sockaddr_is_any(); + + diag("sockaddr_net_match"); + test_net_match(); + + diag("sockaddr_range_match"); + test_range_match(); + + return 0; +} diff --git a/tests/contrib/test_string.c b/tests/contrib/test_string.c new file mode 100644 index 0000000..fca8b8a --- /dev/null +++ b/tests/contrib/test_string.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include <stdlib.h> + +#include "contrib/string.h" + +static void test_strstrip(void) +{ + char *c = NULL; + + c = strstrip("hello"); + is_string("hello", c, "strstrip: no whitespace"); + free(c); + + c = strstrip("world \n"); + is_string("world", c, "strstrip: trailing whitespace"); + free(c); + + c = strstrip(" \n banana"); + is_string("banana", c, "strstrip: leading whitespace"); + free(c); + + c = strstrip(" \t hello world \n"); + is_string("hello world", c, "strstrip: leading and trailing"); + free(c); + + c = strstrip(""); + is_string("", c, "strstrip: empty string"); + free(c); + + c = strstrip(" "); + is_string("", c, "strstrip: just whitespaces"); + free(c); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_strstrip(); + + return 0; +} diff --git a/tests/contrib/test_strtonum.c b/tests/contrib/test_strtonum.c new file mode 100644 index 0000000..48f2559 --- /dev/null +++ b/tests/contrib/test_strtonum.c @@ -0,0 +1,156 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <tap/basic.h> + +#include "contrib/strtonum.h" +#include "libdnssec/error.h" + +static void test_u8(const char *in, uint8_t expected, int errcode) +{ + uint8_t out = 0x11; + assert(expected != out); + + ok(str_to_u8(in, &out) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_u8 %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +static void test_u16(const char *in, uint16_t expected, int errcode) +{ + uint16_t out = 0x0101; + assert(expected != out); + + ok(str_to_u16(in, &out) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_u16 %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +static void test_u32(const char *in, uint32_t expected, int errcode) +{ + uint32_t out = 0x010101; + assert(expected != out); + + ok(str_to_u32(in, &out) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_u32 %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +static void test_int(const char *in, int expected, int errcode) +{ + int out = 12345; + assert(expected != out); + + ok(str_to_int(in, &out, INT_MIN, INT_MAX) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_int %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +static void test_size(const char *in, size_t expected, size_t min, size_t max, + int errcode) +{ + size_t out = 12345; + assert(expected != out); + + ok(str_to_size(in, &out, min, max) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_int %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +// mute warn_unused_result +#define asprintf(args, ...) do { \ + int r = (asprintf)(args, ##__VA_ARGS__); assert(r >= 0); (void)r; \ +} while (0); + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_u8("-1", 0, KNOT_EINVAL); + test_u8("256", 0, KNOT_ERANGE); + test_u8("0x1", 0, KNOT_EINVAL); + test_u8(" 1", 0, KNOT_EINVAL); + test_u8("1 ", 0, KNOT_EINVAL); + test_u8("0", 0, KNOT_EOK); + test_u8("42", 42, KNOT_EOK); + test_u8("+84", 84, KNOT_EOK); + test_u8("255", UINT8_MAX, KNOT_EOK); + + test_u16("-1", 0, KNOT_EINVAL); + test_u16("65536", 0, KNOT_ERANGE); + test_u16("0x1", 0, KNOT_EINVAL); + test_u16(" 1", 0, KNOT_EINVAL); + test_u16("1 ", 0, KNOT_EINVAL); + test_u16("0", 0, KNOT_EOK); + test_u16("65280", 65280, KNOT_EOK); + test_u16("+256", 256, KNOT_EOK); + test_u16("65535", UINT16_MAX, KNOT_EOK); + + test_u32("-1", 0, KNOT_EINVAL); + test_u32("4294967296", 0, KNOT_ERANGE); + test_u32("0x1", 0, KNOT_EINVAL); + test_u32(" 1", 0, KNOT_EINVAL); + test_u32("1 ", 0, KNOT_EINVAL); + test_u32("0", 0, KNOT_EOK); + test_u32("65280", 65280, KNOT_EOK); + test_u32("+256", 256, KNOT_EOK); + test_u32("4294967295", UINT32_MAX, KNOT_EOK); + + test_size("-1", 0, 0, 1, KNOT_EINVAL); + test_size("4294967296", 0, 0, 1, KNOT_ERANGE); + test_size("0", 0, 1, 2, KNOT_ERANGE); + test_size("0x1", 0, 0, 1, KNOT_EINVAL); + test_size(" 1", 0, 0, 1, KNOT_EINVAL); + test_size("1 ", 0, 0, 1, KNOT_EINVAL); + test_size("0", 0, 0, 1, KNOT_EOK); + test_size("65280", 65280, 0, 65280, KNOT_EOK); + test_size("+256", 256, 0, 65280, KNOT_EOK); + + char *int_under = NULL; + asprintf(&int_under, "%lld", (long long)INT_MIN - 1); + char *int_min = NULL; + asprintf(&int_min, "%lld", (long long)INT_MIN); + char *int_max = NULL; + asprintf(&int_max, "%lld", (long long)INT_MAX); + char *int_over = NULL; + asprintf(&int_over, "%lld", (long long)INT_MAX + 1); + + test_int(int_under, 0, KNOT_ERANGE); + test_int(int_over, 0, KNOT_ERANGE); + test_int("0x1", 0, KNOT_EINVAL); + test_int(" 1", 0, KNOT_EINVAL); + test_int("1 ", 0, KNOT_EINVAL); + test_int(int_min, INT_MIN, KNOT_EOK); + test_int("0", 0, KNOT_EOK); + test_int("268435459", 268435459, KNOT_EOK); + test_int("+1073741827", 1073741827, KNOT_EOK); + test_int(int_max, INT_MAX, KNOT_EOK); + + free(int_under); + free(int_min); + free(int_max); + free(int_over); + + return 0; +} diff --git a/tests/contrib/test_time.c b/tests/contrib/test_time.c new file mode 100644 index 0000000..a21f8c2 --- /dev/null +++ b/tests/contrib/test_time.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <string.h> + +#include "contrib/time.h" + +static void test_now(void) +{ + struct timespec t = time_now(); + ok(t.tv_sec != 0, "time_now() returns something"); +} + +static void test_diff(void) +{ + struct timespec t1 = { 10, 1000 }; + struct timespec t2 = { 50, 1500 }; + struct timespec t3 = { 70, 500 }; + + struct timespec res; + + res = time_diff(&t1, &t2); + ok(res.tv_sec == 40 && res.tv_nsec == 500, "time_diff()"); + + res = time_diff(&t2, &t3); + ok(res.tv_sec == 19 && res.tv_nsec == 999999000, "time_diff() ns overflow"); + + res = time_diff(&t3, &t1); + ok(res.tv_sec == -60 && res.tv_nsec == 500, "time_diff() negative"); + + res = time_diff(&t2, &t1); + ok(res.tv_sec == -41 && res.tv_nsec == 999999500, "time_diff() negative"); +} + +static void test_diff_ms(void) +{ + struct timespec t1 = { 10, 1000 }; + struct timespec t2 = { 50, 500 }; + + float ms = 0.0; + + ms = time_diff_ms(&t1, &t2); + ok(39990.0 < ms && ms < 40010.0, "time_diff_ms()"); + + ms = time_diff_ms(&t2, &t1); + ok(-40010.0 < ms && ms < -39990.0, "time_diff_ms() negative"); +} + +static void test_knot_time(void) +{ + knot_time_t a = knot_time(); + knot_time_t inf = 0; + knot_time_t c; + knot_timediff_t d; + int ret; + + ok(a != 0, "knot time not zero"); + + ret = knot_time_cmp(a, a); + ok(ret == 0, "compare same times"); + + ret = knot_time_cmp(a - 1, a + 1); + ok(ret == -1, "compare smaller time"); + + ret = knot_time_cmp(a + 10, a - 10); + ok(ret == 1, "compare bigger time"); + + ret = knot_time_cmp(inf, inf); + ok(ret == 0, "compare two infinities"); + + ret = knot_time_cmp(a, inf); + ok(ret == -1, "compare time and infty"); + + ret = knot_time_cmp(inf, a); + ok(ret == 1, "compare infty and time"); + + c = knot_time_min(a, a); + ok(c == a, "take same time"); + + c = knot_time_min(a, a + 1); + ok(c == a, "take first smaller"); + + c = knot_time_min(a + 1, a); + ok(c == a, "take second smaller"); + + c = knot_time_min(inf, inf); + ok(c == inf, "take same infty"); + + c = knot_time_min(a, inf); + ok(c == a, "take first finite"); + + c = knot_time_min(inf, a); + ok(c == a, "take second finite"); + + d = knot_time_diff(a + 1, a); + ok(d == 1, "positive diff"); + + d = knot_time_diff(a, a + 1); + ok(d == -1, "negative diff"); + + d = knot_time_diff(inf, inf); + ok(d == KNOT_TIMEDIFF_MAX, "positive double infty diff"); + + d = knot_time_diff(inf, a); + ok(d == KNOT_TIMEDIFF_MAX, "positive infty diff"); + + d = knot_time_diff(a, inf); + ok(d == KNOT_TIMEDIFF_MIN, "negative infty diff"); +} + +static void test_time_parse_expect(int ret, knot_time_t res, + knot_time_t expected, const char *msg) +{ + ok(ret == 0, "time_parse %s ok", msg); + ok(res == expected, "time_parse %s result", msg); +} + +static void test_time_parse(void) +{ + knot_time_t res; + int ret; + + ret = knot_time_parse("", "", &res); + test_time_parse_expect(ret, res, 0, "nihilist"); + + ret = knot_time_parse("#", "12345", &res); + test_time_parse_expect(ret, res, 12345, "unix"); + + ret = knot_time_parse("+-#U", "-1h", &res); + test_time_parse_expect(ret, res, knot_time() - 3600, "hour"); + + ret = knot_time_parse("+-#u'nths'|+-#u'nutes'", "+1minutes", &res); + test_time_parse_expect(ret, res, knot_time() + 60, "minute"); +} + +static void test_time_print_expect(int ret, const char *res, int res_len, + const char *expected, const char *msg) +{ + ok(ret == 0, "time_print %s ok", msg); + ok(strncmp(res, expected, res_len) == 0, "time_print %s result", msg); +} + +static void test_time_print(void) +{ + char buff[100]; + int bufl = sizeof(buff); + int ret; + knot_time_t t = 44000, t2, big; + + ret = knot_time_print(TIME_PRINT_UNIX, t, buff, bufl); + test_time_print_expect(ret, buff, bufl, "44000", "unix"); + + t2 = knot_time_add(knot_time(), -10000); + ret = knot_time_print(TIME_PRINT_RELSEC, t2, buff, bufl); + test_time_print_expect(ret, buff, bufl, "-10000", "relsec"); + + ret = knot_time_print(TIME_PRINT_ISO8601, t, buff, bufl); + buff[11] = '0', buff[12] = '0'; // zeroing 'hours' field to avoid locality issues + test_time_print_expect(ret, buff, bufl, "1970-01-01T00:13:20Z", "iso"); + + t2 = knot_time_add(knot_time(), -10000); + ret = knot_time_print(TIME_PRINT_HUMAN_MIXED, t2, buff, bufl); + test_time_print_expect(ret, buff, bufl, "-2h46m40s", "negative human mixed"); + big = knot_time_add(knot_time(), 2 * 365 * 24 * 3600 + 1); + ret = knot_time_print(TIME_PRINT_HUMAN_MIXED, big, buff, bufl); + test_time_print_expect(ret, buff, bufl, "+2Y1s", "big human mixed"); + + t2 = knot_time_add(knot_time(), -10000); + ret = knot_time_print(TIME_PRINT_HUMAN_LOWER, t2, buff, bufl); + test_time_print_expect(ret, buff, bufl, "-2h46mi40s", "negative human lower"); + big = knot_time_add(knot_time(), 2 * 365 * 24 * 3600 + 1); + ret = knot_time_print(TIME_PRINT_HUMAN_LOWER, big, buff, bufl); + test_time_print_expect(ret, buff, bufl, "+2y1s", "big human lower"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_now(); + test_diff(); + test_diff_ms(); + test_knot_time(); + test_time_parse(); + test_time_print(); + + return 0; +} diff --git a/tests/contrib/test_wire_ctx.c b/tests/contrib/test_wire_ctx.c new file mode 100644 index 0000000..93456c3 --- /dev/null +++ b/tests/contrib/test_wire_ctx.c @@ -0,0 +1,287 @@ +/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <netinet/in.h> +#include <stdio.h> + +#include "libknot/errcode.h" +#include "contrib/wire_ctx.h" + +#define OK(wire) { \ + is_int(KNOT_EOK, (wire)->error, "check for no error"); \ +} + +#define NOK(wire, code) { \ + is_int(code, (wire)->error, "check for error"); \ +} + +void ok_offset(wire_ctx_t *wire, size_t max, size_t i) +{ + wire_ctx_set_offset(wire, i); + OK(wire); + is_int(max - i, wire_ctx_available(wire), "get available %zu", max - i); + OK(wire); + is_int(i, wire_ctx_offset(wire), "get start position %zu", i); + OK(wire); +} + +void nok_offset(wire_ctx_t *wire, size_t max) +{ + wire_ctx_set_offset(wire, max); + OK(wire); + wire_ctx_set_offset(wire, max + 1); + NOK(wire, KNOT_ERANGE); + is_int(0, wire_ctx_available(wire), "get available %i", 0); + NOK(wire, KNOT_ERANGE); + is_int(max, wire_ctx_offset(wire), "get last start position %zu", max); + NOK(wire, KNOT_ERANGE); +} + +void offset_test(void) +{ + diag("offset operation"); + + const size_t LEN = 3; + uint8_t data[LEN]; + + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); + + // First free byte. + ok_offset(&wire, LEN, 0); + // Last free byte. + ok_offset(&wire, LEN, 2); + // First non-free byte. + ok_offset(&wire, LEN, 3); + // Invalid offset. + nok_offset(&wire, LEN); +} + +void skip_test(void) +{ + diag("skip operation"); + + uint8_t data[3]; + + // Forward skips. + + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); + + wire_ctx_skip(&wire, 2); + OK(&wire); + is_int(2, wire_ctx_offset(&wire), "skip by offset %i", 2); + + wire_ctx_skip(&wire, 1); + OK(&wire); + is_int(3, wire_ctx_offset(&wire), "skip by offset %i", 1); + + // Out-of-bounds skip. + wire_ctx_skip(&wire, 1); + NOK(&wire, KNOT_ERANGE); + is_int(3, wire_ctx_offset(&wire), "out-of-bounds skip by %i", 1); + + // Backward skips. + + wire = wire_ctx_init(data, sizeof(data)); + + wire_ctx_set_offset(&wire, 3); + OK(&wire); + + wire_ctx_skip(&wire, -2); + OK(&wire); + is_int(1, wire_ctx_offset(&wire), "skip by offset %i", -2); + + wire_ctx_skip(&wire, -1); + OK(&wire); + is_int(0, wire_ctx_offset(&wire), "skip by offset %i", -1); + + // Out-of-bounds skip. + wire_ctx_skip(&wire, -1); + NOK(&wire, KNOT_ERANGE); + is_int(0, wire_ctx_offset(&wire), "out-of-bounds skip by %i", -1); +} + +void clear_test(void) +{ + diag("clear operation"); + + uint8_t data[] = { 1, 2, 3 }; + + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); + + wire_ctx_clear(&wire, 10); + NOK(&wire, KNOT_ESPACE); + is_int(1, data[0], "no attempt to clear"); + + wire = wire_ctx_init(data, sizeof(data)); + wire_ctx_clear(&wire, 3); + OK(&wire); + is_int(0, wire_ctx_available(&wire), "no space available"); + for (int i = 0; i < sizeof(data); i++) { + is_int(0, data[i], "wire position %i is zero", i); + } +} + +#define check_rw(size, value, ...) { \ + const uint8_t expect[] = { __VA_ARGS__ }; \ + uint8_t data[sizeof(expect)] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); \ + \ + wire_ctx_write_u ## size(&wire, value); \ + OK(&wire); \ + ok(memcmp(data, expect, sizeof(expect)) == 0, "write %i value", size); \ + is_int(size/8, wire_ctx_offset(&wire), "write %i offset", size); \ + \ + wire_ctx_set_offset(&wire, 0); \ + OK(&wire); \ + \ + uint64_t num = wire_ctx_read_u ## size(&wire); \ + OK(&wire); \ + is_int(value, num, "read %i value", size); \ + is_int(size/8, wire_ctx_offset(&wire), "read %i offset", size); \ +} + +#define check_general_rw(...) { \ + const uint8_t expect[] = { __VA_ARGS__ }; \ + uint8_t data[sizeof(expect)] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); \ + \ + wire_ctx_write(&wire, expect, sizeof(expect)); \ + OK(&wire); \ + ok(memcmp(data, expect, sizeof(expect)) == 0, "write value"); \ + is_int(sizeof(expect), wire_ctx_offset(&wire), "write offset"); \ + \ + wire_ctx_set_offset(&wire, 0); \ + OK(&wire); \ + \ + uint8_t d[sizeof(expect)] = { 0 }; \ + wire_ctx_read(&wire, d, sizeof(expect)); \ + OK(&wire); \ + ok(memcmp(d, expect, sizeof(expect)) == 0, "read value"); \ + is_int(sizeof(expect), wire_ctx_offset(&wire), "read offset"); \ +} + +void read_write_test(void) +{ + diag("read and write operation"); + + check_rw( 8, 0x11, 0x11); + check_rw(16, 0x1122, 0x11, 0x22); + check_rw(32, 0x11223344, 0x11, 0x22, 0x33, 0x44); + check_rw(48, 0x112233445566, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66); + check_rw(64, 0x1122334455667788, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88); + + check_general_rw(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x10); +} + +#define check_rw_over(size) { \ + uint8_t data[1] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); \ + wire_ctx_set_offset(&wire, 1); \ + OK(&wire); \ + \ + wire_ctx_write_u ## size(&wire, 0); \ + NOK(&wire, KNOT_ESPACE); \ + is_int(1, wire_ctx_offset(&wire), "err write %i offset", size); \ + \ + wire = wire_ctx_init(data, sizeof(data)); \ + wire_ctx_set_offset(&wire, 1); \ + OK(&wire); \ + \ + uint64_t num = wire_ctx_read_u ## size(&wire); \ + NOK(&wire, KNOT_EFEWDATA); \ + is_int(0, num, "err read %i value", size); \ + is_int(1, wire_ctx_offset(&wire), "err read %i offset", size); \ +} + +#define check_general_rw_over(void) { \ + uint8_t data[1] = { 0 }; \ + uint8_t d[2] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); \ + wire_ctx_write(&wire, d, sizeof(d)); \ + NOK(&wire, KNOT_ESPACE); \ + is_int(0, wire_ctx_offset(&wire), "err write offset"); \ + \ + wire = wire_ctx_init(data, sizeof(data)); \ + wire_ctx_read(&wire, d, sizeof(d)); \ + NOK(&wire, KNOT_EFEWDATA); \ + is_int(0, wire_ctx_offset(&wire), "err read offset"); \ +} + +void read_write_overflow_test(void) +{ + diag("overflow read and write operation"); + + check_rw_over(8); + check_rw_over(16); + check_rw_over(32); + check_rw_over(48); + check_rw_over(64); + + check_general_rw_over(); +} + +#define check_ro(size) { \ + uint8_t data[8] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init_const(data, sizeof(data)); \ + \ + wire_ctx_write_u ## size(&wire, 0); \ + NOK(&wire, KNOT_EACCES); \ + is_int(0, wire_ctx_offset(&wire), "err write %i offset", size); \ +} + +#define check_general_ro(void) { \ + uint8_t data[8] = { 0 }; \ + uint8_t d[2] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init_const(data, sizeof(data)); \ + \ + wire_ctx_write(&wire, d, sizeof(d)); \ + NOK(&wire, KNOT_EACCES); \ + is_int(0, wire_ctx_offset(&wire), "err write offset"); \ +} + +void write_readonly_test(void) +{ + diag("readonly write operation"); + + check_ro(8); + check_ro(16); + check_ro(32); + check_ro(48); + check_ro(64); + + check_general_ro(); +} + +int main(void) +{ + plan_lazy(); + + offset_test(); + skip_test(); + clear_test(); + read_write_test(); + read_write_overflow_test(); + write_readonly_test(); + + return 0; +} diff --git a/tests/knot/semantic_check_data/cdnskey.cds b/tests/knot/semantic_check_data/cdnskey.cds new file mode 100644 index 0000000..354ad81 --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.cds @@ -0,0 +1,10 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns2.example.com. hostmaster.example.com. 2010135808 10800 3600 1209600 7200 +example.com. 3600 NS dns2.example.com. +example.com. 3600 MX 10 mail.example.com. +example.com. 3600 DNSKEY 256 3 8 AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVwYkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEeCUJfyc/mRXcmh5uYl1JvzAM1zprtljZt +example.com. 3600 DNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 DNSKEY 257 3 8 AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKfjqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU80AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbmLIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpMCLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRndpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n/4lgdSiBtvByLCXoWEYIGRs= +example.com. 3600 CDNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 CDS 53851 8 2 6F8129D687EC387C948E6F4B0AC9AA01481CCEBF7570AFEC582897E7725122D6 +dns2.example.com. 3600 A 192.0.2.1 diff --git a/tests/knot/semantic_check_data/cdnskey.invalid b/tests/knot/semantic_check_data/cdnskey.invalid new file mode 100644 index 0000000..9c971ab --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.invalid @@ -0,0 +1,10 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns2.example.com. hostmaster.example.com. 2010135808 10800 3600 1209600 7200 +example.com. 3600 NS dns2.example.com. +example.com. 3600 MX 10 mail.example.com. +example.com. 3600 DNSKEY 256 3 8 AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVwYkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEeCUJfyc/mRXcmh5uYl1JvzAM1zprtljZt +example.com. 3600 DNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 DNSKEY 257 3 8 AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKfjqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU80AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbmLIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpMCLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRndpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n/4lgdSiBtvByLCXoWEYIGRs= +example.com. 3600 CDNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 CDS 53851 8 2 668159D684EC387C948E6F4B0AC9AA01481CCEBF7570AFEC582897E7725122D6 +dns2.example.com. 3600 A 192.0.2.1 diff --git a/tests/knot/semantic_check_data/cdnskey.invalid.param b/tests/knot/semantic_check_data/cdnskey.invalid.param new file mode 100644 index 0000000..07f78db --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.invalid.param @@ -0,0 +1,10 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns2.example.com. hostmaster.example.com. 2010135808 10800 3600 1209600 7200 +example.com. 3600 NS dns2.example.com. +example.com. 3600 MX 10 mail.example.com. +example.com. 3600 DNSKEY 256 3 8 AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVwYkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEeCUJfyc/mRXcmh5uYl1JvzAM1zprtljZt +example.com. 3600 DNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 DNSKEY 257 3 8 AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKfjqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU80AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbmLIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpMCLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRndpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n/4lgdSiBtvByLCXoWEYIGRs= +example.com. 3600 CDNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 CDS 53851 4 2 6F8129D687EC387C948E6F4B0AC9AA01481CCEBF7570AFEC582897E7725122D6 +dns2.example.com. 3600 A 192.0.2.1 diff --git a/tests/knot/semantic_check_data/cdnskey.nocdnskey b/tests/knot/semantic_check_data/cdnskey.nocdnskey new file mode 100644 index 0000000..40c3096 --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.nocdnskey @@ -0,0 +1,9 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns2.example.com. hostmaster.example.com. 2010135808 10800 3600 1209600 7200 +example.com. 3600 NS dns2.example.com. +example.com. 3600 MX 10 mail.example.com. +example.com. 3600 DNSKEY 256 3 8 AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVwYkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEeCUJfyc/mRXcmh5uYl1JvzAM1zprtljZt +example.com. 3600 DNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 DNSKEY 257 3 8 AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKfjqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU80AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbmLIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpMCLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRndpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n/4lgdSiBtvByLCXoWEYIGRs= +example.com. 3600 CDS 53851 8 2 6F8129D687EC387C948E6F4B0AC9AA01481CCEBF7570AFEC582897E7725122D6 +dns2.example.com. 3600 A 192.0.2.1 diff --git a/tests/knot/semantic_check_data/cdnskey.nocds b/tests/knot/semantic_check_data/cdnskey.nocds new file mode 100644 index 0000000..8966caf --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.nocds @@ -0,0 +1,9 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns2.example.com. hostmaster.example.com. 2010135808 10800 3600 1209600 7200 +example.com. 3600 NS dns2.example.com. +example.com. 3600 MX 10 mail.example.com. +example.com. 3600 DNSKEY 256 3 8 AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVwYkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEeCUJfyc/mRXcmh5uYl1JvzAM1zprtljZt +example.com. 3600 DNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 DNSKEY 257 3 8 AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKfjqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU80AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbmLIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpMCLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRndpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n/4lgdSiBtvByLCXoWEYIGRs= +example.com. 3600 CDNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +dns2.example.com. 3600 A 192.0.2.1 diff --git a/tests/knot/semantic_check_data/cdnskey.nodnskey b/tests/knot/semantic_check_data/cdnskey.nodnskey new file mode 100644 index 0000000..8f8e458 --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.nodnskey @@ -0,0 +1,9 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns2.example.com. hostmaster.example.com. 2010135808 10800 3600 1209600 7200 +example.com. 3600 NS dns2.example.com. +example.com. 3600 MX 10 mail.example.com. +example.com. 3600 DNSKEY 256 3 8 AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVwYkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEeCUJfyc/mRXcmh5uYl1JvzAM1zprtljZt +example.com. 3600 DNSKEY 257 3 8 AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKfjqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU80AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbmLIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpMCLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRndpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n/4lgdSiBtvByLCXoWEYIGRs= +example.com. 3600 CDNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 CDS 53851 8 2 6F8129D687EC387C948E6F4B0AC9AA01481CCEBF7570AFEC582897E7725122D6 +dns2.example.com. 3600 A 192.0.2.1 diff --git a/tests/knot/semantic_check_data/cdnskey.two b/tests/knot/semantic_check_data/cdnskey.two new file mode 100644 index 0000000..81c4a1f --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.two @@ -0,0 +1,13 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns2.example.com. hostmaster.example.com. 2010135808 10800 3600 1209600 7200 +example.com. 3600 NS dns2.example.com. +example.com. 3600 MX 10 mail.example.com. +example.com. 3600 DNSKEY 256 3 8 AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVwYkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEeCUJfyc/mRXcmh5uYl1JvzAM1zprtljZt +example.com. 3600 DNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 DNSKEY 257 3 8 AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKfjqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU80AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbmLIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpMCLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRndpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n/4lgdSiBtvByLCXoWEYIGRs= +example.com. 3600 CDNSKEY 257 3 8 AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYToARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5WmnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Tax7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCNbGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4NodQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQEHYAd/AP8YgaovS8N1fJyh0= +example.com. 3600 CDNSKEY 257 3 8 AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKfjqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU80AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbmLIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpMCLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRndpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n/4lgdSiBtvByLCXoWEYIGRs= + +example.com. 3600 CDS 53851 8 2 6F8129D687EC387C948E6F4B0AC9AA01481CCEBF7570AFEC582897E7725122D6 +example.com. 3600 CDS 53852 8 2 6F8129D687EC387C948E6F4B0AC9AA01481CCEBF7570AFEC582897E7725122D6 +dns2.example.com. 3600 A 192.0.2.1 diff --git a/tests/knot/semantic_check_data/cname_extra_01.zone b/tests/knot/semantic_check_data/cname_extra_01.zone new file mode 100644 index 0000000..ae3f27a --- /dev/null +++ b/tests/knot/semantic_check_data/cname_extra_01.zone @@ -0,0 +1,18 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111218 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + MX 10 mail + +dns1 A 192.0.2.1 + +; error CNAME, node contains other records +email CNAME mail + A 192.0.2.2 diff --git a/tests/knot/semantic_check_data/cname_extra_02.signed b/tests/knot/semantic_check_data/cname_extra_02.signed new file mode 100644 index 0000000..724a8da --- /dev/null +++ b/tests/knot/semantic_check_data/cname_extra_02.signed @@ -0,0 +1,76 @@ +email.example.com. 3600 IN CNAME mail.example.com. + 3600 RRSIG CNAME 7 3 3600 ( + 20840201000000 20160224073150 29600 example.com. + IxkF8oqOEzhlZDSRBIi4448EGvQwxm0QDFE3 + JExA4Byx2QaJvXo8LoCeyQxS/f9E6bXpXQk2 + 4dgQxUrRZqnKEA== ) + 86400 NSEC example.com. CNAME RRSIG NSEC A + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224073150 29600 example.com. + iKA+5qsYA7A7JN7Df99aJnToYESjqordQgVj + yMS/1RVBYEGE4y3ggehzAxvc8bsNYnUwGeGt + vse5dMVKCcIaPA== ) +; CNAME extra record A +email.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224073150 29600 example.com. + DummySignatureDEADBEEFToYESjqordQgVj + yMS/1RVBYEGE4y3ggehzAxvc8bsNYnUwGeGt + vse5dMVKCcIaPA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224073150 29600 example.com. + MT+QgXcsDzkrFgncNwFyH8lwXiOTpj1rnPgs + OUIOfIhyJyzT1hpozAHt+IWOPHUkKjBN1C5y + SwyTnlqwJtG0yw== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224073150 29600 example.com. + Mr0Gu7PUu9PsUBflhd8tMhcQ9+ve+z561/ml + kP6PL0MHgLg7V8KVmL2tc7+JAhSOVSpJ4BGQ + c9HKD15lFDFEgw== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224073150 29600 example.com. + oEMpoEhi86OM/SdyobPEh90zF3c3FhOgv68j + paD5BLUsAntf3qU+KoIMb9iVglp+VTGrg0Ol + XdJ2D/xSMA+XHA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224073150 29600 example.com. + WOtx+LBKbS2MOahlpDJMqgeH1TI5dZoQitmA + SOkDRlJgfPsiKeiaGMrnWN9xnPZOVr9MsInE + sKYjh6EZM1nuBQ== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224073150 31323 example.com. + nL4eJLv62C56wexu10DMPHqXCXSE/3vRe4es + 4e0e1CkY9bdj+LgLfgs7CH7UDNXFX2CxKxHd + mL4sp5AtaA8fnQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224073150 29600 example.com. + nn2dG+ORbcNQWHT87ijfOddx0SKCSE+8hAxt + SiQQpxAzPw13CZmnbYas8uvFFtth6U689V3h + rMzzZcxQEA1z8w== ) + 86400 NSEC email.example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224073150 29600 example.com. + BFz1Z7dbBNgHXDOaufuCoIzGHbwyLUrA+Wad + QBPD9xCYkXHoHfvVOhtEeMR19Rz+fi6ottJI + 4AWItiobBC/DAQ== ) diff --git a/tests/knot/semantic_check_data/cname_multiple.zone b/tests/knot/semantic_check_data/cname_multiple.zone new file mode 100644 index 0000000..971c34f --- /dev/null +++ b/tests/knot/semantic_check_data/cname_multiple.zone @@ -0,0 +1,15 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111214 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + NS dns1 + +dns1 A 192.0.2.1 + +email CNAME mail +email CNAME mail2 diff --git a/tests/knot/semantic_check_data/different_signer_name.signed b/tests/knot/semantic_check_data/different_signer_name.signed new file mode 100644 index 0000000..60a7f08 --- /dev/null +++ b/tests/knot/semantic_check_data/different_signer_name.signed @@ -0,0 +1,58 @@ +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224081051 29600 example.com. + fEcJTvz6hu2rhfrdc/pS2/P/OWhq1dZhnUGS + 6+bamvMIqfNuYasJzeMZp1zneEETiMf7h+0E + cdmHKHKdVTukCA== ) + 86400 NSEC example.com. A RRSIG NSEC +; different signer name in RRSIG + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224081051 29600 different.com. + V6veOuBzm7n82hwIBbln9lY3pxKR/h8d7okC + deEeaF6jpDt8aoTJjo0UbtEJJwBNKARKfe4F + 9U0NVIL0HnN2/Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224081051 29600 example.com. + Pej4N9K4S9PA8wV0Ks6KtqAblfd05eRmv8T9 + fBnR8V3vCtYONryKOP3cFlMXr2quWDCh5iwF + CQU98zle4CI9fg== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224081051 29600 example.com. + UY1XRRhfD6a9xOm/+FsAo2/uYG/HRWR4k33B + amre+LBqabcXm9qX8wOU2W1h/sK/v8WFRjIn + dnCCjY/iwixfGg== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224081051 29600 example.com. + IWxMxnZfLFFrQ3xOujrKKedNvIiIXN9QCL/G + Y615FWxxQcufNEZmlRILStAKtVsRJTFSInBP + NoTix1W8vttyeA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081051 29600 example.com. + dA9WweUpYtqqCm18zk+Jv3Md7WtVlXuvSeX3 + 5IHmbezmlzrPpHBs+gWdD6bnGwlRRcea7FkS + u0Nt96PkXVuXPA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081051 31323 example.com. + nvruQZ5cZZ9+/I6wAh5AjWlxomueuuFiFoZe + XYBFmB+VH+eWpWL2Lp4hgaQ6UyKaHAKqtzMC + pqVA7Vwz4HEftQ== ) diff --git a/tests/knot/semantic_check_data/dname_apex_nsec3.signed b/tests/knot/semantic_check_data/dname_apex_nsec3.signed new file mode 100644 index 0000000..287fe35 --- /dev/null +++ b/tests/knot/semantic_check_data/dname_apex_nsec3.signed @@ -0,0 +1,23 @@ +;; Zone dump (Knot DNS 2.6.0) +example.com. 3600 SOA dns1.com. hostmaster.com. 2010111216 21600 3600 604800 86400 +example.com. 3600 NS dns1.com. +example.com. 3600 DNAME bar.example.com. +example.com. 0 CDNSKEY 257 3 13 p3J5T0YFTf9IGjHFhS5oFGGBDOjs25Tz29eT5sAK7WxXoapa4Vw3C9zBH/BdDH1RmeUR6OHPY1+x2NiouNm05g== +example.com. 0 CDS 2073 13 2 B345AF792A41656301EC57A4CE7E03C02A5E3C8F422FAB2FCD67C25649DB1285 +example.com. 3600 DNSKEY 256 3 13 UthmrB0FXNo/yZ3N0cnG/OJxG0FR7CT6KadbK4n22rMzfwq87jnobJ0xOpC7aEpGgDbypR0rK+KIAbRv4Prfeg== +example.com. 3600 DNSKEY 257 3 13 p3J5T0YFTf9IGjHFhS5oFGGBDOjs25Tz29eT5sAK7WxXoapa4Vw3C9zBH/BdDH1RmeUR6OHPY1+x2NiouNm05g== +example.com. 0 NSEC3PARAM 1 0 10 90E4D95759B9FB50 +;; DNSSEC signatures +example.com. 3600 RRSIG NS 13 2 3600 20670924135857 20171006122857 46856 example.com. I2YeGSYvj56eHe7bkbnOpziu18gAdwMGEH5ZAGiuZzL37M2lRB/2rtAxWpxP1G1+idFXahAx6q2X5pK1o/yZWQ== +example.com. 3600 RRSIG SOA 13 2 3600 20670924135857 20171006122857 46856 example.com. NULugLRW6r+y6AAJS2tcFt5BBWJMMxq3q0wvYirSvzzt5A6vwWC2ocJ2A2kftoDrIQWYHl1ppsxHTMsvw3NKfQ== +example.com. 3600 RRSIG DNAME 13 2 3600 20670924135857 20171006122857 46856 example.com. PhUAnuLYFE3ySc9mMoExr+WoGf6it4/571GhjYyhgfUWQs1pE8WJismYG9NFle6Q3OlmDJSEWQwHBHxQmOeyKw== +example.com. 3600 RRSIG DNSKEY 13 2 3600 20670924135857 20171006122857 2073 example.com. ZnhiPDiX/3RUW5rdLO8pKcIe+orbYloDD1mxhmfvfJ52IGdCV+okDu2M559pUB8Ihb/6H9DDl1qO5lTVGpVEMg== +example.com. 0 RRSIG NSEC3PARAM 13 2 0 20670924135857 20171006122857 46856 example.com. DxyzDQGkONU+NTxBswKZRWc3kPQxH929PaD5S4g6MoH6EJ/X52mb5om0oXpXLuOTEo2Cij8c3aghLN2h3eiw5Q== +example.com. 0 RRSIG CDS 13 2 0 20670924135857 20171006122857 46856 example.com. 8tPTolSZPvZUSpIs+nb4x/QRrNFgZG0jqqWWnQH8zy3CRS4L91SU5Z08aVz632n35toWv+uqG8LXI0sLKm6M4g== +example.com. 0 RRSIG CDNSKEY 13 2 0 20670924135857 20171006122857 46856 example.com. 80MTgMHXqc8Eb+3LPjl9fJ6sjNR40MPVKUfD/Qw0mzWHjz8ZOUDxNZViHnmyoz4JoorrO5b2yAx+ojpt+FyQLg== +;; DNSSEC NSEC3 chain +9sq7g935u0bb7md3rn34uh1aknnjhf1k.example.com. 86400 NSEC3 1 0 10 90E4D95759B9FB50 9SQ7G935U0BB7MD3RN34UH1AKNNJHF1K NS SOA DNAME RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY +;; DNSSEC NSEC3 signatures +9sq7g935u0bb7md3rn34uh1aknnjhf1k.example.com. 86400 RRSIG NSEC3 13 3 86400 20670924135857 20171006122857 46856 example.com. sFlwNYgq6HoBDlXp9vC0Ck5uJ76rJyf4zfdQmTnJ8aB/44XvDoQ+tGIn4ilVN2SxzyT1A4c/nWOyMMCVhjXARg== +;; Written 17 records +;; Time 2017-10-06 15:58:57 CEST diff --git a/tests/knot/semantic_check_data/dname_children.zone b/tests/knot/semantic_check_data/dname_children.zone new file mode 100644 index 0000000..5758833 --- /dev/null +++ b/tests/knot/semantic_check_data/dname_children.zone @@ -0,0 +1,16 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111214 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + NS dns1 + +dns1 A 192.0.2.1 + AAAA 2001:DB8::1 + +foo DNAME bar +bar.foo A 192.0.0.1 diff --git a/tests/knot/semantic_check_data/dnskey_param_error.signed b/tests/knot/semantic_check_data/dnskey_param_error.signed new file mode 100644 index 0000000..1a2e936 --- /dev/null +++ b/tests/knot/semantic_check_data/dnskey_param_error.signed @@ -0,0 +1,70 @@ +; Zone without any semantic error + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + W9EprjaR4loSnNW96h4rLsquPDw3LHYvD05k + djkQofHSkMNZAJ7Q+eA3Fs2ik5fnJFM7wi5C + MtFsV2TfqMJFmg== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + I9Je1S7XhZIW9C0fWE8NwFLC2rhHklddNYBO + dxVKL/lxENU4jPPBwZBGrcYn2WVHgkIzjG0n + EOHONAgRFPi3Xw== ) + 3600 DNSKEY 1 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 5 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + vO2UQiTN/CNUZOmSEg8kJlR/UqiAZHc4qMwj + 9u31sbPmOMuni+ZGuVCFFoEMtZerIkkQowkB + sXJFkvCP5oF2rA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 31323 example.com. + Z+aaLu4rmzekfhlj6A0ClREloRi8MloRHf/3 + Dlw/RYY1hrOCfcZKEY6AXeVdUwESEsSkSOco + CbhyGHH10dKAAg== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229083110 29600 example.com. + d69kc52VdALI8fbdbflsVsltc1m7bI6QsJ5U + IDE9fy5VqcufZecZMKuozPDuF2vBA8ADFIRU + OfYgKs6YNIOLWg== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 1 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + D24JCtCcNzwsY1FXVliAjxMm+x95N2eUTXn0 + M8NK5glSk1yLtnAUKzHxpRExAJLGUiaG4yPu + 2yGZuqwNvJztzw== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + F7y+xW/C7iICgmZeYrF4e7Yx4kWZAZPAMzlu + PtWVuf37ySg1VfEWcQcDP04vF2rXVUqSMEcj + bqUVN5W8Hoazxw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229083110 29600 example.com. + MoYrL/lToC4AHo6KCZRiBRmCMWHUAx2Xt32A + P4lDpwA+wiBWkCZSfVTh60AosS/BIGtBb2BK + mszMx8CLBvkjRg== ) diff --git a/tests/knot/semantic_check_data/duplicate.signature b/tests/knot/semantic_check_data/duplicate.signature new file mode 100644 index 0000000..77bf21f --- /dev/null +++ b/tests/knot/semantic_check_data/duplicate.signature @@ -0,0 +1,19 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns1.example.com. hostmaster.example.com. 2010112269 10800 3600 1209600 7200 +example.com. 3600 NS dns1.example.com. +example.com. 3600 DNSKEY 256 3 7 AwEAAd0e6EjJ0PgChDpbjB9QtvJ0ZqwKC/j7wlEOOB9owqefH/taZ37w6QR8Ysvvv2058AflDcCP3qlaOXp+ogq7AhayA+K4kc/UQyTPCe2jXKlX9IB0KAsr8nO9UEXzjYuyBw80Ry86Xxmj7OGYRu8eRm3ruOjVJy8hCrEQ7680an303Iu3Ixnmo8lPTPPMg4dbFXZ/RW6Sanrr/Sy6fre87XY58yywqX9lZOh5eqBeZG9WvU/HycrDkx5AcwD5etVk98tVTnofShY34ePZWDmRHEtvBpMzNObdomgM5we+DawC6P+Z8PFeGz+OgN7WVzkjm+MmYAk1aIeLQyNIE8SyMts= +example.com. 3600 DNSKEY 257 3 7 AwEAAea81n0wL09ZMejh806rJ0Km3MYC+ySPWnOmV70nEmONbnduRPpXWjYSqFmH5kldfNdCH403kI/YCMYDYBAPFPbhxuZuVBaJJqOQVsI4rpwj+XiANfGFAq9pZ0oA8iH7gSoNUCf6+g2hcP0ajYoqCjUZ7ZZQNytV/x6foW5t5PbyPNeAU1AEKxk2VSg1TMfkccZqTIx1ofS0N102Z4tOBn26judPqLc0tXMCJc7wgekqG04IGe7UWfk9xWtwo2SbtX9diErF8DJ93C17OWkb04n1xCm3i8/XZadA/HrBjfX/NvlHF8qnUQzzxN7UGrvBD4hE12R9ICj4YNFZViOTdvs= +dns1.example.com. 3600 A 192.0.2.1 +;; DNSSEC signatures +example.com. 3600 RRSIG NS 7 2 3600 20170403124401 20170403124311 40703 example.com. ltKNDw2O/sIwQUsv3UCKqOtZYvWNJ0mHo2xDxpzZXfAiMbgR4k7jBIkpSEpcBiBlH7EvWom7CYVigPu8Y+j/Jq4uv+wmVF47OVY3YZvuzfprWj+iOQwPlfDJfUPx+U+73SSsZ21B5/+auB5cada730B4gQKmldleVGg5aov4H2+BpEyrsSs2o79qiXNBzLPqrZEmT0nfUAvQC8xhFV/71I8Q5qtfa3vO6DLSOBmBUtAlGKqfpWoZ2w+QDdA6rtOe0haizTZUtghL2ut47bdTR253brhUccL6nnLc5//jTUBToIhmG/p698xLnU9BYnuHIi74xsb3hVr5b46W5gAGKw== +example.com. 3600 RRSIG SOA 7 2 3600 20170403124401 20170403124311 40703 example.com. E9a+I8HDh6ycTVkFgOWkzbH7PWds7ewp1M5lUci13ZzMVWsJeFW7t1tLnnOtvz2H8pq5/BevPB8iZBA7rHH7GxoQ5P8xrxAO6HvuRZT8O4kYAWRZ0QHhMIvY8f6VqTyoOmzgIGt0nJ3BL/XJgxIiFrsiLyih6+dkckEu62F22+FFvlv49ufKkCo+EUQPCzo7ZYODc8xKWo97SmaADzjfz7Hq9UPHraUgLhNkfBDbI9YPCGKaJaAiqCBy/6ih3SyHxVPLcIz95okeo5AJVszFIS+8pNPZssJBpWsLKYyAGzs2dsliRwS9z+a3wkHXJIfbLX+r3kGhcG4lQMYDz9SrFA== +example.com. 7200 RRSIG NSEC 7 2 7200 20170403124401 20170403124311 40703 example.com. poh0BT+nUD3sM05axVGC+k7jj1r3YVNcx4bn/0cviNxzCqLY9RGgImPWsmkTgbJpmCox9SHzpTqL8acIQDNZaciNH9WeYKvn7wkap3z6jtCuQRezM3nUx7E37fzbnNC8MUoWkV37y3FSmtiza9l1isrE5dGkNMOsBcPvIp5wrbQ+dH4cMdcgQuW+NDjee6czIeeYtyarBWhq30S2lxroh8VXlrFDTcbiIY4UoGzJDfevvsonNFQXc+p7qq2fU1fyU1e3Ugty9I23g6fLhLcrmflVbYpcgE8/02K4asu5D7x/dOq21OU/jJfeudk66l6CVw7c3Qh/N63jRn8SsCj0Sg== +example.com. 3600 RRSIG DNSKEY 7 2 3600 20170403124401 20170403124311 5154 example.com. RmAPllqg+CEX+vj5KKmXGYsF8vqbqLoXSYqSOSWbvgWRazKaQU98fpJWdrmqylkR6Xa1fnbvliP4N/0MGremNejsNPvMsJ4GvpyM75Mb4BEf5mwwikW6xov9V/n1AN9grWofj/r5evsZYcxIR7naM9oxV6qJvy8fFIjthG805MO18bYk1/Och2x9TgUf6DTqKNBHQjk1AfrhVvpuLjdNnNT16Ak3izrCLOm2tuNTaflkYkD0n06ZIAsz1krJWztpncA2csnKQmdybSL95wZnFeb6nkmq+P5vk3PuTENIMURYMCNfzBHogLfbVG5HpDhaHkcM2zSe1qATbp9xRZujLw== +dns1.example.com. 3600 RRSIG A 7 3 3600 20170403124401 20170403124311 40703 example.com. iYfVT+HPDqMyH9f8aLrzNK6sOCoo38tlRJ5tjiko0DOpsWp20LLgVQLvKsTs3SfdC0gYzMVQCgzfDMbAgrEvmm4ZEQT/NSUhcO2t08f6pABn6GSdoswFupi0LGdQmgj/MbOET02OTALh9I6g3Ir1+bF+C10GS/8CYqffO/52IEJylc6AzDCwAjfkI/55hsuv2H8Wp5cqEG5yAlL4fK+U2zQWEuAGOtGbEuzeKcEDV6iiAuFge7ClW+CbB3gQxEhDdx5TQNNAcpzHmum5yfsfcFkIezZqIzEvOQWg1nJVcLvYnuBqyMWv/uGbG4CxTDy49U9JB/6QfilMk38VVcitZA== +dns1.example.com. 7200 RRSIG NSEC 7 3 7200 20170403124401 20170403124311 40703 example.com. gtRE8TafAp50tzk3rAub93X69pp4J7uPzXPM0UAAp97oVMqcqvuZh80fICLmKl7xShvBx+AYfV+2CoeMW66CXVHTP8CyIjLyi32EGgL75Y2xs55/lEOaMl8hREgxniopCWGX/5vjmY0SBdGWVQVyeQeb0DbTXFWQNw/1LUPueoM1zqGcHFKFt5Y1GidboUEDsNeCmG3ZzGV9/v9sVUezzDK53uaHm8Ojz6E4N7kg6qXDF32ZAxs0dDjh46bsaTNvMLCEXqO2imHx9Omc2wYyCt/roMoeYiulXQ7yHYt0yQuCYwqxxMqJ4z9jvLNdLxH3YZYV0CVUrNgNC/5vtUILsQ== +dns1.example.com. 3600 RRSIG A 7 3 3600 20170216152943 20170216152853 45258 example.com. j7H3N22L+tqfwuSd4GhIwMyjrFSY3+kypIcOvg0Ipbj4pAHsJOJTiW454Ueq54G/0ntoHxgmGLv3d/EV9prMPPQz8eqtRcYFip2NuEF9bJsIG3SMy+0HolPK+8D7B0MOGFA2TExKNknS7sJy/Jn/yQrf7BHubC61zWnqB+vN7MNlJASXEvy3008oi4FScSsrAVIrZK+z7utY4exkCVfELC7flGenoyPDFR12y8WpN/Tk6q1H37x+EKaQgFj361Bm6f/InPKW8Npn/SNCIJ2DvSWAnj6+2n1mse0sC+rKhRIDMDopu7JzTjpVs9U/p9BY5dtH/3YvST4Vz3syqd1unA== +;; DNSSEC NSEC chain +example.com. 7200 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 7200 NSEC example.com. A RRSIG NSEC +;; Written 13 records +;; Time 2017-04-03 14:43:12 CEST diff --git a/tests/knot/semantic_check_data/invalid_ds.signed b/tests/knot/semantic_check_data/invalid_ds.signed new file mode 100644 index 0000000..2435014 --- /dev/null +++ b/tests/knot/semantic_check_data/invalid_ds.signed @@ -0,0 +1,106 @@ + + +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + 3600 IN DS 60485 5 3 ( 2BB183AF5F22588179A53B0A + 98631FAD1A292118 ) + 3600 IN DS 60485 5 7 ( 2BB183AF5F22588179A53B0A + 98631FAD1A292118 ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 1 10 - ( + UI312KQOP1NG8IQEIEFNPSLA94KB5Q92 + A RRSIG ) +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + KElp8dLKBKFzgEFV8r5aP9pCyYUD+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) + +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) + + + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) + + diff --git a/tests/knot/semantic_check_data/missing.signed b/tests/knot/semantic_check_data/missing.signed new file mode 100644 index 0000000..75c7d22 --- /dev/null +++ b/tests/knot/semantic_check_data/missing.signed @@ -0,0 +1,20 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns1.example.com. hostmaster.example.com. 1081539379 3600 300 3600000 3600 +example.com. 3600 NS dns1.example.com. +example.com. 3600 DNSKEY 256 3 7 AwEAAaBgc4O+4UWd7mzSyelnPb/le/x0q/E90B/xnlf56kgEFMvEGz++o6CMRXr5JfgyxDDsahxTwFoWu30KJry4MjgcwlETM63DFpIYtyDBsi8TlQFEp5NDrlYUWlPGiPfywZBVkHGFMcFct+5/ZalTzYIP39tDytZcPZ/IgQRQZA9qeHYIw51YX9IlNMalHFCtJyrpzCdo22FY/vwBwSbdCa+vzkH1Uu8JkIqyAvAGkuwVisgpMpzWhvJNi5WSAnQfwOcsYCftINAHdRXtuqyG+uU/RDcZ2psx+woi+mYzEPeYV9MEqWpDyIz7jS7e1hK/1o05+qY8Eu2gt4enRj9BQr0= +example.com. 3600 DNSKEY 256 3 7 AwEAAfcfJSUnim+cR3YEc4VfdJ5W65GNlK0LQaAh6vAejH7uol8VYmXdlyz+wlhad+DyRM5Jl+XJVFMMyFUqWx+Q63DPRtl+TlN/2pWU2gsNHUoovFhFpdX1cQMVoxr2QLgsm1ASTeqvZV8Dn0xAlNRihNv877sTySjveaH0JpuVCMpe5DB1zVbAzLgDqFKAvwJCumdycp7RzMi9PqS1XtsEInKi+X/zZteTJbDO7l+tFt9/NgFxiaLgNo8Gz2oVBTQvAbjCDEi2mPA/YJrpOGZWNkB2L9HFSfzZih8BbgUI3Fh4lhS8XCVrfVV7K9YR2F5NBVi7h0Mk15hzNsSS7tRK1FM= +example.com. 3600 DNSKEY 257 3 7 AwEAAcjdwuJkjM8G5rk967z1cJqF88BqpvN2GN/6Tj1XA5AbIx+33qy5JI6K43ehlT/neLizOCk/JyXaw8gcjQaDKcIy0vKysXvI6yK4PNgHTdzQunBqGTfvPDlXKCle550R/DJF2OZH/T7jgX2GhQlem6UB3A23n24YP50IzAmXK9RYdE/dMFXU5jEz+CjcHNkB8ZCb2VrKE9RDjY88vr6lyM2kPbvBtx4UaUSEzwlDMRc3Wf+dBWKm6mKWAPsHZM/cux+S2mca/cxEA1ngCgBBbm7824WjTXgDs14QWuwruMTqLPDujUYND5kbsiuhQsfEFGVq2UyhGEZG/NoIEEg7qLc= +dns1.example.com. 3600 AAAA 2001:db8::3 +;; DNSSEC signatures +example.com. 3600 RRSIG NS 7 2 3600 20840201000000 20160302125715 7242 example.com. B/6k7YAQGkiz6IkssLZblExgMZBE+Flkhv/leVgvM4RLPPpQ2znouYyrSbVCcU5irA7PFLbee5Mn1aWj2S57L8yGJjHBuamQSIO0GcvGcmXi1CrdaYXSofo3PtnKpM8/mG3+8RCUL5YhoxhTK4Y5gJrYGPkRPKsBTw2Qd2TUJFebtYgCuGN8Q3UwbeYPw89rNbqC3a7zsGwJoZKgDnm3NwCWcv6NRTcQA/H5v6T0/QvYbZpBMrjl3EiAWOccdUlQnALngGSzbJ2GnmK933VXYhuAoSKEN6thauOBSLkdCh9afkUzo/t7xhTJszo0F1uuavs8PYf3HjmdnMwdPMkUuQ== +example.com. 3600 RRSIG SOA 7 2 3600 20840201000000 20160302125715 7242 example.com. dHmPqRl9snHFavwkkAFZqHDmvUrI3+e+dmEexqgW9txr30fbrkeGAp6ApdZlqJiDTJ/2q0UoyQxSYe/BzgV4gEBgTTgfmC7m9eHVLTD70KMlNuvwC4jkh1vWT1Zn6IFUsQtJ+54XfRTe/2VHyeK7saqsA/ARRZGOzk6To8CWxNCApUdLZMQO9UTX7uVcXKkPvfMvlhx1fmn4OE8ntwbY1oPosQb987N8V8x9Rb2hINr4DCkXNDydDZAh4vsZO0DHPlmyfkyNguQDmdgnDz1CVbJzguy8tqeMGT7CrwU8AmX3JADQTHoxjnWEidLLUa/gNDRFcRc5YMcdZyImHqdNZQ== +example.com. 3600 RRSIG NSEC 7 2 3600 20840201000000 20160302125715 7242 example.com. bjw2G/BwF2xTP/QSkKqdr7byUS+nqMvfppuhZmH0VcysAKN2oqsV51bn7gWej6dnx0svtX7nCOlwdDFSCMJld5BGZFnAfhS+XVc/wTeZGMi1BkeJxlT3UbGLhf2DuLLyL969HPltL527vSysjBEmi7OsTlH+wXD6SW35ZClajNSRLjxrRpVHTGpA5uyyysHRYNXAKS3+SSc1N/Fovjgzi68exWD0BKTGia7Nf9Fn+bqvhbYh+pMHA7djPFJIsER3OCBx7H1KMxl6rap7Q3rC0I289xnnsOqRh/GnzSVgvobKWozOOs9XXNg+w9ioSos+kbzTxxSEvLKqNBgCbLjUHg== +example.com. 3600 RRSIG DNSKEY 7 2 3600 20840201000000 20160302125715 37855 example.com. EHXazcQ27b5Cjqd1T8TAui2PrUqEq7cBxk45OA8BfBDmOuH2vXFVL+juCM2gCvQ+0oZmcJmpkjMCxUqQekXgxRy21PlEzJfR3VHRDSYCSogR9cCLw9T9OiFXugZAtYcLVXVHddKu0+t5yeQqdStgLBiz9EmeuPFYd/h/BxKI8FGx/TjHNzd06SKgxlZAT/vCGhEswgSIpxJm4Ju561vT2/Hh+NmD4jIKVf0OUSkfRVRbxpzMs0HaZx6s0T2mcL8so/rEXjSIORkw56Q7x3EmYQDxNJjoNo4nHKT0/pciCey+vHj9pxxaiave8wLBG96JpgJgSV7BG8TTbE2q62wX1Q== +dns1.example.com. 3600 RRSIG AAAA 7 3 3600 20840201000000 20160302125715 7242 example.com. h0oZ7ghuhANB27zD+M1m0NyVUHND7g2qI1IfEKDjMzZ34wyqM0xWLm/Izln86ol4naDvJU3a7hsJS/95DdvW/s711Oi2nKhX/Hkjvnzu8WVcf5DvEKYQe/fyZ676hnwviKqFzwmfTAKgIuSvt2uZzJkpcyL8ZE6O/GdPrcR6rTuuDI30F4zXIWPmuMNLR2qJv59DwM0tZScLdmRGKGnZNpdxDvtbCsZrXBUPrOE5XpAw+fe8+oL3UEeKQZq8qFhVvegl4TAuk1a8CS+zG4E1ABQKp86J1h0G4l/ajmWqq2T59lHsBAOuX0IbKHEHIJzwRd9EV7LM59EtJVacx8ZCkw== +dns1.example.com. 3600 RRSIG NSEC 7 3 3600 20840201000000 20160302125715 7242 example.com. Pq6F6akEhyIqch7vwWJ5C53FW1UW/Y8vseFqB6tzql5bnIYjEwikgiWR85uvSUNGvsjHbadBYiVh2i68k80ws/2LecQCvguSH+rMkqqY9go+pBh3pdiNlJaJZp3zJQ6+E35xOA+p0G5t84Et3satJl3OcpVthrdBKuotpDg4P+nOpfLHkI3FO5vehxs71HmESQli5JllhPNMH6WZfWsP74D4DgRjUpIK9hGznCeuZxJT5+S5wL4fzqb+P20W30bsQqMbo9GNdPy5AdbwZoEKJVoN3HC/sv03ScQzWUxjamHCQOeZFys25fFlh7+JU1xYSb3V/fPhUUuf7OsBVvn7+g== +mail.example.com. 7200 RRSIG NSEC 7 3 7200 20840201000000 20160302125715 19578 example.com. gjNXoKVddN+Z3MmHXxs0v4Gv/3zaTAg0mBSLkSp8Ion6qKj/aR2y50QhNfZGVEZSmyerDiaVpfPMN+q9mwx+6xmv4/G97DkadXBYt5IXGR1fXhMCF+RLJb5ePYjQKSk2TfRMJAlk1Mowfvlp8rXFrT576y2F+IXKbpiJOdRt/13Wo5IUbw6LLFDOeZ3fUiZtBmoWTTjBnrGWYdb+ePcSXID+qM5TmRXqIOFceJvt/RhGZ5LYAchgM2sZDf4Asacxg6Z6vS2cA1opTLMAIu+cuEmq61cSJxWHblfXIpPMXFG+4i+nkCxEFxWyxt9edlAeHS/l2AiHQl5QeuzwEjFI2g== +;; DNSSEC NSEC chain +example.com. 3600 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 3600 NSEC example.com. AAAA RRSIG NSEC +;; Written 14 records +;; Time 2017-03-31 15:38:20 CEST diff --git a/tests/knot/semantic_check_data/missing_glue_01.zone b/tests/knot/semantic_check_data/missing_glue_01.zone new file mode 100644 index 0000000..6900d0e --- /dev/null +++ b/tests/knot/semantic_check_data/missing_glue_01.zone @@ -0,0 +1,14 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + NS dns2 + +; no A records for NS diff --git a/tests/knot/semantic_check_data/missing_glue_02.zone b/tests/knot/semantic_check_data/missing_glue_02.zone new file mode 100644 index 0000000..1fcbc1f --- /dev/null +++ b/tests/knot/semantic_check_data/missing_glue_02.zone @@ -0,0 +1,16 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + NS dns2 + +dns1 A 192.0.2.1 + +; missing A record for dns2 diff --git a/tests/knot/semantic_check_data/missing_glue_03.zone b/tests/knot/semantic_check_data/missing_glue_03.zone new file mode 100644 index 0000000..4485d43 --- /dev/null +++ b/tests/knot/semantic_check_data/missing_glue_03.zone @@ -0,0 +1,15 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + NS dns1 + +dns1 A 192.0.2.1 + +deleg NS ns1.deleg +; missing A record for ns1.deleg diff --git a/tests/knot/semantic_check_data/missing_ns.zone b/tests/knot/semantic_check_data/missing_ns.zone new file mode 100644 index 0000000..7d71d78 --- /dev/null +++ b/tests/knot/semantic_check_data/missing_ns.zone @@ -0,0 +1,10 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111214 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum +; missing NS in SOA diff --git a/tests/knot/semantic_check_data/no_error_delegaton_bitmap.signed b/tests/knot/semantic_check_data/no_error_delegaton_bitmap.signed new file mode 100644 index 0000000..82f4261 --- /dev/null +++ b/tests/knot/semantic_check_data/no_error_delegaton_bitmap.signed @@ -0,0 +1,66 @@ +; Zone without any semantic error + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224170742 29600 example.com. + imfvFljZ29MFD+AVQgb8/jeBgRPGJHXWw7jv + lCijFIMnH2gvHeUbKZTQLuxegeQ62ZJsu7w6 + RI4aS0fffncK8g== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224170742 29600 example.com. + pnKWGmJdaur8QVQQ+xo9SbpDvC4E1lvSW1o6 + wOUdzE5AMqy9+jB73BCC6Ota+Bt7vBCpAU2L + WFq6sB7oFj3vUA== ) + 86400 NSEC deleg.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224170742 29600 example.com. + b5bzGxN44wwyABHRjgBSY+YhN+mWbFJsyWJ0 + e7FQ3QGKwQkgKiOnUOElGu9qWy5KinPOvTTm + 96SOBVuVxfTK3Q== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224170742 29600 example.com. + rHeZv1qbt/28Nu44kYsoQdawfXdiWzq0YM7f + mI6QevXbyLx2QvgwlhSCc+sAoVkmQg+448M8 + N7CcSooQE6z1eg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224170742 31323 example.com. + TlUfbDLPLMwqxeiDwqX3vtN5HGxL8+JnEpF7 + rgE6Knf3I0oI3oBYBPKpMBYnQXQHUPqoK3uo + MLngsROcqxwi6w== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + 86400 NSEC dns1.example.com. NS RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224170742 29600 example.com. + O81uip6/VmZE6dhWYNNj5FH2CnatytEgFiLW + k886unXnF4/pXpSlwUfZ4iIcA8qY6BRw+AS+ + 97Y6p2ACTw1/KA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224170742 29600 example.com. + qrtmPmS7uGQS9Ytb25zLhyfajR7X7sZWXcIU + T61PSMeJyAYsOHdPB7VHxCRSv7QWYyrK9mh2 + ohpYTvvvo1iptg== ) + 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224170742 29600 example.com. + NJ0Z8NZPBykmhuU/fb4x3AVOdZc6YebfQyYD + PaDTxHpquIh5ThfVtmawIpA6eVFkSscbUFEL + rjeRsepFYI3uig== ) diff --git a/tests/knot/semantic_check_data/no_error_nsec3_delegation.signed b/tests/knot/semantic_check_data/no_error_nsec3_delegation.signed new file mode 100644 index 0000000..8585171 --- /dev/null +++ b/tests/knot/semantic_check_data/no_error_nsec3_delegation.signed @@ -0,0 +1,78 @@ +; Zone without any semantic error + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + W9EprjaR4loSnNW96h4rLsquPDw3LHYvD05k + djkQofHSkMNZAJ7Q+eA3Fs2ik5fnJFM7wi5C + MtFsV2TfqMJFmg== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + I9Je1S7XhZIW9C0fWE8NwFLC2rhHklddNYBO + dxVKL/lxENU4jPPBwZBGrcYn2WVHgkIzjG0n + EOHONAgRFPi3Xw== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + vO2UQiTN/CNUZOmSEg8kJlR/UqiAZHc4qMwj + 9u31sbPmOMuni+ZGuVCFFoEMtZerIkkQowkB + sXJFkvCP5oF2rA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 31323 example.com. + Z+aaLu4rmzekfhlj6A0ClREloRi8MloRHf/3 + Dlw/RYY1hrOCfcZKEY6AXeVdUwESEsSkSOco + CbhyGHH10dKAAg== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229083110 29600 example.com. + d69kc52VdALI8fbdbflsVsltc1m7bI6QsJ5U + IDE9fy5VqcufZecZMKuozPDuF2vBA8ADFIRU + OfYgKs6YNIOLWg== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + D24JCtCcNzwsY1FXVliAjxMm+x95N2eUTXn0 + M8NK5glSk1yLtnAUKzHxpRExAJLGUiaG4yPu + 2yGZuqwNvJztzw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + NS ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + jRNMrWLfS4yzRHQOBxs6/GKWIzx6AZV5lyCm + 7bYTV9wS3owDJSQhJ7lft0WbBmUMtV3tP9Xr + Yc+yW48p2Vr+QQ== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + F7y+xW/C7iICgmZeYrF4e7Yx4kWZAZPAMzlu + PtWVuf37ySg1VfEWcQcDP04vF2rXVUqSMEcj + bqUVN5W8Hoazxw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229083110 29600 example.com. + MoYrL/lToC4AHo6KCZRiBRmCMWHUAx2Xt32A + P4lDpwA+wiBWkCZSfVTh60AosS/BIGtBb2BK + mszMx8CLBvkjRg== ) diff --git a/tests/knot/semantic_check_data/no_error_nsec3_optout.signed b/tests/knot/semantic_check_data/no_error_nsec3_optout.signed new file mode 100644 index 0000000..4fde7f5 --- /dev/null +++ b/tests/knot/semantic_check_data/no_error_nsec3_optout.signed @@ -0,0 +1,98 @@ +; Zone without any semantic error +example.com. 3600 SOA dns1.example.com. hostmaster.example.com. 2010111221 21600 3600 604800 86400 + 3600 NS dns1.example.com. + 432000000 DNSKEY 256 3 7 ( + AwEAAdwI5CT9W2+RYXwUeD9m4LT1dLInHKLynsjrIzNTgbLmr5bqC/eWE8c0OsZpZmUbY0u04CzO + 2SXnk7zsDzH8GvcUfJHFnC+ZGuK45DChwv+k6kUmwm5nJUVD2qye3mucPvHX1Ss2NOrd+xqKu/t2 + fVAOWKAh+r4XNN5eKg5rmkl38/A90JtiLg6Imp/O83ZG//ZUykFal0sujTbVP8MaLTMsXwHE46xf + i1tZDqObyY8TQTf0CtDm7d3LJvlDT1IST5NRU32fOtRUqdnTiMLbQQufwe1cCreZ+P4ej8DeI4gv + N/8lRCSnBBOnmwIPq4bjEdxnK9WRKmfLIpoK+fdO3dk= ) + 432000000 DNSKEY 257 3 7 ( + AwEAAbWZLegQDKxDkaW1NvVwZ/nn0qsLEPW3nO+sJpExg52NvM5eugR02H0mwrULG5jAAHaAZ5C9 + eXE3i3asxiyUIygx+/8n2VQIVml/iKfRgqoS6tEAZzL11DL0q/dWf8dF5A6yJQWqifGBXGRms3AU + Ec7pri7LfX3CBSqieiuHBAkqJVrJm6I73kduk4/tUEVEzJEmoNEHDDAAhpHhDo6g6ytzmdfTTNyz + VSWyAzn65+Eg2F3MaQOptoPsrIUdAud0UPCk49tdLUgaCAT0Kd1NICD9ANd+ba1mWmsWXkudAPsw + 4WNLFZQUxlEsVPg4IsxZyrl3cyGDeLnXLLg0lWTGgJE= ) + 0 CDNSKEY 257 3 7 ( + AwEAAbWZLegQDKxDkaW1NvVwZ/nn0qsLEPW3nO+sJpExg52NvM5eugR02H0mwrULG5jAAHaAZ5C9 + eXE3i3asxiyUIygx+/8n2VQIVml/iKfRgqoS6tEAZzL11DL0q/dWf8dF5A6yJQWqifGBXGRms3AU + Ec7pri7LfX3CBSqieiuHBAkqJVrJm6I73kduk4/tUEVEzJEmoNEHDDAAhpHhDo6g6ytzmdfTTNyz + VSWyAzn65+Eg2F3MaQOptoPsrIUdAud0UPCk49tdLUgaCAT0Kd1NICD9ANd+ba1mWmsWXkudAPsw + 4WNLFZQUxlEsVPg4IsxZyrl3cyGDeLnXLLg0lWTGgJE= ) + 0 CDS 53991 7 2 E97D72CCA0AC77B5515FF2DBE9A662B55E2647A47497A1166696BF94A9E02DE6 + 0 NSEC3PARAM 1 0 10 7A148F1404032E16 +deleg.example.com. 3600 NS deleg.example.com. + 3600 A 192.0.2.1 +dns1.example.com. 3600 A 192.0.2.1 +;; DNSSEC signatures +example.com. 3600 RRSIG NS 7 2 3600 ( + 20670913080225 20170912080225 13839 example.com. VxLYvx9K8iCokjVJRDJbj8dyc6kinzf6 + /iM/kjDSKQoSBlCRR3+pczeq9NE/qUWQkLzqGd8sTfaatXD8/8UW1L9v5wToxoBPnhfO92V1ExTCq1uH + cUeuAs5FEPRzHZDXyHD2P5/lOzVI3YjTaH5Ub9uIvpELNGpA3P+AWfyr2agglRAAcf8eFbjzUd6U1kjX + L7SuLz/XChsWlAvwPNj932nyZrqlce1m0AOVFkF/YriZ/uGrRnSioAXOEW7HaV9KNmCqx4qks1qfSjEH + B/AwIsrk+ZWfVsR/0EaAWnXcjd/RWe+4jN9aKWX9tomSC6G7TL71fiKwPZ4C0/mkwp1LaA== ) + 3600 RRSIG SOA 7 2 3600 ( + 20670913080225 20170912080225 13839 example.com. IcI4kyxzAAKDj9skK4/OcTdyOfxS + +O3Y+kSuPOQnO1fFcJV0ZWOxGc2ElO4ecKyiYdwlEU0WRuSy5JEnfEqzFGjdUmmhmI95w61KdbGk + VCsSyGV0AsSSVNrIo0KNXAhfcoWkULXk0CsRc/5Fglt7bzaArdd5nyeNLHP26zcFdGhZAZDOS13o + 7g/mHrV2dqQZl1VTxvURoW20uAmVX48koPEeOz70Yh+YKG0z1209YhN4ASB57l26bxjdzS1FIaul + Wu+OZr7JmfDuQMkVdWJG31jmXeLDiEUhFFD6Po2cijr1xvvxE6cmedjabCTCT0+U5mnHVAlxGhdw + 0jBF3ec5ZQ== ) + 432000000 RRSIG DNSKEY 7 2 432000000 ( + 20670913080225 20170912080225 53991 example.com. DCBKQjY99s29NtqD3/+zoMpL5vh2 + mvgufudFWkBl2tmiH90SPe7BTUaMCu+kwiOSJh3U6ToywvKG7i8Tn820BleAC78c8TDtSxrJdzTlxhOm + o29dUObmvwKzMBsyAaj/2mQfY9GZNYxem7OyaZjbdrV4Rb4ghyy7Rttg+xle6tVH76+/MCcsdBur1NrR + r8HXtV8Sd+h0GCYeQvhMi5btIJK0OAHStTyU5iCmLIh28rxxHfmU5aRFkzanT83Xj7VdoF3fmjIE9Uww + fWX6PUzIoxEfm5a+v0EGbzqGOEgCnQ7cJo3DQkx0ouZT1bWTJQ2Hv9i323aAB/boGLR7b2wHrg== ) + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20670913080225 20170912080225 13839 example.com. bOrMfjlEwZhfbcGmy4XYve/qZ8BV + n0t7JIBlKP/t9oFeukvxSHZnj3iT3sXq94Ck2DTDhRSw98rKG5V0tlAR/XGOz9Mx/nrY/NW5zX+1 + zty1+6naf09QQsWUwseuUPu5uz1aEB6sIGj2V9bQWuHZdkIQkiVzN9SgD3olKmjOLsJxRS/ycJ59 + I5so/g4wfC/jD7+NE8clkLJ5ME226brQOv/3xEFJC/IGR92uSvkzN1r7F0UZEozgu1UGykj16HU7 + x/8YqT57xWiTcuZoSP1KoU494nO47dDhvO0pdMnIvozFnSI3heEJSVcZFxtePJ5gIUEp+wxGrayb + N0dQmCmrzg== ) + 0 RRSIG CDS 7 2 0 ( + 20670913080225 20170912080225 13839 example.com. jckEGuG5vvRBpT0GIj/XXctC + TfcWnGRZv2Lj4kwZk14yKqrfFSB9G8glilIDdWeM0AvBYPFuEMTj34+HJxPbnTxaYYiX4wBpJfKB + mNbcVsJZeK5DtnuvOvCrTwdiEFqR+tG04uTVAh9TEBHude3zatgbbzYzFMP/N+XlERw7qm2im9iB + Jq++HjD+etKI7qYlJmcFzLvVNPR/sIHdDvl9tbwrjNpv/s2Df/KO1lrtMERiZMXHLWV70CstuDGj + fIM/dAV06MShs38qwaCC/CeLtKkj6pvOJqIJciRnc+7Ln86iSdSDyczD+Yp6aTsRpoIUgswU7FkS + pSKmkZdhW6+jmQ== ) + 0 RRSIG CDNSKEY 7 2 0 ( + 20670913080225 20170912080225 13839 example.com. ALnyl9KnQ/zTbq/OSzJ5k7I2JqjD + JGbxu7Kuzbh2fAG7RHnN7INvaK+YhZX7w9sUHQSIj62u37wr5HS+1zgAfSKTd5k/OQC6y2FB4c2A + D4MCb5FaE0zJ1KmjFc3uZnEKfTl8b30A0dunRLgVHZHSmd4R/nJ3yAvm2+LumW0htP5lhcc7Xoi8 + FJQ6KYg/ske0GCsMm5Ye+xO7m2QPbkgyOgq901rTBRMLbodbRXb8ZAFJGtl/iYmKG6pqxzQadeFQ + PxsL1bsdTvYsxIicQ6CpIOmvx/hl2aDi2f+vvfA4dHd2W2EDB4mMvRK09HadmBXimEkVJ+Tl++rg + WpiekXzI1g== ) +dns1.example.com. 3600 RRSIG A 7 3 3600 ( + 20670913080225 20170912080225 13839 example.com. tBFbAbT4K6Uv9LlTfGb+2jkg3vJm + D+PAqNW5PGhP26b+AMxOaVKPEVLD9oLhyrJv0Pt2IN/VVIvQ04fdqPwvS+z4XqZ4R5X5jb+vh5WY + 1UsprBwkx5gViGlv9tcjB1ryg+U5A6e7VYccYMSVc0qB8trbk+z9TBbFFs5cXNUDLrCLQQm2TVTq + zKvxASK6/DdI+ZQd9RHDCd7im4pVYBA+R/QgQzzNhyhzqXoKzy3AFvxPWw6MX+ugX9Ea5HAF4uUx + xQmXEKmPMQey95WKk9ruqLRuaxGlDUWSq355ppGVppiN2oa53w00oUfacwo9MNIgiDi9Av5EG5EC + gbvq8Ze8jw== ) +;; DNSSEC NSEC3 chain +036n766anb525cqa642tmm3r4occikb7.example.com. 86400 NSEC3 1 0 10 7A148F1404032E16 BGV0LKAMJSOEC22ARUGDNLTTCB70AF7U A RRSIG +bgv0lkamjsoec22arugdnlttcb70af7u.example.com. 86400 NSEC3 1 0 10 7A148F1404032E16 S57MPBJ9OEOU9OH6HSV2ANMCV8BHLRMR NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY +s57mpbj9oeou9oh6hsv2anmcv8bhlrmr.example.com. 86400 NSEC3 1 0 10 7A148F1404032E16 036N766ANB525CQA642TMM3R4OCCIKB7 NS +;; DNSSEC NSEC3 signatures +036n766anb525cqa642tmm3r4occikb7.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20670913080225 20170912080225 13839 example.com. Ej5/ql3a/6yjyk2PZfX9MhlnzclyrCnj + DpCF9dg2pqf/G4Z3rKef/PNbUPYgvvS/tmwyP+qb10BYvpH1Lp2bxSGrdPAfs5ge5KyCxa6rmwwP0eEc + C2AviCdbtJceB4fmxTvCt+2pgTCrWTnoWsaJYHlj5BRjaFXbqkCi954rIAy/YJoU9vqjysCZbfARastK + yt9rpeDePnKLsZRDP2ENi45m5dHLQQ6t3j45MCZXLi2Qp6Kh1FCkU6mYQNRhGpi2bi3dUCJYLp3CpchG + kQxFV3Jik0g0vMcpEW31rzx7WgWMpjAbW5DahIDd9f2Do/OmyjAjYZYFBPJtz2QV1PBNeg== ) +bgv0lkamjsoec22arugdnlttcb70af7u.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20670913080225 20170912080225 13839 example.com. huMYkoTMTSZdLdr06vWbvGaSih5L+pxc + fSMlmfww1NCJtJwm4WAyzegR2VAaGpok1gDxfhyPEpdO0WHZe2UbRpVMq/xuOWXCBXrHPzg9825687su + q4T+WY2nenwxi5bLs8S/v+w3VjOh6NlldNg9gg9xsmhcOghoBS2xpS9Mmj23y8U/J19uuTrQL4gb/Olz + gfGQ9JeLGArJfr7Sj+KcpLLqGolja0xdeWClCoDtcgZ3DilxpKuPkbQ/Dr1ejWOPXJIFaBaOV58CdpEK + omvQ5VMmdWaKZx+Uku/JELkeSiSJVxaC69JKAjDddbNUKHUnktJBFKHpsbRPAO1zHbxF8A== ) +s57mpbj9oeou9oh6hsv2anmcv8bhlrmr.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20670913080225 20170912080225 13839 example.com. NOIPazxgOpFTiExjI/CArS9iu1C0ZnXg + M9vEt1n/OX5g0HT0YLrvifSqLw/MN8W4t4xrSM+n/cGLUFcwP9+Zk3NeLrz9gCBmrneYZn+DCV3LF+lU + nKNc2lu9khFAHLwZCR+Wtj3bUpQREywqT7mmthlYGlN0wLfSTMSRc4HXlEzELx00tENA4kJy8HnPOdJU + rDjJPMa4mSxDBbgoGRkd6EhWtaUep1kQOR3sKqLYOBq8U1yARkGQuuLI/xcItjqRnVw5KYoUzyPtKoVg + 1RyCcQxd9wZp06joiMKKQhQCo2/S2Ez1pkBhc7GNxJ7wT1rLQbl2yf7Lupf2YFpfQkWzBQ== ) + diff --git a/tests/knot/semantic_check_data/no_error_wildcard_glue.zone b/tests/knot/semantic_check_data/no_error_wildcard_glue.zone new file mode 100644 index 0000000..3cf1e9f --- /dev/null +++ b/tests/knot/semantic_check_data/no_error_wildcard_glue.zone @@ -0,0 +1,18 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + +dns1 A 1.2.3.4 + +abc NS a.ns.abc +0.ns.abc A 1.2.3.4 +*.ns.abc AAAA ::1 + diff --git a/tests/knot/semantic_check_data/no_rrsig.signed b/tests/knot/semantic_check_data/no_rrsig.signed new file mode 100644 index 0000000..6a3161b --- /dev/null +++ b/tests/knot/semantic_check_data/no_rrsig.signed @@ -0,0 +1,48 @@ +dns1.example.com. 3600 IN A 192.0.2.1 + 86400 NSEC example.com. A NSEC +; missing RRSIGs + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224081310 29600 example.com. + ieEKhIV69ywg+YFSqdz0t17eE+PLl1eR4kpv + Mq6Q6TfjC7V5/PcFW6KRoP50RFp4m4cD0E7T + GpmpnPF++QV1Vw== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224081310 29600 example.com. + kYbAbCGzyWPBEfc0TH1calUiKsZi12MH3TNV + 7vtjOvIYEqeNmuJkrw899a7nOPNoahB6h7o/ + DXuRlFqYYCC16Q== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224081310 29600 example.com. + PchT9RWRkLCMxWAQ3ut6LZlh4MYT4CkAPThQ + cnIn0ORi/fVgGzlifQ88xfEdEr1ZoXk9PlhT + 5b+wocBOl2HhGg== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081310 29600 example.com. + JLcSyR8KgSicUou0c7Zs7Ol1DYiaQ8Lfyort + 8a+5OP3em3r3NH1nJkiVfs8+xdvUcGlGkbib + RKlfRWiIcOEalQ== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081310 31323 example.com. + EQMX5DPXhwa+blMRkzl+swUW3BtzpGJ5tGEU + hkH7bJfM51gIAO5qnUO/mMPnEA8b4dc20nnZ + 8j8lETDjqBLgDQ== ) diff --git a/tests/knot/semantic_check_data/no_rrsig_with_delegation.signed b/tests/knot/semantic_check_data/no_rrsig_with_delegation.signed new file mode 100644 index 0000000..2c36b9b --- /dev/null +++ b/tests/knot/semantic_check_data/no_rrsig_with_delegation.signed @@ -0,0 +1,61 @@ +ns.deleg.example.com. 3600 IN A 192.168.0.2 +deleg.example.com. 3600 IN NS ns.deleg.example.com. + 86400 NSEC dns1.example.com. NS NSEC +; missing RRSIG for NSEC record + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224081610 29600 example.com. + HhnlCtlIaZFVklpzVUnzm6AzFd65CSc4WCJL + f2o7Gkevu+HTnkiPN6gqtERC/BKJz1EKd2fC + KDyLxXw6KeTRAw== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224081610 29600 example.com. + rcHuZd9wTYykzis+9Z8uyqD8V9h22szf2bmE + GYNyJBlHZO0sOmys31xnvDfQ9sdk9hf1TUfB + 9ACGIF5lDHBEog== ) + 86400 NSEC deleg.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224081610 29600 example.com. + YGSe1OINjOY3I8BY1EoxcOJsDZ/DjGCT5nqY + J6BBjTcbT5S1W61SN50xc2sGB4Q8F2KTotAe + arzn4DGDt9mOMw== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081610 29600 example.com. + rdmqHOUXqhwrJusNt/7FTV+AtO/v6Md3LXzj + /QzR/pCADNC6ZA+FvqaOycnUxoryKk7PY3pM + 5ispCMuEx/1OGA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081610 31323 example.com. + jELyXsaJx+G4heZJ96dyE12hSyTNFazwWDkq + 1Mkja9/bTTdYAd+t8fhf/c35bUiTVJWMivJe + +YcCwqGf2U+2zw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224081610 29600 example.com. + ln2xuvghOWBDOfyk19Wwtv3oc8+1go3WQuMf + vel5x/uHVx6voNA25cpFIQ6nPlCo8pmd5R3w + paMxgoQtBkzBcA== ) + 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224081610 29600 example.com. + EEKcIegUeyn/1FIgxHV+gSX3b/ygQPAcjD8g + aCt1yiO0B1xmVm09RJNxzCLaTKxQENhxIoUZ + 2l7250pBQnrlAQ== ) diff --git a/tests/knot/semantic_check_data/nsec3_chain_01.signed b/tests/knot/semantic_check_data/nsec3_chain_01.signed new file mode 100644 index 0000000..cd90b9f --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_chain_01.signed @@ -0,0 +1,80 @@ +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ ; wrong next record + NS ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) +; RRSIGs for NSEC3s +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229140652 29600 example.com. + PjEM7Bxxb7w67366fKCLkR9BVFAL0RI8RJCZ + 5aqoMVuy+ui7MLKxKT2LfeTHgBw1Cww1bbJw + Ip2zu0/ZGPfKzA== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229140652 29600 example.com. + DUMMYDUMMYDUMMYgc7Jx/FgAlruRjwsS/YJa + sZRspDGZhSqK2daV5K0lmK+XL8BoOtp7aXtq + VER5XcWLOebCdw== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229140652 29600 example.com. + XsJa0IUE2ddTohJmiuNVd/Po1ZOK0PDCuU7/ + CS0/wiZ5ZlxPdVUAYXuC7HhGH+ZPsqwZ4oUU + ToDbFqfdzmC1XQ== ) + +; other zone data without error +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229140652 29600 example.com. + u5QMvOSkZBUM5tLiEAq3A+x4Ha17ZsNUYqeI + SuYA1+NbaBDxAtT6scB9aeA4lOTQ0TZvpGFE + YF/XxGtqvwdZ8g== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229140652 29600 example.com. + ELZOh4iS9DpAafa8NTaI/eNL3Qwy+lsmgrzF + 7jaoR5yOURl/RZSJY+m9Peaq4ALcROdGJ0O4 + miSpdTIZsBSGZg== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229140652 29600 example.com. + sjxCP/grgOR+4vmXw7HU/hGSx5dS5QxM00IA + gZNJ6Lqf+4OSL3TEa1/qqRSFTl5uv3rqh5W4 + 8p2JoT1ZkcJj6w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229140652 31323 example.com. + jrH48r1iPFRfbyIZWcARQrejVgrE9v8qqt4R + uPHjz5t7PYmZYH544SI9HtaWGkIJ9jzlxr5l + ikCWo1we50y9Lg== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229140652 29600 example.com. + yIXzhQw8c/c/in+doXX5JmqoGiqoYD2Hhw6d + /aGXc5QLQqxyATXln02vkwt1d7DK/ha1vkfx + bvGdduXDQ7YZ+g== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229140652 29600 example.com. + aMRzV/1+m9wQHWezSiwkmDEbnS85wB9dA5x/ + u2P7NPsgwMnRdfpVIMfaVhSJH88i5OlLTvL1 + sSK+RADpuoqnLA== ) diff --git a/tests/knot/semantic_check_data/nsec3_chain_02.signed b/tests/knot/semantic_check_data/nsec3_chain_02.signed new file mode 100644 index 0000000..ca70cfa --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_chain_02.signed @@ -0,0 +1,94 @@ +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ ; wrong next + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + NS ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 ; wrong next + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + oErbN3Xw+0zAqkz5KC5nOsINblBc4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + ep1TVqEISn2ZOiBtizK2eyuuhsYyD37X9Bw2 + 9JOkecZnmzCwBqfMCBvRYmNRpMd512+ZnW/I + 1vIViE7CGwkHyA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySginature6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) diff --git a/tests/knot/semantic_check_data/nsec3_chain_03.signed b/tests/knot/semantic_check_data/nsec3_chain_03.signed new file mode 100644 index 0000000..80112f8 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_chain_03.signed @@ -0,0 +1,94 @@ +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A ; wrong next + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT ; wrong next + NS ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + KElp8dLKBKFzgEFV8r5aP9pCyYUD+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignatureD37X9Bw2 + 9JOkecZnmzCwBqfMCBvRYmNRpMd512+ZnW/I + 1vIViE7CGwkHyA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) diff --git a/tests/knot/semantic_check_data/nsec3_ds.signed b/tests/knot/semantic_check_data/nsec3_ds.signed new file mode 100644 index 0000000..d37d400 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_ds.signed @@ -0,0 +1,109 @@ + + +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + 3600 IN DS 60485 5 1 ( 2BB183AF5F22588179A53B0A + 98631FAD1A292118 ) +deleg.example.com. 3600 IN RRSIG DS 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 1 10 - ( + UI312KQOP1NG8IQEIEFNPSLA94KB5Q92 + A RRSIG ) +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + KElp8dLKBKFzgEFV8r5aP9pCyYUD+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) + +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) + + + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) + + diff --git a/tests/knot/semantic_check_data/nsec3_missing.signed b/tests/knot/semantic_check_data/nsec3_missing.signed new file mode 100644 index 0000000..4974956 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_missing.signed @@ -0,0 +1,120 @@ + +; extra record without corresponding NSEC3 +extra.example.com. 3600 IN A 1.2.3.4 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature12345678 + 123456789123456789123456789123456789 + lqhxunAbh08dsQ== ) +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + UI312KQOP1NG8IQEIEFNPSLA94KB5Q92 + NS ) +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN A 1.2.3.4 +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG A 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + + +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + KElp8dLKBKFzgEFV8r5aP9pCyYUD+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignatureD37X9Bw2 + 9JOkecZnmzCwBqfMCBvRYmNRpMd512+ZnW/I + 1vIViE7CGwkHyA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) + + diff --git a/tests/knot/semantic_check_data/nsec3_optout.signed b/tests/knot/semantic_check_data/nsec3_optout.signed new file mode 100644 index 0000000..c9caa5d --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_optout.signed @@ -0,0 +1,81 @@ + +; insecure delegation, not covered by NSEC3 or opt-out +zzz.example.com. 3600 IN NS zzz.example.com. + 3600 A 192.0.2.1 + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + W9EprjaR4loSnNW96h4rLsquPDw3LHYvD05k + djkQofHSkMNZAJ7Q+eA3Fs2ik5fnJFM7wi5C + MtFsV2TfqMJFmg== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + I9Je1S7XhZIW9C0fWE8NwFLC2rhHklddNYBO + dxVKL/lxENU4jPPBwZBGrcYn2WVHgkIzjG0n + EOHONAgRFPi3Xw== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + vO2UQiTN/CNUZOmSEg8kJlR/UqiAZHc4qMwj + 9u31sbPmOMuni+ZGuVCFFoEMtZerIkkQowkB + sXJFkvCP5oF2rA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 31323 example.com. + Z+aaLu4rmzekfhlj6A0ClREloRi8MloRHf/3 + Dlw/RYY1hrOCfcZKEY6AXeVdUwESEsSkSOco + CbhyGHH10dKAAg== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229083110 29600 example.com. + d69kc52VdALI8fbdbflsVsltc1m7bI6QsJ5U + IDE9fy5VqcufZecZMKuozPDuF2vBA8ADFIRU + OfYgKs6YNIOLWg== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + D24JCtCcNzwsY1FXVliAjxMm+x95N2eUTXn0 + M8NK5glSk1yLtnAUKzHxpRExAJLGUiaG4yPu + 2yGZuqwNvJztzw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + NS ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + jRNMrWLfS4yzRHQOBxs6/GKWIzx6AZV5lyCm + 7bYTV9wS3owDJSQhJ7lft0WbBmUMtV3tP9Xr + Yc+yW48p2Vr+QQ== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + F7y+xW/C7iICgmZeYrF4e7Yx4kWZAZPAMzlu + PtWVuf37ySg1VfEWcQcDP04vF2rXVUqSMEcj + bqUVN5W8Hoazxw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229083110 29600 example.com. + MoYrL/lToC4AHo6KCZRiBRmCMWHUAx2Xt32A + P4lDpwA+wiBWkCZSfVTh60AosS/BIGtBb2BK + mszMx8CLBvkjRg== ) diff --git a/tests/knot/semantic_check_data/nsec3_param_invalid.signed b/tests/knot/semantic_check_data/nsec3_param_invalid.signed new file mode 100644 index 0000000..c7d8d6d --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_param_invalid.signed @@ -0,0 +1,70 @@ +; Zone without any semantic error + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + W9EprjaR4loSnNW96h4rLsquPDw3LHYvD05k + djkQofHSkMNZAJ7Q+eA3Fs2ik5fnJFM7wi5C + MtFsV2TfqMJFmg== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + I9Je1S7XhZIW9C0fWE8NwFLC2rhHklddNYBO + dxVKL/lxENU4jPPBwZBGrcYn2WVHgkIzjG0n + EOHONAgRFPi3Xw== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + vO2UQiTN/CNUZOmSEg8kJlR/UqiAZHc4qMwj + 9u31sbPmOMuni+ZGuVCFFoEMtZerIkkQowkB + sXJFkvCP5oF2rA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 31323 example.com. + Z+aaLu4rmzekfhlj6A0ClREloRi8MloRHf/3 + Dlw/RYY1hrOCfcZKEY6AXeVdUwESEsSkSOco + CbhyGHH10dKAAg== ) + 0 NSEC3PARAM 1 4 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229083110 29600 example.com. + d69kc52VdALI8fbdbflsVsltc1m7bI6QsJ5U + IDE9fy5VqcufZecZMKuozPDuF2vBA8ADFIRU + OfYgKs6YNIOLWg== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 1 15 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + D24JCtCcNzwsY1FXVliAjxMm+x95N2eUTXn0 + M8NK5glSk1yLtnAUKzHxpRExAJLGUiaG4yPu + 2yGZuqwNvJztzw== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 4 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + F7y+xW/C7iICgmZeYrF4e7Yx4kWZAZPAMzlu + PtWVuf37ySg1VfEWcQcDP04vF2rXVUqSMEcj + bqUVN5W8Hoazxw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229083110 29600 example.com. + MoYrL/lToC4AHo6KCZRiBRmCMWHUAx2Xt32A + P4lDpwA+wiBWkCZSfVTh60AosS/BIGtBb2BK + mszMx8CLBvkjRg== ) diff --git a/tests/knot/semantic_check_data/nsec3_wrong_bitmap_01.signed b/tests/knot/semantic_check_data/nsec3_wrong_bitmap_01.signed new file mode 100644 index 0000000..a3024d8 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_wrong_bitmap_01.signed @@ -0,0 +1,70 @@ +; example.com -- missing DNSKEY in type bitmap +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG NSEC3PARAM ) +; dns1.example.com +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + li23VC44fumpMHhKwWug2J1C2fwCMiwgofYO + DKydNYsJyYTlyi8ezLJ2KoBlCtOc4Fp0NbqS + aN8CKWh7fQVnkQ== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + Y8olY2OClZgC+QHnOhY52LONVOcctOnl8jNY + /c7sCHZO4TdPPDHDhpbVntQD+Vc4fUTx+cXY + GrF5sLbhddBJXg== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + fx2rZzhyYrp1b4tNH1SmM852VbGEeZdKrD+f + ZoInny1m8sovb1J9ORtVbGkOYOnInDMLWMCX + fghHC2MafuFV+Q== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160225083237 31323 example.com. + TcNU6AlrYhJLrNlkfOPJzO6A77j6C39IPoP4 + OfmY2ClA5Vx2JO0vQ4bIHR7GIW8fiMe6M6tt + ZwQImhVWdG414A== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160225083237 29600 example.com. + iY0WB0dN1hQXoctaMwvvXzn7paQt5xUyucT3 + xwo6HAI8Y+OJlecUfOpkkQ9lqIfsqPTXmgbY + RieoZGrWR6ZvaQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160225083237 29600 example.com. + QptUkTNS7umNQ5V6Z9DyGl6z+rG7G3TFmHG8 + p9HGaKifSxjwSFW0nZ9/s86XHQ8ql5+bQmPa + xw39ntBmQLVxfg== ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160225083237 29600 example.com. + CPx6000z5m1zUUpVhki1u9U7P/WMr7PUJAk3 + G0w3v+/Lw56mDzYzNuTpPzS0noe0LKuecqRu + m99KpLyLOx+9QA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160225083237 29600 example.com. + m2z+hx+8hTA7Phu6QzGJrq+o4MiURpda3fYm + 0wTDmXtfPKsHmojGr3kBlvUMg16s2gpvNyCL + MSlnJ+7KCkI+Mw== ) diff --git a/tests/knot/semantic_check_data/nsec3_wrong_bitmap_02.signed b/tests/knot/semantic_check_data/nsec3_wrong_bitmap_02.signed new file mode 100644 index 0000000..e3e4940 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_wrong_bitmap_02.signed @@ -0,0 +1,70 @@ +; example.com +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) +; dns1.example.com -- extra type in bitmap - NSEC +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG NSEC) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + li23VC44fumpMHhKwWug2J1C2fwCMiwgofYO + DKydNYsJyYTlyi8ezLJ2KoBlCtOc4Fp0NbqS + aN8CKWh7fQVnkQ== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + Y8olY2OClZgC+QHnOhY52LONVOcctOnl8jNY + /c7sCHZO4TdPPDHDhpbVntQD+Vc4fUTx+cXY + GrF5sLbhddBJXg== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + fx2rZzhyYrp1b4tNH1SmM852VbGEeZdKrD+f + ZoInny1m8sovb1J9ORtVbGkOYOnInDMLWMCX + fghHC2MafuFV+Q== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160225083237 31323 example.com. + TcNU6AlrYhJLrNlkfOPJzO6A77j6C39IPoP4 + OfmY2ClA5Vx2JO0vQ4bIHR7GIW8fiMe6M6tt + ZwQImhVWdG414A== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160225083237 29600 example.com. + iY0WB0dN1hQXoctaMwvvXzn7paQt5xUyucT3 + xwo6HAI8Y+OJlecUfOpkkQ9lqIfsqPTXmgbY + RieoZGrWR6ZvaQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160225083237 29600 example.com. + QptUkTNS7umNQ5V6Z9DyGl6z+rG7G3TFmHG8 + p9HGaKifSxjwSFW0nZ9/s86XHQ8ql5+bQmPa + xw39ntBmQLVxfg== ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160225083237 29600 example.com. + CPx6000z5m1zUUpVhki1u9U7P/WMr7PUJAk3 + G0w3v+/Lw56mDzYzNuTpPzS0noe0LKuecqRu + m99KpLyLOx+9QA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160225083237 29600 example.com. + m2z+hx+8hTA7Phu6QzGJrq+o4MiURpda3fYm + 0wTDmXtfPKsHmojGr3kBlvUMg16s2gpvNyCL + MSlnJ+7KCkI+Mw== ) diff --git a/tests/knot/semantic_check_data/nsec_broken_chain_01.signed b/tests/knot/semantic_check_data/nsec_broken_chain_01.signed new file mode 100644 index 0000000..cb41dce --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_broken_chain_01.signed @@ -0,0 +1,72 @@ +; not coherent NSEC chain +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC example.com. A RRSIG NSEC +www.example.com. 86400 NSEC example.com. A RRSIG NSEC + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) +www.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) diff --git a/tests/knot/semantic_check_data/nsec_broken_chain_02.signed b/tests/knot/semantic_check_data/nsec_broken_chain_02.signed new file mode 100644 index 0000000..27d8ebb --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_broken_chain_02.signed @@ -0,0 +1,73 @@ +; not coherent NSEC chain +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC www.example.com. A RRSIG NSEC +www.example.com. 86400 NSEC www.example.com. A RRSIG NSEC + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) +www.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) + +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) diff --git a/tests/knot/semantic_check_data/nsec_missing.signed b/tests/knot/semantic_check_data/nsec_missing.signed new file mode 100644 index 0000000..e901607 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_missing.signed @@ -0,0 +1,67 @@ +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC example.com. A RRSIG NSEC +; missing NSEC for www.example.com. + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) + +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) diff --git a/tests/knot/semantic_check_data/nsec_multiple.signed b/tests/knot/semantic_check_data/nsec_multiple.signed new file mode 100644 index 0000000..fc8e41b --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_multiple.signed @@ -0,0 +1,74 @@ +; not coherent NSEC chain +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC www.example.com. A RRSIG NSEC +www.example.com. 86400 NSEC example.com. A RRSIG NSEC +www.example.com. 86400 NSEC www.example.com. A RRSIG NSEC + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) +www.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) + +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) diff --git a/tests/knot/semantic_check_data/nsec_wrong_bitmap_01.signed b/tests/knot/semantic_check_data/nsec_wrong_bitmap_01.signed new file mode 100644 index 0000000..058a0a3 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_wrong_bitmap_01.signed @@ -0,0 +1,73 @@ +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC www.example.com. A RRSIG NSEC + +; extra AAAA type in NSEC bitmap +www.example.com. 86400 NSEC example.com. A RRSIG NSEC AAAA +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) +www.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) diff --git a/tests/knot/semantic_check_data/nsec_wrong_bitmap_02.signed b/tests/knot/semantic_check_data/nsec_wrong_bitmap_02.signed new file mode 100644 index 0000000..dafdc92 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_wrong_bitmap_02.signed @@ -0,0 +1,73 @@ +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC www.example.com. A RRSIG NSEC + +; missing A type in NSEC bitmap +www.example.com. 86400 NSEC example.com. RRSIG NSEC +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) +www.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) diff --git a/tests/knot/semantic_check_data/rrsig_rdata_ttl.signed b/tests/knot/semantic_check_data/rrsig_rdata_ttl.signed new file mode 100644 index 0000000..b626b45 --- /dev/null +++ b/tests/knot/semantic_check_data/rrsig_rdata_ttl.signed @@ -0,0 +1,58 @@ +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 600 ( + 20840201000000 20160201000000 29600 example.com. + f24sVhH1P/0mEMYTMbFLrWmJtl6kqZF6yzaS + TcyK6JhVM4sDT//YnjizJGsTVGSCelz3FxMj + LdiUm9AD05uY6A== ) + +dns1.example.com. 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160201000000 29600 example.com. + FgQ4VD1yDeA+uvJ+o8e1F28ijooV1IMfEtki + kLbaIvFcgZbPvTnXXHyesHO2OPiRsc7zF576 + Z6prBT8CkMM7bw== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + kINKkWiBvb9Dpb0vghlLhXyObSzsYYNsOqe9 + pWJN4lI4F2O3T6biPTQPsq3mYMR+6x9gPr6v + ysEPHlGtLdTLag== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + LkagMndC+wJGlQycPDvNmCZ0/QuBB7Zo4UVZ + He5jzQrE3Hnq8tn+/QfJ/yn62qCZ87DETwTT + rGaLqOTYRb1isg== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160201000000 29600 example.com. + YDJ1tQvNlv8Y7cGioq8nkbaETx7wmyJKqa0B + 8hDLClYA4nf9UtyVXqZCISa2PlgRdBc5GEEh + U5BuLr4wYXqEFA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + FPOm8y3e09jh0fv0ZaOecWbdIXDAoERVKdjz + qsg1Etop1n6nDhO/lW3pwOUe02Zq2vretu2W + DozlDr5E6ZoqPA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160201000000 31323 example.com. + cZTevjvA8UO9Tqet/pbsN0Peep6aN8heyxMK + XP/Twsj4u0DeClKeIN7pd7Gi7Aac/UV2dev/ + x/90SM22VQVpeQ== ) diff --git a/tests/knot/semantic_check_data/rrsig_signed.signed b/tests/knot/semantic_check_data/rrsig_signed.signed new file mode 100644 index 0000000..2798026 --- /dev/null +++ b/tests/knot/semantic_check_data/rrsig_signed.signed @@ -0,0 +1,62 @@ +dns1.example.com. 86400 RRSIG RRSIG 7 3 86400 ( + 20840201000000 20160201000000 29600 example.com. + DummySignatureDEADBEEF8ijooV1IMfEtki + kLbaIvFcgZbPvTnXXHyesHO2OPiRsc7zF576 + Z6prBT8CkMM7bw== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + kINKkWiBvb9Dpb0vghlLhXyObSzsYYNsOqe9 + pWJN4lI4F2O3T6biPTQPsq3mYMR+6x9gPr6v + ysEPHlGtLdTLag== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + LkagMndC+wJGlQycPDvNmCZ0/QuBB7Zo4UVZ + He5jzQrE3Hnq8tn+/QfJ/yn62qCZ87DETwTT + rGaLqOTYRb1isg== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160201000000 29600 example.com. + YDJ1tQvNlv8Y7cGioq8nkbaETx7wmyJKqa0B + 8hDLClYA4nf9UtyVXqZCISa2PlgRdBc5GEEh + U5BuLr4wYXqEFA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + FPOm8y3e09jh0fv0ZaOecWbdIXDAoERVKdjz + qsg1Etop1n6nDhO/lW3pwOUe02Zq2vretu2W + DozlDr5E6ZoqPA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160201000000 31323 example.com. + cZTevjvA8UO9Tqet/pbsN0Peep6aN8heyxMK + XP/Twsj4u0DeClKeIN7pd7Gi7Aac/UV2dev/ + x/90SM22VQVpeQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160201000000 29600 example.com. + f24sVhH1P/0mEMYTMbFLrWmJtl6kqZF6yzaS + TcyK6JhVM4sDT//YnjizJGsTVGSCelz3FxMj + LdiUm9AD05uY6A== ) + 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160201000000 29600 example.com. + FgQ4VD1yDeA+uvJ+o8e1F28ijooV1IMfEtki + kLbaIvFcgZbPvTnXXHyesHO2OPiRsc7zF576 + Z6prBT8CkMM7bw== ) diff --git a/tests/knot/semantic_check_data/rrsig_ttl.signed b/tests/knot/semantic_check_data/rrsig_ttl.signed new file mode 100644 index 0000000..04be771 --- /dev/null +++ b/tests/knot/semantic_check_data/rrsig_ttl.signed @@ -0,0 +1,58 @@ +dns1.example.com. 3600 IN A 192.0.2.1 + 600 RRSIG A 7 3 3600 ( + 20840201000000 20160201000000 29600 example.com. + f24sVhH1P/0mEMYTMbFLrWmJtl6kqZF6yzaS + TcyK6JhVM4sDT//YnjizJGsTVGSCelz3FxMj + LdiUm9AD05uY6A== ) + +dns1.example.com. 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160201000000 29600 example.com. + FgQ4VD1yDeA+uvJ+o8e1F28ijooV1IMfEtki + kLbaIvFcgZbPvTnXXHyesHO2OPiRsc7zF576 + Z6prBT8CkMM7bw== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + kINKkWiBvb9Dpb0vghlLhXyObSzsYYNsOqe9 + pWJN4lI4F2O3T6biPTQPsq3mYMR+6x9gPr6v + ysEPHlGtLdTLag== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + LkagMndC+wJGlQycPDvNmCZ0/QuBB7Zo4UVZ + He5jzQrE3Hnq8tn+/QfJ/yn62qCZ87DETwTT + rGaLqOTYRb1isg== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160201000000 29600 example.com. + YDJ1tQvNlv8Y7cGioq8nkbaETx7wmyJKqa0B + 8hDLClYA4nf9UtyVXqZCISa2PlgRdBc5GEEh + U5BuLr4wYXqEFA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + FPOm8y3e09jh0fv0ZaOecWbdIXDAoERVKdjz + qsg1Etop1n6nDhO/lW3pwOUe02Zq2vretu2W + DozlDr5E6ZoqPA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160201000000 31323 example.com. + cZTevjvA8UO9Tqet/pbsN0Peep6aN8heyxMK + XP/Twsj4u0DeClKeIN7pd7Gi7Aac/UV2dev/ + x/90SM22VQVpeQ== ) diff --git a/tests/knot/test_acl.c b/tests/knot/test_acl.c new file mode 100644 index 0000000..be35607 --- /dev/null +++ b/tests/knot/test_acl.c @@ -0,0 +1,200 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <tap/basic.h> + +#include "test_conf.h" +#include "libknot/libknot.h" +#include "knot/updates/acl.h" +#include "contrib/sockaddr.h" + +#define ZONE "example.zone" +#define KEY1 "key1_md5" +#define KEY2 "key2_md5" +#define KEY3 "key3_sha256" + +static void check_sockaddr_set(struct sockaddr_storage *ss, int family, + const char *straddr, int port) +{ + int ret = sockaddr_set(ss, family, straddr, port); + ok(ret == 0, "set address '%s'", straddr); +} + +static void test_acl_allowed(void) +{ + int ret; + conf_val_t acl; + struct sockaddr_storage addr = { 0 }; + + knot_dname_t *zone_name = knot_dname_from_str_alloc(ZONE); + ok(zone_name != NULL, "create zone dname"); + knot_dname_t *key1_name = knot_dname_from_str_alloc(KEY1); + ok(key1_name != NULL, "create "KEY1); + knot_dname_t *key2_name = knot_dname_from_str_alloc(KEY2); + ok(key2_name != NULL, "create "KEY2); + knot_dname_t *key3_name = knot_dname_from_str_alloc(KEY3); + ok(key3_name != NULL, "create "KEY3); + + knot_tsig_key_t key0 = { 0 }; + knot_tsig_key_t key1 = { DNSSEC_TSIG_HMAC_MD5, key1_name }; + knot_tsig_key_t key2 = { DNSSEC_TSIG_HMAC_MD5, key2_name }; + knot_tsig_key_t key3 = { DNSSEC_TSIG_HMAC_SHA256, key3_name }; + + const char *conf_str = + "key:\n" + " - id: "KEY1"\n" + " algorithm: hmac-md5\n" + " secret: Zm9v\n" + " - id: "KEY2"\n" + " algorithm: hmac-md5\n" + " secret: Zm9v\n" + " - id: "KEY3"\n" + " algorithm: hmac-sha256\n" + " secret: Zm8=\n" + "\n" + "acl:\n" + " - id: acl_key_addr\n" + " address: [ 2001::1 ]\n" + " key: [ key1_md5 ]\n" + " action: [ transfer ]\n" + " - id: acl_deny\n" + " address: [ 240.0.0.2 ]\n" + " action: [ notify ]\n" + " deny: on\n" + " - id: acl_no_action_deny\n" + " address: [ 240.0.0.3 ]\n" + " deny: on\n" + " - id: acl_multi_addr\n" + " address: [ 192.168.1.1, 240.0.0.0/24 ]\n" + " action: [ notify, update ]\n" + " - id: acl_multi_key\n" + " key: [ key2_md5, key3_sha256 ]\n" + " action: [ notify, update ]\n" + " - id: acl_range_addr\n" + " address: [ 100.0.0.0-100.0.0.5, ::0-::5 ]\n" + " action: [ transfer ]\n" + "\n" + "zone:\n" + " - domain: "ZONE"\n" + " acl: [ acl_key_addr, acl_deny, acl_no_action_deny ]\n" + " acl: [ acl_multi_addr, acl_multi_key ]\n" + " acl: [ acl_range_addr ]"; + + ret = test_conf(conf_str, NULL); + is_int(KNOT_EOK, ret, "Prepare configuration"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NONE, &addr, &key1); + ok(ret == true, "Address, key, empty action"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key1); + ok(ret == true, "Address, key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::2", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key1); + ok(ret == false, "Address not match, key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0); + ok(ret == false, "Address match, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key2); + ok(ret == false, "Address match, key not match, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key1); + ok(ret == false, "Address, key match, action not match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key0); + ok(ret == true, "Second address match, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key1); + ok(ret == false, "Second address match, extra key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.2", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key0); + ok(ret == false, "Denied address match, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.2", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key0); + ok(ret == true, "Denied address match, no key, action not match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.3", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key0); + ok(ret == false, "Denied address match, no key, no action"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "1.1.1.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key3); + ok(ret == true, "Arbitrary address, second key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "100.0.0.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0); + ok(ret == true, "IPv4 address from range, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0); + ok(ret == true, "IPv6 address from range, no key, action match"); + + conf_free(conf()); + knot_dname_free(zone_name, NULL); + knot_dname_free(key1_name, NULL); + knot_dname_free(key2_name, NULL); + knot_dname_free(key3_name, NULL); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("acl_allowed"); + test_acl_allowed(); + + return 0; +} diff --git a/tests/knot/test_changeset.c b/tests/knot/test_changeset.c new file mode 100644 index 0000000..16179ec --- /dev/null +++ b/tests/knot/test_changeset.c @@ -0,0 +1,188 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <assert.h> +#include <tap/basic.h> + +#include "libknot/errcode.h" +#include "libknot/error.h" +#include "knot/updates/changesets.h" + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test with NULL changeset + ok(changeset_size(NULL) == 0, "changeset: NULL size"); + ok(changeset_empty(NULL), "changeset: NULL empty"); + + // Test creation. + knot_dname_t *d = knot_dname_from_str_alloc("test."); + assert(d); + changeset_t *ch = changeset_new(d); + knot_dname_free(d, NULL); + ok(ch != NULL, "changeset: new"); + if (!ch) { + return 1; + } + ok(changeset_empty(ch), "changeset: empty"); + ch->soa_to = (knot_rrset_t *)0xdeadbeef; + ok(!changeset_empty(ch), "changseset: empty SOA"); + ch->soa_to = NULL; + ok(changeset_size(ch) == 0, "changeset: empty size"); + + // Test additions. + d = knot_dname_from_str_alloc("non.terminals.test."); + assert(d); + knot_rrset_t *apex_txt_rr = knot_rrset_new(d, KNOT_RRTYPE_TXT, KNOT_CLASS_IN, 3600, NULL); + assert(apex_txt_rr); + uint8_t data[8] = "\7teststr"; + knot_rrset_add_rdata(apex_txt_rr, data, sizeof(data), NULL); + + int ret = changeset_add_addition(ch, apex_txt_rr, CHANGESET_CHECK); + is_int(KNOT_EOK, ret, "changeset: add RRSet"); + ok(changeset_size(ch) == 1, "changeset: size add"); + ret = changeset_add_removal(ch, apex_txt_rr, CHANGESET_CHECK); + is_int(KNOT_EOK, ret, "changeset: rem RRSet"); + ok(changeset_size(ch) == 1, "changeset: size remove"); + ok(!changeset_empty(ch), "changeset: empty"); + changeset_add_addition(ch, apex_txt_rr, CHANGESET_CHECK); + + // Add another RR to node. + knot_rrset_t *apex_spf_rr = knot_rrset_new(d, KNOT_RRTYPE_SPF, KNOT_CLASS_IN, 3600, NULL); + assert(apex_spf_rr); + knot_rrset_add_rdata(apex_spf_rr, data, sizeof(data), NULL); + ret = changeset_add_addition(ch, apex_spf_rr, CHANGESET_CHECK); + is_int(KNOT_EOK, ret, "changeset: add multiple"); + + // Add another node. + knot_dname_free(d, NULL); + d = knot_dname_from_str_alloc("here.come.more.non.terminals.test"); + assert(d); + knot_rrset_t *other_rr = knot_rrset_new(d, KNOT_RRTYPE_TXT, KNOT_CLASS_IN, 3600, NULL); + assert(other_rr); + knot_rrset_add_rdata(other_rr, data, sizeof(data), NULL); + ret = changeset_add_addition(ch, other_rr, CHANGESET_CHECK); + is_int(KNOT_EOK, ret, "changeset: remove multiple"); + + // Test add traversal. + changeset_iter_t it; + ret = changeset_iter_add(&it, ch); + is_int(KNOT_EOK, ret, "changeset: create iter add"); + // Order: non.terminals.test. TXT, SPF, here.come.more.non.terminals.test. TXT. + knot_rrset_t iter = changeset_iter_next(&it); + bool trav_ok = knot_rrset_equal(&iter, apex_txt_rr, KNOT_RRSET_COMPARE_WHOLE); + iter = changeset_iter_next(&it); + trav_ok = trav_ok && knot_rrset_equal(&iter, apex_spf_rr, KNOT_RRSET_COMPARE_WHOLE); + iter = changeset_iter_next(&it); + trav_ok = trav_ok && knot_rrset_equal(&iter, other_rr, KNOT_RRSET_COMPARE_WHOLE); + + ok(trav_ok, "changeset: add traversal"); + + iter = changeset_iter_next(&it); + changeset_iter_clear(&it); + ok(knot_rrset_empty(&iter), "changeset: traversal: skip non-terminals"); + + changeset_add_removal(ch, apex_txt_rr, CHANGESET_CHECK); + changeset_add_removal(ch, apex_txt_rr, CHANGESET_CHECK); + + // Test remove traversal. + ret = changeset_iter_rem(&it, ch); + is_int(KNOT_EOK, ret, "changeset: create iter rem"); + iter = changeset_iter_next(&it); + ok(knot_rrset_equal(&iter, apex_txt_rr, KNOT_RRSET_COMPARE_WHOLE), + "changeset: rem traversal"); + changeset_iter_clear(&it); + + // Test all traversal - just count. + ret = changeset_iter_all(&it, ch); + is_int(KNOT_EOK, ret, "changest: create iter all"); + size_t size = 0; + iter = changeset_iter_next(&it); + while (!knot_rrset_empty(&iter)) { + ++size; + iter = changeset_iter_next(&it); + } + changeset_iter_clear(&it); + ok(size == 3, "changeset: iter all"); + + // Create new changeset. + knot_dname_free(d, NULL); + d = knot_dname_from_str_alloc("test."); + assert(d); + changeset_t *ch2 = changeset_new(d); + knot_dname_free(d, NULL); + assert(ch2); + // Add something to add section. + knot_dname_free(apex_txt_rr->owner, NULL); + apex_txt_rr->owner = knot_dname_from_str_alloc("something.test."); + assert(apex_txt_rr->owner); + ret = changeset_add_addition(ch2, apex_txt_rr, CHANGESET_CHECK); + assert(ret == KNOT_EOK); + + // Add something to remove section. + knot_dname_free(apex_txt_rr->owner, NULL); + apex_txt_rr->owner = + knot_dname_from_str_alloc("and.now.for.something.completely.different.test."); + assert(apex_txt_rr->owner); + ret = changeset_add_removal(ch2, apex_txt_rr, CHANGESET_CHECK); + assert(ret == KNOT_EOK); + + // Test merge. + ret = changeset_merge(ch, ch2, 0); + ok(ret == KNOT_EOK && changeset_size(ch) == 5, "changeset: merge"); + + // Test preapply fix. + zone_contents_t *z = zone_contents_new((const knot_dname_t *)"\x04""test"); + knot_dname_free(apex_txt_rr->owner, NULL); + apex_txt_rr->owner = knot_dname_from_str_alloc("something.test."); + assert(apex_txt_rr->owner); + zone_node_t *znode = NULL; + ret = zone_contents_add_rr(z, apex_txt_rr, &znode); + assert(ret == KNOT_EOK); + ret = changeset_preapply_fix(z, ch2); + ok(ret == KNOT_EOK, "changeset: preapply fix ok (%s)", knot_strerror(ret)); + ok(changeset_empty(ch2), "changeset: preapply fix works"); + zone_contents_deep_free(z); + + // Test cancelout. + ret = changeset_add_removal(ch2, apex_txt_rr, 0); + assert(ret == KNOT_EOK); + ret = changeset_add_addition(ch2, apex_txt_rr, 0); + assert(ret == KNOT_EOK); + ret = changeset_cancelout(ch2); + ok(ret == KNOT_EOK, "changeset: cancelout ok (%s)", knot_strerror(ret)); + ok(changeset_empty(ch2), "changeset: cancelout works"); + + // Test cleanup. + changeset_clear(ch); + ok(changeset_empty(ch), "changeset: clear"); + free(ch); + + list_t chgs; + init_list(&chgs); + add_head(&chgs, &ch2->n); + changesets_clear(&chgs); + ok(changeset_empty(ch2), "changeset: clear list"); + free(ch2); + + knot_rrset_free(apex_txt_rr, NULL); + knot_rrset_free(apex_spf_rr, NULL); + knot_rrset_free(other_rr, NULL); + + return 0; +} diff --git a/tests/knot/test_conf.c b/tests/knot/test_conf.c new file mode 100644 index 0000000..59ae4dd --- /dev/null +++ b/tests/knot/test_conf.c @@ -0,0 +1,210 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "knot/conf/conf.c" +#include "test_conf.h" + +#define ZONE_ARPA "0/25.2.0.192.in-addr.arpa." +#define ZONE_ROOT "." +#define ZONE_1LABEL "x." +#define ZONE_3LABEL "abc.ab.a." +#define ZONE_UNKNOWN "unknown." + +static void check_name(const char *zone, const char *name, const char *ref) +{ + knot_dname_t *z = knot_dname_from_str_alloc(zone); + + char *file = get_filename(NULL, NULL, z, name); + ok(file != NULL, "Get zonefile path for %s", zone); + if (file != NULL) { + ok(strcmp(file, ref) == 0, "Zonefile path compare %s", name); + free(file); + } + + knot_dname_free(z, NULL); +} + +static void check_name_err(const char *zone, const char *name) +{ + knot_dname_t *z = knot_dname_from_str_alloc(zone); + + ok(get_filename(NULL, NULL, z, name) == NULL, "Invalid name %s", name); + + knot_dname_free(z, NULL); +} + +static void test_get_filename(void) +{ + // Name formatter. + char *zone = "abc"; + check_name(zone, "/%s", "/abc"); + + zone = "."; + check_name(zone, "/%s", "/"); + + // Char formatter. + zone = "abc.def.g"; + check_name(zone, "/%c[0]", "/a"); + check_name(zone, "/%c[3]", "/."); + check_name(zone, "/%c[8]", "/g"); + check_name(zone, "/%c[9]", "/."); + check_name(zone, "/%c[10]", "/"); + check_name(zone, "/%c[255]", "/"); + check_name(zone, "/%c[0-1]", "/ab"); + check_name(zone, "/%c[1-1]", "/b"); + check_name(zone, "/%c[1-3]", "/bc."); + check_name(zone, "/%c[1-4]", "/bc.d"); + check_name(zone, "/%c[254-255]", "/"); + check_name_err(zone, "/%c"); + check_name_err(zone, "/%cx"); + check_name_err(zone, "/%c[a]"); + check_name_err(zone, "/%c[:]"); + check_name_err(zone, "/%c[/]"); + check_name_err(zone, "/%c[-1]"); + check_name_err(zone, "/%c[256]"); + check_name_err(zone, "/%c["); + check_name_err(zone, "/%c[1"); + check_name_err(zone, "/%c[1-"); + check_name_err(zone, "/%c[1-2"); + check_name_err(zone, "/%c[1-b]"); + check_name_err(zone, "/%c[8-0]"); + + zone = "abcd"; + check_name(zone, "/%c[2-9]", "/cd."); + check_name(zone, "/%c[3]", "/d"); + check_name(zone, "/%c[4]", "/."); + + zone = "."; + check_name(zone, "/%c[0]", "/."); + check_name(zone, "/%c[1]", "/"); + + // Label formatter. + zone = "abc.def.gh"; + check_name(zone, "/%l[0]", "/gh"); + check_name(zone, "/%l[1]", "/def"); + check_name(zone, "/%l[2]", "/abc"); + check_name(zone, "/%l[3]", "/"); + check_name(zone, "/%l[255]", "/"); + check_name(zone, "/%l[0]-%l[1]-%l[2]", "/gh-def-abc"); + check_name_err(zone, "/%l[0-1]"); + check_name_err(zone, "/%l[-1]"); + check_name_err(zone, "/%l[256]"); + + zone = "."; + check_name(zone, "/%l[0]", "/"); + check_name(zone, "/%l[1]", "/"); +} + +static void test_conf_zonefile(void) +{ + int ret; + char *file; + + knot_dname_t *zone_arpa = knot_dname_from_str_alloc(ZONE_ARPA); + ok(zone_arpa != NULL, "create dname "ZONE_ARPA); + knot_dname_t *zone_root = knot_dname_from_str_alloc(ZONE_ROOT); + ok(zone_root != NULL, "create dname "ZONE_ROOT); + knot_dname_t *zone_1label = knot_dname_from_str_alloc(ZONE_1LABEL); + ok(zone_1label != NULL, "create dname "ZONE_1LABEL); + knot_dname_t *zone_3label = knot_dname_from_str_alloc(ZONE_3LABEL); + ok(zone_3label != NULL, "create dname "ZONE_3LABEL); + knot_dname_t *zone_unknown = knot_dname_from_str_alloc(ZONE_UNKNOWN); + ok(zone_unknown != NULL, "create dname "ZONE_UNKNOWN); + + const char *conf_str = + "template:\n" + " - id: default\n" + " storage: /tmp\n" + "\n" + "zone:\n" + " - domain: "ZONE_ARPA"\n" + " file: dir/a%%b/%s.suffix/%a\n" + " - domain: "ZONE_ROOT"\n" + " file: /%s\n" + " - domain: "ZONE_1LABEL"\n" + " file: /%s\n" + " - domain: "ZONE_3LABEL"\n"; + + ret = test_conf(conf_str, NULL); + is_int(KNOT_EOK, ret, "Prepare configuration"); + + // Relative path with formatters. + file = conf_zonefile(conf(), zone_arpa); + ok(file != NULL, "Get zonefile path for "ZONE_ARPA); + if (file != NULL) { + ok(strcmp(file, "/tmp/dir/a%b/0_25.2.0.192.in-addr.arpa.suffix/") == 0, + "Zonefile path compare for "ZONE_ARPA); + free(file); + } + + // Absolute path without formatters - root zone. + file = conf_zonefile(conf(), zone_root); + ok(file != NULL, "Get zonefile path for "ZONE_ROOT); + if (file != NULL) { + ok(strcmp(file, "/") == 0, + "Zonefile path compare for "ZONE_ROOT); + free(file); + } + + // Absolute path without formatters - non-root zone. + file = conf_zonefile(conf(), zone_1label); + ok(file != NULL, "Get zonefile path for "ZONE_1LABEL); + if (file != NULL) { + ok(strcmp(file, "/x") == 0, + "Zonefile path compare for "ZONE_1LABEL); + free(file); + } + + // Default zonefile path. + file = conf_zonefile(conf(), zone_3label); + ok(file != NULL, "Get zonefile path for "ZONE_3LABEL); + if (file != NULL) { + ok(strcmp(file, "/tmp/abc.ab.a.zone") == 0, + "Zonefile path compare for "ZONE_3LABEL); + free(file); + } + + // Unknown zone zonefile path. + file = conf_zonefile(conf(), zone_unknown); + ok(file != NULL, "Get zonefile path for "ZONE_UNKNOWN); + if (file != NULL) { + ok(strcmp(file, "/tmp/unknown.zone") == 0, + "Zonefile path compare for "ZONE_UNKNOWN); + free(file); + } + + conf_free(conf()); + knot_dname_free(zone_arpa, NULL); + knot_dname_free(zone_root, NULL); + knot_dname_free(zone_1label, NULL); + knot_dname_free(zone_3label, NULL); + knot_dname_free(zone_unknown, NULL); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("get_filename"); + test_get_filename(); + + diag("conf_zonefile"); + test_conf_zonefile(); + + return 0; +} diff --git a/tests/knot/test_conf.h b/tests/knot/test_conf.h new file mode 100644 index 0000000..708692a --- /dev/null +++ b/tests/knot/test_conf.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include "knot/conf/conf.h" +#include "libknot/errcode.h" + +/* Prepare server configuration. */ +static inline int test_conf(const char *conf_str, const yp_item_t *schema) +{ + // Use default schema if not specified. + if (schema == NULL) { + schema = conf_schema; + } + + conf_t *new_conf = NULL; + int ret = conf_new(&new_conf, schema, NULL, 2 * 1024 * 1024, CONF_FNONE); + if (ret != KNOT_EOK) { + return ret; + } + + ret = conf_import(new_conf, conf_str, false); + if (ret != KNOT_EOK) { + conf_free(new_conf); + return ret; + } + + conf_update(new_conf, CONF_UPD_FNONE); + + return KNOT_EOK; +} diff --git a/tests/knot/test_conf_tools.c b/tests/knot/test_conf_tools.c new file mode 100644 index 0000000..178b269 --- /dev/null +++ b/tests/knot/test_conf_tools.c @@ -0,0 +1,123 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/yparser/yptrafo.h" +#include "knot/conf/tools.h" +#include "libknot/libknot.h" + +static void mod_id_test(const char *txt, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, + mod_id_to_bin, + mod_id_to_txt } }; + + diag("module id \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(memcmp(b, val, b_len) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void mod_id_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, + mod_id_to_bin, + mod_id_to_txt } }; + + diag("module id \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void edns_opt_test(const char *txt, uint16_t code, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, + edns_opt_to_bin, + edns_opt_to_txt } }; + + diag("edns option \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + uint64_t c = knot_wire_read_u64(b); + ok(c == code, "compare code"); + ok(memcmp(yp_bin(b + sizeof(uint64_t)), val, + yp_bin_len(b + sizeof(uint64_t))) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void edns_opt_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, + edns_opt_to_bin, + edns_opt_to_txt } }; + + diag("edns option \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Module id tests. */ + mod_id_test("module/id", "\x06moduleid"); + mod_id_test("module", "\x06module"); + mod_id_bad_test("module/", KNOT_EINVAL); + mod_id_bad_test("/", KNOT_EINVAL); + mod_id_bad_test("/id", KNOT_EINVAL); + + /* EDNS option tests. */ + edns_opt_test("0:", 0, ""); + edns_opt_test("65535:", 65535, ""); + edns_opt_test("1:abc", 1, "abc"); + edns_opt_test("1:0x0102", 1, "\x01\x02"); + edns_opt_bad_test("0", KNOT_EINVAL); + edns_opt_bad_test("-1:a", KNOT_ERANGE); + edns_opt_bad_test("65536:a", KNOT_ERANGE); + edns_opt_bad_test("0:0xa", KNOT_EINVAL); + + return 0; +} diff --git a/tests/knot/test_confdb.c b/tests/knot/test_confdb.c new file mode 100644 index 0000000..a650872 --- /dev/null +++ b/tests/knot/test_confdb.c @@ -0,0 +1,489 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "test_conf.h" +#include "knot/conf/confdb.c" + +static void check_db_content(conf_t *conf, knot_db_txn_t *txn, int count) +{ + ok(db_check_version(conf, txn) == KNOT_EOK, "Version check"); + if (count >= 0) { + ok(conf->api->count(txn) == 1 + count, "Check DB entries count"); + } +} + +static void check_code( + conf_t *conf, + knot_db_txn_t *txn, + uint8_t section_code, + const yp_name_t *name, + db_action_t action, + int ret, + uint8_t ref_code) +{ + uint8_t code = 0; + ok(db_code(conf, txn, section_code, name, action, &code) == ret, + "Compare DB code return"); + + if (ret != KNOT_EOK) { + return; + } + + uint8_t k[64] = { section_code, 0 }; + memcpy(k + 2, name + 1, name[0]); + knot_db_val_t key = { .data = k, .len = 2 + name[0] }; + knot_db_val_t val; + + ret = conf->api->find(txn, &key, &val, 0); + switch (action) { + case DB_GET: + case DB_SET: + ok(code == ref_code, "Compare DB code"); + is_int(KNOT_EOK, ret, "Find DB code"); + ok(val.len == 1, "Compare DB code length"); + ok(((uint8_t *)val.data)[0] == code, "Compare DB code value"); + break; + case DB_DEL: + is_int(KNOT_ENOENT, ret, "Find item code"); + break; + } +} + +static void test_db_code(conf_t *conf, knot_db_txn_t *txn) +{ + // Add codes. + check_code(conf, txn, 0, C_SERVER, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 1); + check_code(conf, txn, 0, C_LOG, DB_SET, KNOT_EOK, KEY1_FIRST + 1); + check_db_content(conf, txn, 2); + check_code(conf, txn, 2, C_IDENT, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 3); + check_code(conf, txn, 0, C_ZONE, DB_SET, KNOT_EOK, KEY1_FIRST + 2); + check_db_content(conf, txn, 4); + check_code(conf, txn, 2, C_VERSION, DB_SET, KNOT_EOK, KEY1_FIRST + 1); + check_db_content(conf, txn, 5); + + // Add existing code (no change). + check_code(conf, txn, 0, C_SERVER, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 5); + + // Get codes. + check_code(conf, txn, 0, C_SERVER, DB_GET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 5); + check_code(conf, txn, 0, C_RMT, DB_GET, KNOT_ENOENT, 0); + check_db_content(conf, txn, 5); + + // Delete not existing code. + check_code(conf, txn, 0, C_COMMENT, DB_DEL, KNOT_ENOENT, 0); + check_db_content(conf, txn, 5); + + // Delete codes. + check_code(conf, txn, 0, C_SERVER, DB_DEL, KNOT_EOK, 0); + check_db_content(conf, txn, 4); + check_code(conf, txn, 2, C_IDENT, DB_DEL, KNOT_EOK, 0); + check_db_content(conf, txn, 3); + + // Reuse deleted codes. + check_code(conf, txn, 0, C_ACL, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 4); + check_code(conf, txn, 2, C_NSID, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 5); +} + +static void check_set( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0, + const yp_name_t *key1, + const uint8_t *id, + size_t id_len, + int ret, + const uint8_t *data, + size_t data_len, + const uint8_t *exp_data, + size_t exp_data_len) +{ + ok(conf_db_set(conf, txn, key0, key1, id, id_len, data, data_len) == ret, + "Check set return"); + + if (ret != KNOT_EOK || (key1 == NULL && id == NULL)) { + return; + } + + uint8_t section_code, item_code; + section_code = 0, item_code = 0; // prevents Wuninitialized + ok(db_code(conf, txn, KEY0_ROOT, key0, DB_GET, §ion_code) == KNOT_EOK, + "Get DB section code"); + if (key1 != NULL) { + ok(db_code(conf, txn, section_code, key1, DB_GET, &item_code) == KNOT_EOK, + "Get DB item code"); + } else { + item_code = KEY1_ID; + } + + uint8_t k[64] = { section_code, item_code }; + if (id != NULL) { + memcpy(k + 2, id, id_len); + } + knot_db_val_t key = { .data = k, .len = 2 + id_len }; + knot_db_val_t val; + + ok(conf->api->find(txn, &key, &val, 0) == KNOT_EOK, "Get inserted data"); + ok(val.len == exp_data_len, "Compare data length"); + ok(memcmp(val.data, exp_data, exp_data_len) == 0, "Compare data"); + + check_db_content(conf, txn, -1); +} + +static void test_conf_db_set(conf_t *conf, knot_db_txn_t *txn) +{ + // Set section without item - noop. + check_set(conf, txn, C_INCL, NULL, NULL, 0, KNOT_EOK, NULL, 0, NULL, 0); + + // Set singlevalued item. + check_set(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK, + (uint8_t *)"\0", 1, (uint8_t *)"\0", 1); + check_set(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK, + (uint8_t *)"a b\0", 4, (uint8_t *)"a b\0", 4); + + // Set multivalued item. + check_set(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"\0", 1, (uint8_t *)"\x00\x01""\0", 3); + check_set(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"a\0", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""a\0", 7); + check_set(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"b\0", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""a\0""\x00\x02""b\0", 11); + + // Set group id. + check_set(conf, txn, C_ZONE, NULL, (uint8_t *)"id", 2, KNOT_EOK, + NULL, 0, (uint8_t *)"", 0); + + // Set singlevalued item with id. + check_set(conf, txn, C_ZONE, C_FILE, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"\0", 1, (uint8_t *)"\0", 1); + check_set(conf, txn, C_ZONE, C_FILE, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"a b\0", 4, (uint8_t *)"a b\0", 4); + + // Set multivalued item with id. + check_set(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"\0", 1, (uint8_t *)"\x00\x01""\0", 3); + check_set(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"a\0", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""a\0", 7); + check_set(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"b\0", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""a\0""\x00\x02""b\0", 11); + + // ERR set invalid section. + check_set(conf, txn, C_MASTER, NULL, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0, NULL, 0); + + // ERR set invalid item. + check_set(conf, txn, C_SERVER, C_DOMAIN, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0, NULL, 0); + + // ERR redefine section id. + check_set(conf, txn, C_ZONE, NULL, (uint8_t *)"id", 2, KNOT_CONF_EREDEFINE, + NULL, 0, NULL, 0); + + // ERR set singlevalued item with non-existing id. + check_set(conf, txn, C_ZONE, C_FILE, (uint8_t *)"idx", 3, KNOT_YP_EINVAL_ID, + NULL, 0, NULL, 0); +} + +static void check_get( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0, + const yp_name_t *key1, + const uint8_t *id, + size_t id_len, + int ret, + const uint8_t *exp_data, + size_t exp_data_len) +{ + conf_val_t val; + ok(conf_db_get(conf, txn, key0, key1, id, id_len, &val) == ret, + "Check get return"); + + if (ret != KNOT_EOK) { + return; + } + + ok(val.blob_len == exp_data_len, "Compare data length"); + ok(val.blob != NULL && memcmp(val.blob, exp_data, exp_data_len) == 0, + "Compare data"); + + check_db_content(conf, txn, -1); +} + +static void test_conf_db_get(conf_t *conf, knot_db_txn_t *txn) +{ + // Get singlevalued item. + check_get(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK, + (uint8_t *)"a b\0", 4); + + // Get multivalued item. + check_get(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"\x00\x01""\0""\x00\x02""a\0""\x00\x02""b\0", 11); + + // Get group id. + check_get(conf, txn, C_ZONE, NULL, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"", 0); + + // Get singlevalued item with id. + check_get(conf, txn, C_ZONE, C_FILE, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"a b\0", 4); + + // Get multivalued item with id. + check_get(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"\x00\x01""\0""\x00\x02""a\0""\x00\x02""b\0", 11); + + // ERR get section without item. + check_get(conf, txn, C_INCL, NULL, NULL, 0, KNOT_EINVAL, NULL, 0); + + // ERR get invalid section. + check_get(conf, txn, C_MASTER, NULL, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0); + + // ERR get invalid item. + check_get(conf, txn, C_SERVER, C_DOMAIN, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0); + + // ERR get singlevalued item with non-existing id. + check_get(conf, txn, C_ZONE, C_FILE, (uint8_t *)"idx", 3, KNOT_YP_EINVAL_ID, + NULL, 0); +} + +static void check_unset( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0, + const yp_name_t *key1, + const uint8_t *id, + size_t id_len, + int ret, + const uint8_t *data, + size_t data_len, + const uint8_t *exp_data, + size_t exp_data_len) +{ + ok(conf_db_unset(conf, txn, key0, key1, id, id_len, data, data_len, false) == ret, + "Check unset return"); + + if (ret != KNOT_EOK) { + return; + } + + uint8_t section_code, item_code; + ok(db_code(conf, txn, KEY0_ROOT, key0, DB_GET, §ion_code) == KNOT_EOK, + "Get DB section code"); + if (key1 != NULL) { + ok(db_code(conf, txn, section_code, key1, DB_GET, &item_code) == KNOT_EOK, + "Get DB item code"); + } else { + item_code = KEY1_ID; + } + + uint8_t k[64] = { section_code, item_code }; + if (id != NULL) { + memcpy(k + 2, id, id_len); + } + knot_db_val_t key = { .data = k, .len = 2 + id_len }; + knot_db_val_t val; + + ret = conf->api->find(txn, &key, &val, 0); + if (exp_data != NULL) { + is_int(KNOT_EOK, ret, "Get deleted data"); + ok(val.len == exp_data_len, "Compare data length"); + ok(memcmp(val.data, exp_data, exp_data_len) == 0, "Compare data"); + } else { + is_int(KNOT_ENOENT, ret, "Get deleted data"); + } + + check_db_content(conf, txn, -1); +} + +static void check_unset_key( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0, + const yp_name_t *key1, + const uint8_t *id, + size_t id_len, + int ret) +{ + ok(conf_db_unset(conf, txn, key0, key1, id, id_len, NULL, 0, true) == ret, + "Check unset return"); + + if (ret != KNOT_EOK) { + return; + } + + uint8_t section_code, item_code; + ret = db_code(conf, txn, KEY0_ROOT, key0, DB_GET, §ion_code); + if (key1 == NULL && id_len == 0) { + is_int(KNOT_ENOENT, ret, "Get DB section code"); + } else { + is_int(KNOT_EOK, ret, "Get DB section code"); + ret = db_code(conf, txn, section_code, key1, DB_GET, &item_code); + is_int(KNOT_ENOENT, ret, "Get DB item code"); + } + + check_db_content(conf, txn, -1); +} + +static void test_conf_db_unset(conf_t *conf, knot_db_txn_t *txn) +{ + // ERR unset section without item. + check_unset(conf, txn, C_INCL, NULL, NULL, 0, KNOT_ENOENT, + NULL, 0, NULL, 0); + + // ERR unset invalid section. + check_unset(conf, txn, C_MASTER, NULL, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0, NULL, 0); + + // ERR unset invalid item. + check_unset(conf, txn, C_SERVER, C_DOMAIN, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0, NULL, 0); + + // ERR unset singlevalued item with non-existing id. + check_unset(conf, txn, C_ZONE, C_FILE, (uint8_t *)"idx", 3, KNOT_YP_EINVAL_ID, + NULL, 0, NULL, 0); + + // ERR unset singlevalued item invalid value. + check_unset(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_ENOENT, + (uint8_t *)"x\0", 2, NULL, 0); + + // Unset singlevalued item data. + check_unset(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK, + (uint8_t *)"a b\0", 4, NULL, 0); + // Unset item. + check_unset_key(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK); + + // Unset multivalued item. + check_unset(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"a", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""b\0", 7); + check_unset(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"", 1, (uint8_t *)"\x00\x02""b\0", 4); + check_unset(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"b", 2, NULL, 0); + // Unset item. + check_unset_key(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK); + // Unset section. + check_unset_key(conf, txn, C_SERVER, NULL, NULL, 0, KNOT_EOK); + + // Unset singlevalued item with id - all data at one step. + check_unset(conf, txn, C_ZONE, C_FILE, (uint8_t *)"id", 2, KNOT_EOK, + NULL, 0, NULL, 0); + + // Unset multivalued item with id - all data at one step (non-null data!). + check_unset(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + NULL + 1, 0, NULL, 0); + + // Unset group id. + check_unset(conf, txn, C_ZONE, NULL, (uint8_t *)"id", 2, KNOT_EOK, + NULL, 0, NULL, 0); +} + +static void test_conf_db_iter(conf_t *conf, knot_db_txn_t *txn) +{ + const size_t total = 4; + char names[][10] = { "alfa", "beta", "delta", "epsilon" }; + + // Prepare identifiers to iterate through. + for (size_t i = 0; i < total; i++) { + check_set(conf, txn, C_RMT, NULL, (uint8_t *)names[i], + strlen(names[i]), KNOT_EOK, NULL, 0, (uint8_t *)"", 0); + } + + // Create section iterator. + conf_iter_t iter; + int ret = conf_db_iter_begin(conf, txn, C_RMT, &iter); + is_int(KNOT_EOK, ret, "Create iterator"); + + // Iterate through the section. + size_t count = 0; + while (ret == KNOT_EOK) { + const uint8_t *id; + size_t id_len; + id = NULL, id_len = 0; // prevents Wuinitialized + ret = conf_db_iter_id(conf, &iter, &id, &id_len); + is_int(KNOT_EOK, ret, "Get iteration id"); + ok(id_len == strlen(names[count]), "Compare iteration id length"); + ok(memcmp(id, names[count], id_len) == 0, "Compare iteration id"); + + ok(conf_db_iter_del(conf, &iter) == KNOT_EOK, "Delete iteration key"); + + count++; + ret = conf_db_iter_next(conf, &iter); + } + is_int(KNOT_EOF, ret, "Finished iteration"); + ok(count == total, "Check iteration count"); + + // Check empty section. + ret = conf_db_iter_begin(conf, txn, C_RMT, &iter); + is_int(KNOT_ENOENT, ret, "Create iterator"); + + // ERR non-iterable section. + ok(conf_db_iter_begin(conf, txn, C_SERVER, &iter) == KNOT_ENOTSUP, "Create iterator"); + + // ERR empty section. + ok(conf_db_iter_begin(conf, txn, C_ZONE, &iter) == KNOT_ENOENT, "Create iterator"); + + // ERR section with no code. + ok(conf_db_iter_begin(conf, txn, C_LOG, &iter) == KNOT_ENOENT, "Create iterator"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + ok(test_conf("", NULL) == KNOT_EOK, "Prepare configuration"); + check_db_content(conf(), &conf()->read_txn, 0); + + knot_db_txn_t txn; + ok(conf()->api->txn_begin(conf()->db, &txn, 0) == KNOT_EOK, "Begin transaction"); + + diag("db_code"); + test_db_code(conf(), &txn); + + conf()->api->txn_abort(&txn); + + ok(conf()->api->txn_begin(conf()->db, &txn, 0) == KNOT_EOK, "Begin transaction"); + + diag("conf_db_set"); + test_conf_db_set(conf(), &txn); + + diag("conf_db_get"); + test_conf_db_get(conf(), &txn); + + diag("conf_db_unset"); + test_conf_db_unset(conf(), &txn); + + conf()->api->txn_abort(&txn); + + ok(conf()->api->txn_begin(conf()->db, &txn, 0) == KNOT_EOK, "Begin transaction"); + + diag("conf_db_iter"); + test_conf_db_iter(conf(), &txn); + + conf()->api->txn_abort(&txn); + + conf_free(conf()); + + return 0; +} diff --git a/tests/knot/test_confio.c b/tests/knot/test_confio.c new file mode 100644 index 0000000..6519d22 --- /dev/null +++ b/tests/knot/test_confio.c @@ -0,0 +1,1009 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "test_conf.h" +#include "knot/conf/confio.h" +#include "knot/conf/tools.h" +#include "libknot/yparser/yptrafo.h" +#include "contrib/string.h" +#include "contrib/openbsd/strlcat.h" + +#define SKIP_OPENBSD skip("Nested transactions are not supported on OpenBSD"); +#define OUT_LEN 1024 +#define ZONE1 "zone1" +#define ZONE2 "zone2" +#define ZONE3 "zone3" + +char *format_key(conf_io_t *io) +{ + char id[KNOT_DNAME_TXT_MAXLEN + 1] = "\0"; + size_t id_len = sizeof(id); + + // Get the textual item id. + if (io->id_len > 0 && !io->id_as_data) { + if (yp_item_to_txt(io->key0->var.g.id, io->id, io->id_len, id, + &id_len, YP_SNOQUOTE) != KNOT_EOK) { + return NULL; + } + } + + // Get the item prefix. + const char *prefix = ""; + switch (io->type) { + case NEW: prefix = "+"; break; + case OLD: prefix = "-"; break; + default: break; + } + + // Format the item key. + return sprintf_alloc( + "%s%.*s%s%.*s%s%s%.*s", + prefix, (int)io->key0->name[0], io->key0->name + 1, + (io->id_len > 0 && !io->id_as_data ? "[" : ""), + (io->id_len > 0 && !io->id_as_data ? (int)id_len : 0), id, + (io->id_len > 0 && !io->id_as_data ? "]" : ""), + (io->key1 != NULL ? "." : ""), + (io->key1 != NULL ? (int)io->key1->name[0] : 0), + (io->key1 != NULL ? io->key1->name + 1 : "")); +} + +static int append_data(const yp_item_t *item, const uint8_t *bin, size_t bin_len, + char *out, size_t out_len) +{ + char buf[YP_MAX_TXT_DATA_LEN + 1] = "\0"; + size_t buf_len = sizeof(buf); + + int ret = yp_item_to_txt(item, bin, bin_len, buf, &buf_len, YP_SNONE); + if (ret != KNOT_EOK) { + return ret; + } + + if (strlcat(out, buf, out_len) >= out_len) { + return KNOT_ESPACE; + } + + return KNOT_EOK; +} + +char *format_data(conf_io_t *io) +{ + char out[YP_MAX_TXT_DATA_LEN + 1] = "\0"; + + // Return the item identifier as the item data. + if (io->id_as_data) { + if (append_data(io->key0->var.g.id, io->id, io->id_len, out, + sizeof(out)) != KNOT_EOK) { + return NULL; + } + + return strdup(out); + } + + // Check for no data. + if (io->data.val == NULL && io->data.bin == NULL) { + return NULL; + } + + const yp_item_t *item = (io->key1 != NULL) ? io->key1 : io->key0; + + // Format explicit binary data value. + if (io->data.bin != NULL) { + if (append_data(item, io->data.bin, io->data.bin_len, out, + sizeof(out)) != KNOT_EOK) { + return NULL; + } + // Format multivalued item data. + } else if (item->flags & YP_FMULTI) { + size_t values = conf_val_count(io->data.val); + for (size_t i = 0; i < values; i++) { + // Skip other values if known index (counted from 1). + if (io->data.index > 0 && + io->data.index != i + 1) { + conf_val_next(io->data.val); + continue; + } + + if (i > 0) { + if (strlcat(out, " ", sizeof(out)) >= sizeof(out)) { + return NULL; + } + } + + conf_val(io->data.val); + if (append_data(item, io->data.val->data, io->data.val->len, + out, sizeof(out)) != KNOT_EOK) { + return NULL; + } + + conf_val_next(io->data.val); + } + // Format singlevalued item data. + } else { + conf_val(io->data.val); + if (append_data(item, io->data.val->data, io->data.val->len, out, + sizeof(out)) != KNOT_EOK) { + return NULL; + } + } + + return strdup(out); +} + +static int format_item(conf_io_t *io) +{ + char *out = (char *)io->misc; + + // Get the item key and data strings. + char *key = format_key(io); + char *data = format_data(io); + + // Format the item. + char *item = sprintf_alloc( + "%s%s%s%s", + (*out != '\0' ? "\n" : ""), + (key != NULL ? key : ""), + (data != NULL ? " = " : ""), + (data != NULL ? data : "")); + free(key); + free(data); + if (item == NULL) { + return KNOT_ENOMEM; + } + + // Append the item. + if (strlcat(out, item, OUT_LEN) >= OUT_LEN) { + free(item); + return KNOT_ESPACE; + } + + free(item); + + return KNOT_EOK; +} + +static void test_conf_io_begin(void) +{ + ok(conf_io_begin(true) == KNOT_TXN_ENOTEXISTS, "begin child txn with no parent"); + ok(conf()->io.txn == NULL, "check txn depth"); + +#if defined(__OpenBSD__) + SKIP_OPENBSD +#else + ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn"); + ok(conf()->io.txn == &(conf()->io.txn_stack[0]), "check txn depth"); + + ok(conf_io_begin(false) == KNOT_TXN_EEXISTS, "begin another parent txn"); + ok(conf()->io.txn == &(conf()->io.txn_stack[0]), "check txn depth"); + + for (int i = 1; i < CONF_MAX_TXN_DEPTH; i++) { + ok(conf_io_begin(true) == KNOT_EOK, "begin child txn"); + ok(conf()->io.txn == &(conf()->io.txn_stack[i]), "check txn depth"); + } + ok(conf_io_begin(true) == KNOT_TXN_EEXISTS, "begin another child txn"); + ok(conf()->io.txn == &(conf()->io.txn_stack[CONF_MAX_TXN_DEPTH - 1]), + "check txn depth"); + + conf_io_abort(false); + ok(conf()->io.txn == NULL, "check txn depth"); +#endif +} + +static void test_conf_io_abort(void) +{ +#if defined(__OpenBSD__) + SKIP_OPENBSD +#else + // Test child persistence after subchild abort. + + ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn"); + char idx[2] = { '0' }; + ok(conf_io_set("server", "version", NULL, idx) == + KNOT_EOK, "set single value '%s'", idx); + + for (int i = 1; i < CONF_MAX_TXN_DEPTH; i++) { + char idx[2] = { '0' + i }; + ok(conf_io_begin(true) == KNOT_EOK, "begin child txn %s", idx); + ok(conf_io_set("server", "version", NULL, idx) == + KNOT_EOK, "set single value '%s'", idx); + } + + for (int i = CONF_MAX_TXN_DEPTH - 1; i > 0; i--) { + char idx[2] = { '0' + i }; + conf_io_abort(true); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + const char *data = conf_str(&val); + ok(*data == (idx[0] - 1), "compare txn data '%s'", data); + } + + conf_io_abort(false); + ok(conf()->io.txn == NULL, "check txn depth"); + + // Test child abort with committed subchild. + ok(conf_io_begin(false) == KNOT_EOK, "begin new parent txn"); + ok(conf_io_begin(true) == KNOT_EOK, "begin child txn"); + ok(conf_io_begin(true) == KNOT_EOK, "begin subchild txn"); + ok(conf_io_set("server", "version", NULL, "text") == + KNOT_EOK, "set single value"); + ok(conf_io_commit(true) == KNOT_EOK, "commit subchild txn"); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + const char *data = conf_str(&val); + ok(strcmp(data, "text") == 0, "compare subchild txn data '%s'", data); + conf_io_abort(true); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + conf_io_abort(false); + + // Test unchanged read_txn. + val = conf_get_txn(conf(), &conf()->read_txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); +#endif +} + +static void test_conf_io_commit(void) +{ + ok(conf_io_commit(false) == KNOT_TXN_ENOTEXISTS, "commit no txt txn"); + ok(conf_io_commit(true) == KNOT_TXN_ENOTEXISTS, "commit no txt txn"); + +#if defined(__OpenBSD__) + SKIP_OPENBSD +#else + // Test subchild persistence after commit. + + ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn"); + char idx[2] = { '0' }; + ok(conf_io_set("server", "version", NULL, idx) == + KNOT_EOK, "set single value '%s'", idx); + + for (int i = 1; i < CONF_MAX_TXN_DEPTH; i++) { + char idx[2] = { '0' + i }; + ok(conf_io_begin(true) == KNOT_EOK, "begin child txn %s", idx); + ok(conf_io_set("server", "version", NULL, idx) == + KNOT_EOK, "set single value '%s'", idx); + } + + for (int i = CONF_MAX_TXN_DEPTH - 1; i > 0; i--) { + char idx[2] = { '0' + i }; + ok(conf_io_commit(true) == KNOT_EOK, "commit child txn %s", idx); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + const char *data = conf_str(&val); + ok(*data == ('0' + CONF_MAX_TXN_DEPTH - 1), "compare txn data '%s'", data); + } + + ok(conf_io_commit(false) == KNOT_EOK, "commit parent txn"); + ok(conf()->io.txn == NULL, "check txn depth"); + + // Test child persistence after parent commit. + ok(conf_io_begin(false) == KNOT_EOK, "begin new parent txn"); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + idx[0] = '0' + CONF_MAX_TXN_DEPTH - 1; + const char *data = conf_str(&val); + ok(strcmp(data, idx) == 0, "compare final data '%s'", data); + conf_io_abort(false); + + // Test unchanged read_txn. + val = conf_get_txn(conf(), &conf()->read_txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); +#endif +} + +static void test_conf_io_check(void) +{ + conf_io_t io = { NULL }; + + // ERR no txn. + ok(conf_io_check(&io) == + KNOT_TXN_ENOTEXISTS, "check without active txn"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // Section check. + ok(conf_io_set("remote", "id", NULL, "remote1") == + KNOT_EOK, "set remote id"); + ok(conf_io_check(&io) == + KNOT_EINVAL, "check missing remote address"); + ok(io.error.code == KNOT_EINVAL, "compare error code"); + + ok(conf_io_set("remote", "address", "remote1", "1.1.1.1") == + KNOT_EOK, "set remote address"); + ok(conf_io_check(&io) == + KNOT_EOK, "check remote address"); + ok(io.error.code == KNOT_EOK, "compare error code"); + + // Item check. + ok(conf_io_set("zone", "domain", NULL, ZONE1) == + KNOT_EOK, "set zone domain "ZONE1); + ok(conf_io_set("zone", "master", ZONE1, "remote1") == + KNOT_EOK, "set zone master"); + + ok(conf_io_check(&io) == + KNOT_EOK, "check all"); + + ok(conf_io_unset("remote", NULL, NULL, NULL) == + KNOT_EOK, "unset remotes"); + + ok(conf_io_check(&io) == + KNOT_ENOENT, "check missing master remote"); + ok(io.error.code == KNOT_ENOENT, "compare error code"); + + conf_io_abort(false); +} + +static void test_conf_io_set(void) +{ + // ERR no txn. + ok(conf_io_set("server", "version", NULL, "text") == + KNOT_TXN_ENOTEXISTS, "set without active txn"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // ERR. + ok(conf_io_set(NULL, NULL, NULL, NULL) == + KNOT_EINVAL, "set NULL key0"); + ok(conf_io_set("", NULL, NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "set empty key0"); + ok(conf_io_set("uknown", NULL, NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "set unknown key0"); + ok(conf_io_set("server", "unknown", NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "set unknown key1"); + ok(conf_io_set("include", NULL, NULL, NULL) == + KNOT_YP_ENODATA, "set non-group without data"); + ok(conf_io_set("server", "background-workers", NULL, "x") == + KNOT_EINVAL, "set invalid data"); + + // ERR callback + ok(conf_io_set("include", NULL, NULL, "invalid") == + KNOT_EFILE, "set invalid callback value"); + + // Single group, no item, no value. + ok(conf_io_set("server", NULL, NULL, NULL) == + KNOT_ENOTSUP, "set group no value"); + // Single group, no item, value. + ok(conf_io_set("server", NULL, NULL, "text") == + KNOT_YP_ENOTSUP_DATA, "set group value"); + // Single group, item, no value. + ok(conf_io_set("server", "version", NULL, NULL) == + KNOT_YP_ENODATA, "set group item no value"); + + // Single group, single value. + ok(conf_io_set("server", "version", NULL, "text") == + KNOT_EOK, "set single value"); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "text") == 0, "check entry value"); + + // Single group, multi value. + ok(conf_io_set("server", "listen", NULL, "1.1.1.1") == + KNOT_EOK, "set multivalue 1"); + ok(conf_io_set("server", "listen", NULL, "1.1.1.2") == + KNOT_EOK, "set multivalue 2"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_EOK, "check entry"); + ok(conf_val_count(&val) == 2, "check entry value count"); + + // Prepare dnames. + knot_dname_t *zone1 = knot_dname_from_str_alloc(ZONE1); + ok(zone1 != NULL, "create dname "ZONE1); + knot_dname_t *zone2 = knot_dname_from_str_alloc(ZONE2); + ok(zone2 != NULL, "create dname "ZONE2); + knot_dname_t *zone3 = knot_dname_from_str_alloc(ZONE3); + ok(zone3 != NULL, "create dname "ZONE3); + + // Multi group no id. + ok(conf_io_set("zone", "domain", NULL, NULL) == + KNOT_YP_ENOID, "set zone empty domain"); + + // Multi group ids. + ok(conf_io_set("zone", "domain", NULL, ZONE1) == + KNOT_EOK, "set zone domain "ZONE1); + ok(conf_io_set("zone", NULL, ZONE2, NULL) == + KNOT_EOK, "set zone domain "ZONE2); + + // Multi group, single value. + ok(conf_io_set("zone", "file", ZONE1, "name") == + KNOT_EOK, "set zone file"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "name") == 0, "check entry value"); + + // Multi group, single value, bad id. + ok(conf_io_set("zone", "file", ZONE3, "name") == + KNOT_YP_EINVAL_ID, "set zone file"); + + // Multi group, single value, all ids. + ok(conf_io_set("zone", "comment", NULL, "abc") == + KNOT_EOK, "set zones comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "abc") == 0, "check entry value"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "abc") == 0, "check entry value"); + + // Prepare different comment. + ok(conf_io_set("zone", "domain", NULL, ZONE3) == + KNOT_EOK, "set zone domain "ZONE3); + ok(conf_io_set("zone", "comment", ZONE3, "xyz") == + KNOT_EOK, "set zone comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone3); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "xyz") == 0, "check entry value"); + + knot_dname_free(zone1, NULL); + knot_dname_free(zone2, NULL); + knot_dname_free(zone3, NULL); + + ok(conf_io_commit(false) == KNOT_EOK, "commit txn"); + + // Update read-only transaction. + ok(conf_refresh_txn(conf()) == KNOT_EOK, "update read-only txn"); +} + +static void test_conf_io_unset(void) +{ + // ERR no txn. + ok(conf_io_unset("server", "version", NULL, "text") == + KNOT_TXN_ENOTEXISTS, "unset without active txn"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // ERR. + ok(conf_io_unset("", NULL, NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "unset unknown key0"); + ok(conf_io_unset("uknown", NULL, NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "unset unknown key0"); + ok(conf_io_unset("server", "unknown", NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "unset unknown key1"); + ok(conf_io_unset("include", NULL, NULL, "file") == + KNOT_ENOTSUP, "unset non-group item"); + ok(conf_io_unset("server", "background-workers", NULL, "x") == + KNOT_EINVAL, "unset invalid data"); + + // Single group, single value. + ok(conf_io_unset("server", "version", NULL, "") == + KNOT_ENOENT, "unset zero length text value"); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + + ok(conf_io_unset("server", "version", NULL, "bad text") == + KNOT_ENOENT, "unset bad value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + + ok(conf_io_unset("server", "version", NULL, "text") == + KNOT_EOK, "unset explicit value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + ok(conf_io_unset("server", "version", NULL, NULL) == + KNOT_EOK, "unset value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + + // Single group, multi value. + ok(conf_io_unset("server", "listen", NULL, "9.9.9.9") == + KNOT_ENOENT, "unset bad value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_EOK, "check entry"); + + ok(conf_io_unset("server", "listen", NULL, "1.1.1.1") == + KNOT_EOK, "unset explicit value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_EOK, "check entry"); + ok(conf_val_count(&val) == 1, "check entry value count"); + + ok(conf_io_unset("server", "listen", NULL, NULL) == + KNOT_EOK, "unset value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_ENOENT, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Whole section items. + ok(conf_io_unset("server", NULL, NULL, NULL) == + KNOT_EOK, "unset section"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_ENOENT, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Prepare dnames. + knot_dname_t *zone1 = knot_dname_from_str_alloc(ZONE1); + ok(zone1 != NULL, "create dname "ZONE1); + knot_dname_t *zone2 = knot_dname_from_str_alloc(ZONE2); + ok(zone2 != NULL, "create dname "ZONE2); + knot_dname_t *zone3 = knot_dname_from_str_alloc(ZONE3); + ok(zone3 != NULL, "create dname "ZONE3); + + // Multi group, single value. + ok(conf_io_unset("zone", "file", ZONE1, "name") == + KNOT_EOK, "unset zone file"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + + // Multi group, single bad value, all ids. + ok(conf_io_unset("zone", "comment", NULL, "other") == + KNOT_EOK, "unset zones comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_EOK, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_EOK, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone3); + ok(val.code == KNOT_EOK, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Multi group, single value (not all match), all ids. + ok(conf_io_unset("zone", "comment", NULL, "abc") == + KNOT_EOK, "unset some zones comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone3); + ok(val.code == KNOT_EOK, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Multi group, single value (all match), all ids. + ok(conf_io_unset("zone", "comment", NULL, NULL) == + KNOT_EOK, "unset all zones comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone3); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Multi group, all items, specific id. + ok(conf_io_unset("zone", NULL, ZONE1, NULL) == + KNOT_EOK, "unset zone items"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_EOK, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Multi group, all items, all ids. + ok(conf_io_unset("zone", NULL, NULL, NULL) == + KNOT_EOK, "unset zone items"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // All groups. + ok(conf_io_unset(NULL, NULL, NULL, NULL) == + KNOT_EOK, "unset all"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_ENOENT, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + + knot_dname_free(zone1, NULL); + knot_dname_free(zone2, NULL); + knot_dname_free(zone3, NULL); + + conf_io_abort(false); +} + +static void test_conf_io_get(void) +{ + const char *ref; + char out[OUT_LEN]; + + conf_io_t io = { + .fcn = format_item, + .misc = out + }; + + // ERR no txn. + ok(conf_io_get("server", "version", NULL, false, &io) == + KNOT_TXN_ENOTEXISTS, "get without active txn"); + + // Get current, no active txn. + *out = '\0'; + ok(conf_io_get("server", "version", NULL, true, &io) == + KNOT_EOK, "get current without active txn"); + ref = "server.version = \"text\""; + ok(strcmp(ref, out) == 0, "compare result"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // ERR. + ok(conf_io_get("", NULL, NULL, true, &io) == + KNOT_YP_EINVAL_ITEM, "get empty key0"); + ok(conf_io_get("uknown", NULL, NULL, true, &io) == + KNOT_YP_EINVAL_ITEM, "get unknown key0"); + ok(conf_io_get("server", "unknown", NULL, true, &io) == + KNOT_YP_EINVAL_ITEM, "get unknown key1"); + ok(conf_io_get("include", NULL, NULL, true, &io) == + KNOT_ENOTSUP, "get non-group item"); + + // Update item in the active txn. + ok(conf_io_set("server", "version", NULL, "new text") == + KNOT_EOK, "set single value"); + + // Get new, active txn. + *out = '\0'; + ok(conf_io_get("server", "version", NULL, false, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.version = \"new text\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Get current, active txn. + *out = '\0'; + ok(conf_io_get("server", "version", NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.version = \"text\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Multi value. + *out = '\0'; + ok(conf_io_get("server", "listen", NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.listen = \"1.1.1.1\" \"1.1.1.2\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Single group. + *out = '\0'; + ok(conf_io_get("server", NULL, NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.version = \"text\"\n" + "server.listen = \"1.1.1.1\" \"1.1.1.2\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Prepare dnames. + knot_dname_t *zone1 = knot_dname_from_str_alloc(ZONE1); + ok(zone1 != NULL, "create dname "ZONE1); + + // Multi group, all values, all ids. + *out = '\0'; + ok(conf_io_get("zone", NULL, NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "zone.domain = \"zone1.\"\n" + "zone[zone1.].file = \"name\"\n" + "zone[zone1.].comment = \"abc\"\n" + "zone.domain = \"zone2.\"\n" + "zone[zone2.].comment = \"abc\"\n" + "zone.domain = \"zone3.\"\n" + "zone[zone3.].comment = \"xyz\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Multi group ids. + *out = '\0'; + ok(conf_io_get("zone", "domain", NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "zone.domain = \"zone1.\"\n" + "zone.domain = \"zone2.\"\n" + "zone.domain = \"zone3.\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Multi group, all values, single id. + *out = '\0'; + ok(conf_io_get("zone", NULL, ZONE1, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "zone.domain = \"zone1.\"\n" + "zone[zone1.].file = \"name\"\n" + "zone[zone1.].comment = \"abc\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Multi group, single value, single id. + *out = '\0'; + ok(conf_io_get("zone", "file", ZONE1, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "zone[zone1.].file = \"name\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // All groups. + *out = '\0'; + ok(conf_io_get(NULL, NULL, NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.version = \"text\"\n" + "server.listen = \"1.1.1.1\" \"1.1.1.2\"\n" + "zone.domain = \"zone1.\"\n" + "zone[zone1.].file = \"name\"\n" + "zone[zone1.].comment = \"abc\"\n" + "zone.domain = \"zone2.\"\n" + "zone[zone2.].comment = \"abc\"\n" + "zone.domain = \"zone3.\"\n" + "zone[zone3.].comment = \"xyz\""; + ok(strcmp(ref, out) == 0, "compare result"); + + knot_dname_free(zone1, NULL); + + conf_io_abort(false); +} + +static void test_conf_io_diff(void) +{ + const char *ref; + char out[OUT_LEN]; + + conf_io_t io = { + .fcn = format_item, + .misc = out + }; + + // ERR no txn. + ok(conf_io_diff("server", "version", NULL, &io) == + KNOT_TXN_ENOTEXISTS, "diff without active txn"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // ERR. + ok(conf_io_diff("", NULL, NULL, &io) == + KNOT_YP_EINVAL_ITEM, "diff empty key0"); + ok(conf_io_diff("uknown", NULL, NULL, &io) == + KNOT_YP_EINVAL_ITEM, "diff unknown key0"); + ok(conf_io_diff("server", "unknown", NULL, &io) == + KNOT_YP_EINVAL_ITEM, "diff unknown key1"); + ok(conf_io_diff("include", NULL, NULL, &io) == + KNOT_ENOTSUP, "diff non-group item"); + + *out = '\0'; + ok(conf_io_diff(NULL, NULL, NULL, &io) == KNOT_EOK, "diff no change"); + ref = ""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Update singlevalued item. + ok(conf_io_set("server", "version", NULL, "new text") == + KNOT_EOK, "set single value"); + + *out = '\0'; + ok(conf_io_diff("server", "version", NULL, &io) == KNOT_EOK, "diff single item"); + ref = "-server.version = \"text\"\n" + "+server.version = \"new text\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Update multivalued item. + ok(conf_io_unset("server", "listen", NULL, "1.1.1.1") == + KNOT_EOK, "unset multivalue"); + ok(conf_io_set("server", "listen", NULL, "1.1.1.3") == + KNOT_EOK, "set multivalue"); + + *out = '\0'; + ok(conf_io_diff("server", "listen", NULL, &io) == KNOT_EOK, "diff multi item"); + ref = "-server.listen = \"1.1.1.1\" \"1.1.1.2\"\n" + "+server.listen = \"1.1.1.2\" \"1.1.1.3\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Unset single item. + ok(conf_io_unset("zone", "comment", ZONE3, NULL) == + KNOT_EOK, "unset multivalue"); + + *out = '\0'; + ok(conf_io_diff("zone", NULL, ZONE3, &io) == KNOT_EOK, "diff section"); + ref = "-zone[zone3.].comment = \"xyz\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Unset id. + ok(conf_io_unset("zone", NULL, ZONE1, NULL) == + KNOT_EOK, "unset id"); + ok(conf_io_unset("zone", NULL, ZONE2, NULL) == + KNOT_EOK, "unset id"); + + *out = '\0'; + ok(conf_io_diff("zone", NULL, ZONE2, &io) == KNOT_EOK, "diff id section"); + ref = "-zone.domain = \"zone2.\"\n" + "-zone[zone2.].comment = \"abc\""; + ok(strcmp(ref, out) == 0, "compare result"); + + *out = '\0'; + ok(conf_io_diff("zone", "domain", NULL, &io) == KNOT_EOK, "diff id"); + ref = "-zone.domain = \"zone1.\"\n" + "-zone.domain = \"zone2.\""; + ok(strcmp(ref, out) == 0, "compare result"); + + *out = '\0'; + ok(conf_io_diff(NULL, NULL, NULL, &io) == KNOT_EOK, "diff whole change"); + ref = "-server.version = \"text\"\n" + "+server.version = \"new text\"\n" + "-server.listen = \"1.1.1.1\" \"1.1.1.2\"\n" + "+server.listen = \"1.1.1.2\" \"1.1.1.3\"\n" + "-zone.domain = \"zone1.\"\n" + "-zone[zone1.].file = \"name\"\n" + "-zone[zone1.].comment = \"abc\"\n" + "-zone.domain = \"zone2.\"\n" + "-zone[zone2.].comment = \"abc\"\n" + "-zone[zone3.].comment = \"xyz\""; + ok(strcmp(ref, out) == 0, "compare result"); + + conf_io_abort(false); +} + +static void test_conf_io_list(void) +{ + const char *ref; + char out[OUT_LEN]; + + conf_io_t io = { + .fcn = format_item, + .misc = out + }; + + // ERR. + ok(conf_io_list("", &io) == + KNOT_YP_EINVAL_ITEM, "list empty key0"); + ok(conf_io_list("uknown", &io) == + KNOT_YP_EINVAL_ITEM, "list unknown key0"); + ok(conf_io_list("include", &io) == + KNOT_ENOTSUP, "list non-group item"); + + // Desc schema. + *out = '\0'; + ok(conf_io_list(NULL, &io) == + KNOT_EOK, "list schema"); + ref = "server\n" + "control\n" + "remote\n" + "template\n" + "zone\n" + "include"; + ok(strcmp(ref, out) == 0, "compare result"); + + // Desc group. + *out = '\0'; + ok(conf_io_list("server", &io) == + KNOT_EOK, "list group"); + ref = "server.version\n" + "server.background-workers\n" + "server.listen\n" + "server.tcp-handshake-timeout\n" + "server.tcp-idle-timeout\n" + "server.tcp-reply-timeout\n" + "server.max-tcp-clients\n" + "server.max-udp-payload\n" + "server.max-ipv4-udp-payload\n" + "server.max-ipv6-udp-payload\n" + "server.edns-client-subnet\n" + "server.answer-rotation"; + ok(strcmp(ref, out) == 0, "compare result"); +} + +static const yp_item_t desc_server[] = { + { C_VERSION, YP_TSTR, YP_VNONE }, + { C_BG_WORKERS, YP_TINT, YP_VNONE }, + { C_LISTEN, YP_TADDR, YP_VNONE, YP_FMULTI }, + // Required config cache items - assert fix. + { C_TCP_HSHAKE_TIMEOUT, YP_TINT, YP_VNONE }, + { C_TCP_IDLE_TIMEOUT, YP_TINT, YP_VNONE }, + { C_TCP_REPLY_TIMEOUT, YP_TINT, YP_VNONE }, + { C_MAX_TCP_CLIENTS, YP_TINT, YP_VNONE }, + { C_MAX_UDP_PAYLOAD, YP_TINT, YP_VNONE }, + { C_MAX_IPV4_UDP_PAYLOAD, YP_TINT, YP_VNONE }, + { C_MAX_IPV6_UDP_PAYLOAD, YP_TINT, YP_VNONE }, + { C_ECS, YP_TBOOL, YP_VNONE }, + { C_ANS_ROTATION, YP_TBOOL, YP_VNONE }, + { NULL } +}; + +static const yp_item_t desc_control[] = { + { C_TIMEOUT, YP_TINT, YP_VNONE }, + { NULL } +}; + +static const yp_item_t desc_remote[] = { + { C_ID, YP_TSTR, YP_VNONE }, + { C_ADDR, YP_TADDR, YP_VNONE, YP_FMULTI }, + { NULL } +}; + +#define ZONE_ITEMS \ + { C_FILE, YP_TSTR, YP_VNONE }, \ + { C_MASTER, YP_TREF, YP_VREF = { C_RMT }, YP_FMULTI, { check_ref } }, \ + { C_DNSSEC_SIGNING, YP_TBOOL, YP_VNONE }, \ + { C_COMMENT, YP_TSTR, YP_VNONE }, + +static const yp_item_t desc_template[] = { + { C_ID, YP_TSTR, YP_VNONE }, + ZONE_ITEMS + { NULL } +}; + +static const yp_item_t desc_zone[] = { + { C_DOMAIN, YP_TDNAME, YP_VNONE }, + ZONE_ITEMS + { NULL } +}; + +const yp_item_t test_schema[] = { + { C_SRV, YP_TGRP, YP_VGRP = { desc_server } }, + { C_CTL, YP_TGRP, YP_VGRP = { desc_control } }, + { C_RMT, YP_TGRP, YP_VGRP = { desc_remote }, YP_FMULTI, { check_remote } }, + { C_TPL, YP_TGRP, YP_VGRP = { desc_template }, YP_FMULTI, { check_template } }, + { C_ZONE, YP_TGRP, YP_VGRP = { desc_zone }, YP_FMULTI, { check_zone } }, + { C_INCL, YP_TSTR, YP_VNONE, YP_FNONE, { include_file } }, + { NULL } +}; + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + ok(test_conf("", test_schema) == KNOT_EOK, "Prepare configuration"); + + diag("conf_io_begin"); + test_conf_io_begin(); + + diag("conf_io_abort"); + test_conf_io_abort(); + + diag("conf_io_commit"); + test_conf_io_commit(); + + diag("conf_io_check"); + test_conf_io_check(); + + diag("conf_io_set"); + test_conf_io_set(); + + diag("conf_io_unset"); + test_conf_io_unset(); + + diag("conf_io_get"); + test_conf_io_get(); + + diag("conf_io_diff"); + test_conf_io_diff(); + + diag("conf_io_list"); + test_conf_io_list(); + + conf_free(conf()); + + return 0; +} diff --git a/tests/knot/test_dthreads.c b/tests/knot/test_dthreads.c new file mode 100644 index 0000000..0637e7c --- /dev/null +++ b/tests/knot/test_dthreads.c @@ -0,0 +1,145 @@ +/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include <stdlib.h> +#include <tap/basic.h> + +#include "knot/server/dthreads.h" + +/* Unit runnable data. */ +static pthread_mutex_t _runnable_mx; +static volatile int _runnable_i = 0; +static const int _runnable_cycles = 10000; + +/*! \brief Unit runnable. */ +int runnable(struct dthread *thread) +{ + for (int i = 0; i < _runnable_cycles; ++i) { + + // Increase counter + pthread_mutex_lock(&_runnable_mx); + ++_runnable_i; + pthread_mutex_unlock(&_runnable_mx); + + // Cancellation point + if (dt_is_cancelled(thread)) { + break; + } + + // Yield + sched_yield(); + } + + return 0; +} + +/* Destructor data. */ +static volatile int _destructor_data = 0; +static pthread_mutex_t _destructor_mx; + +/*! \brief Thread destructor. */ +int destruct(struct dthread *thread) +{ + pthread_mutex_lock(&_destructor_mx); + _destructor_data += 1; + pthread_mutex_unlock(&_destructor_mx); + + return 0; +} + +// Signal handler +static void interrupt_handle(int s) +{ +} + +/*! API: run tests. */ +int main(int argc, char *argv[]) +{ + plan(8); + + // Register service and signal handler + struct sigaction sa; + sa.sa_handler = interrupt_handle; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, NULL); // Interrupt + + /* Initialize */ + srand(time(NULL)); + pthread_mutex_init(&_runnable_mx, NULL); + pthread_mutex_init(&_destructor_mx, NULL); + + /* Test 1: Create unit */ + int size = 2; + dt_unit_t *unit = dt_create(size, &runnable, NULL, NULL); + ok(unit != NULL, "dthreads: create unit (size %d)", size); + if (unit == NULL) { + skip_block(7, "No dthreads unit"); + goto skip_all; + } + + /* Test 2: Start tasks. */ + _runnable_i = 0; + ok(dt_start(unit) == 0, "dthreads: start single task"); + + /* Test 3: Wait for tasks. */ + ok(dt_join(unit) == 0, "dthreads: join threads"); + + /* Test 4: Compare counter. */ + int expected = _runnable_cycles * 2; + is_int(expected, _runnable_i, "dthreads: result ok"); + + /* Test 5: Deinitialize */ + dt_delete(&unit); + ok(unit == NULL, "dthreads: delete unit"); + + /* Test 6: Wrong values. */ + unit = dt_create(-1, NULL, NULL, NULL); + ok(unit == NULL, "dthreads: create with negative count"); + + /* Test 7: NULL operations crashing. */ + int ret = 0; + ret += dt_activate(0); + ret += dt_cancel(0); + ret += dt_compact(0); + dt_delete(0); + ret += dt_is_cancelled(0); + ret += dt_join(0); + ret += dt_signalize(0, SIGALRM); + ret += dt_start(0); + ret += dt_stop(0); + ret += dt_unit_lock(0); + ret += dt_unit_unlock(0); + is_int(-198, ret, "dthreads: correct values when passed NULL context"); + + /* Test 8: Thread destructor. */ + _destructor_data = 0; + unit = dt_create(2, 0, destruct, 0); + dt_start(unit); + dt_stop(unit); + dt_join(unit); + is_int(2, _destructor_data, "dthreads: destructor with dt_create_coherent()"); + dt_delete(&unit); + +skip_all: + + pthread_mutex_destroy(&_runnable_mx); + pthread_mutex_destroy(&_destructor_mx); + return 0; +} diff --git a/tests/knot/test_fdset.c b/tests/knot/test_fdset.c new file mode 100644 index 0000000..181838c --- /dev/null +++ b/tests/knot/test_fdset.c @@ -0,0 +1,152 @@ +/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <sys/time.h> +#include <pthread.h> +#include <fcntl.h> +#include <unistd.h> +#include <tap/basic.h> +#include <time.h> + +#include "knot/common/fdset.h" + +#define WRITE_PATTERN ((char) 0xde) +#define WRITE_PATTERN_LEN sizeof(char) + +/* Subtract the `struct timeval' values X and Y, + storing the result in RESULT. + Return 1 if the difference is negative, otherwise 0. + Copyright http://www.delorie.com/gnu/docs/glibc/libc_428.html +*/ +static int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval* y) +{ + /* Perform the carry for the later subtraction by updating y. */ + if (x->tv_usec < y->tv_usec) { + int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; + y->tv_usec -= 1000000 * nsec; + y->tv_sec += nsec; + } + if (x->tv_usec - y->tv_usec > 1000000) { + int nsec = (x->tv_usec - y->tv_usec) / 1000000; + y->tv_usec += 1000000 * nsec; + y->tv_sec -= nsec; + } + + /* Compute the time remaining to wait. + tv_usec is certainly positive. */ + result->tv_sec = x->tv_sec - y->tv_sec; + result->tv_usec = x->tv_usec - y->tv_usec; + + /* Return 1 if result is negative. */ + return x->tv_sec < y->tv_sec; +} + +static size_t timeval_diff(struct timeval *from, struct timeval *to) { + struct timeval res; + timeval_subtract(&res, to, from); + return res.tv_sec*1000 + res.tv_usec/1000; +} + +void* thr_action(void *arg) +{ + int *fd = (int *)arg; + + /* Sleep for 100ms. */ + struct timespec ts = { .tv_nsec = 1e8 }; + nanosleep(&ts, NULL); + + /* Write pattern. */ + char pattern = WRITE_PATTERN; + if (write(*fd, &pattern, WRITE_PATTERN_LEN) == -1) { + // Error. + } + + return NULL; +} + +int main(int argc, char *argv[]) +{ + plan(12); + + /* 1. Create fdset. */ + fdset_t set; + int ret = fdset_init(&set, 32); + is_int(0, ret, "fdset: init"); + + /* 2. Create pipe. */ + int fds[2], tmpfds[2]; + ret = pipe(fds); + ok(ret >= 0, "fdset: pipe() works"); + ret = pipe(tmpfds); + ok(ret >= 0, "fdset: 2nd pipe() works"); + + /* 3. Add fd to set. */ + ret = fdset_add(&set, fds[0], POLLIN, NULL); + is_int(0, ret, "fdset: add to set works"); + fdset_add(&set, tmpfds[0], POLLIN, NULL); + + /* Schedule write. */ + struct timeval ts, te; + gettimeofday(&ts, 0); + pthread_t t; + pthread_create(&t, 0, thr_action, &fds[1]); + + /* 4. Watch fdset. */ + int nfds = poll(set.pfd, set.n, 60 * 1000); + gettimeofday(&te, 0); + size_t diff = timeval_diff(&ts, &te); + + ok(nfds > 0, "fdset: poll returned %d events in %zu ms", nfds, diff); + + /* 5. Prepare event set. */ + ok(set.pfd[0].revents & POLLIN, "fdset: pipe is active"); + + /* 6. Receive data. */ + char buf = 0x00; + ret = read(set.pfd[0].fd, &buf, WRITE_PATTERN_LEN); + ok(ret >= 0 && buf == WRITE_PATTERN, "fdset: contains valid data"); + + /* 7-9. Remove from event set. */ + ret = fdset_remove(&set, 0); + is_int(0, ret, "fdset: remove from fdset works"); + close(fds[0]); + close(fds[1]); + ret = fdset_remove(&set, 0); + close(tmpfds[1]); + close(tmpfds[1]); + is_int(0, ret, "fdset: remove from fdset works (2)"); + ret = fdset_remove(&set, 0); + ok(ret != 0, "fdset: removing nonexistent item"); + + /* 10. Crash test. */ + fdset_init(0, 0); + fdset_add(0, 1, 1, 0); + fdset_add(0, 0, 1, 0); + fdset_remove(0, 1); + fdset_remove(0, 0); + ok(1, "fdset: crash test successful"); + + /* 11. Destroy fdset. */ + ret = fdset_clear(&set); + is_int(0, ret, "fdset: destroyed"); + + /* Cleanup. */ + pthread_join(t, 0); + + return 0; +} diff --git a/tests/knot/test_journal.c b/tests/knot/test_journal.c new file mode 100644 index 0000000..e12cc84 --- /dev/null +++ b/tests/knot/test_journal.c @@ -0,0 +1,746 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <unistd.h> +#include <sys/stat.h> +#include <tap/basic.h> +#include <tap/files.h> + +#include "libknot/libknot.h" +#include "knot/journal/journal.c" +#include "knot/zone/zone.h" +#include "knot/zone/zone-diff.h" +#include "libknot/rrtype/soa.h" +#include "test_conf.h" + +#define RAND_RR_LABEL 16 +#define RAND_RR_PAYLOAD 64 +#define MIN_SOA_SIZE 22 + +char *test_dir_name; +journal_db_t *db; +journal_t *j; +const knot_dname_t *apex = (const uint8_t *)"\4test"; + +static void set_conf(int zonefile_sync, size_t journal_usage) +{ + char conf_str[512]; + snprintf(conf_str, sizeof(conf_str), + "zone:\n" + " - domain: %s\n" + " zonefile-sync: %d\n" + " max-journal-usage: %zu\n" + " max-journal-depth: 1000\n", + (const char *)(apex + 1), zonefile_sync, journal_usage); + int ret = test_conf(conf_str, NULL); + (void)ret; + assert(ret == KNOT_EOK); +} + +static void unset_conf(void) +{ + conf_update(NULL, CONF_UPD_FNONE); +} + +/*! \brief Generate random string with given length. */ +static int randstr(char* dst, size_t len) +{ + for (int i = 0; i < len - 1; ++i) { + dst[i] = '0' + (int) (('Z'-'0') * (rand() / (RAND_MAX + 1.0))); + } + dst[len - 1] = '\0'; + + return 0; +} + +/*! \brief Init RRSet with type SOA and given serial. */ +static void init_soa(knot_rrset_t *rr, const uint32_t serial, const knot_dname_t *apex) +{ + knot_rrset_init(rr, knot_dname_copy(apex, NULL), KNOT_RRTYPE_SOA, KNOT_CLASS_IN, 3600); + + uint8_t soa_data[MIN_SOA_SIZE] = { 0 }; + int ret = knot_rrset_add_rdata(rr, soa_data, sizeof(soa_data), NULL); + knot_soa_serial_set(rr->rrs.rdata, serial); + (void)ret; + assert(ret == KNOT_EOK); +} + +/*! \brief Init RRSet with type TXT, random owner and random payload. */ +static void init_random_rr(knot_rrset_t *rr , const knot_dname_t *apex) +{ + /* Create random label. */ + char owner[RAND_RR_LABEL + knot_dname_size(apex)]; + owner[0] = RAND_RR_LABEL - 1; + randstr(owner + 1, RAND_RR_LABEL); + + /* Append zone apex. */ + memcpy(owner + RAND_RR_LABEL, apex, knot_dname_size(apex)); + knot_rrset_init(rr, knot_dname_copy((knot_dname_t *)owner, NULL), + KNOT_RRTYPE_TXT, KNOT_CLASS_IN, 3600); + + /* Create random RDATA. */ + uint8_t txt[RAND_RR_PAYLOAD + 1]; + txt[0] = RAND_RR_PAYLOAD - 1; + randstr((char *)(txt + 1), RAND_RR_PAYLOAD); + + int ret = knot_rrset_add_rdata(rr, txt, RAND_RR_PAYLOAD, NULL); + (void)ret; + assert(ret == KNOT_EOK); +} + +/*! \brief Init changeset with random changes. */ +static void init_random_changeset(changeset_t *ch, const uint32_t from, const uint32_t to, + const size_t size, const knot_dname_t *apex, bool is_bootstrap) +{ + // Add SOAs + knot_rrset_t soa; + + if (is_bootstrap) { + ch->soa_from = NULL; + } else { + init_soa(&soa, from, apex); + ch->soa_from = knot_rrset_copy(&soa, NULL); + assert(ch->soa_from); + knot_rrset_clear(&soa, NULL); + } + + init_soa(&soa, to, apex); + ch->soa_to = knot_rrset_copy(&soa, NULL); + assert(ch->soa_to); + knot_rrset_clear(&soa, NULL); + + // Add RRs to add section + for (size_t i = 0; i < size / 2; ++i) { + knot_rrset_t rr; + init_random_rr(&rr, apex); + int ret = changeset_add_addition(ch, &rr, 0); + (void)ret; + assert(ret == KNOT_EOK); + knot_rrset_clear(&rr, NULL); + } + + // Add RRs to remove section + for (size_t i = 0; i < size / 2 && !is_bootstrap; ++i) { + knot_rrset_t rr; + init_random_rr(&rr, apex); + int ret = changeset_add_removal(ch, &rr, 0); + (void)ret; + assert(ret == KNOT_EOK); + knot_rrset_clear(&rr, NULL); + } +} + +static void changeset_set_soa_serials(changeset_t *ch, uint32_t from, uint32_t to, + const knot_dname_t *apex) +{ + knot_rrset_t soa; + + init_soa(&soa, from, apex); + knot_rrset_free(ch->soa_from, NULL); + ch->soa_from = knot_rrset_copy(&soa, NULL); + assert(ch->soa_from); + knot_rrset_clear(&soa, NULL); + + init_soa(&soa, to, apex); + knot_rrset_free(ch->soa_to, NULL); + ch->soa_to = knot_rrset_copy(&soa, NULL); + assert(ch->soa_to); + knot_rrset_clear(&soa, NULL); +} + +/*! \brief Compare two changesets for equality. */ +static bool changesets_eq(const changeset_t *ch1, changeset_t *ch2) +{ + if (changeset_size(ch1) != changeset_size(ch2)) { + return false; + } + + changeset_iter_t it1; + changeset_iter_all(&it1, ch1); + changeset_iter_t it2; + changeset_iter_all(&it2, ch2); + + knot_rrset_t rr1 = changeset_iter_next(&it1); + knot_rrset_t rr2 = changeset_iter_next(&it2); + bool ret = true; + while (!knot_rrset_empty(&rr1)) { + if (!knot_rrset_equal(&rr1, &rr2, KNOT_RRSET_COMPARE_WHOLE)) { + ret = false; + break; + } + rr1 = changeset_iter_next(&it1); + rr2 = changeset_iter_next(&it2); + } + + changeset_iter_clear(&it1); + changeset_iter_clear(&it2); + + return ret; +} + +static bool changesets_list_eq(list_t *l1, list_t *l2) +{ + node_t *n = NULL; + node_t *k = HEAD(*l2); + WALK_LIST(n, *l1) { + if (k == NULL) { + return false; + } + + changeset_t *ch1 = (changeset_t *) n; + changeset_t *ch2 = (changeset_t *) k; + if (!changesets_eq(ch1, ch2)) { + return false; + } + + k = k->next; + } + + if (k->next != NULL) { + return false; + } + + return true; +} + +/*! \brief Test a list of changesets for continuity. */ +static bool test_continuity(list_t *l) +{ + node_t *n = NULL; + uint32_t key1, key2; + WALK_LIST(n, *l) { + if (n == TAIL(*l)) { + break; + } + changeset_t *ch1 = (changeset_t *) n; + changeset_t *ch2 = (changeset_t *) n->next; + key1 = knot_soa_serial(ch1->soa_to->rrs.rdata); + key2 = knot_soa_serial(ch2->soa_from->rrs.rdata); + if (key1 != key2) { + return KNOT_EINVAL; + } + } + + return KNOT_EOK; +} + +static void test_journal_db(void) +{ + int ret, ret2 = KNOT_EOK; + + ret = journal_db_init(&db, test_dir_name, 2 * 1024 * 1024, JOURNAL_MODE_ASYNC); + is_int(KNOT_EOK, ret, "journal: init db (%d)", ret); + + ret = journal_open_db(&db); + is_int(KNOT_EOK, ret, "journal: open db (%d)", ret); + + journal_db_close(&db); + ok(db == NULL, "journal: close and destroy db"); + + ret = journal_db_init(&db, test_dir_name, 4 * 1024 * 1024, JOURNAL_MODE_ASYNC); + if (ret == KNOT_EOK) ret2 = journal_open_db(&db); + ok(ret == KNOT_EOK && ret2 == KNOT_EOK, "journal: open with bigger mapsize (%d, %d)", ret, ret2); + journal_db_close(&db); + + ret = journal_db_init(&db, test_dir_name, 1024 * 1024, JOURNAL_MODE_ASYNC); + if (ret == KNOT_EOK) ret2 = journal_open_db(&db); + ok(ret == KNOT_EOK && ret2 == KNOT_EOK, "journal: open with smaller mapsize (%d, %d)", ret, ret2); + journal_db_close(&db); +} + +/*! \brief Test behavior with real changesets. */ +static void test_store_load(void) +{ + int ret, ret2 = KNOT_EOK; + + set_conf(1000, 512 * 1024); + + j = journal_new(); + ok(j != NULL, "journal: new"); + + ret = journal_db_init(&db, test_dir_name, (512 + 1024) * 1024, JOURNAL_MODE_ASYNC); + if (ret == KNOT_EOK) ret2 = journal_open(j, &db, apex); + is_int(KNOT_EOK, ret, "journal: open (%d, %d)", ret, ret2); + + /* Save and load changeset. */ + changeset_t *m_ch = changeset_new(apex); + init_random_changeset(m_ch, 0, 1, 128, apex, false); + ret = journal_store_changeset(j, m_ch); + is_int(KNOT_EOK, ret, "journal: store changeset (%d)", ret); + ret = journal_check(j, JOURNAL_CHECK_INFO); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + list_t l, k; + init_list(&l); + init_list(&k); + ret = journal_load_changesets(j, &l, 0); + add_tail(&k, &m_ch->n); + ok(ret == KNOT_EOK && changesets_list_eq(&l, &k), "journal: load changeset (%d)", ret); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + + /* Load ctx's. */ + chgset_ctx_list_t cl = { { 0 }, 0 }; + ret = journal_load_chgset_ctx(j, &cl, 0); + ok(ret == KNOT_EOK, "journal: chgset_ctx: load (%s)", knot_strerror(ret)); + chgset_ctx_list_close(&cl); + + changesets_free(&l); + changesets_free(&k); + + /* Flush the journal. */ + ret = journal_flush(j); + is_int(KNOT_EOK, ret, "journal: first and simple flush (%d)", ret); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + init_list(&l); + init_list(&k); + + /* Fill the journal. */ + ret = KNOT_EOK; + uint32_t serial = 1; + for (; ret == KNOT_EOK && serial < 40000; ++serial) { + changeset_t *m_ch2 = changeset_new(apex); + init_random_changeset(m_ch2, serial, serial + 1, 128, apex, false); + ret = journal_store_changeset(j, m_ch2); + if (ret != KNOT_EOK) { + changeset_free(m_ch2); + break; + } + add_tail(&k, &m_ch2->n); + } + is_int(KNOT_EBUSY, ret, "journal: overfill with changesets (%d inserted) (%d should= %d)", + serial, ret, KNOT_EBUSY); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + + /* Load all changesets stored until now. */ + ret = journal_load_changesets(j, &l, 1); + ok(ret == KNOT_EOK && changesets_list_eq(&l, &k), "journal: load changesets (%d)", ret); + + changesets_free(&l); + init_list(&l); + ret = journal_load_changesets(j, &l, 1); + ok(ret == KNOT_EOK && changesets_list_eq(&l, &k), "journal: re-load changesets (%d)", ret); + + ret = journal_load_chgset_ctx(j, &cl, 1); + ok(ret == KNOT_EOK, "journal: chgset_ctx: load 2 (%s)", knot_strerror(ret)); + ok(list_size(&cl.l) == list_size(&l), "journal: chgset_ctx: load size %zu ?== %zu", list_size(&cl.l), list_size(&l)); + chgset_ctx_list_close(&cl); + + changesets_free(&l); + init_list(&l); + + /* Flush the journal. */ + ret = journal_flush(j); + is_int(KNOT_EOK, ret, "journal: second flush (%d)", ret); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + + /* Test whether the journal kept changesets after flush. */ + ret = journal_load_changesets(j, &l, 1); + ok(ret == KNOT_EOK && changesets_list_eq(&l, &k), "journal: load right after flush (%d)", ret); + + changesets_free(&k); + changesets_free(&l); + init_list(&k); + init_list(&l); + + /* Store next changeset. */ + changeset_t ch; + ret = changeset_init(&ch, apex); + ok(ret == KNOT_EOK, "journal: changeset init (%d)", ret); + init_random_changeset(&ch, serial, serial + 1, 128, apex, false); + ret = journal_store_changeset(j, &ch); + changeset_clear(&ch); + is_int(KNOT_EOK, ret, "journal: store after flush (%d)", ret); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + + /* Load last changesets. */ + init_list(&l); + ret = journal_load_changesets(j, &l, serial); + changesets_free(&l); + is_int(KNOT_EOK, ret, "journal: load changesets after flush (%d)", ret); + + /* Flush the journal again. */ + ret = journal_flush(j); + is_int(KNOT_EOK, ret, "journal: flush again (%d)", ret); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + + /* Fill the journal using a list. */ + uint32_t m_serial = 1; + for (; m_serial < serial / 2; ++m_serial) { + changeset_t *m_ch7 = changeset_new(apex); + init_random_changeset(m_ch7, m_serial, m_serial + 1, 128, apex, false); + add_tail(&l, &m_ch7->n); + } + ret = journal_store_changesets(j, &l); + is_int(KNOT_EOK, ret, "journal: fill with changesets using a list (%d inserted)", m_serial); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + + /* Cleanup. */ + changesets_free(&l); + init_list(&l); + + /* Load all previous changesets. */ + ret = journal_load_changesets(j, &l, 1); + ok(ret == KNOT_EOK && knot_soa_serial(((changeset_t *)TAIL(l))->soa_to->rrs.rdata) == m_serial, + "journal: load all changesets"); + + /* Check for changeset ordering. */ + ok(test_continuity(&l) == KNOT_EOK, "journal: changesets are in order"); + + /* Cleanup. */ + changesets_free(&l); + init_list(&l); + ret = journal_flush(j); + is_int(KNOT_EOK, ret, "journal: allways ok journal_flush 0"); + ret = journal_drop_changesets(j); /* Clear the journal for the collision test */ + is_int(KNOT_EOK, ret, "journal: allways ok journal_drop_changesets"); + + /* Test for serial number collision handling. We insert changesets + * with valid serial sequence that overflows and then collides with itself. + * The sequence is 0 -> 1 -> 2 -> 2147483647 -> 4294967294 -> 1 which should + * remove changesets 0->1 and 1->2. */ + ok(EMPTY_LIST(k), "journal: empty list k"); + ok(EMPTY_LIST(l), "journal: empty list l"); + changeset_t *m_ch3 = changeset_new(apex); + init_random_changeset(m_ch3, 0, 1, 128, apex, false); + ret = journal_store_changeset(j, m_ch3); + is_int(KNOT_EOK, ret, "journal: allways ok journal_store_changeset 1"); + changeset_set_soa_serials(m_ch3, 1, 2, apex); + ret = journal_store_changeset(j, m_ch3); + is_int(KNOT_EOK, ret, "journal: allways ok journal_store_changeset 2"); + changeset_set_soa_serials(m_ch3, 2, 2147483647, apex); + add_tail(&k, &m_ch3->n); + ret = journal_store_changeset(j, m_ch3); + is_int(KNOT_EOK, ret, "journal: allways ok journal_store_changeset 3"); + changeset_t *m_ch4 = changeset_new(apex); + init_random_changeset(m_ch4, 2147483647, 4294967294, 128, apex, false); + add_tail(&k, &m_ch4->n); + ret = journal_store_changeset(j, m_ch4); + is_int(KNOT_EOK, ret, "journal: allways ok journal_store_changeset 4"); + changeset_t *m_ch5 = changeset_new(apex); + init_random_changeset(m_ch5, 4294967294, 1, 128, apex, false); + add_tail(&k, &m_ch5->n); + ret = journal_store_changeset(j, m_ch5); + is_int(KNOT_EBUSY, ret, "journal: allways ok journal_store_changeset 5"); + ret = journal_flush(j); + is_int(KNOT_EOK, ret, "journal: allways ok journal_flush 1"); + ret = journal_store_changeset(j, m_ch5); + is_int(KNOT_EOK, ret, "journal: allways ok journal_store_changeset 6"); + ret = journal_flush(j); + is_int(KNOT_EOK, ret, "journal: allways ok journal_flush 2"); + ret = journal_load_changesets(j, &l, 0); + ret2 = journal_load_changesets(j, &l, 1); + int ret3 = journal_load_changesets(j, &l, 2); + fprintf(stderr, "ret=%d ret2=%d ret3=%d\n", ret, ret2, ret3); + ok(ret == KNOT_ENOENT && ret2 == KNOT_ENOENT && ret3 == KNOT_EOK && + changesets_list_eq(&l, &k), "journal: serial collision"); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + is_int(KNOT_EOK, ret, "journal check (%d)", ret); + + /* Cleanup. */ + changesets_free(&l); + changesets_free(&k); + + init_list(&l); + init_list(&k); + + /* Check bootstrap changeset */ + ret = journal_drop_changesets(j); + ok(ret == KNOT_EOK, "journal: journal_drop_changesets must be ok"); + + changeset_t *m_ch6 = changeset_new(apex); + init_random_changeset(m_ch6, 0, 1, 128, apex, true); + ret = journal_store_changeset(j, m_ch6); + ok(ret == KNOT_EOK, "journal: store bootstrap (%d)", ret); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + ok(ret == KNOT_EOK, "journal check (%d)", ret); + changeset_t *m_ch7 = changeset_new(apex); + init_random_changeset(m_ch7, 1, 2, 128, apex, false); + ret = journal_store_changeset(j, m_ch7); + ok(ret == KNOT_EOK, "journal: store after bootstrap (%d)", ret); + add_tail(&k, &m_ch6->n); + add_tail(&k, &m_ch7->n); + ret = journal_load_bootstrap(j, &l); + ok(ret == KNOT_EOK && changesets_list_eq(&l, &k), "journal: load boostrap (%d)", ret); + ret = journal_check(j, JOURNAL_CHECK_STDERR); + ok(ret == KNOT_EOK, "journal check (%d)", ret); + + changesets_free(&l); + changesets_free(&k); + + init_list(&l); + init_list(&k); + + ret = journal_scrape(j); + ok(ret == KNOT_EOK, "journal: scrape must be ok"); + + unset_conf(); +} + +const uint8_t *rdA = (const uint8_t *) "\x01\x02\x03\x04"; +const uint8_t *rdB = (const uint8_t *) "\x01\x02\x03\x05"; +const uint8_t *rdC = (const uint8_t *) "\x01\x02\x03\x06"; + +// frees owner +static knot_rrset_t * tm_rrset(knot_dname_t * owner, const uint8_t * rdata) +{ + knot_rrset_t * rrs = knot_rrset_new(owner, KNOT_RRTYPE_A, KNOT_CLASS_IN, 3600, NULL); + knot_rrset_add_rdata(rrs, rdata, 4, NULL); + free(owner); + return rrs; +} + +static knot_dname_t * tm_owner(const char * prefix, const knot_dname_t *apex) +{ + knot_dname_t * ret = malloc(strlen(prefix) + knot_dname_size(apex) + 2); + ret[0] = strlen(prefix); + strcpy((char *) (ret + 1), prefix); + memcpy(ret + ret[0] + 1, apex, knot_dname_size(apex)); + return ret; +} + +static knot_rrset_t * tm_rrs(const knot_dname_t * apex, int x) +{ + static knot_rrset_t * rrsA = NULL; + static knot_rrset_t * rrsB = NULL; + static knot_rrset_t * rrsC = NULL; + + if (apex == NULL) { + knot_rrset_free(rrsA, NULL); + knot_rrset_free(rrsB, NULL); + knot_rrset_free(rrsC, NULL); + rrsA = rrsB = rrsC = NULL; + return NULL; + } + + if (rrsA == NULL) rrsA = tm_rrset(tm_owner("aaaaaaaaaaaaaaaaa", apex), rdA); + if (rrsB == NULL) rrsB = tm_rrset(tm_owner("bbbbbbbbbbbbbbbbb", apex), rdB); + if (rrsC == NULL) rrsC = tm_rrset(tm_owner("ccccccccccccccccc", apex), rdC); + switch ((x % 3 + 3) % 3) { + case 0: return rrsA; + case 1: return rrsB; + case 2: return rrsC; + } + assert(0); return NULL; +} + +int tm_rrcnt(const changeset_t * ch, int flg) +{ + changeset_iter_t it; + int i = 0; + if (flg >= 0) changeset_iter_add(&it, ch); + else changeset_iter_rem(&it, ch); + + knot_rrset_t rri; + while (rri = changeset_iter_next(&it), !knot_rrset_empty(&rri)) i++; + + changeset_iter_clear(&it); + return i; +} + +static changeset_t * tm_chs(const knot_dname_t * apex, int x) +{ + static changeset_t * chsI = NULL, * chsX = NULL, * chsY = NULL; + static uint32_t serial = 0; + + if (apex == NULL) { + changeset_free(chsI); + changeset_free(chsX); + changeset_free(chsY); + chsI = chsX = chsY = NULL; + return NULL; + } + + if (chsI == NULL) { + chsI = changeset_new(apex); + assert(chsI != NULL); + changeset_add_addition(chsI, tm_rrs(apex, 0), 0); + changeset_add_addition(chsI, tm_rrs(apex, 1), 0); + } + if (chsX == NULL) { + chsX = changeset_new(apex); + assert(chsX != NULL); + changeset_add_removal(chsX, tm_rrs(apex, 1), 0); + changeset_add_addition(chsX, tm_rrs(apex, 2), 0); + } + if (chsY == NULL) { + chsY = changeset_new(apex); + assert(chsY != NULL); + changeset_add_removal(chsY, tm_rrs(apex, 2), 0); + changeset_add_addition(chsY, tm_rrs(apex, 1), 0); + } + assert(x >= 0); + changeset_t * ret; + if (x == 0) ret = chsI; + else if (x % 2 == 1) ret = chsX; + else ret = chsY; + + changeset_set_soa_serials(ret, serial, serial + 1, apex); + serial++; + + return ret; +} + +static int merged_present(void) +{ + local_txn_t(txn, j); + txn_begin(txn, 0); + int res = md_flag(txn, MERGED_SERIAL_VALID); + txn_abort(txn); + return res; +} + +static void test_merge(void) +{ + int i, ret; + list_t l; + + // allow merge + set_conf(-1, 512 * 1024); + ok(journal_merge_allowed(j), "journal: merge allowed"); + + ret = journal_drop_changesets(j); + is_int(KNOT_EOK, ret, "journal: journal_drop_changesets must be ok"); + + // insert stuff and check the merge + for (i = 0; !merged_present() && i < 40000; i++) { + ret = journal_store_changeset(j, tm_chs(apex, i)); + is_int(KNOT_EOK, ret, "journal: journal_store_changeset must be ok"); + } + init_list(&l); + ret = journal_load_changesets(j, &l, 0); + is_int(KNOT_EOK, ret, "journal: journal_load_changesets must be ok"); + ok(list_size(&l) == 2, "journal: read the merged and one following"); + changeset_t * mch = (changeset_t *)HEAD(l); + ok(list_size(&l) >= 1 && tm_rrcnt(mch, 1) == 2, "journal: merged additions # = 2"); + ok(list_size(&l) >= 1 && tm_rrcnt(mch, -1) == 1, "journal: merged removals # = 1"); + changesets_free(&l); + + // insert one more and check the #s of results + journal_store_changeset(j, tm_chs(apex, i)); + init_list(&l); + ret = journal_load_changesets(j, &l, 0); + is_int(KNOT_EOK, ret, "journal: journal_load_changesets2 must be ok"); + ok(list_size(&l) == 3, "journal: read merged together with new changeset"); + changesets_free(&l); + init_list(&l); + ret = journal_load_changesets(j, &l, (uint32_t) (i - 3)); + is_int(KNOT_EOK, ret, "journal: journal_load_changesets3 must be ok"); + ok(list_size(&l) == 4, "journal: read short history of merged/unmerged changesets"); + changesets_free(&l); + + ret = journal_drop_changesets(j); + assert(ret == KNOT_EOK); + + // disallow merge + unset_conf(); + set_conf(1000, 512 * 1024); + ok(!journal_merge_allowed(j), "journal: merge disallowed"); + + tm_rrs(NULL, 0); + tm_chs(NULL, 0); + unset_conf(); +} + +static void test_stress_base(journal_t *j, size_t update_size, size_t file_size) +{ + int ret; + uint32_t serial = 0; + + journal_close(j); + journal_db_close(&db); + db = NULL; + ret = journal_db_init(&db, test_dir_name, file_size, JOURNAL_MODE_ASYNC); + assert(ret == KNOT_EOK); + ret = journal_open_db(&db); + assert(ret == KNOT_EOK); + ret = journal_open(j, &db, apex); + assert(ret == KNOT_EOK); + + set_conf(1000, file_size / 2); + + changeset_t ch; + ret = changeset_init(&ch, apex); + ok(ret == KNOT_EOK, "journal: changeset init (%d)", ret); + init_random_changeset(&ch, serial, serial + 1, update_size, apex, false); + + for (int i = 1; i <= 6; ++i) { + serial = 0; + while (true) { + changeset_set_soa_serials(&ch, serial, serial + 1, apex); + ret = journal_store_changeset(j, &ch); + if (ret == KNOT_EOK) { + serial++; + } else { + break; + } + } + + int ret = journal_flush(j); + ok(serial > 0 && ret == KNOT_EOK, "journal: pass #%d fillup run (%d inserts)", i, serial); + } + + changeset_clear(&ch); + + unset_conf(); +} + +/*! \brief Test behavior when writing to jurnal and flushing it. */ +static void test_stress(journal_t *j) +{ + diag("stress test: small data"); + test_stress_base(j, 40, (1024 + 512) * 1024); + + diag("stress test: medium data"); + test_stress_base(j, 400, 3 * 1024 * 1024); + + diag("stress test: large data"); + test_stress_base(j, 4000, 10 * 1024 * 1024); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_dir_name = test_mkdtemp(); + + test_journal_db(); + + test_store_load(); + + test_merge(); + + test_stress(j); + + journal_close(j); + journal_free(&j); + journal_db_close(&db); + + test_rm_rf(test_dir_name); + free(test_dir_name); + + return 0; +} diff --git a/tests/knot/test_kasp_db.c b/tests/knot/test_kasp_db.c new file mode 100644 index 0000000..d775d0a --- /dev/null +++ b/tests/knot/test_kasp_db.c @@ -0,0 +1,137 @@ +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> + +#include <tap/basic.h> +#include <tap/files.h> + +#include "libknot/libknot.h" +#include "test_conf.h" +#include "knot/dnssec/kasp/kasp_db.c" + +#define CHARS500_1 "kTZgFfrHPP2EOSK24zRjY9GlgCUEkZNBF5UwqsTWisCxGQT4ieinitjXWT1c" \ + "pj+OR8UX/httSugee+MFsm5yOU/4/211BpLKwwOIAt4Yf8K7Bc+oXTdk15cH" \ + "TRZtshM1AtfjRsX9rsLDsnaFCyMXzty9AQoRxSphjxnUUC6fszfrSsRx7htl" \ + "/Xn1PAuwp9Bfn+FxAws98LYVuwiDqUgn4BR5lELdGd16zNOZnN7v023pmPDM" \ + "nGyvIATuqTCPbFeXTfw7aIDyx2DF+y95/kSnPtY3c1b0Yf+oCv4t3Hx2jjWT" \ + "9zuC6H+d+PL6HWqilJBs7ysn2FVpnE/Yo44VrQ8orw8QFZr1kR6z7AOVAcMk" \ + "ac+44swsc8orGCyJx6OlUfN5oU3YahUfLqg9ewl13+P2chmeI6wUyttKsq/4" \ + "Ud0YQAozBabiAKr1O/Eg7sZR6bV1YkCydQyYgmR/+VOu9D8Ld6uO4DcvhiE/" \ + "2AmTkLsKLxtpMnQqsTnx" +#define CHARS500_2 "pzqkMLvpxUYYg0KuMCcBsk9aMm4b5Ny+vJ5UnTq8DVC0jHJJyyGcljKqfpi3" \ + "MkjfrWY0rbzXFZbZZ6i8bmhhRBcSxE+tK/3AU1LR7ZJsTuITuoJo5LKRH7Uu" \ + "MU7RBAzFuk3o+Pcyk+9UdbiRn9p4QqPTvb+2xfYn1pJvGHofJcQsSsPEe9Hw" \ + "ycVW+kdImvWiidn0/e1G6B2xibovnPKDUBFmTbdZIBKHb/eUUoUCNA9CWt5N" \ + "g8MutK2ixlBJlOvA6CA1V/VW56EJpLqvMxLaoRks5VY5Ls7zWAy97GEFH0Pl" \ + "uO/Rba1du5tsC0MAC08hljlmu9uoPhsvHdBYHUnQ7jDuYnu9GN3DN0Z6oVbV" \ + "N01JQZYhKQK/Bl61oM5JubLydtAypryDoG3IH75LhoVC8iGxDoDkxt3zoi/Q" \ + "PVfPZZsm5j5UOs3wrQL0KWylm2IDK42mrHK8F/XebnOYLNLQaan2a90C+fhH" \ + "a6hvu0RorkZzGNAZkq/D" + +const knot_dname_t *zone1 = (const knot_dname_t *)"\x05""zonea"; +const knot_dname_t *zone2 = (const knot_dname_t *)"\x05""zoneb"; + +kasp_db_t *db; + +const key_params_t params1 = { .id = "key id 1", .keytag = 1, .timing = { 1, 11, 111, 1111, 11111 }, + .public_key = { 520, (uint8_t *)"pk1 plus 500 chars: " CHARS500_1 } }; +const key_params_t params2 = { .id = "key id 2", .keytag = 2, .timing = { 2, 22, 222, 2222, 22222 }, + .public_key = { 520, (uint8_t *)"pk2 plus 500 chars: " CHARS500_2 } }; + +bool params_eq(const key_params_t *a, const key_params_t *b) +{ + return ((a->keytag == b->keytag) && (a->public_key.size == b->public_key.size) && + (a->timing.retire == b->timing.retire) && (strcmp(a->id, b->id) == 0) && + (memcmp(a->public_key.data, b->public_key.data, b->public_key.size) == 0)); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + char *test_dir_name = test_mkdtemp(); + bool ignore = false; + + list_t l; + key_params_t *params; +#define free_params free(params->id); free(params->public_key.data); params->id = NULL; params->public_key.data = NULL; + + int ret = kasp_db_init(&db, test_dir_name, 500*1024*1024); + is_int(KNOT_EOK, ret, "kasp_db: init eok"); + ret = kasp_db_open(db); + is_int(KNOT_EOK, ret, "kasp_db: open eok"); + ok(db->keys_db != NULL, "kasp_db: keys db notnull"); + + ret = kasp_db_add_key(db, zone1, ¶ms1); + is_int(KNOT_EOK, ret, "kasp_db: add key 1 eok"); + + ret = kasp_db_list_keys(db, zone1, &l); + is_int(KNOT_EOK, ret, "kasp_db: list keys 1 eok"); + is_int(1, list_size(&l), "kasp_db: list keys reports one key 1"); + params = ((ptrnode_t *)HEAD(l))->d; + ok(params_eq(params, ¶ms1), "kasp_db: key params equal 1"); + free_params + ptrlist_deep_free(&l, NULL); + + ret = kasp_db_list_keys(db, zone2, &l); + is_int(KNOT_ENOENT, ret, "kasp_db: list keys 1 enoent"); + is_int(0, list_size(&l), "kasp_db: list keys reports no keys 1"); + ptrlist_deep_free(&l, NULL); + + ret = kasp_db_share_key(db, zone1, zone2, params1.id); + is_int(KNOT_EOK, ret, "kasp_db: share key eok"); + + ret = kasp_db_list_keys(db, zone2, &l); + is_int(KNOT_EOK, ret, "kasp_db: list keys 3 eok"); + is_int(1, list_size(&l), "kasp_db: list keys reports one key 2"); + params = ((ptrnode_t *)HEAD(l))->d; + free_params + ptrlist_deep_free(&l, NULL); + + ret = kasp_db_add_key(db, zone2, ¶ms2); + is_int(KNOT_EOK, ret, "kasp_db: add key 2 eok"); + + ret = kasp_db_list_keys(db, zone2, &l); + is_int(KNOT_EOK, ret, "kasp_db: list keys 4 eok"); + is_int(2, list_size(&l), "kasp_db: list keys reports two keys 1"); + params = ((ptrnode_t *)TAIL(l))->d; + ok(params_eq(params, ¶ms2), "kasp_db: key params equal 2"); + free_params + params = ((ptrnode_t *)HEAD(l))->d; + free_params + ptrlist_deep_free(&l, NULL); + + ret = kasp_db_delete_key(db, zone1, params1.id, &ignore); + is_int(KNOT_EOK, ret, "kasp_db: delete key 1 eok"); + + ret = kasp_db_list_keys(db, zone1, &l); + is_int(KNOT_ENOENT, ret, "kasp_db: list keys 2 enoent"); + is_int(list_size(&l), 0, "kasp_db: list keys reports no keys 2"); + ptrlist_deep_free(&l, NULL); + + kasp_db_close(&db); + + test_rm_rf(test_dir_name); + free(test_dir_name); + + return 0; +} + diff --git a/tests/knot/test_node.c b/tests/knot/test_node.c new file mode 100644 index 0000000..ef2a01d --- /dev/null +++ b/tests/knot/test_node.c @@ -0,0 +1,154 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> + +#include "knot/zone/node.h" +#include "libknot/libknot.h" + +static knot_rrset_t *create_dummy_rrset(const knot_dname_t *owner, uint16_t type) +{ + knot_rrset_t *r = knot_rrset_new(owner, type, KNOT_CLASS_IN, 3600, NULL); + assert(r); + uint8_t wire[16] = { 0 }; + memcpy(wire, "testtest", strlen("testtest")); + int ret = knot_rrset_add_rdata(r, wire, strlen("testtest"), NULL); + assert(ret == KNOT_EOK); + (void)ret; + return r; +} + +static knot_rrset_t *create_dummy_rrsig(const knot_dname_t *owner, uint16_t type) +{ + knot_rrset_t *r = knot_rrset_new(owner, KNOT_RRTYPE_RRSIG, KNOT_CLASS_IN, + 3600, NULL); + assert(r); + uint8_t wire[sizeof(uint16_t)]; + knot_wire_write_u16(wire, type); + int ret = knot_rrset_add_rdata(r, wire, sizeof(uint16_t), NULL); + assert(ret == KNOT_EOK); + (void)ret; + return r; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_dname_t *dummy_owner = knot_dname_from_str_alloc("test."); + // Test new + zone_node_t *node = node_new(dummy_owner, NULL); + ok(node != NULL, "Node: new"); + assert(node); + ok(knot_dname_is_equal(node->owner, dummy_owner), "Node: new - set fields"); + + // Test parent setting + zone_node_t *parent = node_new(dummy_owner, NULL); + assert(parent); + node_set_parent(node, parent); + ok(node->parent == parent && parent->children == 1, "Node: set parent."); + + node_free(parent, NULL); + + // Test RRSet addition + knot_rrset_t *dummy_rrset = create_dummy_rrset(dummy_owner, KNOT_RRTYPE_TXT); + int ret = node_add_rrset(node, dummy_rrset, NULL); + ok(ret == KNOT_EOK && node->rrset_count == 1 && + knot_rdataset_eq(&dummy_rrset->rrs, &node->rrs[0].rrs), "Node: add RRSet."); + + // Test shallow copy + node->flags |= NODE_FLAGS_DELEG; + zone_node_t *copy = node_shallow_copy(node, NULL); + ok(copy != NULL, "Node: shallow copy."); + assert(copy); + const bool copy_ok = knot_dname_is_equal(copy->owner, node->owner) && + copy->rrset_count == node->rrset_count && + memcmp(copy->rrs, node->rrs, + copy->rrset_count * sizeof(struct rr_data)) == 0 && + copy->flags == node->flags; + ok(copy_ok, "Node: shallow copy - set fields."); + + node_free(copy, NULL); + + // Test RRSet getters + knot_rrset_t *n_rrset = node_create_rrset(node, KNOT_RRTYPE_TXT); + ok(n_rrset && knot_rrset_equal(n_rrset, dummy_rrset, KNOT_RRSET_COMPARE_WHOLE), + "Node: create existing RRSet."); + + knot_rrset_free(n_rrset, NULL); + + n_rrset = node_create_rrset(node, KNOT_RRTYPE_SOA); + ok(n_rrset == NULL, "Node: create non-existing RRSet."); + + knot_rrset_t stack_rrset = node_rrset(node, KNOT_RRTYPE_TXT); + ok(knot_rrset_equal(&stack_rrset, dummy_rrset, + KNOT_RRSET_COMPARE_WHOLE), "Node: get existing RRSet."); + stack_rrset = node_rrset(node, KNOT_RRTYPE_SOA); + ok(knot_rrset_empty(&stack_rrset), "Node: get non-existent RRSet."); + + knot_rdataset_t *n_rdataset = node_rdataset(node, KNOT_RRTYPE_TXT); + ok(n_rdataset && knot_rdataset_eq(n_rdataset, &dummy_rrset->rrs), + "Node: get existing rdataset."); + n_rdataset = node_rdataset(node, KNOT_RRTYPE_SOA); + ok(n_rdataset == NULL, "Node: get non-existing rdataset."); + + stack_rrset = node_rrset_at(node, 0); + ok(knot_rrset_equal(&stack_rrset, dummy_rrset, KNOT_RRSET_COMPARE_WHOLE), + "Node: get existing position."); + stack_rrset = node_rrset_at(node, 1); + ok(knot_rrset_empty(&stack_rrset), "Node: get non-existent position."); + + // Test TTL mismatch + dummy_rrset->ttl = 1800; + ret = node_add_rrset(node, dummy_rrset, NULL); + ok(ret == KNOT_ETTL && node->rrset_count == 1, + "Node: add RRSet, TTL mismatch."); + + knot_rrset_free(dummy_rrset, NULL); + + // Test bool functions + ok(node_rrtype_exists(node, KNOT_RRTYPE_TXT), "Node: type exists."); + ok(!node_rrtype_exists(node, KNOT_RRTYPE_AAAA), "Node: type does not exist."); + ok(!node_rrtype_is_signed(node, KNOT_RRTYPE_TXT), "Node: type is not signed."); + + dummy_rrset = create_dummy_rrsig(dummy_owner, KNOT_RRTYPE_TXT); + ret = node_add_rrset(node, dummy_rrset, NULL); + assert(ret == KNOT_EOK); + + ok(node_rrtype_is_signed(node, KNOT_RRTYPE_TXT), "Node: type is signed."); + + knot_rrset_free(dummy_rrset, NULL); + + // Test remove RRset + node_remove_rdataset(node, KNOT_RRTYPE_AAAA); + ok(node->rrset_count == 2, "Node: remove non-existent rdataset."); + void *to_free = node_rdataset(node, KNOT_RRTYPE_TXT)->rdata; + node_remove_rdataset(node, KNOT_RRTYPE_TXT); + ok(node->rrset_count == 1, "Node: remove existing rdataset."); + + free(to_free); + + // "Test" freeing + node_free_rrsets(node, NULL); + ok(node->rrset_count == 0, "Node: free RRSets."); + + node_free(node, NULL); + + knot_dname_free(dummy_owner, NULL); + + return 0; +} diff --git a/tests/knot/test_process_query.c b/tests/knot/test_process_query.c new file mode 100644 index 0000000..aa67877 --- /dev/null +++ b/tests/knot/test_process_query.c @@ -0,0 +1,189 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> +#include <string.h> +#include <stdlib.h> + +#include "libknot/descriptor.h" +#include "libknot/packet/wire.h" +#include "knot/nameserver/process_query.h" +#include "test_server.h" +#include "contrib/sockaddr.h" +#include "contrib/ucw/mempool.h" + +/* Basic response check (4 TAP tests). */ +static void answer_sanity_check(const uint8_t *query, + const uint8_t *answer, uint16_t answer_len, + uint8_t expected_rcode, const char *name) +{ + ok(answer_len >= KNOT_WIRE_HEADER_SIZE, "ns: len(%s answer) >= DNS header", name); + if (answer_len >= KNOT_WIRE_HEADER_SIZE) { + ok(knot_wire_get_qr(answer), "ns: %s answer has QR=1", name); + is_int(expected_rcode, knot_wire_get_rcode(answer), "ns: %s answer RCODE=%d", name, expected_rcode); + is_int(knot_wire_get_id(query), knot_wire_get_id(answer), "ns: %s MSGID match", name); + } else { + skip_block(3, "ns: can't check DNS header"); + } +} + +/* Resolve query and check answer for sanity (2 TAP tests). */ +static void exec_query(knot_layer_t *layer, const char *name, + knot_pkt_t *query, + uint8_t expected_rcode) +{ + knot_pkt_t *answer = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL); + assert(answer); + + /* Input packet. */ + knot_pkt_parse(query, 0); + knot_layer_consume(layer, query); + + ok(layer->state == KNOT_STATE_PRODUCE || + layer->state == KNOT_STATE_FAIL, "ns: process %s query", name); + + /* Create answer. */ + knot_layer_produce(layer, answer); + if (layer->state == KNOT_STATE_FAIL) { + /* Allow 1 generic error response. */ + knot_layer_produce(layer, answer); + } + + ok(layer->state == KNOT_STATE_DONE, "ns: answer %s query", name); + + /* Check answer. */ + answer_sanity_check(query->wire, answer->wire, answer->size, expected_rcode, name); + + knot_pkt_free(answer); +} + +/* \internal Helpers */ +#define WIRE_COPY(dst, dst_len, src, src_len) \ + memcpy(dst, src, src_len); \ + dst_len = src_len; + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_mm_t mm; + mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); + + /* Create processing context. */ + knot_layer_t proc; + memset(&proc, 0, sizeof(knot_layer_t)); + knot_layer_init(&proc, &mm, process_query_layer()); + + /* Create fake server environment. */ + server_t server; + int ret = create_fake_server(&server, proc.mm); + is_int(KNOT_EOK, ret, "ns: fake server initialization"); + + zone_t *zone = knot_zonedb_find(server.zone_db, ROOT_DNAME); + + /* Prepare. */ + knot_pkt_t *query = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, proc.mm); + + /* Create query processing parameter. */ + struct sockaddr_storage ss; + memset(&ss, 0, sizeof(struct sockaddr_storage)); + sockaddr_set(&ss, AF_INET, "127.0.0.1", 53); + knotd_qdata_params_t params = { + .remote = &ss, + .server = &server + }; + + /* Query processor (CH zone) */ + knot_layer_begin(&proc, ¶ms); + knot_pkt_clear(query); + knot_pkt_put_question(query, IDSERVER_DNAME, KNOT_CLASS_CH, KNOT_RRTYPE_TXT); + exec_query(&proc, "CH TXT", query, KNOT_RCODE_NOERROR); + + /* Query processor (valid input). */ + knot_layer_reset(&proc); + knot_pkt_clear(query); + knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); + exec_query(&proc, "IN/root", query, KNOT_RCODE_NOERROR); + + /* Query processor (-1 bytes, not enough data). */ + knot_layer_reset(&proc); + query->size -= 1; + exec_query(&proc, "IN/few-data", query, KNOT_RCODE_FORMERR); + query->size += 1; + + /* Query processor (+1 bytes trailing). */ + knot_layer_reset(&proc); + query->wire[query->size] = '\1'; /* Initialize the "garbage" value. */ + query->size += 1; + exec_query(&proc, "IN/trail-garbage", query, KNOT_RCODE_FORMERR); + query->size -= 1; + + /* Forge NOTIFY query from SOA query. */ + knot_layer_reset(&proc); + knot_wire_set_opcode(query->wire, KNOT_OPCODE_NOTIFY); + exec_query(&proc, "IN/notify", query, KNOT_RCODE_NOTAUTH); + + /* Forge AXFR query. */ + knot_layer_reset(&proc); + knot_pkt_clear(query); + knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_AXFR); + exec_query(&proc, "IN/axfr", query, KNOT_RCODE_NOTAUTH); + + /* Forge IXFR query (well formed). */ + knot_layer_reset(&proc); + knot_pkt_clear(query); + knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR); + /* Append SOA RR. */ + knot_rrset_t soa_rr = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA); + knot_pkt_begin(query, KNOT_AUTHORITY); + knot_pkt_put(query, KNOT_COMPR_HINT_NONE, &soa_rr, 0); + exec_query(&proc, "IN/ixfr", query, KNOT_RCODE_NOTAUTH); + + /* \note Tests below are not possible without proper zone and zone data. */ + /* #189 Process UPDATE query. */ + /* #189 Process AXFR client. */ + /* #189 Process IXFR client. */ + + /* Query processor (smaller than DNS header, ignore). */ + knot_layer_reset(&proc); + knot_pkt_clear(query); + knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); + size_t orig_query_size = query->size; + query->size = KNOT_WIRE_HEADER_SIZE - 1; + knot_layer_consume(&proc, query); + ok(proc.state == KNOT_STATE_NOOP, "ns: IN/less-than-header query ignored"); + query->size = orig_query_size; + + /* Query processor (response, ignore). */ + knot_layer_reset(&proc); + knot_wire_set_qr(query->wire); + knot_layer_consume(&proc, query); + ok(proc.state == KNOT_STATE_NOOP, "ns: IN/less-than-header query ignored"); + + /* Finish. */ + knot_layer_finish(&proc); + ok(proc.state == KNOT_STATE_NOOP, "ns: processing end" ); + + /* Cleanup. */ + mp_delete((struct mempool *)mm.ctx); + server_deinit(&server); + conf_free(conf()); + + return 0; +} + +#undef WIRE_COPY diff --git a/tests/knot/test_query_module.c b/tests/knot/test_query_module.c new file mode 100644 index 0000000..cb4a606 --- /dev/null +++ b/tests/knot/test_query_module.c @@ -0,0 +1,83 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <string.h> +#include <stdlib.h> + +#include "libknot/libknot.h" +#include "knot/nameserver/query_module.h" +#include "libknot/packet/pkt.h" + +/* Universal processing stage. */ +unsigned state_visit(unsigned state, knot_pkt_t *pkt, knotd_qdata_t *qdata, + knotd_mod_t *mod) +{ + /* Visit current state */ + bool *state_map = (bool *)mod; + state_map[state] = true; + + return state + 1; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Create a map of expected steps. */ + bool state_map[KNOTD_STAGES] = { false }; + + /* Prepare query plan. */ + struct query_plan *plan = query_plan_create(); + ok(plan != NULL, "query_plan: create"); + + /* Register all stage visits. */ + int ret = KNOT_EOK; + for (unsigned stage = KNOTD_STAGE_BEGIN; stage < KNOTD_STAGES; ++stage) { + ret = query_plan_step(plan, stage, state_visit, state_map); + if (ret != KNOT_EOK) { + break; + } + } + is_int(KNOT_EOK, ret, "query_plan: planned all steps"); + + /* Execute the plan. */ + int state = 0, next_state = 0; + for (unsigned stage = KNOTD_STAGE_BEGIN; stage < KNOTD_STAGES; ++stage) { + struct query_step *step = NULL; + WALK_LIST(step, plan->stage[stage]) { + next_state = step->process(state, NULL, NULL, step->ctx); + if (next_state != state + 1) { + break; + } + state = next_state; + } + } + ok(state == KNOTD_STAGES, "query_plan: executed all steps"); + + /* Verify if all steps executed their callback. */ + for (state = 0; state < KNOTD_STAGES; ++state) { + if (state_map[state] == false) { + break; + } + } + ok(state == KNOTD_STAGES, "query_plan: executed all callbacks"); + + /* Free the query plan. */ + query_plan_free(plan); + + return 0; +} diff --git a/tests/knot/test_requestor.c b/tests/knot/test_requestor.c new file mode 100644 index 0000000..ea87fb7 --- /dev/null +++ b/tests/knot/test_requestor.c @@ -0,0 +1,164 @@ +/* Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> +#include <pthread.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> + +#include "libknot/descriptor.h" +#include "libknot/errcode.h" +#include "knot/query/layer.h" +#include "knot/query/requestor.h" +#include "contrib/mempattern.h" +#include "contrib/net.h" +#include "contrib/sockaddr.h" +#include "contrib/ucw/mempool.h" + +/* @note Purpose of this test is not to verify process_answer functionality, + * but simply if the requesting/receiving works, so mirror is okay. */ +static int reset(knot_layer_t *ctx) { return KNOT_STATE_PRODUCE; } +static int begin(knot_layer_t *ctx, void *module_param) { return reset(ctx); } +static int finish(knot_layer_t *ctx) { return reset(ctx); } +static int in(knot_layer_t *ctx, knot_pkt_t *pkt) { return KNOT_STATE_DONE; } +static int out(knot_layer_t *ctx, knot_pkt_t *pkt) { return KNOT_STATE_CONSUME; } + +static const int TIMEOUT = 2000; + +/*! \brief Dummy answer processing module. */ +const knot_layer_api_t dummy_module = { + &begin, &reset, &finish, &in, &out +}; + +static void set_blocking_mode(int sock) +{ + int flags = fcntl(sock, F_GETFL); + flags &= ~O_NONBLOCK; + fcntl(sock, F_SETFL, flags); +} + +static void *responder_thread(void *arg) +{ + int fd = *(int *)arg; + + set_blocking_mode(fd); + uint8_t buf[KNOT_WIRE_MAX_PKTSIZE] = { 0 }; + while (true) { + int client = accept(fd, NULL, NULL); + if (client < 0) { + break; + } + int len = net_dns_tcp_recv(client, buf, sizeof(buf), -1); + if (len < KNOT_WIRE_HEADER_SIZE) { + close(client); + break; + } + knot_wire_set_qr(buf); + net_dns_tcp_send(client, buf, len, -1); + close(client); + } + + return NULL; +} + +/* Test implementations. */ + +static struct knot_request *make_query(struct knot_requestor *requestor, + const struct sockaddr_storage *dst, + const struct sockaddr_storage *src) +{ + knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, requestor->mm); + assert(pkt); + static const knot_dname_t *root = (uint8_t *)""; + knot_pkt_put_question(pkt, root, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); + + return knot_request_make(requestor->mm, (struct sockaddr *)dst, + (struct sockaddr *)src, pkt, NULL, 0); +} + +static void test_disconnected(struct knot_requestor *requestor, + const struct sockaddr_storage *dst, + const struct sockaddr_storage *src) +{ + struct knot_request *req = make_query(requestor, dst, src); + int ret = knot_requestor_exec(requestor, req, TIMEOUT); + is_int(KNOT_ECONN, ret, "requestor: disconnected/exec"); + knot_request_free(req, requestor->mm); + +} + +static void test_connected(struct knot_requestor *requestor, + const struct sockaddr_storage *dst, + const struct sockaddr_storage *src) +{ + /* Enqueue packet. */ + struct knot_request *req = make_query(requestor, dst, src); + int ret = knot_requestor_exec(requestor, req, TIMEOUT); + is_int(KNOT_EOK, ret, "requestor: connected/exec"); + knot_request_free(req, requestor->mm); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_mm_t mm; + mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); + + /* Initialize requestor. */ + struct knot_requestor requestor; + knot_requestor_init(&requestor, &dummy_module, NULL, &mm); + + /* Define endpoints. */ + struct sockaddr_storage client = { 0 }; + sockaddr_set(&client, AF_INET, "127.0.0.1", 0); + struct sockaddr_storage server = { 0 }; + sockaddr_set(&server, AF_INET, "127.0.0.1", 0); + + /* Bind to random port. */ + int responder_fd = net_bound_socket(SOCK_STREAM, (struct sockaddr *)&server, 0); + assert(responder_fd >= 0); + socklen_t addr_len = sockaddr_len((struct sockaddr *)&server); + getsockname(responder_fd, (struct sockaddr *)&server, &addr_len); + + /* Test requestor in disconnected environment. */ + test_disconnected(&requestor, &server, &client); + + /* Start responder. */ + int ret = listen(responder_fd, 10); + (void)ret; + assert(ret == 0); + pthread_t thread; + pthread_create(&thread, 0, responder_thread, &responder_fd); + + /* Test requestor in connected environment. */ + test_connected(&requestor, &server, &client); + + /* Terminate responder. */ + int conn = net_connected_socket(SOCK_STREAM, (struct sockaddr *)&server, NULL); + assert(conn > 0); + conn = net_dns_tcp_send(conn, (uint8_t *)"", 1, TIMEOUT); + assert(conn > 0); + pthread_join(thread, NULL); + close(responder_fd); + + /* Cleanup. */ + mp_delete((struct mempool *)mm.ctx); + + return 0; +} diff --git a/tests/knot/test_semantic_check.in b/tests/knot/test_semantic_check.in new file mode 100644 index 0000000..ad65f78 --- /dev/null +++ b/tests/knot/test_semantic_check.in @@ -0,0 +1,129 @@ +#!/bin/sh + +KZONECHECK="@top_builddir@/src/kzonecheck" +DATA="@top_srcdir@/tests/knot/semantic_check_data" + +. "@top_srcdir@/tests/tap/libtap.sh" + +TMPDIR=$(test_tmpdir) +LOG="$TMPDIR/log" + +# Params: zonefile fatal_error expected_erros_count semcheck_err_msg +expect_error() +{ + if [ ! -r "$DATA/$1" ]; then + skip_block 4 "missing zone file for test" + return + fi + + "$KZONECHECK" -o example.com "$DATA/$1" > "$LOG" + ok "$1 - check program return" test $? -eq 1 + + fatal=$(grep -E "^Serious semantic error detected" $LOG | wc -l) + ok "$1 - check fatal" test $fatal -eq $2 + + errors=$(grep -E "^\[.+\] $4" $LOG | wc -l) + ok "$1 - check errors" test $errors -eq $3 + if [ $errors != $3 ]; then + diag "expected errors $3 but found $errors" + fi +} + +#param zonefile +test_correct() +{ + $KZONECHECK -o example.com "$DATA/$1" > /dev/null + ok "$1 - correct zone, without error" test $? -eq 0 +} + +if [ ! -x $KZONECHECK ]; then + skip_all "kzonecheck is missing or is not executable" +fi + +# error messages exported from knot/src/zone/semantic-check.c +CDNSKEY_MULTIPLE="multiple CDNSKEY records" +CDNSKEY_NONE="missing CDNSKEY" +CDS_MULTIPLE="multiple CDS records" +CDS_NONE="missing CDS" +CDS_NOT_MATCH="CDS not match CDNSKEY" +CNAME_EXTRA_RECORDS="more records exist at CNAME" +CNAME_MULTIPLE="multiple CNAME records" +DNAME_CHILDREN="child record exists under DNAME" +DNSKEY_PROTO="invalid protocol in DNSKEY" +DS_ALG="invalid algorithm in DS" +NSEC3PARAM_FLAGS="invalid flags in NSEC3PARAM" +NSEC3_ALG="incorrect algorithm in NSEC3" +NSEC3_INSECURE_DELEGATION_OPT="insecure delegation outside NSEC3 opt-out" +NSEC3_ITERS="incorrect number of iterations in NSEC3" +NSEC3_NONE="missing NSEC3" +NSEC3_RDATA_BITMAP="incorrect type bitmap in NSEC3" +NSEC3_RDATA_CHAIN="incoherent NSEC3 chain" +NSEC_NONE="missing NSEC" +NSEC_RDATA_BITMAP="incorrect type bitmap in NSEC" +NSEC_RDATA_CHAIN="incoherent NSEC chain" +NSEC_RDATA_MULTIPLE="multiple NSEC records" +NS_APEX="missing NS at the zone apex" +NS_GLUE="missing glue record" +RRSIG_EXPIRED="expired RRSIG" +RRSIG_NO_RRSIG="missing RRSIG" +RRSIG_RDATA_DNSKEY_OWNER="wrong signer's name in RRSIG" +RRSIG_RDATA_TTL="wrong original TTL in RRSIG" +RRSIG_SIGNED="signed RRSIG" +RRSIG_UNVERIFIABLE="unverifiable signature" + +plan_lazy + +expect_error "cname_extra_01.zone" 1 1 "$CNAME_EXTRA_RECORDS" +expect_error "cname_extra_02.signed" 1 1 "$CNAME_EXTRA_RECORDS" +expect_error "cname_multiple.zone" 1 1 "$CNAME_MULTIPLE" +expect_error "dname_children.zone" 1 1 "$DNAME_CHILDREN" + +expect_error "missing_ns.zone" 0 1 "$NS_APEX" +expect_error "missing_glue_01.zone" 0 2 "$NS_GLUE" +expect_error "missing_glue_02.zone" 0 1 "$NS_GLUE" +expect_error "missing_glue_03.zone" 0 1 "$NS_GLUE" +expect_error "different_signer_name.signed" 0 1 "$RRSIG_RDATA_DNSKEY_OWNER \(record type NSEC\)" +expect_error "different_signer_name.signed" 0 1 "$RRSIG_UNVERIFIABLE \(record type NSEC\)" +expect_error "no_rrsig.signed" 0 1 "$RRSIG_NO_RRSIG \(record type A\)" +expect_error "no_rrsig.signed" 0 1 "$RRSIG_NO_RRSIG \(record type NSEC\)" +expect_error "no_rrsig_with_delegation.signed" 0 1 "$RRSIG_NO_RRSIG \(record type NSEC\)" +expect_error "nsec_broken_chain_01.signed" 0 1 "$NSEC_RDATA_CHAIN" +expect_error "nsec_broken_chain_02.signed" 0 1 "$NSEC_RDATA_CHAIN" +expect_error "nsec_missing.signed" 0 1 "$NSEC_NONE" +expect_error "nsec_multiple.signed" 0 1 "$NSEC_RDATA_MULTIPLE" +expect_error "nsec_wrong_bitmap_01.signed" 0 1 "$NSEC_RDATA_BITMAP" +expect_error "nsec_wrong_bitmap_02.signed" 0 1 "$NSEC_RDATA_BITMAP" +expect_error "nsec3_missing.signed" 0 1 "$NSEC3_NONE" +expect_error "nsec3_wrong_bitmap_01.signed" 0 1 "$NSEC3_RDATA_BITMAP" +expect_error "nsec3_wrong_bitmap_02.signed" 0 1 "$NSEC3_RDATA_BITMAP" +expect_error "nsec3_ds.signed" 0 1 "$NSEC3_NONE" +expect_error "nsec3_optout.signed" 0 1 "$NSEC3_INSECURE_DELEGATION_OPT" +expect_error "nsec3_chain_01.signed" 0 1 "$NSEC3_RDATA_CHAIN" +expect_error "nsec3_chain_02.signed" 0 2 "$NSEC3_RDATA_CHAIN" +expect_error "nsec3_chain_03.signed" 0 2 "$NSEC3_RDATA_CHAIN" +expect_error "nsec3_param_invalid.signed" 0 1 "$NSEC3_ALG" +expect_error "nsec3_param_invalid.signed" 0 1 "$NSEC3_ITERS" +expect_error "nsec3_param_invalid.signed" 0 1 "$NSEC3PARAM_FLAGS" +expect_error "rrsig_signed.signed" 0 1 "$RRSIG_SIGNED" +expect_error "rrsig_rdata_ttl.signed" 0 1 "$RRSIG_RDATA_TTL \(record type A\)" +expect_error "duplicate.signature" 0 7 "$RRSIG_EXPIRED" +expect_error "missing.signed" 0 1 "$NSEC_NONE" +expect_error "dnskey_param_error.signed" 0 1 "$DNSKEY_PROTO" +expect_error "invalid_ds.signed" 0 2 "$DS_ALG \(keytag 60485\)" +expect_error "cdnskey.invalid" 0 1 "$CDS_NOT_MATCH" +expect_error "cdnskey.invalid.param" 0 1 "$CDS_NOT_MATCH" +expect_error "cdnskey.nocds" 0 1 "$CDS_NONE" +expect_error "cdnskey.nocdnskey" 0 1 "$CDNSKEY_NONE" +expect_error "cdnskey.nodnskey" 0 1 "$CDNSKEY_NOT_MATCH" +expect_error "cdnskey.two" 0 1 "$CDS_MULTIPLE" +expect_error "cdnskey.two" 0 1 "$CDNSKEY_MULTIPLE" + +test_correct "rrsig_ttl.signed" +test_correct "no_error_delegaton_bitmap.signed" +test_correct "no_error_nsec3_delegation.signed" +test_correct "no_error_nsec3_optout.signed" +test_correct "no_error_wildcard_glue.zone" +test_correct "cdnskey.cds" +test_correct "dname_apex_nsec3.signed" + +rm $LOG diff --git a/tests/knot/test_server.c b/tests/knot/test_server.c new file mode 100644 index 0000000..c1cc2ad --- /dev/null +++ b/tests/knot/test_server.c @@ -0,0 +1,68 @@ +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include "knot/server/server.h" +#include "test_conf.h" + +// Signal handler +static void interrupt_handle(int s) +{ +} + +/*! API: run tests. */ +int main(int argc, char *argv[]) +{ + plan(2); + + server_t server; + int ret = 0; + + /* Some random configuration just to apply the default conf schema */ + ret = test_conf("", NULL); + assert(ret == KNOT_EOK); + + /* Register service and signal handler */ + struct sigaction sa; + sa.sa_handler = interrupt_handle; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, NULL); // Interrupt + + /* Test server for correct initialization */ + ret = server_init(&server, 1); + is_int(KNOT_EOK, ret, "server: initialized"); + if (ret != KNOT_EOK) { + return 1; + } + + /* Test server startup */ + ret = server_start(&server, false); + is_int(KNOT_EOK, ret, "server: started ok"); + if (ret != KNOT_EOK) { + return 1; + } + + server_stop(&server); + + /* Wait for server to finish. */ + server_wait(&server); + + /* Wait for server to finish. */ + server_deinit(&server); + + return 0; +} diff --git a/tests/knot/test_server.h b/tests/knot/test_server.h new file mode 100644 index 0000000..4a6e427 --- /dev/null +++ b/tests/knot/test_server.h @@ -0,0 +1,86 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "test_conf.h" +#include "knot/server/server.h" +#include "contrib/mempattern.h" + +/* Some domain names. */ +#define ROOT_DNAME ((const uint8_t *)"") +#define EXAMPLE_DNAME ((const uint8_t *)"\x7""example") +#define IDSERVER_DNAME ((const uint8_t *)"\2""id""\6""server") + +/* Create fake root zone. */ +static inline void create_root_zone(server_t *server, knot_mm_t *mm) +{ + /* SOA RDATA. */ + #define SOA_RDLEN 30 + static const uint8_t SOA_RDATA[SOA_RDLEN] = { + 0x02, 'n', 's', 0x00, /* ns. */ + 0x04, 'm', 'a', 'i', 'l', 0x00,/* mail. */ + 0x77, 0xdf, 0x1e, 0x63, /* serial */ + 0x00, 0x01, 0x51, 0x80, /* refresh */ + 0x00, 0x00, 0x1c, 0x20, /* retry */ + 0x00, 0x0a, 0x8c, 0x00, /* expire */ + 0x00, 0x00, 0x0e, 0x10 /* min ttl */ + }; + + /* Insert root zone. */ + zone_t *root = zone_new(ROOT_DNAME); + root->journal_db = &server->journal_db; + root->contents = zone_contents_new(root->name); + + knot_rrset_t *soa = knot_rrset_new(root->name, KNOT_RRTYPE_SOA, KNOT_CLASS_IN, + 7200, mm); + knot_rrset_add_rdata(soa, SOA_RDATA, SOA_RDLEN, mm); + node_add_rrset(root->contents->apex, soa, NULL); + knot_rrset_free(soa, mm); + + /* Bake the zone. */ + zone_contents_adjust_full(root->contents); + + /* Switch zone db. */ + knot_zonedb_free(&server->zone_db); + server->zone_db = knot_zonedb_new(); + knot_zonedb_insert(server->zone_db, root); +} + +/* Create fake server. */ +static inline int create_fake_server(server_t *server, knot_mm_t *mm) +{ + int ret; + + /* Load test configuration. */ + const char *conf_str = "server:\n identity: bogus.ns\n version: 0.11\n nsid: ""\n" + "zone:\n - domain: .\n zonefile-sync: -1\n"; + ret = test_conf(conf_str, NULL); + if (ret != KNOT_EOK) { + return ret; + } + + /* Create name server. */ + ret = server_init(server, 1); + if (ret != KNOT_EOK) { + return ret; + } + + /* Insert root zone. */ + create_root_zone(server, mm); + + return KNOT_EOK; +} diff --git a/tests/knot/test_worker_pool.c b/tests/knot/test_worker_pool.c new file mode 100644 index 0000000..e644aa6 --- /dev/null +++ b/tests/knot/test_worker_pool.c @@ -0,0 +1,152 @@ +/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include <errno.h> +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include <time.h> + +#include "knot/worker/pool.h" +#include "knot/worker/queue.h" + +#define THREADS 4 +#define TASKS_BATCH 40 + +/*! + * Task execution log. + */ +typedef struct task_log { + pthread_mutex_t mx; + unsigned executed; +} task_log_t; + +/*! + * Get number of executed tasks and clear. + */ +static unsigned executed_reset(task_log_t *log) +{ + pthread_mutex_lock(&log->mx); + unsigned result = log->executed; + log->executed = 0; + pthread_mutex_unlock(&log->mx); + + return result; +} + +/*! + * Simple task, just increases the counter in the log. + */ +static void task_counting(task_t *task) +{ + task_log_t *log = task->ctx; + + pthread_mutex_lock(&log->mx); + log->executed += 1; + pthread_mutex_unlock(&log->mx); +} + +static void interrupt_handle(int s) +{ +} + +int main(void) +{ + plan_lazy(); + + struct sigaction sa; + sa.sa_handler = interrupt_handle; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, NULL); // Interrupt + + // create pool + + worker_pool_t *pool = worker_pool_create(THREADS); + ok(pool != NULL, "create worker pool"); + if (!pool) { + return 1; + } + + task_log_t log = { + .mx = PTHREAD_MUTEX_INITIALIZER, + }; + + // schedule jobs while pool is stopped + + task_t task = { .run = task_counting, .ctx = &log }; + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + sched_yield(); + ok(executed_reset(&log) == 0, "executed count before start"); + + // start and wait for finish + + worker_pool_start(pool); + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after start"); + + // add additional jobs while pool is running + + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after add"); + + // temporary suspension + + worker_pool_suspend(pool); + + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + sched_yield(); + ok(executed_reset(&log) == 0, "executed count after suspend"); + + worker_pool_resume(pool); + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after resume"); + + // try clean + + pthread_mutex_lock(&log.mx); + for (int i = 0; i < THREADS + TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + sched_yield(); + worker_pool_clear(pool); + pthread_mutex_unlock(&log.mx); + + worker_pool_wait(pool); + ok(executed_reset(&log) <= THREADS, "executed count after clear"); + + // cleanup + + worker_pool_stop(pool); + worker_pool_join(pool); + worker_pool_destroy(pool); + + pthread_mutex_destroy(&log.mx); + + return 0; +} diff --git a/tests/knot/test_worker_queue.c b/tests/knot/test_worker_queue.c new file mode 100644 index 0000000..d35f0aa --- /dev/null +++ b/tests/knot/test_worker_queue.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include "knot/worker/queue.h" + +int main(void) +{ + plan_lazy(); + + task_t task_one = { 0 }; + task_t task_two = { 0 }; + task_t task_three = { 0 }; + + // init + + worker_queue_t queue; + worker_queue_init(&queue); + ok(1, "queue init"); + + // enqueue + + worker_queue_enqueue(&queue, &task_one); + ok(1, "enqueue first"); + worker_queue_enqueue(&queue, &task_two); + ok(1, "enqueue second"); + + // dequeue + + ok(worker_queue_dequeue(&queue) == &task_one, "dequeue first"); + ok(worker_queue_dequeue(&queue) == &task_two, "dequeue second"); + ok(worker_queue_dequeue(&queue) == NULL, "dequeue from empty"); + + // deinit + + worker_queue_enqueue(&queue, &task_three); + ok(1, "enqueue third"); + + worker_queue_deinit(&queue); + ok(1, "queue deinit"); + + return 0; +} diff --git a/tests/knot/test_zone-tree.c b/tests/knot/test_zone-tree.c new file mode 100644 index 0000000..a1fab68 --- /dev/null +++ b/tests/knot/test_zone-tree.c @@ -0,0 +1,118 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <tap/basic.h> + +#include "libknot/errcode.h" +#include "knot/zone/zone-tree.h" + +#define NCOUNT 4 +static knot_dname_t* NAME[NCOUNT]; +static zone_node_t NODE[NCOUNT]; +static knot_dname_t* ORDER[NCOUNT]; +static void ztree_init_data(void) +{ + NAME[0] = knot_dname_from_str_alloc("."); + NAME[1] = knot_dname_from_str_alloc("master.ac."); + NAME[2] = knot_dname_from_str_alloc("ac."); + NAME[3] = knot_dname_from_str_alloc("ns."); + + knot_dname_t *order[NCOUNT] = { + NAME[0], NAME[2], NAME[1], NAME[3] + }; + memcpy(ORDER, order, NCOUNT * sizeof(knot_dname_t*)); + + for (unsigned i = 0; i < NCOUNT; ++i) { + memset(NODE + i, 0, sizeof(zone_node_t)); + NODE[i].owner = NAME[i]; + NODE[i].prev = NODE + ((NCOUNT + i - 1) % NCOUNT); + NODE[i].rrset_count = 1; /* required for ordered search */ + } +} + +static void ztree_free_data(void) +{ + for (unsigned i = 0; i < NCOUNT; ++i) { + knot_dname_free(NAME[i], NULL); + } +} + +static int ztree_iter_data(zone_node_t **node, void *data) +{ + unsigned *i = (unsigned *)data; + knot_dname_t *owner = (*node)->owner; + int result = KNOT_EOK; + if (owner != ORDER[*i]) { + result = KNOT_ERROR; + char *exp_s = knot_dname_to_str_alloc(ORDER[*i]); + char *owner_s = knot_dname_to_str_alloc(owner); + diag("ztree: at index: %u expected '%s' got '%s'\n", *i, exp_s, owner_s); + free(exp_s); + free(owner_s); + } + ++(*i); + return result; +} + +int main(int argc, char *argv[]) +{ + plan(5); + + ztree_init_data(); + + /* 1. create test */ + zone_tree_t* t = zone_tree_create(); + ok(t != NULL, "ztree: created"); + + /* 2. insert test */ + unsigned passed = 1; + for (unsigned i = 0; i < NCOUNT; ++i) { + if (zone_tree_insert(t, NODE + i) != KNOT_EOK) { + passed = 0; + break; + } + } + ok(passed, "ztree: insertion"); + + /* 3. check data test */ + passed = 1; + for (unsigned i = 0; i < NCOUNT; ++i) { + zone_node_t *node = zone_tree_get(t, NAME[i]); + if (node == NULL || node != NODE + i) { + passed = 0; + break; + } + } + ok(passed, "ztree: lookup"); + + /* 4. ordered lookup */ + zone_node_t *node = NULL; + zone_node_t *prev = NULL; + knot_dname_t *tmp_dn = knot_dname_from_str_alloc("z.ac."); + zone_tree_get_less_or_equal(t, tmp_dn, &node, &prev); + knot_dname_free(tmp_dn, NULL); + ok(prev == NODE + 1, "ztree: ordered lookup"); + + /* 5. ordered traversal */ + unsigned i = 0; + int ret = zone_tree_apply(t, ztree_iter_data, &i); + ok (ret == KNOT_EOK, "ztree: ordered traversal"); + + zone_tree_free(&t); + ztree_free_data(); + return 0; +} diff --git a/tests/knot/test_zone-update.c b/tests/knot/test_zone-update.c new file mode 100644 index 0000000..5e528dd --- /dev/null +++ b/tests/knot/test_zone-update.c @@ -0,0 +1,336 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> +#include <tap/files.h> + +#include "test_conf.h" +#include "contrib/macros.h" +#include "contrib/getline.h" +#include "knot/updates/zone-update.h" +#include "knot/zone/node.h" +#include "libzscanner/scanner.h" +#include "knot/server/server.h" + +static const char *zone_str1 = "test. 600 IN SOA ns.test. m.test. 1 900 300 4800 900 \n"; +static const char *zone_str2 = "test. IN TXT \"test\"\n"; +static const char *add_str = "test. IN TXT \"test2\"\n"; +static const char *del_str = "test. IN TXT \"test\"\n"; +static const char *node_str1 = "node.test. IN TXT \"abc\"\n"; +static const char *node_str2 = "node.test. IN TXT \"def\"\n"; + +knot_rrset_t rrset; + +/*!< \brief Returns true if node contains given RR in its RRSets. */ +static bool node_contains_rr(const zone_node_t *node, + const knot_rrset_t *rrset) +{ + const knot_rdataset_t *zone_rrs = node_rdataset(node, rrset->type); + if (zone_rrs != NULL) { + knot_rdata_t *rr = rrset->rrs.rdata; + for (size_t i = 0; i < rrset->rrs.count; ++i) { + if (!knot_rdataset_member(zone_rrs, rr)) { + return false; + } + rr = knot_rdataset_next(rr); + } + + return true; + } else { + return false; + } +} + +static void process_rr(zs_scanner_t *scanner) +{ + knot_rrset_init(&rrset, scanner->r_owner, scanner->r_type, scanner->r_class, + scanner->r_ttl); + + int ret = knot_rrset_add_rdata(&rrset, scanner->r_data, + scanner->r_data_length, NULL); + (void)ret; + assert(ret == KNOT_EOK); +} + +void test_full(zone_t *zone, zs_scanner_t *sc) +{ + zone_update_t update; + /* Init update */ + int ret = zone_update_init(&update, zone, UPDATE_FULL); + is_int(KNOT_EOK, ret, "zone update: init full"); + + if (zs_set_input_string(sc, zone_str1, strlen(zone_str1)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + + /* First addition */ + ret = zone_update_add(&update, &rrset); + knot_rdataset_clear(&rrset.rrs, NULL); + is_int(KNOT_EOK, ret, "full zone update: first addition"); + + if (zs_set_input_string(sc, zone_str2, strlen(zone_str2)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + + /* Second addition */ + ret = zone_update_add(&update, &rrset); + zone_node_t *node = (zone_node_t *) zone_update_get_node(&update, rrset.owner); + bool rrset_present = node_contains_rr(node, &rrset); + ok(ret == KNOT_EOK && rrset_present, "full zone update: second addition"); + + /* Removal */ + ret = zone_update_remove(&update, &rrset); + node = (zone_node_t *) zone_update_get_node(&update, rrset.owner); + rrset_present = node_contains_rr(node, &rrset); + ok(ret == KNOT_EOK && !rrset_present, "full zone update: removal"); + + /* Last addition */ + ret = zone_update_add(&update, &rrset); + node = (zone_node_t *) zone_update_get_node(&update, rrset.owner); + rrset_present = node_contains_rr(node, &rrset); + ok(ret == KNOT_EOK && rrset_present, "full zone update: last addition"); + + knot_rdataset_clear(&rrset.rrs, NULL); + + /* Prepare node removal */ + if (zs_set_input_string(sc, node_str1, strlen(node_str1)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + + if (zs_set_input_string(sc, node_str2, strlen(node_str2)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + knot_dname_t *rem_node_name = knot_dname_from_str_alloc("node.test"); + node = (zone_node_t *) zone_update_get_node(&update, rem_node_name); + assert(node && node_rdataset(node, KNOT_RRTYPE_TXT)->count == 2); + /* Node removal */ + ret = zone_update_remove_node(&update, rem_node_name); + node = (zone_node_t *) zone_update_get_node(&update, rem_node_name); + ok(ret == KNOT_EOK && !node, "full zone update: node removal"); + knot_dname_free(rem_node_name, NULL); + + /* Test iteration */ + zone_update_iter_t it; + ret = zone_update_iter(&it, &update); + is_int(KNOT_EOK, ret, "full zone update: init iter"); + + const zone_node_t *iter_node = zone_update_iter_val(&it); + assert(iter_node); + if (zs_set_input_string(sc, zone_str1, strlen(zone_str1)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + rrset_present = node_contains_rr(iter_node, &rrset); + ok(rrset_present, "full zone update: first iter value check"); + knot_rdataset_clear(&rrset.rrs, NULL); + + if (zs_set_input_string(sc, zone_str2, strlen(zone_str2)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + rrset_present = node_contains_rr(iter_node, &rrset); + ok(rrset_present, "full zone update: second iter value check"); + knot_rdataset_clear(&rrset.rrs, NULL); + + ret = zone_update_iter_next(&it); + is_int(KNOT_EOK, ret, "full zone update: iter next"); + + iter_node = zone_update_iter_val(&it); + ok(iter_node == NULL, "full zone update: iter val past end"); + + zone_update_iter_finish(&it); + + /* Re-add a node for later incremental functionality test */ + if (zs_set_input_string(sc, node_str1, strlen(node_str1)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + + /* Commit */ + ret = zone_update_commit(conf(), &update); + node = zone_contents_find_node_for_rr(zone->contents, &rrset); + rrset_present = node_contains_rr(node, &rrset); + ok(ret == KNOT_EOK && rrset_present, "full zone update: commit"); + + knot_rdataset_clear(&rrset.rrs, NULL); +} + +void test_incremental(zone_t *zone, zs_scanner_t *sc) +{ + int ret = KNOT_EOK; + + /* Init update */ + zone_update_t update; + zone_update_init(&update, zone, UPDATE_INCREMENTAL); + ok(update.zone == zone && changeset_empty(&update.change) && update.mm.alloc, + "incremental zone update: init"); + + if (zs_set_input_string(sc, add_str, strlen(add_str)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + + /* Addition */ + ret = zone_update_add(&update, &rrset); + knot_rdataset_clear(&rrset.rrs, NULL); + is_int(KNOT_EOK, ret, "incremental zone update: addition"); + + const zone_node_t *synth_node = zone_update_get_apex(&update); + ok(synth_node && node_rdataset(synth_node, KNOT_RRTYPE_TXT)->count == 2, + "incremental zone update: add change"); + + if (zs_set_input_string(sc, del_str, strlen(del_str)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + /* Removal */ + ret = zone_update_remove(&update, &rrset); + is_int(KNOT_EOK, ret, "incremental zone update: removal"); + knot_rdataset_clear(&rrset.rrs, NULL); + + synth_node = zone_update_get_apex(&update); + ok(synth_node && node_rdataset(synth_node, KNOT_RRTYPE_TXT)->count == 1, + "incremental zone update: del change"); + + /* Prepare node removal */ + if (zs_set_input_string(sc, node_str2, strlen(node_str2)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + + knot_dname_t *rem_node_name = knot_dname_from_str_alloc("node.test"); + synth_node = zone_update_get_node(&update, rem_node_name); + assert(synth_node && node_rdataset(synth_node, KNOT_RRTYPE_TXT)->count == 2); + /* Node Removal */ + ret = zone_update_remove_node(&update, rem_node_name); + synth_node = zone_update_get_node(&update, rem_node_name); + ok(ret == KNOT_EOK && !synth_node, + "incremental zone update: node removal"); + knot_dname_free(rem_node_name, NULL); + + /* Test iteration */ + zone_update_iter_t it; + ret = zone_update_iter(&it, &update); + is_int(KNOT_EOK, ret, "incremental zone update: init iter"); + + if (zs_set_input_string(sc, del_str, strlen(del_str)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + const zone_node_t *iter_node = zone_update_iter_val(&it); + assert(iter_node); + + bool rrset_present = node_contains_rr(iter_node, &rrset); + ok(!rrset_present, "incremental zone update: first iter value check"); + + knot_rdataset_clear(&rrset.rrs, NULL); + + if (zs_set_input_string(sc, add_str, strlen(add_str)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + rrset_present = node_contains_rr(iter_node, &rrset); + ok(rrset_present, "incremental zone update: second iter value check"); + knot_rdataset_clear(&rrset.rrs, NULL); + + ret = zone_update_iter_next(&it); + is_int(KNOT_EOK, ret, "incremental zone update: iter next"); + ret = zone_update_iter_next(&it); + is_int(KNOT_EOK, ret, "incremental zone update: iter next"); + + iter_node = zone_update_iter_val(&it); + ok(iter_node == NULL, "incremental zone update: iter val past end"); + + zone_update_iter_finish(&it); + + /* Commit */ + ret = zone_update_commit(conf(), &update); + iter_node = zone_contents_find_node_for_rr(zone->contents, &rrset); + rrset_present = node_contains_rr(iter_node, &rrset); + ok(ret == KNOT_EOK && rrset_present, "incremental zone update: commit"); + + knot_rdataset_clear(&rrset.rrs, NULL); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + char *temp_dir = test_mkdtemp(); + ok(temp_dir != NULL, "make temporary directory"); + + char conf_str[512]; + snprintf(conf_str, sizeof(conf_str), + "zone:\n" + " - domain: test.\n" + "template:\n" + " - id: default\n" + " max-journal-db-size: 100M\n" + " storage: %s\n", + temp_dir); + + /* Load test configuration. */ + int ret = test_conf(conf_str, NULL); + is_int(KNOT_EOK, ret, "load configuration"); + + server_t server; + ret = server_init(&server, 1); + is_int(KNOT_EOK, ret, "server init"); + + /* Set up empty zone */ + knot_dname_t *apex = knot_dname_from_str_alloc("test"); + assert(apex); + zone_t *zone = zone_new(apex); + zone->journal_db = &server.journal_db; + + /* Setup zscanner */ + zs_scanner_t sc; + if (zs_init(&sc, "test.", KNOT_CLASS_IN, 3600) != 0 || + zs_set_processing(&sc, process_rr, NULL, NULL) != 0) { + assert(0); + } + + /* Test FULL update, commit it and use the result to test the INCREMENTAL update */ + test_full(zone, &sc); + test_incremental(zone, &sc); + + zs_deinit(&sc); + zone_free(&zone); + server_deinit(&server); + knot_dname_free(apex, NULL); + conf_free(conf()); + test_rm_rf(temp_dir); + free(temp_dir); + + return 0; +} diff --git a/tests/knot/test_zone_events.c b/tests/knot/test_zone_events.c new file mode 100644 index 0000000..801c2d9 --- /dev/null +++ b/tests/knot/test_zone_events.c @@ -0,0 +1,99 @@ +/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include "knot/common/evsched.h" +#include "knot/worker/pool.h" +#include "knot/events/events.h" +#include "knot/zone/zone.h" + +static void test_scheduling(zone_t *zone) +{ + const time_t now = time(NULL); + const unsigned offset = 1000; + + time_t timestamp = 0; + zone_event_type_t event = 0; + + timestamp = zone_events_get_next(zone, &event); + ok(timestamp < 0 && event == ZONE_EVENT_INVALID, "nothing planned"); + + // scheduling + + zone_events_schedule_at(zone, ZONE_EVENT_EXPIRE, now + offset); + zone_events_schedule_at(zone, ZONE_EVENT_FLUSH, now + (offset / 2)); + + for (int i = 0; i < ZONE_EVENT_COUNT; i++) { + time_t t = zone_events_get_time(zone, i); + bool scheduled = i == ZONE_EVENT_EXPIRE || i == ZONE_EVENT_FLUSH; + const char *name = zone_events_get_name(i); + + ok((t > 0) == scheduled && name, "event %s (%s)", name, + scheduled ? "scheduled" : "not scheduled"); + } + + // queuing + + timestamp = zone_events_get_next(zone, &event); + ok(timestamp >= now + (offset / 2) && event == ZONE_EVENT_FLUSH, "flush is next"); + + zone_events_schedule_at(zone, ZONE_EVENT_FLUSH, 0); + + timestamp = zone_events_get_next(zone, &event); + ok(timestamp >= now + offset && event == ZONE_EVENT_EXPIRE, "expire is next"); + + zone_events_schedule_at(zone, ZONE_EVENT_EXPIRE, 0); + + timestamp = zone_events_get_next(zone, &event); + ok(timestamp < 0 && event == ZONE_EVENT_INVALID, "nothing planned"); + + // zone_events_enqueue + + // zone_events_freeze + // zone_events_start +} + +int main(void) +{ + plan_lazy(); + + int r; + + evsched_t sched = { 0 }; + worker_pool_t *pool = NULL; + zone_t zone = { 0 }; + + r = evsched_init(&sched, NULL); + ok(r == KNOT_EOK, "create scheduler"); + + pool = worker_pool_create(1); + ok(pool != NULL, "create worker pool"); + + r = zone_events_init(&zone); + ok(r == KNOT_EOK, "zone events init"); + + r = zone_events_setup(&zone, pool, &sched, NULL); + ok(r == KNOT_EOK, "zone events setup"); + + test_scheduling(&zone); + + zone_events_deinit(&zone); + worker_pool_destroy(pool); + evsched_deinit(&sched); + + return 0; +} diff --git a/tests/knot/test_zone_serial.c b/tests/knot/test_zone_serial.c new file mode 100644 index 0000000..73b7f4c --- /dev/null +++ b/tests/knot/test_zone_serial.c @@ -0,0 +1,134 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <stdlib.h> +#include <time.h> + +#include "knot/zone/serial.h" +#include "knot/conf/schema.h" +#include "contrib/strtonum.h" + +enum serials { + S_LOWEST = 0, // lowest value + S_2LOWEST = 1, // second lowest value + S_BELOW_MIDDLE = 0x7fffffff, // one below middle + S_ABOVE_MIDDLE = 0x80000000, // one above middle + S_2HIGHEST = 0xffffffff - 1, // second highest value + S_HIGHEST = 0xffffffff // highest value +}; + +static uint32_t random_serial(void) +{ + uint32_t s = rand() & 0xff; + s |= (rand() & 0xff) << 8; + s |= (rand() & 0xff) << 16; + s |= (rand() & 0xff) << 24; + + return s; +} + +static void check_dateserial(uint32_t current, uint32_t expected, const char *msg) +{ + uint32_t next = serial_next(current, SERIAL_POLICY_DATESERIAL); + ok(next == expected, "dateserial: %s", msg); +} + +static void test_dateserial(void) +{ + time_t now = time(NULL); + + struct tm *gm_ret = gmtime(&now); + + char str[32]; + int ret1 = strftime(str, sizeof(str), "%Y%m%d00", gm_ret); + + uint32_t serial0 = 0; + int ret2 = str_to_u32(str, &serial0); + + ok(gm_ret != NULL && ret1 > 0 && ret2 == KNOT_EOK, + "dateseril: prepare current value"); + + check_dateserial(2000010100, serial0, "from old date"); + check_dateserial(serial0, serial0 + 1, "today's first increment"); + check_dateserial(serial0 + 98, serial0 + 99, "today's last increment"); + check_dateserial(2100010100, 2100010101, "from future date"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Serial compare test. */ + ok(serial_compare(S_LOWEST, S_BELOW_MIDDLE) == SERIAL_LOWER, + "serial compare: lowest < below middle"); + ok(serial_compare(S_BELOW_MIDDLE, S_LOWEST) == SERIAL_GREATER, + "serial compare: below middle > lowest"); + + /* Corner-case: these serials' distance is exactly 2^31. */ + ok(serial_compare(S_LOWEST, S_ABOVE_MIDDLE) == SERIAL_INCOMPARABLE, + "serial compare: lowest < above_middle"); + ok(serial_compare(S_ABOVE_MIDDLE, S_LOWEST) == SERIAL_INCOMPARABLE, + "serial compare: above_middle < lowest"); + + ok(serial_compare(S_LOWEST, S_HIGHEST) == SERIAL_GREATER, + "serial compare: lowest > highest"); + ok(serial_compare(S_HIGHEST, S_LOWEST) == SERIAL_LOWER, + "serial compare: highest < lowest"); + + ok(serial_compare(S_2LOWEST, S_ABOVE_MIDDLE) == SERIAL_LOWER, + "serial compare: 2nd lowest < above middle"); + ok(serial_compare(S_ABOVE_MIDDLE, S_2LOWEST) == SERIAL_GREATER, + "serial compare: above middle > 2nd lowest"); + + /* Corner-case: these serials' distance is exactly 2^31. */ + ok(serial_compare(S_BELOW_MIDDLE, S_HIGHEST) == SERIAL_INCOMPARABLE, + "serial compare: below middle < highest"); + ok(serial_compare(S_HIGHEST, S_BELOW_MIDDLE) == SERIAL_INCOMPARABLE, + "serial compare: highest < below middle"); + + ok(serial_compare(S_BELOW_MIDDLE, S_2HIGHEST) == SERIAL_LOWER, + "serial compare: below middle < 2nd highest"); + ok(serial_compare(S_2HIGHEST, S_BELOW_MIDDLE) == SERIAL_GREATER, + "serial compare: 2nd highest > below middle"); + + ok(serial_compare(S_ABOVE_MIDDLE, S_HIGHEST) == SERIAL_LOWER, + "serial compare: above middle < highest"); + ok(serial_compare(S_HIGHEST, S_ABOVE_MIDDLE) == SERIAL_GREATER, + "serial compare: highest > above middle"); + + ok(serial_compare(S_LOWEST, S_LOWEST) == SERIAL_EQUAL, + "serial compare: lowest == lowest"); + ok(serial_compare(S_HIGHEST, S_HIGHEST) == SERIAL_EQUAL, + "serial compare: highest == highest"); + + ok(serial_compare(S_LOWEST - 1, S_HIGHEST) == SERIAL_EQUAL, + "serial compare: lowest - 1 == highest"); + ok(serial_compare(S_LOWEST, S_HIGHEST + 1) == SERIAL_EQUAL, + "serial compare: lowest== highest + 1"); + + /* Corner-case: these serials' distance is exactly 2^31. */ + uint32_t s1 = random_serial(); + uint32_t s2 = s1 + S_ABOVE_MIDDLE; // exactly the 'opposite' number + ok(serial_compare(s1, s2) == SERIAL_INCOMPARABLE, + "serial compare: random opposites (s1 < s2)"); + ok(serial_compare(s2, s1) == SERIAL_INCOMPARABLE, + "serial compare: random opposites (s2 < s1)"); + + test_dateserial(); + + return 0; +} diff --git a/tests/knot/test_zone_timers.c b/tests/knot/test_zone_timers.c new file mode 100644 index 0000000..d60aa8e --- /dev/null +++ b/tests/knot/test_zone_timers.c @@ -0,0 +1,102 @@ +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> +#include <tap/files.h> + +#include "knot/zone/timers.h" +#include "libknot/db/db_lmdb.h" +#include "libknot/dname.h" +#include "libknot/error.h" + +static const zone_timers_t MOCK_TIMERS = { + .soa_expire = 3600, + .last_refresh = 1474559950, + .next_refresh = 1474559960, + .last_flush = 1474559900, +}; + +static bool keep_all(const knot_dname_t *zone, void *data) +{ + return true; +} + +static bool remove_all(const knot_dname_t *zone, void *data) +{ + return false; +} + +static bool timers_eq(const zone_timers_t *a, const zone_timers_t *b) +{ + return a->soa_expire == b->soa_expire && + a->last_refresh == b->last_refresh && + a->next_refresh == b->next_refresh && + a->last_flush == b->last_flush; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + assert(knot_db_lmdb_api()); + + char *dbid = test_mkdtemp(); + if (!dbid) { + return EXIT_FAILURE; + } + + const knot_dname_t *zone = (uint8_t *)"\x7""example""\x3""com"; + struct zone_timers timers = MOCK_TIMERS; + + // Create database + knot_db_t *db = NULL; + int ret = zone_timers_open(dbid, &db, 1024 * 1024); + ok(ret == KNOT_EOK && db != NULL, "zone_timers_open()"); + + // Lookup nonexistent + ret = zone_timers_read(db, zone, &timers); + is_int(KNOT_ENOENT, ret, "zone_timer_read() nonexistent"); + + // Write timers + ret = zone_timers_write(db, zone, &timers, NULL); + is_int(KNOT_EOK, ret, "zone_timers_write()"); + + // Read timers + memset(&timers, 0, sizeof(timers)); + ret = zone_timers_read(db, zone, &timers); + ok(ret == KNOT_EOK && timers_eq(&timers, &MOCK_TIMERS), "zone_timers_read()"); + + // Sweep none + ret = zone_timers_sweep(db, keep_all, NULL); + is_int(KNOT_EOK, ret, "zone_timers_sweep() none"); + ret = zone_timers_read(db, zone, &timers); + is_int(KNOT_EOK, ret, "zone_timers_read()"); + + // Sweep all + ret = zone_timers_sweep(db, remove_all, NULL); + is_int(KNOT_EOK, ret, "zone_timers_sweep() all"); + ret = zone_timers_read(db, zone, &timers); + is_int(KNOT_ENOENT, ret, "zone_timers_read() nonexistent"); + + // Clean up. + zone_timers_close(db); + test_rm_rf(dbid); + free(dbid); + + return EXIT_SUCCESS; +} diff --git a/tests/knot/test_zonedb.c b/tests/knot/test_zonedb.c new file mode 100644 index 0000000..3ec2b93 --- /dev/null +++ b/tests/knot/test_zonedb.c @@ -0,0 +1,115 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "knot/zone/zone.h" +#include "knot/zone/zonedb.h" +#include "contrib/openbsd/strlcat.h" +#include "contrib/openbsd/strlcpy.h" + +#define ZONE_COUNT 10 +static const char *zone_list[ZONE_COUNT] = { + ".", + "com", + "net", + "c.com", + "a.com", + "a.net", + "b.net", + "c.a.com", + "b.b.b.com", + "b.b.b.b.net", +}; + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Create database. */ + char buf[KNOT_DNAME_MAXLEN]; + const char *prefix = "zzz."; + size_t nr_passed = 0; + knot_dname_t *dname = NULL; + zone_t *zones[ZONE_COUNT] = {0}; + knot_zonedb_t *db = knot_zonedb_new(); + ok(db != NULL, "zonedb: new"); + + /* Populate. */ + for (unsigned i = 0; i < ZONE_COUNT; ++i) { + knot_dname_t *zone_name = knot_dname_from_str_alloc(zone_list[i]); + zones[i] = zone_new(zone_name); + knot_dname_free(zone_name, NULL); + + if (zones[i] == NULL) { + goto cleanup; + } + if (knot_zonedb_insert(db, zones[i]) == KNOT_EOK) { + ++nr_passed; + } else { + diag("knot_zonedb_add_zone(%s) failed", zone_list[i]); + } + } + ok(nr_passed == ZONE_COUNT, "zonedb: add zones"); + + /* Lookup of exact names. */ + nr_passed = 0; + for (unsigned i = 0; i < ZONE_COUNT; ++i) { + dname = knot_dname_from_str_alloc(zone_list[i]); + if (knot_zonedb_find(db, dname) == zones[i]) { + ++nr_passed; + } else { + diag("knot_zonedb_find(%s) failed", zone_list[i]); + } + knot_dname_free(dname, NULL); + } + ok(nr_passed == ZONE_COUNT, "zonedb: find exact zones"); + + /* Lookup of sub-names. */ + nr_passed = 0; + for (unsigned i = 0; i < ZONE_COUNT; ++i) { + strlcpy(buf, prefix, sizeof(buf)); + if (strcmp(zone_list[i], ".") != 0) { + strlcat(buf, zone_list[i], sizeof(buf)); + } + dname = knot_dname_from_str_alloc(buf); + if (knot_zonedb_find_suffix(db, dname) == zones[i]) { + ++nr_passed; + } else { + diag("knot_zonedb_find_suffix(%s) failed", buf); + } + knot_dname_free(dname, NULL); + } + ok(nr_passed == ZONE_COUNT, "zonedb: find zones for subnames"); + + /* Remove all zones. */ + nr_passed = 0; + for (unsigned i = 0; i < ZONE_COUNT; ++i) { + dname = knot_dname_from_str_alloc(zone_list[i]); + if (knot_zonedb_del(db, dname) == KNOT_EOK) { + zone_free(&zones[i]); + ++nr_passed; + } else { + diag("knot_zonedb_remove_zone(%s) failed", zone_list[i]); + } + knot_dname_free(dname, NULL); + } + ok(nr_passed == ZONE_COUNT, "zonedb: removed all zones"); + +cleanup: + knot_zonedb_deep_free(&db); + return 0; +} diff --git a/tests/libdnssec/sample_keys.h b/tests/libdnssec/sample_keys.h new file mode 100644 index 0000000..c788ed5 --- /dev/null +++ b/tests/libdnssec/sample_keys.h @@ -0,0 +1,407 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <binary.h> + +typedef struct key_parameters { + // DNSSEC fields + uint8_t *name; + uint16_t flags; + uint8_t protocol; + uint8_t algorithm; + dnssec_binary_t public_key; + + // DNSSEC wire format + dnssec_binary_t rdata; + + // Hashes + const char *key_id; + uint16_t keytag; + dnssec_binary_t ds_sha1; + dnssec_binary_t ds_sha256; + dnssec_binary_t ds_sha384; + + // Key information + unsigned bit_size; + + // Private key in PEM + dnssec_binary_t pem; +} key_parameters_t; + +/* + +RSA-SHA-256 + +rsa. IN DNSKEY 256 3 8 AwEAAaqwL+O6GcCPkRZjoObfIJHcHPwQQY9mnAg6kROea2gsyRJOAwBNQPCfXoPtmrU0BiZ0aGBVTVPAvZh+HJRu9NEfTNDPK2HSyHdSucjY1qs6WAub6oWHJuLBxMesftpnUwoLnVZyN+pOblUZUMsvxP3PlS+mA+E6NyQX0F/fcfGL +rsa. IN DS 37335 8 1 2ABEFAAB07A900F8CB5B266FC930EEBEF51766F6 +rsa. IN DS 37335 8 2 30226484F230814C08C6DD9E2DF6E7A3DB860C2552A418CBF70D0FEE94DFA15F +rsa. IN DS 37335 8 4 978E0F7766096E131E3E90C50B63DBD825E7428E864BC5A3D32F3135A3786F0CDC6A070B6B8D760190F0F572B03CA4C0 + +Modulus: qrAv47oZwI+RFmOg5t8gkdwc/BBBj2acCDqRE55raCzJEk4DAE1A8J9eg+2atTQGJnRoYFVNU8C9mH4clG700R9M0M8rYdLId1K5yNjWqzpYC5vqhYcm4sHEx6x+2mdTCgudVnI36k5uVRlQyy/E/c+VL6YD4To3JBfQX99x8Ys= +PublicExponent: AQAB +PrivateExponent: NGDSoVBHfMbRoAw8oPxRk1D3eAZJCAdV1FSclmej0BkGLt7PnvUV+4D8UQHF2ts3E+/e48jpbM0VoUj53jbaWx1ULVmQ1cpJY0XLsRUmaQdOwEnSgXjtQy2htlth8RinB+LnVG8eUS9jWnEEikfvCLH0ptkOa/u6GKFUMj+Q95k= +Prime1: 4ZZj/YD5xvjxEuE0uR0KedsZeGT6iHqwtmJuLNuhFaeXIw5vXXZmg88U/lIo2t0DESYTbfXglw0eu62MwWb+5w== +Prime2: wbMU0wM6MYaDs4FfEeuTXT14P3cXZOFGikJPWiIUGoMGvDgYzxdiFoHzGdLkapsPizTqBKMtYQ9CYQa8g1cXvQ== +Exponent1: ywKuZVqGbdtmB9mHuvc5kEPuffxRwjS3hsq538CfDH/PcYryCagdxYy8lcqWXa/7rJkZbyGQxh7Wg4tBWmM4DQ== +Exponent2: L8MYv29sSgoBL6IW7zRHghZGMGANRLLH0g/HwVHl4yOr5X1voKEDbslcSGHYMPFLQ+goTDxwVB6PH52pnjk7gQ== +Coefficient: USHiV/UQkTz3BlxZc1IAiUQv9/Ba8wtHWSVp+YqPhxt1sfdiyUMXtlA4f6WAKAGMraoRw4wIcYr+N6Wx+wwXZw== + +-----BEGIN PRIVATE KEY----- +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKqwL+O6GcCPkRZj +oObfIJHcHPwQQY9mnAg6kROea2gsyRJOAwBNQPCfXoPtmrU0BiZ0aGBVTVPAvZh+ +HJRu9NEfTNDPK2HSyHdSucjY1qs6WAub6oWHJuLBxMesftpnUwoLnVZyN+pOblUZ +UMsvxP3PlS+mA+E6NyQX0F/fcfGLAgMBAAECgYA0YNKhUEd8xtGgDDyg/FGTUPd4 +BkkIB1XUVJyWZ6PQGQYu3s+e9RX7gPxRAcXa2zcT797jyOlszRWhSPneNtpbHVQt +WZDVykljRcuxFSZpB07ASdKBeO1DLaG2W2HxGKcH4udUbx5RL2NacQSKR+8IsfSm +2Q5r+7oYoVQyP5D3mQJBAOGWY/2A+cb48RLhNLkdCnnbGXhk+oh6sLZibizboRWn +lyMOb112ZoPPFP5SKNrdAxEmE2314JcNHrutjMFm/ucCQQDBsxTTAzoxhoOzgV8R +65NdPXg/dxdk4UaKQk9aIhQagwa8OBjPF2IWgfMZ0uRqmw+LNOoEoy1hD0JhBryD +Vxe9AkEAywKuZVqGbdtmB9mHuvc5kEPuffxRwjS3hsq538CfDH/PcYryCagdxYy8 +lcqWXa/7rJkZbyGQxh7Wg4tBWmM4DQJAL8MYv29sSgoBL6IW7zRHghZGMGANRLLH +0g/HwVHl4yOr5X1voKEDbslcSGHYMPFLQ+goTDxwVB6PH52pnjk7gQJAUSHiV/UQ +kTz3BlxZc1IAiUQv9/Ba8wtHWSVp+YqPhxt1sfdiyUMXtlA4f6WAKAGMraoRw4wI +cYr+N6Wx+wwXZw== +-----END PRIVATE KEY----- + +*/ + +static const key_parameters_t SAMPLE_RSA_KEY = { + .name = (uint8_t *)"\x03""rsa", + .flags = 256, + .protocol = 3, + .algorithm = 8, + .public_key = { .size = 132, .data = (uint8_t []) { + 0x03, 0x01, 0x00, 0x01, 0xaa, 0xb0, 0x2f, 0xe3, 0xba, 0x19, + 0xc0, 0x8f, 0x91, 0x16, 0x63, 0xa0, 0xe6, 0xdf, 0x20, 0x91, + 0xdc, 0x1c, 0xfc, 0x10, 0x41, 0x8f, 0x66, 0x9c, 0x08, 0x3a, + 0x91, 0x13, 0x9e, 0x6b, 0x68, 0x2c, 0xc9, 0x12, 0x4e, 0x03, + 0x00, 0x4d, 0x40, 0xf0, 0x9f, 0x5e, 0x83, 0xed, 0x9a, 0xb5, + 0x34, 0x06, 0x26, 0x74, 0x68, 0x60, 0x55, 0x4d, 0x53, 0xc0, + 0xbd, 0x98, 0x7e, 0x1c, 0x94, 0x6e, 0xf4, 0xd1, 0x1f, 0x4c, + 0xd0, 0xcf, 0x2b, 0x61, 0xd2, 0xc8, 0x77, 0x52, 0xb9, 0xc8, + 0xd8, 0xd6, 0xab, 0x3a, 0x58, 0x0b, 0x9b, 0xea, 0x85, 0x87, + 0x26, 0xe2, 0xc1, 0xc4, 0xc7, 0xac, 0x7e, 0xda, 0x67, 0x53, + 0x0a, 0x0b, 0x9d, 0x56, 0x72, 0x37, 0xea, 0x4e, 0x6e, 0x55, + 0x19, 0x50, 0xcb, 0x2f, 0xc4, 0xfd, 0xcf, 0x95, 0x2f, 0xa6, + 0x03, 0xe1, 0x3a, 0x37, 0x24, 0x17, 0xd0, 0x5f, 0xdf, 0x71, + 0xf1, 0x8b, + }}, + .rdata = { .size = 136, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x08, + 0x03, 0x01, 0x00, 0x01, 0xaa, 0xb0, 0x2f, 0xe3, 0xba, 0x19, + 0xc0, 0x8f, 0x91, 0x16, 0x63, 0xa0, 0xe6, 0xdf, 0x20, 0x91, + 0xdc, 0x1c, 0xfc, 0x10, 0x41, 0x8f, 0x66, 0x9c, 0x08, 0x3a, + 0x91, 0x13, 0x9e, 0x6b, 0x68, 0x2c, 0xc9, 0x12, 0x4e, 0x03, + 0x00, 0x4d, 0x40, 0xf0, 0x9f, 0x5e, 0x83, 0xed, 0x9a, 0xb5, + 0x34, 0x06, 0x26, 0x74, 0x68, 0x60, 0x55, 0x4d, 0x53, 0xc0, + 0xbd, 0x98, 0x7e, 0x1c, 0x94, 0x6e, 0xf4, 0xd1, 0x1f, 0x4c, + 0xd0, 0xcf, 0x2b, 0x61, 0xd2, 0xc8, 0x77, 0x52, 0xb9, 0xc8, + 0xd8, 0xd6, 0xab, 0x3a, 0x58, 0x0b, 0x9b, 0xea, 0x85, 0x87, + 0x26, 0xe2, 0xc1, 0xc4, 0xc7, 0xac, 0x7e, 0xda, 0x67, 0x53, + 0x0a, 0x0b, 0x9d, 0x56, 0x72, 0x37, 0xea, 0x4e, 0x6e, 0x55, + 0x19, 0x50, 0xcb, 0x2f, 0xc4, 0xfd, 0xcf, 0x95, 0x2f, 0xa6, + 0x03, 0xe1, 0x3a, 0x37, 0x24, 0x17, 0xd0, 0x5f, 0xdf, 0x71, + 0xf1, 0x8b, + }}, + .key_id = "76f0d6c093d8328bc7f0e25bd8cde5575bad9b44", + .keytag = 37335, + .ds_sha1 = { .size = 24, .data = (uint8_t []) { + 0x91, 0xd7, 0x08, 0x01, + 0x2a, 0xbe, 0xfa, 0xab, 0x07, 0xa9, 0x00, 0xf8, 0xcb, 0x5b, + 0x26, 0x6f, 0xc9, 0x30, 0xee, 0xbe, 0xf5, 0x17, 0x66, 0xf6, + }}, + .ds_sha256 = { .size = 36, .data = (uint8_t []) { + 0x91, 0xd7, 0x08, 0x02, + 0x30, 0x22, 0x64, 0x84, 0xf2, 0x30, 0x81, 0x4c, 0x08, 0xc6, + 0xdd, 0x9e, 0x2d, 0xf6, 0xe7, 0xa3, 0xdb, 0x86, 0x0c, 0x25, + 0x52, 0xa4, 0x18, 0xcb, 0xf7, 0x0d, 0x0f, 0xee, 0x94, 0xdf, + 0xa1, 0x5f, + }}, + .ds_sha384 = { .size = 52, .data = (uint8_t []) { + 0x91, 0xd7, 0x08, 0x04, + 0x97, 0x8e, 0x0f, 0x77, 0x66, 0x09, 0x6e, 0x13, 0x1e, 0x3e, + 0x90, 0xc5, 0x0b, 0x63, 0xdb, 0xd8, 0x25, 0xe7, 0x42, 0x8e, + 0x86, 0x4b, 0xc5, 0xa3, 0xd3, 0x2f, 0x31, 0x35, 0xa3, 0x78, + 0x6f, 0x0c, 0xdc, 0x6a, 0x07, 0x0b, 0x6b, 0x8d, 0x76, 0x01, + 0x90, 0xf0, 0xf5, 0x72, 0xb0, 0x3c, 0xa4, 0xc0, + }}, + .bit_size = 1024, + .pem = { .size = 916, .data = (uint8_t []) { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, + 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, + 0x49, 0x43, 0x64, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4e, + 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, + 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43, + 0x41, 0x6d, 0x41, 0x77, 0x67, 0x67, 0x4a, 0x63, 0x41, 0x67, + 0x45, 0x41, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4b, 0x71, 0x77, + 0x4c, 0x2b, 0x4f, 0x36, 0x47, 0x63, 0x43, 0x50, 0x6b, 0x52, + 0x5a, 0x6a, 0x0a, 0x6f, 0x4f, 0x62, 0x66, 0x49, 0x4a, 0x48, + 0x63, 0x48, 0x50, 0x77, 0x51, 0x51, 0x59, 0x39, 0x6d, 0x6e, + 0x41, 0x67, 0x36, 0x6b, 0x52, 0x4f, 0x65, 0x61, 0x32, 0x67, + 0x73, 0x79, 0x52, 0x4a, 0x4f, 0x41, 0x77, 0x42, 0x4e, 0x51, + 0x50, 0x43, 0x66, 0x58, 0x6f, 0x50, 0x74, 0x6d, 0x72, 0x55, + 0x30, 0x42, 0x69, 0x5a, 0x30, 0x61, 0x47, 0x42, 0x56, 0x54, + 0x56, 0x50, 0x41, 0x76, 0x5a, 0x68, 0x2b, 0x0a, 0x48, 0x4a, + 0x52, 0x75, 0x39, 0x4e, 0x45, 0x66, 0x54, 0x4e, 0x44, 0x50, + 0x4b, 0x32, 0x48, 0x53, 0x79, 0x48, 0x64, 0x53, 0x75, 0x63, + 0x6a, 0x59, 0x31, 0x71, 0x73, 0x36, 0x57, 0x41, 0x75, 0x62, + 0x36, 0x6f, 0x57, 0x48, 0x4a, 0x75, 0x4c, 0x42, 0x78, 0x4d, + 0x65, 0x73, 0x66, 0x74, 0x70, 0x6e, 0x55, 0x77, 0x6f, 0x4c, + 0x6e, 0x56, 0x5a, 0x79, 0x4e, 0x2b, 0x70, 0x4f, 0x62, 0x6c, + 0x55, 0x5a, 0x0a, 0x55, 0x4d, 0x73, 0x76, 0x78, 0x50, 0x33, + 0x50, 0x6c, 0x53, 0x2b, 0x6d, 0x41, 0x2b, 0x45, 0x36, 0x4e, + 0x79, 0x51, 0x58, 0x30, 0x46, 0x2f, 0x66, 0x63, 0x66, 0x47, + 0x4c, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x43, 0x67, + 0x59, 0x41, 0x30, 0x59, 0x4e, 0x4b, 0x68, 0x55, 0x45, 0x64, + 0x38, 0x78, 0x74, 0x47, 0x67, 0x44, 0x44, 0x79, 0x67, 0x2f, + 0x46, 0x47, 0x54, 0x55, 0x50, 0x64, 0x34, 0x0a, 0x42, 0x6b, + 0x6b, 0x49, 0x42, 0x31, 0x58, 0x55, 0x56, 0x4a, 0x79, 0x57, + 0x5a, 0x36, 0x50, 0x51, 0x47, 0x51, 0x59, 0x75, 0x33, 0x73, + 0x2b, 0x65, 0x39, 0x52, 0x58, 0x37, 0x67, 0x50, 0x78, 0x52, + 0x41, 0x63, 0x58, 0x61, 0x32, 0x7a, 0x63, 0x54, 0x37, 0x39, + 0x37, 0x6a, 0x79, 0x4f, 0x6c, 0x73, 0x7a, 0x52, 0x57, 0x68, + 0x53, 0x50, 0x6e, 0x65, 0x4e, 0x74, 0x70, 0x62, 0x48, 0x56, + 0x51, 0x74, 0x0a, 0x57, 0x5a, 0x44, 0x56, 0x79, 0x6b, 0x6c, + 0x6a, 0x52, 0x63, 0x75, 0x78, 0x46, 0x53, 0x5a, 0x70, 0x42, + 0x30, 0x37, 0x41, 0x53, 0x64, 0x4b, 0x42, 0x65, 0x4f, 0x31, + 0x44, 0x4c, 0x61, 0x47, 0x32, 0x57, 0x32, 0x48, 0x78, 0x47, + 0x4b, 0x63, 0x48, 0x34, 0x75, 0x64, 0x55, 0x62, 0x78, 0x35, + 0x52, 0x4c, 0x32, 0x4e, 0x61, 0x63, 0x51, 0x53, 0x4b, 0x52, + 0x2b, 0x38, 0x49, 0x73, 0x66, 0x53, 0x6d, 0x0a, 0x32, 0x51, + 0x35, 0x72, 0x2b, 0x37, 0x6f, 0x59, 0x6f, 0x56, 0x51, 0x79, + 0x50, 0x35, 0x44, 0x33, 0x6d, 0x51, 0x4a, 0x42, 0x41, 0x4f, + 0x47, 0x57, 0x59, 0x2f, 0x32, 0x41, 0x2b, 0x63, 0x62, 0x34, + 0x38, 0x52, 0x4c, 0x68, 0x4e, 0x4c, 0x6b, 0x64, 0x43, 0x6e, + 0x6e, 0x62, 0x47, 0x58, 0x68, 0x6b, 0x2b, 0x6f, 0x68, 0x36, + 0x73, 0x4c, 0x5a, 0x69, 0x62, 0x69, 0x7a, 0x62, 0x6f, 0x52, + 0x57, 0x6e, 0x0a, 0x6c, 0x79, 0x4d, 0x4f, 0x62, 0x31, 0x31, + 0x32, 0x5a, 0x6f, 0x50, 0x50, 0x46, 0x50, 0x35, 0x53, 0x4b, + 0x4e, 0x72, 0x64, 0x41, 0x78, 0x45, 0x6d, 0x45, 0x32, 0x33, + 0x31, 0x34, 0x4a, 0x63, 0x4e, 0x48, 0x72, 0x75, 0x74, 0x6a, + 0x4d, 0x46, 0x6d, 0x2f, 0x75, 0x63, 0x43, 0x51, 0x51, 0x44, + 0x42, 0x73, 0x78, 0x54, 0x54, 0x41, 0x7a, 0x6f, 0x78, 0x68, + 0x6f, 0x4f, 0x7a, 0x67, 0x56, 0x38, 0x52, 0x0a, 0x36, 0x35, + 0x4e, 0x64, 0x50, 0x58, 0x67, 0x2f, 0x64, 0x78, 0x64, 0x6b, + 0x34, 0x55, 0x61, 0x4b, 0x51, 0x6b, 0x39, 0x61, 0x49, 0x68, + 0x51, 0x61, 0x67, 0x77, 0x61, 0x38, 0x4f, 0x42, 0x6a, 0x50, + 0x46, 0x32, 0x49, 0x57, 0x67, 0x66, 0x4d, 0x5a, 0x30, 0x75, + 0x52, 0x71, 0x6d, 0x77, 0x2b, 0x4c, 0x4e, 0x4f, 0x6f, 0x45, + 0x6f, 0x79, 0x31, 0x68, 0x44, 0x30, 0x4a, 0x68, 0x42, 0x72, + 0x79, 0x44, 0x0a, 0x56, 0x78, 0x65, 0x39, 0x41, 0x6b, 0x45, + 0x41, 0x79, 0x77, 0x4b, 0x75, 0x5a, 0x56, 0x71, 0x47, 0x62, + 0x64, 0x74, 0x6d, 0x42, 0x39, 0x6d, 0x48, 0x75, 0x76, 0x63, + 0x35, 0x6b, 0x45, 0x50, 0x75, 0x66, 0x66, 0x78, 0x52, 0x77, + 0x6a, 0x53, 0x33, 0x68, 0x73, 0x71, 0x35, 0x33, 0x38, 0x43, + 0x66, 0x44, 0x48, 0x2f, 0x50, 0x63, 0x59, 0x72, 0x79, 0x43, + 0x61, 0x67, 0x64, 0x78, 0x59, 0x79, 0x38, 0x0a, 0x6c, 0x63, + 0x71, 0x57, 0x58, 0x61, 0x2f, 0x37, 0x72, 0x4a, 0x6b, 0x5a, + 0x62, 0x79, 0x47, 0x51, 0x78, 0x68, 0x37, 0x57, 0x67, 0x34, + 0x74, 0x42, 0x57, 0x6d, 0x4d, 0x34, 0x44, 0x51, 0x4a, 0x41, + 0x4c, 0x38, 0x4d, 0x59, 0x76, 0x32, 0x39, 0x73, 0x53, 0x67, + 0x6f, 0x42, 0x4c, 0x36, 0x49, 0x57, 0x37, 0x7a, 0x52, 0x48, + 0x67, 0x68, 0x5a, 0x47, 0x4d, 0x47, 0x41, 0x4e, 0x52, 0x4c, + 0x4c, 0x48, 0x0a, 0x30, 0x67, 0x2f, 0x48, 0x77, 0x56, 0x48, + 0x6c, 0x34, 0x79, 0x4f, 0x72, 0x35, 0x58, 0x31, 0x76, 0x6f, + 0x4b, 0x45, 0x44, 0x62, 0x73, 0x6c, 0x63, 0x53, 0x47, 0x48, + 0x59, 0x4d, 0x50, 0x46, 0x4c, 0x51, 0x2b, 0x67, 0x6f, 0x54, + 0x44, 0x78, 0x77, 0x56, 0x42, 0x36, 0x50, 0x48, 0x35, 0x32, + 0x70, 0x6e, 0x6a, 0x6b, 0x37, 0x67, 0x51, 0x4a, 0x41, 0x55, + 0x53, 0x48, 0x69, 0x56, 0x2f, 0x55, 0x51, 0x0a, 0x6b, 0x54, + 0x7a, 0x33, 0x42, 0x6c, 0x78, 0x5a, 0x63, 0x31, 0x49, 0x41, + 0x69, 0x55, 0x51, 0x76, 0x39, 0x2f, 0x42, 0x61, 0x38, 0x77, + 0x74, 0x48, 0x57, 0x53, 0x56, 0x70, 0x2b, 0x59, 0x71, 0x50, + 0x68, 0x78, 0x74, 0x31, 0x73, 0x66, 0x64, 0x69, 0x79, 0x55, + 0x4d, 0x58, 0x74, 0x6c, 0x41, 0x34, 0x66, 0x36, 0x57, 0x41, + 0x4b, 0x41, 0x47, 0x4d, 0x72, 0x61, 0x6f, 0x52, 0x77, 0x34, + 0x77, 0x49, 0x0a, 0x63, 0x59, 0x72, 0x2b, 0x4e, 0x36, 0x57, + 0x78, 0x2b, 0x77, 0x77, 0x58, 0x5a, 0x77, 0x3d, 0x3d, 0x0a, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + }}, +}; + +/* + +ECDSA-P256-SHA256 + +ecdsa. IN DNSKEY 256 3 13 8uD7C4THTM/w7uhryRSToeE/jKT78/p853RX0L5EwrZrSLBubLPiBw7g bvUP6SsIga5ZQ4CSAxNmYA/gZsuXzA== +ecdsa. IN DS 5345 13 1 954103ac7c43810ce9f414e80f30ab1cbe49b236 +ecdsa. IN DS 5345 13 2 bac2107036e735b50f85006ce409a19a3438cab272e70769ebda032239a3d0ca +ecdsa. IN DS 5345 13 4 a0ac6790483872be72a258314200a88ab75cdd70f66a18a09f0f414c074df0989fdb1df0e67d82d4312cda67b93a76c1 + +PrivateKey: iyLIPdk3DOIxVmmSYlmTstbtUPiVlEyDX46psyCwNVQ= + +-----BEGIN PRIVATE KEY----- +MIGUAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHoweAIBAQQhAIsiyD3ZNwziMVZp +kmJZk7LW7VD4lZRMg1+OqbMgsDVUoAoGCCqGSM49AwEHoUQDQgAE8uD7C4THTM/w +7uhryRSToeE/jKT78/p853RX0L5EwrZrSLBubLPiBw7gbvUP6SsIga5ZQ4CSAxNm +YA/gZsuXzA== +-----END PRIVATE KEY----- + +*/ + +static const key_parameters_t SAMPLE_ECDSA_KEY = { + .name = (uint8_t *)"\x05""ecdsa", + .flags = 256, + .protocol = 3, + .algorithm = 13, + .public_key = { .size = 64, .data = (uint8_t []) { + 0xf2, 0xe0, 0xfb, 0x0b, 0x84, 0xc7, 0x4c, 0xcf, 0xf0, 0xee, + 0xe8, 0x6b, 0xc9, 0x14, 0x93, 0xa1, 0xe1, 0x3f, 0x8c, 0xa4, + 0xfb, 0xf3, 0xfa, 0x7c, 0xe7, 0x74, 0x57, 0xd0, 0xbe, 0x44, + 0xc2, 0xb6, 0x6b, 0x48, 0xb0, 0x6e, 0x6c, 0xb3, 0xe2, 0x07, + 0x0e, 0xe0, 0x6e, 0xf5, 0x0f, 0xe9, 0x2b, 0x08, 0x81, 0xae, + 0x59, 0x43, 0x80, 0x92, 0x03, 0x13, 0x66, 0x60, 0x0f, 0xe0, + 0x66, 0xcb, 0x97, 0xcc, + }}, + .rdata = { .size = 68, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x0d, + 0xf2, 0xe0, 0xfb, 0x0b, 0x84, 0xc7, 0x4c, 0xcf, 0xf0, 0xee, + 0xe8, 0x6b, 0xc9, 0x14, 0x93, 0xa1, 0xe1, 0x3f, 0x8c, 0xa4, + 0xfb, 0xf3, 0xfa, 0x7c, 0xe7, 0x74, 0x57, 0xd0, 0xbe, 0x44, + 0xc2, 0xb6, 0x6b, 0x48, 0xb0, 0x6e, 0x6c, 0xb3, 0xe2, 0x07, + 0x0e, 0xe0, 0x6e, 0xf5, 0x0f, 0xe9, 0x2b, 0x08, 0x81, 0xae, + 0x59, 0x43, 0x80, 0x92, 0x03, 0x13, 0x66, 0x60, 0x0f, 0xe0, + 0x66, 0xcb, 0x97, 0xcc, + }}, + .keytag = 5345, + .key_id = "47fd10011e76cc6741af586041eae5519465fc8d", + .ds_sha1 = { .size = 24, .data = (uint8_t []) { + 0x14, 0xe1, 0x0d, 0x01, + 0x95, 0x41, 0x03, 0xac, 0x7c, 0x43, 0x81, 0x0c, 0xe9, 0xf4, + 0x14, 0xe8, 0x0f, 0x30, 0xab, 0x1c, 0xbe, 0x49, 0xb2, 0x36, + }}, + .ds_sha256 = { .size = 36, .data = (uint8_t []) { + 0x14, 0xe1, 0x0d, 0x02, + 0xba, 0xc2, 0x10, 0x70, 0x36, 0xe7, 0x35, 0xb5, 0x0f, 0x85, + 0x00, 0x6c, 0xe4, 0x09, 0xa1, 0x9a, 0x34, 0x38, 0xca, 0xb2, + 0x72, 0xe7, 0x07, 0x69, 0xeb, 0xda, 0x03, 0x22, 0x39, 0xa3, + 0xd0, 0xca, + }}, + .ds_sha384 = { .size = 52, .data = (uint8_t []) { + 0x14, 0xe1, 0x0d, 0x04, + 0xa0, 0xac, 0x67, 0x90, 0x48, 0x38, 0x72, 0xbe, 0x72, 0xa2, + 0x58, 0x31, 0x42, 0x00, 0xa8, 0x8a, 0xb7, 0x5c, 0xdd, 0x70, + 0xf6, 0x6a, 0x18, 0xa0, 0x9f, 0x0f, 0x41, 0x4c, 0x07, 0x4d, + 0xf0, 0x98, 0x9f, 0xdb, 0x1d, 0xf0, 0xe6, 0x7d, 0x82, 0xd4, + 0x31, 0x2c, 0xda, 0x67, 0xb9, 0x3a, 0x76, 0xc1, + }}, + .bit_size = 256, + .pem = { .size = 262, .data = (uint8_t []) { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, + 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, + 0x47, 0x55, 0x41, 0x67, 0x45, 0x41, 0x4d, 0x42, 0x4d, 0x47, + 0x42, 0x79, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x41, 0x67, + 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, + 0x41, 0x77, 0x45, 0x48, 0x42, 0x48, 0x6f, 0x77, 0x65, 0x41, + 0x49, 0x42, 0x41, 0x51, 0x51, 0x68, 0x41, 0x49, 0x73, 0x69, + 0x79, 0x44, 0x33, 0x5a, 0x4e, 0x77, 0x7a, 0x69, 0x4d, 0x56, + 0x5a, 0x70, 0x0a, 0x6b, 0x6d, 0x4a, 0x5a, 0x6b, 0x37, 0x4c, + 0x57, 0x37, 0x56, 0x44, 0x34, 0x6c, 0x5a, 0x52, 0x4d, 0x67, + 0x31, 0x2b, 0x4f, 0x71, 0x62, 0x4d, 0x67, 0x73, 0x44, 0x56, + 0x55, 0x6f, 0x41, 0x6f, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, + 0x4d, 0x34, 0x39, 0x41, 0x77, 0x45, 0x48, 0x6f, 0x55, 0x51, + 0x44, 0x51, 0x67, 0x41, 0x45, 0x38, 0x75, 0x44, 0x37, 0x43, + 0x34, 0x54, 0x48, 0x54, 0x4d, 0x2f, 0x77, 0x0a, 0x37, 0x75, + 0x68, 0x72, 0x79, 0x52, 0x53, 0x54, 0x6f, 0x65, 0x45, 0x2f, + 0x6a, 0x4b, 0x54, 0x37, 0x38, 0x2f, 0x70, 0x38, 0x35, 0x33, + 0x52, 0x58, 0x30, 0x4c, 0x35, 0x45, 0x77, 0x72, 0x5a, 0x72, + 0x53, 0x4c, 0x42, 0x75, 0x62, 0x4c, 0x50, 0x69, 0x42, 0x77, + 0x37, 0x67, 0x62, 0x76, 0x55, 0x50, 0x36, 0x53, 0x73, 0x49, + 0x67, 0x61, 0x35, 0x5a, 0x51, 0x34, 0x43, 0x53, 0x41, 0x78, + 0x4e, 0x6d, 0x0a, 0x59, 0x41, 0x2f, 0x67, 0x5a, 0x73, 0x75, + 0x58, 0x7a, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, + 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x0a, + }}, +}; + +/* + * Private-key-format: v1.2 + * Algorithm: 15 (ED25519) + * PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI= + * + * example.com. 3600 IN DNSKEY 256 3 15 ( + * l02Woi0iS8Aa25FQkUd9RMzZHJpBoRQwAQEX1SxZJA4= ) + * + * example.com. 3600 IN DS 3612 15 2 ( + * 3aa5ab37efce57f737fc1627013fee07bdf241bd10f3b1964ab55c78e79 + * a304b ) + * + * example.com. 3600 IN MX 10 mail.example.com. + * + * example.com. 3600 IN RRSIG MX 15 2 3600 ( + * 1440021600 1438207200 3613 example.com. ( + * oL9krJun7xfBOIWcGHi7mag5/hdZrKWw15jPGrHpjQeRAvTdszaPD+QLs3f + * x8A4M3e23mRZ9VrbpMngwcrqNAg== ) + */ + +static const key_parameters_t SAMPLE_ED25519_KEY = { + .name = (uint8_t *)"\x07""ed25519", + .flags = 256, + .protocol = 3, + .algorithm = 15, + .public_key = { .size = 32, .data = (uint8_t []) { + 0x97, 0x4d, 0x96, 0xa2, 0x2d, 0x22, 0x4b, 0xc0, 0x1a, 0xdb, 0x91, 0x50, + 0x91, 0x47, 0x7d, 0x44, 0xcc, 0xd9, 0x1c, 0x9a, 0x41, 0xa1, 0x14, 0x30, + 0x01, 0x01, 0x17, 0xd5, 0x2c, 0x59, 0x24, 0x0e, + }}, + .rdata = { .size = 36, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x0f, + 0x97, 0x4d, 0x96, 0xa2, 0x2d, 0x22, 0x4b, 0xc0, 0x1a, 0xdb, 0x91, 0x50, + 0x91, 0x47, 0x7d, 0x44, 0xcc, 0xd9, 0x1c, 0x9a, 0x41, 0xa1, 0x14, 0x30, + 0x01, 0x01, 0x17, 0xd5, 0x2c, 0x59, 0x24, 0x0e, + }}, + .keytag = 3612, + .key_id = "bea75b99fb22ee1a68106ad6399e4acc43eb9929", + .ds_sha1 = { .size = 24, .data = (uint8_t []) { + 0x0e, 0x1c, 0x0f, 0x01, + 0x50, 0x12, 0x49, 0x72, 0x1e, 0x1f, 0x09, 0xa7, 0x9d, 0x30, 0xd5, 0xc6, + 0xc4, 0xdc, 0xa1, 0xdc, 0x1d, 0xa4, 0xed, 0x5d, + }}, + .ds_sha256 = { .size = 36, .data = (uint8_t []) { + 0x0e, 0x1c, 0x0f, 0x02, + 0x1b, 0x1c, 0x87, 0x66, 0xb2, 0xa9, 0x65, 0x66, 0xff, 0x19, 0x6f, 0x77, + 0xc0, 0xc4, 0x19, 0x4a, 0xf8, 0x6a, 0xaa, 0x10, 0x9c, 0x53, 0x46, 0xff, + 0x60, 0x23, 0x1a, 0x27, 0xd2, 0xb0, 0x7a, 0xc0, + }}, + .ds_sha384 = { .size = 52, .data = (uint8_t []) { + 0x0e, 0x1c, 0x0f, 0x04, + 0xd1, 0x18, 0x31, 0x15, 0x3a, 0xf4, 0x98, 0x5e, 0xfb, 0xd0, 0xae, 0x79, + 0x2c, 0x96, 0x7e, 0xb4, 0xaf, 0xf3, 0xc3, 0x54, 0x88, 0xdb, 0x95, 0xf7, + 0xe2, 0xf8, 0x5d, 0xce, 0xc7, 0x4a, 0xe8, 0xf5, 0x9f, 0x9a, 0x72, 0x64, + 0x17, 0x98, 0xc9, 0x1c, 0x67, 0xc6, 0x75, 0xdb, 0x1d, 0x71, 0x0c, 0x18, + }}, + .bit_size = 256, + .pem = { .size = 119, .data = (uint8_t []) { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x43, 0x34, 0x43, 0x41, 0x51, 0x41, 0x77, + 0x42, 0x51, 0x59, 0x44, 0x4b, 0x32, 0x56, 0x77, 0x42, 0x43, 0x49, 0x45, + 0x49, 0x44, 0x67, 0x79, 0x4d, 0x6a, 0x59, 0x77, 0x4d, 0x7a, 0x67, 0x30, + 0x4e, 0x6a, 0x49, 0x34, 0x4d, 0x44, 0x67, 0x77, 0x4d, 0x54, 0x49, 0x79, + 0x4e, 0x6a, 0x51, 0x31, 0x4d, 0x54, 0x6b, 0x77, 0x4d, 0x6a, 0x41, 0x30, + 0x4d, 0x54, 0x51, 0x79, 0x4d, 0x6a, 0x59, 0x79, 0x0a, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, + 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a + }}, +}; diff --git a/tests/libdnssec/test_binary.c b/tests/libdnssec/test_binary.c new file mode 100644 index 0000000..cab3185 --- /dev/null +++ b/tests/libdnssec/test_binary.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "binary.h" +#include "error.h" + +typedef struct test_string { + const char *encoded; + size_t encoded_size; + const char *decoded; + size_t decoded_size; +} test_string_t; + +static void test_base64(void) +{ + test_string_t data[] = { + { "", 0, "", 0 }, + { "YQ==", 4, "a", 1 }, + { "YWI=", 4, "ab", 2 }, + { "YWJj", 4, "abc", 3 }, + { "YWJjZA==", 8, "abcd", 4 }, + { "YWJjZGU=", 8, "abcde", 5 }, + { "YWJjZGVm", 8, "abcdef", 6 }, + { NULL } + }; + + for (int i = 0; data[i].encoded != NULL; i++) { + test_string_t *ts = &data[i]; + + const dnssec_binary_t base64 = { + .size = ts->encoded_size, + .data = (uint8_t *) ts->encoded + }; + + dnssec_binary_t binary = { 0 }; + + int r = dnssec_binary_from_base64(&base64, &binary); + ok(r == DNSSEC_EOK && + binary.size == ts->decoded_size && + (binary.size == 0 || memcmp(binary.data, ts->decoded, binary.size) == 0), + "dnssec_binary_from_base64() for '%s'", ts->encoded); + + dnssec_binary_t encoded = { 0 }; + r = dnssec_binary_to_base64(&binary, &encoded); + ok(r == DNSSEC_EOK && + encoded.size == ts->encoded_size && + memcmp(encoded.data, ts->encoded, encoded.size) == 0, + "dnssec_binary_to_base64() for '%s'", ts->encoded); + + dnssec_binary_free(&binary); + dnssec_binary_free(&encoded); + } +} + +static void test_dup(void) +{ + dnssec_binary_t src = { .size = 5, .data = (uint8_t *) "ahoj" }; + dnssec_binary_t dst = { 0 }; + + int r = dnssec_binary_dup(&src, &dst); + ok(r == DNSSEC_EOK && + src.size == dst.size && memcmp(src.data, dst.data, src.size) == 0, + "dnssec_binary_dup()"); + + dnssec_binary_free(&dst); +} + +int main(void) +{ + plan_lazy(); + + test_base64(); + test_dup(); + + return 0; +} diff --git a/tests/libdnssec/test_crypto.c b/tests/libdnssec/test_crypto.c new file mode 100644 index 0000000..617637b --- /dev/null +++ b/tests/libdnssec/test_crypto.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include "crypto.h" + +int main(void) +{ + plan_lazy(); + + // not much we can test + + dnssec_crypto_init(); + ok(1, "dnssec_crypto_init() didn't crash"); + + dnssec_crypto_reinit(); + ok(1, "dnssec_crypto_reinit() didn't crash"); + + dnssec_crypto_cleanup(); + ok(1, "dnssec_crypto_cleanup() didn't crash"); + + return 0; +} diff --git a/tests/libdnssec/test_key.c b/tests/libdnssec/test_key.c new file mode 100644 index 0000000..0a73739 --- /dev/null +++ b/tests/libdnssec/test_key.c @@ -0,0 +1,212 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <string.h> + +#include "binary.h" +#include "crypto.h" +#include "error.h" +#include "key.h" + +#include "sample_keys.h" + +#define check_attr_scalar(key, type, name, def_val, set_val) { \ + type value = dnssec_key_get_##name(key); \ + ok(value == def_val, #name " default"); \ + int r = dnssec_key_set_##name(key, set_val); \ + ok(r == DNSSEC_EOK, #name " set"); \ + value = dnssec_key_get_##name(key); \ + ok(value == set_val, #name " get"); \ +} + +static void check_key_tag(dnssec_key_t *key, const key_parameters_t *params) +{ + uint16_t keytag = dnssec_key_get_keytag(key); + ok(keytag == params->keytag, "get keytag"); +} + +static void check_key_size(dnssec_key_t *key, const key_parameters_t *params) +{ + ok(dnssec_key_get_size(key) == params->bit_size, + "key size %u bits", params->bit_size); +} + +static void check_usage(dnssec_key_t *key, bool ok_verify, bool ok_sign) +{ + ok(dnssec_key_can_verify(key) == ok_verify, + "%s verify", ok_verify ? "can" : "cannot"); + ok(dnssec_key_can_sign(key) == ok_sign, + "%s sign", ok_sign ? "can" : "cannot"); +} + +static void test_public_key(const key_parameters_t *params) +{ + dnssec_key_t *key = NULL; + int r = dnssec_key_new(&key); + ok(r == DNSSEC_EOK && key != NULL, "create key"); + + // create from parameters + + r = dnssec_key_set_pubkey(key, ¶ms->public_key); + ok(r == DNSSEC_INVALID_KEY_ALGORITHM, + "set public key (fails, no algorithm set)"); + + check_attr_scalar(key, uint16_t, flags, 256, params->flags); + check_attr_scalar(key, uint8_t, protocol, 3, params->protocol); + check_attr_scalar(key, uint8_t, algorithm, 0, params->algorithm); + + r = dnssec_key_set_pubkey(key, ¶ms->public_key); + ok(r == DNSSEC_EOK, "set public key (succeeds)"); + + r = dnssec_key_set_pubkey(key, ¶ms->public_key); + ok(r == DNSSEC_KEY_ALREADY_PRESENT, + "set public key (fails, already present)"); + + dnssec_binary_t rdata = { 0 }; + r = dnssec_key_get_rdata(key, &rdata); + ok(r == DNSSEC_EOK && dnssec_binary_cmp(&rdata, ¶ms->rdata) == 0, + "get RDATA"); + + check_key_tag(key, params); + + // create from RDATA + + dnssec_key_clear(key); + r = dnssec_key_set_rdata(key, ¶ms->rdata); + ok(r == DNSSEC_EOK, "set RDATA"); + + check_key_tag(key, params); + check_key_size(key, params); + check_usage(key, true, false); + + // create copy + + dnssec_key_t *copy = dnssec_key_dup(key); + ok(copy != NULL, "duplicate key"); + + check_key_tag(copy, params); + check_key_size(copy, params); + check_usage(copy, true, false); + + dnssec_key_free(copy); + dnssec_key_free(key); +} + +static void test_private_key(const key_parameters_t *params) +{ + dnssec_key_t *key = NULL; + int r = dnssec_key_new(&key); + ok(r == DNSSEC_EOK && key != NULL, "create key"); + + // import to public + + r = dnssec_key_set_rdata(key, ¶ms->rdata); + ok(r == DNSSEC_EOK, "set RDATA"); + + r = dnssec_key_load_pkcs8(key, ¶ms->pem); + ok(r == DNSSEC_EOK, "load private key (1)"); + + ok(dnssec_key_can_verify(key), "can verify"); + ok(dnssec_key_can_sign(key), "can sign"); + + // purely from parameters + + dnssec_key_clear(key); + + dnssec_key_set_algorithm(key, params->algorithm); + dnssec_key_set_flags(key, params->flags); + r = dnssec_key_load_pkcs8(key, ¶ms->pem); + ok(r == DNSSEC_EOK, "load private key (2)"); + + dnssec_binary_t rdata = { 0 }; + r = dnssec_key_get_rdata(key, &rdata); + ok(r == DNSSEC_EOK && dnssec_binary_cmp(&rdata, ¶ms->rdata) == 0, + "get RDATA"); + + check_key_tag(key, params); + check_key_size(key, params); + check_usage(key, true, true); + + // create copy + + dnssec_key_t *copy = dnssec_key_dup(key); + ok(copy != NULL, "duplicate key"); + + check_key_tag(copy, params); + check_key_size(copy, params); + check_usage(copy, true, false); + + dnssec_key_free(copy); + dnssec_key_free(key); +} + +static void test_naming(void) +{ + dnssec_key_t *key = NULL; + dnssec_key_new(&key); + + const uint8_t *input = (uint8_t *)"\x07""eXample""\x03""COM"; + const uint8_t *expected = (uint8_t *)"\x07""example""\x03""com"; + size_t expected_size = 13; + + ok(dnssec_key_get_dname(key) == NULL, "implicit key name"); + + dnssec_key_set_dname(key, input); + const uint8_t *output = dnssec_key_get_dname(key); + + ok(strlen((char *)output) + 1 == 13 && + memcmp(output, expected, expected_size) == 0, + "set key name"); + + dnssec_key_set_dname(key, NULL); + ok(dnssec_key_get_dname(key) == NULL, "clear key name"); + + dnssec_key_free(key); +} + +typedef struct keyinfo { + const char *name; + const key_parameters_t *parameters; +} keyinfo_t; + +int main(void) +{ + plan_lazy(); + + dnssec_crypto_init(); + + static const keyinfo_t keys[] = { + { "RSA", &SAMPLE_RSA_KEY }, + { "ECDSA", &SAMPLE_ECDSA_KEY }, +#ifdef HAVE_ED25519 + { "ED25519", &SAMPLE_ED25519_KEY }, +#endif + { NULL } + }; + + for (const keyinfo_t *k = keys; k->name != NULL; k += 1) { + diag("%s key", k->name); + test_public_key(k->parameters); + test_private_key(k->parameters); + } + + test_naming(); + + dnssec_crypto_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_key_algorithm.c b/tests/libdnssec/test_key_algorithm.c new file mode 100644 index 0000000..edffbaa --- /dev/null +++ b/tests/libdnssec/test_key_algorithm.c @@ -0,0 +1,84 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include "error.h" +#include "key.h" + +static void ok_range(dnssec_key_algorithm_t algo, + unsigned exp_min, unsigned exp_max, + const char *name) +{ + unsigned min = 0, max = 0; + int r = dnssec_algorithm_key_size_range(algo, &min, &max); + ok(r == DNSSEC_EOK && min == exp_min && max == exp_max, + "dnssec_algorithm_key_size_range() for %s", name); +} + +static void null_range(void) +{ + dnssec_key_algorithm_t algo = DNSSEC_KEY_ALGORITHM_RSA_SHA256; + unsigned val = 0; + int r; + + r = dnssec_algorithm_key_size_range(algo, NULL, NULL); + ok(r == DNSSEC_EINVAL, "dnssec_algorithm_key_size_range() all null"); + r = dnssec_algorithm_key_size_range(algo, &val, NULL); + ok(r == DNSSEC_EOK && val == 1024, "dnssec_algorithm_key_size_range() min only"); + r = dnssec_algorithm_key_size_range(algo, NULL, &val); + ok(r == DNSSEC_EOK && val == 4096, "dnssec_algorithm_key_size_range() max only"); +} + +static void check_borders(void) +{ + dnssec_key_algorithm_t rsa = DNSSEC_KEY_ALGORITHM_RSA_SHA1; + + ok(dnssec_algorithm_key_size_check(rsa, 1023) == false, "rsa 1023"); + ok(dnssec_algorithm_key_size_check(rsa, 1024) == true, "rsa 1024"); + ok(dnssec_algorithm_key_size_check(rsa, 1025) == true, "rsa 1025"); + ok(dnssec_algorithm_key_size_check(rsa, 4095) == true, "rsa 4095"); + ok(dnssec_algorithm_key_size_check(rsa, 4096) == true, "rsa 4096"); + ok(dnssec_algorithm_key_size_check(rsa, 4097) == false, "rsa 4097"); +} + +static void check_defaults(void) +{ + is_int(2048, dnssec_algorithm_key_size_default(DNSSEC_KEY_ALGORITHM_RSA_SHA1_NSEC3), "rsa default"); + is_int(256, dnssec_algorithm_key_size_default(DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256), "ecc default"); +#ifdef HAVE_ED25519 + is_int(256, dnssec_algorithm_key_size_default(DNSSEC_KEY_ALGORITHM_ED25519), "ed25519 default"); +#endif +} + +int main(void) +{ + plan_lazy(); + + // ranges + ok_range(DNSSEC_KEY_ALGORITHM_RSA_SHA512, 1024, 4096, "RSA/SHA256"); + ok_range(DNSSEC_KEY_ALGORITHM_ECDSA_P384_SHA384, 384, 384, "ECDSA/SHA384"); +#ifdef HAVE_ED25519 + ok_range(DNSSEC_KEY_ALGORITHM_ED25519, 256, 256, "ED25519"); +#endif + null_range(); + + check_borders(); + + check_defaults(); + + return 0; +} diff --git a/tests/libdnssec/test_key_ds.c b/tests/libdnssec/test_key_ds.c new file mode 100644 index 0000000..25d7c9d --- /dev/null +++ b/tests/libdnssec/test_key_ds.c @@ -0,0 +1,116 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> + +#include <stddef.h> +#include <string.h> + +#include "libdnssec/crypto.h" +#include "libdnssec/error.h" +#include "libdnssec/key.h" +#include "sample_keys.h" + +static void test_key(const char *name, const struct key_parameters *params) +{ + dnssec_key_t *key = NULL; + + dnssec_key_new(&key); + dnssec_key_set_dname(key, params->name); + dnssec_key_set_rdata(key, ¶ms->rdata); + + struct ds_type { + const char *name; + dnssec_key_digest_t digest; + size_t params_offset; + }; + + static const struct ds_type DS_TYPES[] = { + { "SHA-1", DNSSEC_KEY_DIGEST_SHA1, offsetof(typeof(*params), ds_sha1) }, + { "SHA-256", DNSSEC_KEY_DIGEST_SHA256, offsetof(typeof(*params), ds_sha256) }, + { "SHA-384", DNSSEC_KEY_DIGEST_SHA384, offsetof(typeof(*params), ds_sha384) }, + { NULL } + }; + + for (const struct ds_type *dt = DS_TYPES; dt->name != NULL; dt++) { + dnssec_binary_t ds = { 0 }; + int r = dnssec_key_create_ds(key, dt->digest, &ds); + + const dnssec_binary_t *expect = (void *)params + dt->params_offset; + + ok(r == DNSSEC_EOK && + ds.size == expect->size && + memcmp(ds.data, expect->data, ds.size) == 0, + "dnssec_key_create_ds() for %s/%s", name, dt->name); + + dnssec_binary_free(&ds); + } + + dnssec_key_free(key); +} + +static void test_errors(const struct key_parameters *params) +{ + dnssec_key_t *key = NULL; + dnssec_binary_t ds = { 0 }; + + int r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, &ds); + is_int(DNSSEC_EINVAL, r, "dnssec_key_create_ds() no key"); + dnssec_binary_free(&ds); + + dnssec_key_new(&key); + r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, &ds); + is_int(DNSSEC_INVALID_KEY_NAME, r, "dnssec_key_create_ds() no key name"); + + dnssec_key_set_dname(key, params->name); + r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, &ds); + is_int(DNSSEC_INVALID_PUBLIC_KEY, r, "dnssec_key_create_ds() no public key"); + + dnssec_key_set_rdata(key, ¶ms->rdata); + r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, NULL); + is_int(DNSSEC_EINVAL, r, "dnssec_key_create_ds() no RDATA buffer"); + + r = dnssec_key_create_ds(key, 3, &ds); + is_int(DNSSEC_INVALID_DS_ALGORITHM, r, "dnssec_key_create_ds() unsupported algorithm"); + + r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, &ds); + is_int(DNSSEC_EOK, r, "dnssec_key_create_ds() valid parameters"); + + dnssec_binary_free(&ds); + dnssec_key_free(key); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + dnssec_crypto_init(); + + test_key("RSA", &SAMPLE_RSA_KEY); + test_key("ECDSA", &SAMPLE_ECDSA_KEY); +#ifdef HAVE_ED25519 + test_key("ED25519", &SAMPLE_ED25519_KEY); +#endif + + test_errors(&SAMPLE_ECDSA_KEY); +#ifdef HAVE_ED25519 + test_errors(&SAMPLE_ED25519_KEY); +#endif + + dnssec_crypto_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_keyid.c b/tests/libdnssec/test_keyid.c new file mode 100644 index 0000000..15bfe98 --- /dev/null +++ b/tests/libdnssec/test_keyid.c @@ -0,0 +1,81 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <stdlib.h> +#include <string.h> + +#include "error.h" +#include "keyid.h" + +static void test_keyid_is_valid_run(const char *param, bool should_ok) +{ + ok(dnssec_keyid_is_valid(param) == should_ok, + "dnssec_keyid_is_valid(\"%s\")", param); +} + +static void test_keyid_is_valid(void) +{ + test_keyid_is_valid_run(NULL, false); + test_keyid_is_valid_run("3e90c5cb1fad5f8512da2028fda3808e749d3bf", false); + test_keyid_is_valid_run("9aa6dAAC706fb6fe4aceb327452a7b5FEA457544", true); + test_keyid_is_valid_run("eac45c184b7f476472c16d5b0c4f0c52389848001", false); + test_keyid_is_valid_run("9aa6daac706fb6fe4aceb32g452a7b5fea457544", false); +} + +static void test_keyid_normalize(void) +{ + char id[] = "3711927404f64CE7df88253d763e442CE39f9B5c"; + const char *id_norm = "3711927404f64ce7df88253d763e442ce39f9b5c"; + + dnssec_keyid_normalize(id); + ok(strcmp(id, id_norm) == 0, "dnssec_keyid_normalize()"); +} + +static void test_keyid_copy(void) +{ + const char *id = "21669f1eca6418f9aBBBf0007e6f73463d467424"; + const char *expected = "21669f1eca6418f9abbbf0007e6f73463d467424"; + + char *copy = dnssec_keyid_copy(id); + ok(copy && strcmp(copy, expected) == 0, "dnssec_keyid_copy()"); + + free(copy); +} + +static void test_keyid_equal(void) +{ + const char *id = "dd63237d4a07867de715499690c9ad12990519f0"; + const char *id_case = "dd63237d4a07867de715499690C9AD12990519F0"; + const char *id_diff = "dd63237d4a07867de715499690c9ad12990519f1"; + + ok(dnssec_keyid_equal(id, NULL) == false, "dnssec_keyid_equal(id, NULL)"); + ok(dnssec_keyid_equal(id, id) == true, "dnssec_keyid_equal(id, id)"); + ok(dnssec_keyid_equal(id, id_case) == true, "dnssec_keyid_equal(id, ID)"); + ok(dnssec_keyid_equal(id, id_diff) == false, "dnssec_keyid_equal(ida, idb)"); +} + +int main(void) +{ + plan_lazy(); + + test_keyid_is_valid(); + test_keyid_normalize(); + test_keyid_copy(); + test_keyid_equal(); + + return 0; +} diff --git a/tests/libdnssec/test_keystore_pkcs11.c b/tests/libdnssec/test_keystore_pkcs11.c new file mode 100644 index 0000000..c83eb82 --- /dev/null +++ b/tests/libdnssec/test_keystore_pkcs11.c @@ -0,0 +1,484 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <tap/files.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include "libdnssec/crypto.h" +#include "libdnssec/error.h" +#include "libdnssec/keystore.h" +#include "libdnssec/sign.h" + +#include "sample_keys.h" + +#define ENV_SOFTHSM_DSO "KNOT_SOFTHSM2_DSO" +#define ENV_SOFTHSM_UTIL "KNOT_SOFTHSM2_UTIL" + +#define SOFTHSM_DSO "libsofthsm2.so" +#define SOFTHSM_CONF "softhsm2.conf" +#define SOFTHSM_CONF_ENV "SOFTHSM2_CONF" +#define SOFTHSM_UTIL "softhsm2-util" + +#define TOKEN_LABEL "libdnssec-test" +#define TOKEN_PIN "1234" +#define TOKEN_SOPIN "123456" + +#define EXIT_EXEC_FAILED 127 + +#ifndef LIBDIR +# include <bits/wordsize.h> +# if __WORDSIZE == 32 +# define LIBDIR "/usr/lib32" +# elif __WORDSIZE == 64 +# define LIBDIR "/usr/lib64" +# endif +#endif + +#define MSG_SOFTWARE "soft -" +#define MSG_PKCS11 "p11 -" + +/*! + * Get SoftHSM DSO path. + */ +static char *libsofthsm_dso(void) +{ + // prefer environment variable + + const char *env = getenv(ENV_SOFTHSM_DSO); + if (env) { + return (env[0] != '\0' ? strdup(env) : NULL); + } + + // autodetection + + static const char *paths[] = { + LIBDIR "/pkcs11/" SOFTHSM_DSO, + LIBDIR "/softhsm/" SOFTHSM_DSO, + LIBDIR "/" SOFTHSM_DSO, + NULL + }; + + for (const char **path_ptr = paths; *path_ptr; path_ptr += 1) { + const char *path = *path_ptr; + if (access(path, R_OK|X_OK) == 0) { + return strdup(path); + } + } + + return NULL; +} + +/*! + * Get SoftHSM utility path. + */ +static char *libsofthsm_util(void) +{ + // prefer environment variable + + const char *env = getenv(ENV_SOFTHSM_UTIL); + if (env && env[0] != '\0') { + return strdup(env); + } + + // fallback, will rely on PATH + + return strdup(SOFTHSM_UTIL); +} + +/*! + * Path to temporary token data. + */ +static char *token_path = NULL; + +/*! + * Cleanup token test data. + */ +static void token_cleanup(void) +{ + test_rm_rf(token_path); + free(token_path); +} + +/*! + * Initialize token using the support tool. + */ +static bool token_init_exec(const char *util) +{ + pid_t child = fork(); + if (child == -1) { + return false; + } + + // child + + if (child == 0) { + fclose(stdin); + fclose(stdout); + fclose(stderr); + + const char *basename = strrchr(util, '/'); + if (basename) { + basename += 1; + } else { + basename = util; + } + + execlp(util, basename, + "--init-token", "--slot=0", "--label=" TOKEN_LABEL, + "--pin=" TOKEN_PIN, "--so-pin=" TOKEN_SOPIN, + NULL); + + exit(EXIT_EXEC_FAILED); + } + + // parent + + int status = 0; + if (waitpid(child, &status, 0) == -1) { + return false; + } + + int exit_code = WIFEXITED(status) ? WEXITSTATUS(status) : -1; + if (exit_code != 0) { + diag("%s exit status %d", util, exit_code); + if (exit_code == EXIT_EXEC_FAILED) { + diag("set %s environment variable to adjust the path", + ENV_SOFTHSM_UTIL); + } + } + + return exit_code == 0; +} + +/*! + * Initialize environment and token for testing. + */ +static bool token_init(void) +{ + token_path = test_mkdtemp(); + if (!token_path) { + return false; + } + + // generate configuration file for unit test + + char config[4096] = { 0 }; + int r = snprintf(config, sizeof(config), "%s/%s", token_path, SOFTHSM_CONF); + if (r <= 0 || r >= sizeof(config)) { + return false; + } + + FILE *file = fopen(config, "w"); + if (!file) { + return false; + } + + fprintf(file, "directories.tokendir = %s\n", token_path); + fprintf(file, "objectstore.backend = file\n"); + fprintf(file, "log.debug = INFO\n"); + + fclose(file); + + // update environment to use the config + + if (setenv(SOFTHSM_CONF_ENV, config, 1) != 0) { + return false; + } + + // initialize token + + char *util = libsofthsm_util(); + if (!util) { + return false; + } + + bool inited = token_init_exec(util); + free(util); + + return inited; +} + +static void create_dnskeys(dnssec_keystore_t *keystore, + dnssec_key_algorithm_t algorithm, const char *id, + dnssec_key_t **p11_key_ptr, dnssec_key_t **soft_key_ptr) +{ + int r; + + // construct PKCS #11 privkey-pubkey key pair + + dnssec_key_t *p11_key = NULL; + r = dnssec_key_new(&p11_key); + ok(r == DNSSEC_EOK && p11_key != NULL, MSG_PKCS11 " dnssec_key_new()"); + + r = dnssec_key_set_algorithm(p11_key, algorithm); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_set_key_algorithm()"); + + r = dnssec_key_import_keystore(p11_key, keystore, id); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_key_import_keystore()"); + + // construct software public key + + dnssec_key_t *soft_key = NULL; + r = dnssec_key_new(&soft_key); + ok(r == DNSSEC_EOK && soft_key != NULL, MSG_SOFTWARE " dnssec_key_new()"); + + dnssec_binary_t rdata = { 0 }; + dnssec_key_get_rdata(p11_key, &rdata); + r = dnssec_key_set_rdata(soft_key, &rdata); + ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_key_set_rdata()"); + + *p11_key_ptr = p11_key; + *soft_key_ptr = soft_key; +} + +static void test_sign(dnssec_key_t *p11_key, dnssec_key_t *soft_key) +{ + int r; + + static const dnssec_binary_t input = { + .data = (uint8_t *)"So Long, and Thanks for All the Fish.", + .size = 37 + }; + + dnssec_binary_t sign = { 0 }; + + // usage constraints + + ok(dnssec_key_can_sign(p11_key), MSG_PKCS11 " dnssec_key_can_sign()"); + ok(dnssec_key_can_verify(p11_key), MSG_PKCS11 " dnssec_key_can_verify()"); + + ok(!dnssec_key_can_sign(soft_key), MSG_SOFTWARE " dnssec_key_can_sign()"); + ok(dnssec_key_can_verify(soft_key), MSG_SOFTWARE " dnssec_key_can_verify()"); + + // PKCS #11 key signature + + dnssec_sign_ctx_t *ctx = NULL; + r = dnssec_sign_new(&ctx, p11_key); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_init() "); + + r = dnssec_sign_add(ctx, &input); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_add()"); + + r = dnssec_sign_write(ctx, &sign); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_write()"); + + // PKCS #11 key verification + + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_init()"); + + r = dnssec_sign_add(ctx, &input); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_add()"); + + r = dnssec_sign_verify(ctx, &sign); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_verify()"); + + // software verification + + dnssec_sign_free(ctx); + ctx = NULL; + + r = dnssec_sign_new(&ctx, soft_key); + ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_init()"); + + r = dnssec_sign_add(ctx, &input); + ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_add()"); + + r = dnssec_sign_verify(ctx, &sign); + ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_verify()"); + + dnssec_binary_free(&sign); + dnssec_sign_free(ctx); +} + +static void test_key_use(dnssec_keystore_t *store, + dnssec_key_algorithm_t algorithm, + const char *keyid) +{ + dnssec_key_t *p11_key = NULL; + dnssec_key_t *soft_key = NULL; + + create_dnskeys(store, algorithm, keyid, &p11_key, &soft_key); + test_sign(p11_key, soft_key); + + dnssec_key_free(p11_key); + dnssec_key_free(soft_key); +} + +static void test_algorithm(dnssec_keystore_t *store, + const key_parameters_t *params) +{ + char *id_generate = NULL; + char *id_import = NULL; + + int r; + + diag("algorithm %d, generated key", params->algorithm); + + r = dnssec_keystore_generate_key(store, params->algorithm, params->bit_size, &id_generate); + ok(r == DNSSEC_EOK && id_generate != NULL, "dnssec_keystore_generate_key()"); + test_key_use(store, params->algorithm, id_generate); + + diag("algorithm %d, imported key", params->algorithm); + + r = dnssec_keystore_import(store, ¶ms->pem, &id_import); + ok(r == DNSSEC_EOK && id_import != NULL, "dnssec_keystore_import()"); + test_key_use(store, params->algorithm, id_import); + + free(id_generate); + free(id_import); +} + +static void test_key_listing(dnssec_keystore_t *store, + const key_parameters_t **key_params, int count) +{ + dnssec_list_t *keys = NULL; + int r = dnssec_keystore_list_keys(store, &keys); + ok(r == DNSSEC_EOK && dnssec_list_size(keys) == count * 2, + "dnssec_keystore_list_keys(), two keys per algorithm"); + + bool imported_found[count]; + for (int i = 0; i < count; i++) { + imported_found[i] = false; + } + + dnssec_list_foreach(item, keys) { + const char *id = dnssec_item_get(item); + for (int i = 0; i < count; i++) { + if (strcmp(id, key_params[i]->key_id) == 0) { + imported_found[i] = true; + break; + } + } + } + + int imported_count = 0; + for (int i = 0; i < count; i++) { + imported_count += imported_found[i] ? 1 : 0; + } + + ok(imported_count == count, "list contains key for all algorithms"); + dnssec_list_free_full(keys, NULL, NULL); + + // key removal + + assert(count > 0); + const key_parameters_t *key_remove = key_params[0]; + + r = dnssec_keystore_remove_key(store, key_remove->key_id); + ok(r == DNSSEC_EOK, "dnssec_keystore_remove_key"); + + keys = NULL; + r = dnssec_keystore_list_keys(store, &keys); + ok(r == DNSSEC_EOK && dnssec_list_size(keys) == count * 2 - 1, + "dnssec_keystore_list_keys(), one less key than before"); + + bool removed_found = false; + dnssec_list_foreach(item, keys) { + const char *id = dnssec_item_get(item); + if (strcmp(id, key_remove->key_id) == 0) { + removed_found = true; + break; + } + } + + ok(!removed_found, "dnssec_keystore_list_keys(), removed key not found"); + + dnssec_list_free_full(keys, NULL, NULL); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + dnssec_crypto_init(); + + // PKCS #11 initialization + + dnssec_keystore_t *store = NULL; + int r = dnssec_keystore_init_pkcs11(&store); + if (r == DNSSEC_NOT_IMPLEMENTED_ERROR) { + skip_all("not supported"); + goto done; + } + ok(r == DNSSEC_EOK && store, "dnssec_keystore_init_pkcs11()"); + + char *dso_name = libsofthsm_dso(); + if (!dso_name) { + skip_all("%s not found, set %s environment variable", + SOFTHSM_DSO, ENV_SOFTHSM_DSO); + goto done; + } + ok(dso_name != NULL, "find token DSO"); + + bool success = token_init(); + if (!success) { + skip_all("failed to configure and initialize the token"); + goto done; + } + ok(success, "initialize the token"); + + char config[4096] = { 0 }; + r = snprintf(config, sizeof(config), "pkcs11:token=%s;pin-value=%s %s", + TOKEN_LABEL, TOKEN_PIN, dso_name); + free(dso_name); + ok(r > 0 && r < sizeof(config), "build configuration"); + + // key store access + + r = dnssec_keystore_init(store, config); + ok(r == DNSSEC_EOK, "dnssec_keystore_init()"); + + r = dnssec_keystore_open(store, config); + ok(r == DNSSEC_EOK, "dnssec_keystore_open()"); + + dnssec_list_t *keys = NULL; + r = dnssec_keystore_list_keys(store, &keys); + ok(r == DNSSEC_EOK && dnssec_list_size(keys) == 0, "dnssec_keystore_list_keys(), empty"); + dnssec_list_free_full(keys, NULL, NULL); + + // key manipulation + + static const int KEYS_COUNT = 2; + static const key_parameters_t *KEYS[] = { + &SAMPLE_RSA_KEY, + &SAMPLE_ECDSA_KEY, + }; + assert(KEYS_COUNT == sizeof(KEYS) / sizeof(*KEYS)); + + for (int i = 0; i < KEYS_COUNT; i++) { + test_algorithm(store, KEYS[i]); + } + + test_key_listing(store, KEYS, KEYS_COUNT); + + r = dnssec_keystore_close(store); + ok(r == DNSSEC_EOK, "dnssec_keystore_close()"); +done: + dnssec_keystore_deinit(store); + dnssec_crypto_cleanup(); + token_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_keystore_pkcs8.c b/tests/libdnssec/test_keystore_pkcs8.c new file mode 100644 index 0000000..b7c74e7 --- /dev/null +++ b/tests/libdnssec/test_keystore_pkcs8.c @@ -0,0 +1,219 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> +#include <tap/basic.h> +#include <stdbool.h> + +#include "binary.h" +#include "crypto.h" +#include "error.h" +#include "key.h" +#include "keyid.h" +#include "keystore.h" + +/* -- mock key store ------------------------------------------------------- */ + +static void *test_handle = (void *)0x42; + +static bool test_handle_new_ok = false; +static int test_handle_new(void **handle_ptr) +{ + if (handle_ptr) { + *handle_ptr = test_handle; + test_handle_new_ok = true; + } + + return DNSSEC_EOK; +} + +static bool test_handle_free_ok = false; +static int test_handle_free(void *handle) +{ + test_handle_free_ok = (handle == test_handle); + + return DNSSEC_EOK; +} + +static bool test_init_ok = false; +static int test_init(void *handle, const char *config) +{ + test_init_ok = (handle == test_handle && config && strcmp(config, "init config") == 0); + + return DNSSEC_EOK; +} + +static bool test_open_ok = false; +static int test_open(void *handle, const char *config) +{ + test_open_ok = (handle == test_handle && config && strcmp(config, "open config") == 0); + + return DNSSEC_EOK; +} + +static bool test_close_ok = false; +static int test_close(void *handle) +{ + test_close_ok = (handle == test_handle); + + return DNSSEC_EOK; +} + +static bool test_write_ok = false; +static char *test_write_id = NULL; +static dnssec_binary_t test_write_pem = { 0 }; +static int test_write(void *handle, const char *id, const dnssec_binary_t *pem) +{ + if (handle == test_handle && id && pem) { + test_write_ok = true; + test_write_id = dnssec_keyid_copy(id); + dnssec_binary_dup(pem, &test_write_pem); + } + + return DNSSEC_EOK; +} + +static bool test_read_ok = false; +static char *test_read_id = NULL; +static int test_read(void *handle, const char *id, dnssec_binary_t *pem) +{ + if (handle == test_handle && id && pem) { + test_read_ok = true; + test_read_id = dnssec_keyid_copy(id); + dnssec_binary_dup(&test_write_pem, pem); + } + + return DNSSEC_EOK; +} + +static bool test_list_ok = false; +static int test_list(void *handle, dnssec_list_t **list_ptr) +{ + if (handle == test_handle && list_ptr) { + test_list_ok = true; + } + + if (list_ptr) { + *list_ptr = dnssec_list_new(); + } + + return DNSSEC_EOK; +} + +static bool test_remove_ok = false; +static char *test_remove_id = NULL; +static int test_remove(void *handle, const char *id) +{ + test_remove_ok = (handle == test_handle && id); + test_remove_id = dnssec_keyid_copy(id); + + return DNSSEC_EOK; +} + +static const dnssec_keystore_pkcs8_functions_t test_store = { + .handle_new = test_handle_new, + .handle_free = test_handle_free, + .init = test_init, + .open = test_open, + .close = test_close, + .read = test_read, + .write = test_write, + .list = test_list, + .remove = test_remove, +}; + +/* -- test plan ------------------------------------------------------------ */ + +int main(void) +{ + plan_lazy(); + + dnssec_crypto_init(); + + int r = 0; + + // create/init/open + + dnssec_keystore_t *store = NULL; + r = dnssec_keystore_init_pkcs8_custom(&store, &test_store); + ok(r == DNSSEC_EOK, "dnssec_keystore_init_pkcs8_custom()"); + ok(test_handle_new_ok, "test_handle_new_ok() called"); + + r = dnssec_keystore_init(store, "init config"); + ok(r == DNSSEC_EOK, "dnssec_keystore_init()"); + ok(test_init_ok, "test_init() called"); + + r = dnssec_keystore_open(store, "open config"); + ok(r == DNSSEC_EOK && test_open_ok, "dnssec_keystore_open()"); + ok(test_open_ok, "test_open() called"); + + // write + + char *gen_id = NULL; + r = dnssec_keystore_generate_key(store, DNSSEC_KEY_ALGORITHM_RSA_SHA256, + 1024, &gen_id); + ok(r == DNSSEC_EOK, "dnssec_keystore_generate_key()"); + ok(test_write_ok, "test_write() called"); + is_string(gen_id, test_write_id, "test_write() correct key ID"); + + // read + + dnssec_key_t *key = NULL; + dnssec_key_new(&key); + dnssec_key_set_algorithm(key, DNSSEC_KEY_ALGORITHM_RSA_SHA256); + r = dnssec_key_import_keystore(key, store, gen_id); + ok(r == DNSSEC_EOK, "dnssec_key_import_keystore()"); + ok(test_read_ok, "test_read() called"); + is_string(gen_id, test_read_id, "test_read() correct key ID"); + dnssec_key_free(key); + + // remove + + r = dnssec_keystore_remove_key(store, gen_id); + ok(r == DNSSEC_EOK, "dnssec_keystore_remove_key()"); + ok(test_remove_ok, "test_remove() called"); + is_string(gen_id, test_remove_id, "test_remove() correct key ID"); + + // close + + r = dnssec_keystore_close(store); + ok(r == DNSSEC_EOK, "dnssec_keystore_clse()"); + ok(test_close_ok, "test_close() called"); + + // list + + dnssec_list_t *list = NULL; + r = dnssec_keystore_list_keys(store, &list); + ok(r == DNSSEC_EOK, "dnssec_keystore_list_keys()"); + ok(test_list_ok, "test_list() called"); + ok(list && dnssec_list_size(list) == 0, "dnssec_list() correct output"); + dnssec_list_free(list); + + // cleanup + + dnssec_keystore_deinit(store); + ok(test_handle_free_ok, "test_handle_free() called"); + + dnssec_crypto_cleanup(); + + free(gen_id); + free(test_write_id); + dnssec_binary_free(&test_write_pem); + free(test_read_id); + free(test_remove_id); + + return 0; +} diff --git a/tests/libdnssec/test_keystore_pkcs8_dir.c b/tests/libdnssec/test_keystore_pkcs8_dir.c new file mode 100644 index 0000000..124b8c3 --- /dev/null +++ b/tests/libdnssec/test_keystore_pkcs8_dir.c @@ -0,0 +1,151 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <string.h> +#include <tap/basic.h> +#include <unistd.h> + +#include "binary.h" +#include "error.h" +#include "key.h" +#include "keystore.h" +#include "keystore/pkcs8_dir.c" + +typedef struct test_pem { + const char *id; + dnssec_binary_t data; +} test_pem_t; + +extern const dnssec_keystore_pkcs8_functions_t PKCS8_DIR_FUNCTIONS; + +const test_pem_t TEST_PEM_A = { + "7b0c9f6a59b1c76b26ed93ea8684f300821eee41", + { .size = 5, .data = (uint8_t *)"hello" } +}; + +const test_pem_t TEST_PEM_B = { + "f4f3e73cf4ee605993c2ef2d790571ade827244c", + { .size = 4, .data = (uint8_t *)"knot" } +}; + +static void rm(const char *dir, const char *file) +{ + char buffer[4096] = { 0 }; + int r = snprintf(buffer, 4096, "%s/%s", dir, file); + if (r < 0) { + ok(0, "rm"); + return; + } + + r = unlink(buffer); + ok(r == 0, "rm %s", buffer); +} + +int main(void) +{ + plan_lazy(); + + int r = 0; + void *handle = NULL; + dnssec_binary_t bin = { 0 }; + + char *dir = test_tmpdir(); + if (!dir) { + return 1; + } + + // create context + + const dnssec_keystore_pkcs8_functions_t *func = &PKCS8_DIR_FUNCTIONS; + + r = func->handle_new(&handle); + ok(r == DNSSEC_EOK && handle != NULL, "new handle"); + + r = func->init(handle, dir); + ok(r == DNSSEC_EOK, "init"); + + r = func->open(handle, dir); + ok(r == DNSSEC_EOK, "open"); + + // non-existent reads + + r = func->read(handle, TEST_PEM_A.id, &bin); + ok(r == DNSSEC_ENOENT && bin.size == 0, "read non-existent"); + + // writing new content + + r = func->write(handle, TEST_PEM_A.id, &TEST_PEM_A.data); + ok(r == DNSSEC_EOK, "write A"); + + r = func->write(handle, TEST_PEM_B.id, &TEST_PEM_B.data); + ok(r == DNSSEC_EOK, "write B"); + + r = func->write(handle, TEST_PEM_A.id, &TEST_PEM_A.data); + ok(r == DNSSEC_EOK, "write A (duplicate)"); + + // content listing + + dnssec_list_t *list = NULL; + r = func->list(handle, &list); + ok(r == DNSSEC_EOK, "get list"); + is_int(2, dnssec_list_size(list), "list size"); + + bool found_a = false; + bool found_b = false; + dnssec_list_foreach(item, list) { + char *id = dnssec_item_get(item); + if (id && strcmp(TEST_PEM_A.id, id) == 0) { found_a = true; } + if (id && strcmp(TEST_PEM_B.id, id) == 0) { found_b = true; } + } + ok(found_a && found_b, "list content"); + + dnssec_list_free_full(list, NULL, NULL); + + // reading existing content + + r = func->read(handle, TEST_PEM_A.id, &bin); + ok(r == DNSSEC_EOK && dnssec_binary_cmp(&TEST_PEM_A.data, &bin) == 0, + "read A"); + dnssec_binary_free(&bin); + + r = func->read(handle, TEST_PEM_B.id, &bin); + ok(r == DNSSEC_EOK && dnssec_binary_cmp(&TEST_PEM_B.data, &bin) == 0, + "read B"); + dnssec_binary_free(&bin); + + // content removal + + r = func->remove(handle, TEST_PEM_A.id); + ok(r == DNSSEC_EOK, "remove A"); + + r = func->read(handle, TEST_PEM_A.id, &bin); + ok(r == DNSSEC_ENOENT && bin.size == 0, "read removed"); + + // cleanup + + r = func->close(handle); + ok(r == DNSSEC_EOK, "close"); + + r = func->handle_free(handle); + ok(r == DNSSEC_EOK, "free handle"); + + rm(dir, "f4f3e73cf4ee605993c2ef2d790571ade827244c.pem"); + + test_tmpdir_free(dir); + + return 0; +} diff --git a/tests/libdnssec/test_keytag.c b/tests/libdnssec/test_keytag.c new file mode 100644 index 0000000..f71426e --- /dev/null +++ b/tests/libdnssec/test_keytag.c @@ -0,0 +1,61 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <stdint.h> + +#include "binary.h" +#include "error.h" +#include "keytag.h" + +int main(void) +{ + plan_lazy(); + + const dnssec_binary_t rsa_md5_rdata = { .size = 72, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x01, + 0x03, 0x01, 0x00, 0x01, 0xa6, 0x83, 0x41, 0x42, 0x58, 0x1b, + 0xc2, 0xa7, 0xc7, 0xd5, 0xef, 0xb5, 0x6c, 0xec, 0x34, 0xc5, + 0xc9, 0x5e, 0x84, 0xa8, 0x35, 0x4a, 0xe0, 0xc2, 0x70, 0xf5, + 0x40, 0xe9, 0x92, 0x06, 0x70, 0x45, 0x88, 0xd3, 0x86, 0xcf, + 0xf5, 0xff, 0x83, 0x08, 0x06, 0x98, 0xe7, 0x8a, 0xa9, 0x2c, + 0xe7, 0xe1, 0x4d, 0xa6, 0x46, 0xef, 0x3a, 0x96, 0x93, 0x8c, + 0xc1, 0x02, 0x00, 0x6f, 0x31, 0x9f, 0xa2, 0x1d + }}; + + uint16_t tag = 0; + ok(dnssec_keytag(&rsa_md5_rdata, &tag) == DNSSEC_EOK && tag == 40866, + "keytag for RSA/MD5"); + + const dnssec_binary_t ecdsa_rdata = { .size = 100, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x0e, + 0xbe, 0x8f, 0x42, 0x92, 0x34, 0xa0, 0x06, 0x5f, 0x18, 0xa1, + 0x15, 0x01, 0x84, 0x50, 0x33, 0x1f, 0x44, 0xa2, 0xbb, 0x61, + 0x2a, 0xc8, 0x86, 0x9c, 0xf3, 0x4b, 0x2e, 0xf9, 0x63, 0xd1, + 0x81, 0x72, 0x56, 0x96, 0xc7, 0x67, 0x34, 0xa1, 0x55, 0xc2, + 0xf3, 0x1d, 0x03, 0xbe, 0x1b, 0x39, 0xeb, 0xa7, 0xb8, 0x2c, + 0x72, 0x2e, 0x58, 0x75, 0x56, 0x42, 0x0b, 0x6f, 0x21, 0xa2, + 0x33, 0xf4, 0x21, 0x00, 0xb7, 0x0f, 0x5a, 0xf7, 0x1a, 0xf0, + 0xe9, 0x94, 0xfa, 0x43, 0xb0, 0x4a, 0x48, 0xb8, 0x64, 0x89, + 0x7b, 0xc9, 0xe0, 0xf7, 0x97, 0x52, 0xf4, 0x85, 0x0f, 0xb4, + 0xf4, 0xfc, 0xe2, 0x10, 0xd4, 0x26 + }}; + + ok(dnssec_keytag(&ecdsa_rdata, &tag) == DNSSEC_EOK && tag == 61768, + "keytag for ECDSA/SHA384"); + + return 0; +} diff --git a/tests/libdnssec/test_list.c b/tests/libdnssec/test_list.c new file mode 100644 index 0000000..cd0a060 --- /dev/null +++ b/tests/libdnssec/test_list.c @@ -0,0 +1,127 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdint.h> +#include <tap/basic.h> + +#include "list.h" + +static void * const free_context = (void *)0xcafe; +static int counter = 0; + +static void item_free(void *pointer, void *data) +{ + if (pointer && data == free_context) { + counter += 1; + } +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* new list */ + + dnssec_list_t *list = dnssec_list_new(); + ok(list != NULL, "create new list"); + + ok(dnssec_list_size(list) == 0, "new list has zero size"); + ok(dnssec_list_is_empty(list), "new list is empty"); + ok(dnssec_list_head(list) == NULL, "new list has no head"); + ok(dnssec_list_tail(list) == NULL, "new list has no tail"); + + /* populate the list */ + + dnssec_list_append(list, (void *)7); + dnssec_list_append(list, (void *)9); + // 7, 9 + + dnssec_list_prepend(list, (void *)5); + dnssec_list_prepend(list, (void *)2); + // 2, 5, 7, 9 + + dnssec_item_t *head = dnssec_list_head(list); + dnssec_list_insert_before(head, (void *)1); + dnssec_list_insert_after(head, (void *)3); + // 1, 2, 3, 5, 7, 9 + + dnssec_item_t *tail = dnssec_list_tail(list); + dnssec_list_insert_before(tail, (void *)8); + dnssec_list_insert_after(tail, (void *)10); + // 1, 2, 3, 5, 7, 8, 9, 10 + + dnssec_item_t *item_5 = dnssec_list_nth(list, 3); + dnssec_list_insert_before(item_5, (void *)4); + dnssec_list_insert_after(item_5, (void *)6); + // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + + ok(dnssec_list_size(list) == 10, "populated list has expected size"); + ok(!dnssec_list_is_empty(list), "populated list is non-empty"); + + // content iteration + + int sum = 0; + int previous = 0; + bool increasing = true; + + for (dnssec_item_t *i = dnssec_list_head(list); i; i = dnssec_list_next(list, i)) { + int number = (int)(intptr_t)dnssec_item_get(i); + sum += number; + + if (previous + 1 != number) { + increasing = false; + } + + previous = number; + } + + ok(sum == 55, "all items are in the list"); + ok(increasing, "append and prepend work"); + + // content lookup + + ok(dnssec_list_contains(list, (void *)7), "contains: positive"); + ok(!dnssec_list_contains(list, (void *)17), "contains: negative"); + + ok(dnssec_list_search(list, (void *)3) == dnssec_list_nth(list, 2), "search: positive"); + ok(dnssec_list_search(list, (void *)12) == NULL, "search: negative"); + + // item removal + + dnssec_list_remove(dnssec_list_head(list)); + dnssec_list_remove(dnssec_list_tail(list)); + dnssec_list_remove(dnssec_list_nth(list, 5)); + + ok(dnssec_list_size(list) == 7, "three items removed"); + + // full free + + counter = 0; + dnssec_list_free_full(list, item_free, free_context); + ok(counter == 7, "list full free"); + + // non-full free + + list = dnssec_list_new(); + dnssec_list_append(list, NULL); + ok(!dnssec_list_is_empty(list), "new list with one item"); + + counter = 0; + dnssec_list_free(list); + ok(counter == 0, "list non-full free"); + + return 0; +} diff --git a/tests/libdnssec/test_nsec_bitmap.c b/tests/libdnssec/test_nsec_bitmap.c new file mode 100644 index 0000000..37676fe --- /dev/null +++ b/tests/libdnssec/test_nsec_bitmap.c @@ -0,0 +1,102 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> + +#include "nsec.h" +#include "libknot/descriptor.h" + +#define TEST_BITMAP_SIZE 18 + +int main(void) +{ + plan_lazy(); + + // Which rrtypes will be contained in the bitmap. + int test_contains_count = 8; + enum knot_rr_type test_contains[] = { + KNOT_RRTYPE_A, + KNOT_RRTYPE_NS, + KNOT_RRTYPE_SOA, + KNOT_RRTYPE_RRSIG, + KNOT_RRTYPE_NSEC, + KNOT_RRTYPE_DNSKEY, + KNOT_RRTYPE_SPF, + KNOT_RRTYPE_CAA + }; + + // Which rrtypes will not be contained in the bitmap. + int test_not_contains_count = 4; + enum knot_rr_type test_not_contains[] = { + KNOT_RRTYPE_AAAA, + KNOT_RRTYPE_MX, + KNOT_RRTYPE_AXFR, + KNOT_RRTYPE_CNAME + }; + + // Allocate new bitmap. + dnssec_nsec_bitmap_t *bitmap = dnssec_nsec_bitmap_new(); + ok(bitmap != NULL, "allocate bitmap"); + if (!bitmap) { + return 1; + } + + // Add the desired RR types to bitmap. + for (int i = 0; i < test_contains_count; i++) { + dnssec_nsec_bitmap_add(bitmap, test_contains[i]); + } + + size_t size = dnssec_nsec_bitmap_size(bitmap); + ok(size == TEST_BITMAP_SIZE, "valid bitmap size"); + if (size != TEST_BITMAP_SIZE) { + dnssec_nsec_bitmap_free(bitmap); + return 1; + } + + const uint8_t expected[TEST_BITMAP_SIZE] = { + 0x00, 0x0D, 0x62, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x01, 0x01, 0x40 + }; + uint8_t encoded[TEST_BITMAP_SIZE] = { 0 }; + dnssec_nsec_bitmap_write(bitmap, encoded); + + ok(memcmp(encoded, expected, TEST_BITMAP_SIZE) == 0, "valid bitmap"); + + // Test contained types. + char rrtype_str[50]; + for (int i = 0; i < test_contains_count; i++) { + bool contains = dnssec_nsec_bitmap_contains(encoded, size, test_contains[i]); + (void)knot_rrtype_to_string(test_contains[i], rrtype_str, 50); + ok(contains, "bitmap contains %s", rrtype_str); + } + + // Test not contained types. + for (int i = 0; i < test_not_contains_count; i++) { + bool contains = dnssec_nsec_bitmap_contains(encoded, size, test_not_contains[i]); + (void)knot_rrtype_to_string(test_not_contains[i], rrtype_str, 50); + ok(!contains, "bitmap does not contain %s", rrtype_str); + } + + dnssec_nsec_bitmap_clear(bitmap); + ok(dnssec_nsec_bitmap_size(bitmap) == 0, "bitmap clear"); + + dnssec_nsec_bitmap_free(bitmap); + return 0; +} diff --git a/tests/libdnssec/test_nsec_hash.c b/tests/libdnssec/test_nsec_hash.c new file mode 100644 index 0000000..47e4501 --- /dev/null +++ b/tests/libdnssec/test_nsec_hash.c @@ -0,0 +1,114 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <tap/basic.h> + +#include "crypto.h" +#include "error.h" +#include "nsec.h" + +static const dnssec_binary_t RDATA = { .size = 9, .data = (uint8_t []) { + 0x01, // algorithm + 0x00, // flags + 0x00, 0x0a, // iterations + 0x04, // salt length + 'a', 'b', 'c', 'd' // salt +}}; + +static void test_length(void) +{ + ok(dnssec_nsec3_hash_length(DNSSEC_NSEC3_ALGORITHM_SHA1) == 20, + "dnssec_nsec3_hash_length() for SHA1"); +} + +static void test_parsing(void) +{ + + dnssec_nsec3_params_t params = { 0 }; + int result = dnssec_nsec3_params_from_rdata(¶ms, &RDATA); + ok(result == DNSSEC_EOK, "dnssec_nsec3_params_from_rdata()"); + + ok(params.algorithm == 1, "algorithm"); + ok(params.flags == 0, "flags"); + ok(params.iterations == 10, "iterations"); + ok(params.salt.size == 4, "salt length"); + ok(params.salt.data != NULL && memcmp(params.salt.data, "abcd", 4) == 0, + "salt content"); + + dnssec_nsec3_params_free(¶ms); + ok(params.salt.data == NULL, "dnssec_nsec3_params_free()"); +} + +static void test_hashing(void) +{ + const dnssec_binary_t dname = { + .size = 13, + .data = (uint8_t *) "\x08""knot-dns""\x02""cz" + }; + + const dnssec_nsec3_params_t params = { + .algorithm = DNSSEC_NSEC3_ALGORITHM_SHA1, + .flags = 0, + .iterations = 7, + .salt = { .size = 14, .data = (uint8_t *) "happywithnsec3" } + }; + + const dnssec_binary_t expected = { .size = 20, .data = (uint8_t []) { + 0x72, 0x40, 0x55, 0x83, 0x92, 0x93, 0x95, 0x28, 0xee, 0xa2, + 0xcc, 0xe1, 0x13, 0xbe, 0xcd, 0x41, 0xee, 0x8a, 0x71, 0xfd + }}; + + dnssec_binary_t hash = { 0 }; + + int result = dnssec_nsec3_hash(&dname, ¶ms, &hash); + ok(result == DNSSEC_EOK, "dnssec_nsec3_hash()"); + + ok(hash.size == expected.size && hash.data != NULL && + memcmp(hash.data, expected.data, expected.size) == 0, + "valid hash"); + + dnssec_binary_free(&hash); +} + +static void test_clear(void) +{ + const dnssec_nsec3_params_t empty = { 0 }; + dnssec_nsec3_params_t params = { 0 }; + + int result = dnssec_nsec3_params_from_rdata(¶ms, &RDATA); + ok(result == DNSSEC_EOK, "dnssec_nsec3_params_from_rdata()"); + + ok(memcmp(¶ms, &empty, sizeof(dnssec_nsec3_params_t)) != 0, + "non-empty after dnssec_nsec3_params_from_rdata()"); + + dnssec_nsec3_params_free(¶ms); + + ok(memcmp(¶ms, &empty, sizeof(dnssec_nsec3_params_t)) == 0, + "cleared after dnssec_nsec3_params_free()"); +} + +int main(void) +{ + plan_lazy(); + + test_length(); + test_parsing(); + test_hashing(); + test_clear(); + + return 0; +} diff --git a/tests/libdnssec/test_random.c b/tests/libdnssec/test_random.c new file mode 100644 index 0000000..7c86aa6 --- /dev/null +++ b/tests/libdnssec/test_random.c @@ -0,0 +1,82 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "crypto.h" +#include "error.h" +#include "random.h" + +int check_buffer(void) +{ + const size_t buffer_size = 128; + uint8_t buffer_prev[buffer_size]; + memset(buffer_prev, 0, buffer_size); + uint8_t buffer[buffer_size]; + memset(buffer, 0, buffer_size); + + for (int i = 0; i < 10; i++) { + int result = dnssec_random_buffer(buffer, buffer_size); + if (result != DNSSEC_EOK) { + return 1; + } + + if (memcmp(buffer, buffer_prev, buffer_size) == 0) { + return 1; + } + + memmove(buffer_prev, buffer, buffer_size); + } + + return 0; +} + +int check_random_type(void) +{ + uint16_t numbers[1000] = { 0 }; + int conflicts = 0; + + for (int i = 0; i < 1000; i++) { + numbers[i] = dnssec_random_uint16_t(); + // check all previous + for (int j = 0; j < i; j++) { + if (numbers[i] == numbers[j]) { + conflicts += 1; + } + } + } + + // allow 5 % of conflicts + return conflicts <= 50 ? 0 : 1; +} + +int main(void) +{ + plan_lazy(); + + dnssec_crypto_init(); + + // quite stupid, just check if it does something + + ok(check_buffer() == 0, "dnssec_random_buffer()"); + ok(check_random_type() == 0, "dnssec_random_uint16_t()"); + + dnssec_crypto_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_shared_bignum.c b/tests/libdnssec/test_shared_bignum.c new file mode 100644 index 0000000..0e8f8d5 --- /dev/null +++ b/tests/libdnssec/test_shared_bignum.c @@ -0,0 +1,128 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <string.h> + +#include "bignum.h" +#include "binary.h" + +#define bin_init(array) { .data = array, .size = sizeof(array) } + +#define test_size(value, usize, ssize, msg) \ + dnssec_binary_t __bin = bin_init(value); \ + is_int(usize, bignum_size_u(&__bin), "bignum_size_u, " msg); \ + is_int(ssize, bignum_size_s(&__bin), "bignum_size_s, " msg) + +#define test_write(num, expect, msg) \ + uint8_t __buffer[sizeof(expect)]; \ + memset(__buffer, 0xaa, sizeof(__buffer)); \ + wire_ctx_t __ctx = wire_ctx_init(__buffer, sizeof(expect)); \ + dnssec_binary_t __num = bin_init(num); \ + dnssec_binary_t __exp = bin_init(expect); \ + bignum_write(&__ctx, sizeof(expect), &__num); \ + dnssec_binary_t __dst = bin_init(__buffer); \ + ok(dnssec_binary_cmp(&__dst, &__exp) == 0, "bignum_write, " msg) + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + { + uint8_t num[] = { }; + test_size(num, 1, 1, "empty string"); + } + + { + uint8_t num[] = { 0x00 }; + test_size(num, 1, 1, "zero"); + } + + { + uint8_t num[] = { 0x00, 0x00, 0x00 }; + test_size(num, 1, 1, "long zero"); + } + + { + uint8_t num[] = { 0x01, 0x02, 0x03 }; + test_size(num, 3, 3, "no MSB"); + } + + { + uint8_t num[] = { 0x7f, 0xff, 0x00, 0x00, 0x00 }; + test_size(num, 5, 5, "no MSB but all other bits"); + } + + { + uint8_t num[] = { 0x84, 0x42 }; + test_size(num, 2, 3, "MSB"); + } + + { + uint8_t num[] = { 0x00, 0x84, 0x42 }; + test_size(num, 2, 3, "MSB and leading zero"); + } + + { + uint8_t num[] = { 0x00, 0x00, 0x00, 0x00, 0xfc, 0xe1, 0xda }; + test_size(num, 3, 4, "MSB, many leading zeroes"); + } + + { + uint8_t num[] = { 0x00, 0x00, 0x00, 0x01 }; + test_size(num, 1, 1, "no MSB, many leading zeroes"); + } + + // test writing + + { + uint8_t num[] = { }; + uint8_t exp[] = { 0x00 }; + test_write(num, exp, "empty string"); + } + + { + uint8_t num[] = { 0x00 }; + uint8_t exp[] = { 0x00 }; + test_write(num, exp, "zero"); + } + + { + uint8_t num[] = { 0x11, 0x22, 0x33 }; + uint8_t exp[] = { 0x00, 0x00, 0x00, 0x11, 0x22, 0x33 }; + test_write(num, exp, "no MSB, right-aligned"); + } + + { + uint8_t num[] = { 0xff, 0xee, 0xdd }; + uint8_t exp[] = { 0x00, 0x00, 0x00, 0xff, 0xee, 0xdd }; + test_write(num, exp, "MSB, right-aligned"); + } + + { + uint8_t num[] = { 0x11, 0x22, 0x33 }; + uint8_t exp[] = { 0x11, 0x22, 0x33 }; + test_write(num, exp, "no MSB, fitting exactly"); + } + + { + uint8_t num[] = { 0xff, 0xee, 0xdd }; + uint8_t exp[] = { 0xff, 0xee, 0xdd }; + test_write(num, exp, "MSB, fitting exactly"); + } + + return 0; +} diff --git a/tests/libdnssec/test_shared_dname.c b/tests/libdnssec/test_shared_dname.c new file mode 100644 index 0000000..8eb93cf --- /dev/null +++ b/tests/libdnssec/test_shared_dname.c @@ -0,0 +1,79 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdbool.h> +#include <string.h> +#include <tap/basic.h> + +#include "dname.h" + +static void ok_length(const char *dname, size_t length, const char *info) +{ + ok(dname_length((uint8_t *)dname) == length, + "dname_length() for %s", info); +} + +static void test_length(void) +{ + ok_length(NULL, 0, "NULL"); + ok_length("", 1, "."); + ok_length("\x2""cz", 4, "cz."); + ok_length("\x7""example""\x3""com", 13, "example.com."); +} + +static bool dname_binary_equal(const uint8_t *one, const uint8_t *two) +{ + return one && two && strcmp((char *)one, (char *)two) == 0; +} + +static void test_copy(void) +{ + const uint8_t *dname = (uint8_t *)"\x3""www""\x8""KNOT-DNS""\x2""cz"; + uint8_t *copy = dname_copy(dname); + ok(dname_binary_equal(dname, copy), "dname_copy()"); + free(copy); +} + +static void test_equal(void) +{ + #define eq(a, b) dname_equal((uint8_t *)a, (uint8_t *)b) + + ok(eq("\x4""kiwi""\x4""limo", "\x4""kiwi""\x4""limo") == true, + "dname_equal() same"); + ok(eq("\x6""orange", "\x6""ORANGE") == true, + "dname_equal() case single label"); + ok(eq("\x6""Banana""\03""Tea", "\x6""bANAna""\x3""tea") == true, + "dname_equal() case two labels"); + ok(eq("\x4""Coco""\x4""MILK", "\x3""cow""\x4""milk") == false, + "dname_equal() different first"); + ok(eq("\x4""LIME""\x5""syrup", "\x4""LIme""\x4""beer") == false, + "dname_equal() different last"); + ok(eq("\x5""apple", "\x5""apple""\x5""shake") == false, + "dname_equal() a prefix of b"); + ok(eq("\x5""apple""\x5""juice", "\x5""apple") == false, + "dname_equal() b prefix of a"); +} + +int main(void) +{ + plan_lazy(); + + test_length(); + test_copy(); + test_equal(); + + return 0; +} diff --git a/tests/libdnssec/test_sign.c b/tests/libdnssec/test_sign.c new file mode 100644 index 0000000..1f61d96 --- /dev/null +++ b/tests/libdnssec/test_sign.c @@ -0,0 +1,184 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> +#include <tap/basic.h> + +#include "sample_keys.h" + +#include "binary.h" +#include "crypto.h" +#include "error.h" +#include "key.h" +#include "sign.h" + +static const dnssec_binary_t input_data = { + .size = 25, + .data = (uint8_t *)"Very good, young padawan." +}; + +static const dnssec_binary_t signed_rsa = { .size = 128, .data = (uint8_t []) { + 0x21, 0xba, 0xff, 0x0c, 0x15, 0x10, 0x73, 0x25, 0xa7, 0x8e, + 0xf4, 0x71, 0x4b, 0xd3, 0x97, 0x6d, 0x95, 0x52, 0xc2, 0x0b, + 0x43, 0xb3, 0x7d, 0x82, 0xe4, 0x3e, 0x2a, 0xc3, 0xb7, 0x17, + 0x5b, 0x05, 0xe9, 0x1e, 0x13, 0xac, 0x27, 0x6f, 0x20, 0x93, + 0x1a, 0xeb, 0xe2, 0x2c, 0x72, 0x70, 0x14, 0xe6, 0x49, 0xa7, + 0x62, 0xdd, 0x4c, 0x72, 0x1e, 0x1d, 0xd8, 0xf9, 0xba, 0xbc, + 0x96, 0x0e, 0xc3, 0xd4, 0xc1, 0x8f, 0x95, 0xdb, 0x01, 0x18, + 0x24, 0x43, 0xbd, 0x2b, 0x52, 0x9b, 0x10, 0x1f, 0xba, 0x0a, + 0x76, 0xbe, 0x0e, 0xaa, 0x91, 0x27, 0x7b, 0x9f, 0xed, 0x5a, + 0xad, 0x96, 0x1a, 0x02, 0x97, 0x42, 0x91, 0x30, 0x03, 0x2b, + 0x5c, 0xb8, 0xcc, 0x6b, 0xcf, 0x39, 0x62, 0x5e, 0x47, 0xae, + 0x6d, 0x5b, 0x43, 0xd2, 0xc2, 0xd8, 0x22, 0x5d, 0xf5, 0x5e, + 0x0a, 0x97, 0x65, 0x41, 0xc7, 0xaa, 0x28, 0x67, +}}; + +static const dnssec_binary_t signed_ecdsa = { .size = 64, .data = (uint8_t []) { + 0xa2, 0x95, 0x76, 0xb5, 0xf5, 0x7e, 0xbd, 0xdd, 0xf5, 0x62, + 0xa2, 0xc3, 0xa4, 0x8d, 0xd4, 0x53, 0x5c, 0xba, 0x29, 0x71, + 0x8c, 0xcc, 0x28, 0x7b, 0x58, 0xf3, 0x1e, 0x4e, 0x58, 0xe2, + 0x36, 0x7e, + 0xa0, 0x1a, 0xb6, 0xe6, 0x29, 0x71, 0x1b, 0xd3, 0x8c, 0x88, + 0xc3, 0xee, 0x12, 0x0e, 0x69, 0x70, 0x55, 0x99, 0xec, 0xd5, + 0xf6, 0x4f, 0x4b, 0xe2, 0x41, 0xd9, 0x10, 0x7e, 0x67, 0xe5, + 0xad, 0x2f, +}}; + +#ifdef HAVE_ED25519 +static const dnssec_binary_t signed_ed25519 = { .size = 64, .data = (uint8_t []) { + 0x0a, 0x9e, 0x51, 0x5f, 0x16, 0x89, 0x49, 0x27, + 0x0e, 0x98, 0x34, 0xd3, 0x48, 0xef, 0x5a, 0x6e, + 0x85, 0x2f, 0x7c, 0xd6, 0xd7, 0xc8, 0xd0, 0xf4, + 0x2c, 0x68, 0x8c, 0x1f, 0xf7, 0xdf, 0xeb, 0x7c, + 0x25, 0xd6, 0x1a, 0x76, 0x3e, 0xaf, 0x28, 0x1f, + 0x1d, 0x08, 0x10, 0x20, 0x1c, 0x01, 0x77, 0x1b, + 0x5a, 0x48, 0xd6, 0xe5, 0x1c, 0xf9, 0xe3, 0xe0, + 0x70, 0x34, 0x5e, 0x02, 0x49, 0xfb, 0x9e, 0x05, + }}; +#endif + +static dnssec_binary_t binary_set_string(char *str) +{ + dnssec_binary_t result = { .data = (uint8_t *)str, .size = strlen(str) }; + return result; +} + +static void check_key(const key_parameters_t *key_data, const dnssec_binary_t *data, + const dnssec_binary_t *signature, bool signature_match) +{ + int r; + + // initialize key from public parameters + + dnssec_key_t *key = NULL; + r = dnssec_key_new(&key); + ok(r == DNSSEC_EOK && key != NULL, "create key"); + r = dnssec_key_set_rdata(key, &key_data->rdata); + ok(r == DNSSEC_EOK, "set RDATA"); + + // check validation on static signature + + dnssec_sign_ctx_t *ctx = NULL; + r = dnssec_sign_new(&ctx, key); + ok(r == DNSSEC_EOK, "create signing context"); + r = dnssec_sign_add(ctx, data); + ok(r == DNSSEC_EOK, "add data to be signed"); + r = dnssec_sign_verify(ctx, signature); + ok(r == DNSSEC_EOK, "signature verified"); + + // create new signature and self-validate + + r = dnssec_key_load_pkcs8(key, &key_data->pem); + ok(r == DNSSEC_EOK, "load private key"); + + if (signature_match) { + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, "reinitialize context"); + r = dnssec_sign_add(ctx, data); + ok(r == DNSSEC_EOK, "add data to be signed"); + dnssec_binary_t new_signature = { 0 }; + r = dnssec_sign_write(ctx, &new_signature); + ok(r == DNSSEC_EOK, "write the signature"); + ok(dnssec_binary_cmp(signature, &new_signature) == 0, + "signature exact match"); + r = dnssec_sign_verify(ctx, &new_signature); + ok(r == DNSSEC_EOK, "reverify the new signature"); + dnssec_binary_free(&new_signature); + } + + // context reinitialization + + dnssec_binary_t tmp = { 0 }; + + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, "reinitialize context"); + + tmp = binary_set_string("bind"); + r = dnssec_sign_add(ctx, &tmp); + ok(r == DNSSEC_EOK, "add data (1)"); + + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, "reinitialize context"); + + tmp = binary_set_string("knot"); + r = dnssec_sign_add(ctx, &tmp); + ok(r == DNSSEC_EOK, "add data (2)"); + + tmp = binary_set_string(" is the best"); + r = dnssec_sign_add(ctx, &tmp); + ok(r == DNSSEC_EOK, "add data (3)"); + + dnssec_binary_t new_signature = { 0 }; + r = dnssec_sign_write(ctx, &new_signature); + ok(r == DNSSEC_EOK, "write signature"); + + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, "reinitialize context"); + + tmp = binary_set_string("knot is the best"); + r = dnssec_sign_add(ctx, &tmp); + ok(r == DNSSEC_EOK, "add data (4)"); + + r = dnssec_sign_verify(ctx, &new_signature); + ok(r == DNSSEC_EOK, "verify signature"); + + dnssec_binary_free(&new_signature); + + // cleanup + + dnssec_sign_free(ctx); + dnssec_key_free(key); +} + +int main(void) +{ + plan_lazy(); + + dnssec_crypto_init(); + + diag("RSA signing"); + check_key(&SAMPLE_RSA_KEY, &input_data, &signed_rsa, true); + diag("ECDSA signing"); + check_key(&SAMPLE_ECDSA_KEY, &input_data, &signed_ecdsa, false); +#ifdef HAVE_ED25519 + diag("ED25519 signing"); + check_key(&SAMPLE_ED25519_KEY, &input_data, &signed_ed25519, true); +#endif + + dnssec_crypto_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_sign_der.c b/tests/libdnssec/test_sign_der.c new file mode 100644 index 0000000..04bfeac --- /dev/null +++ b/tests/libdnssec/test_sign_der.c @@ -0,0 +1,202 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <stdint.h> +#include <string.h> +#include <stdbool.h> + +#include "binary.h" +#include "error.h" +#include "sign/der.c" + +static int binary_eq(const dnssec_binary_t *a, const dnssec_binary_t *b) +{ + return a && b && + a->size == b->size && + memcmp(a->data, b->data, a->size) == 0; +} + +#define DECODE_OK(der, r, s, message) \ + dnssec_binary_t __der = { .data = der, .size = sizeof(der) }; \ + dnssec_binary_t __r = { .data = r, .size = sizeof(r) }; \ + dnssec_binary_t __s = { .data = s, .size = sizeof(s) }; \ + dnssec_binary_t __out_s = { 0 }; \ + dnssec_binary_t __out_r = { 0 }; \ + int _result = dss_sig_value_decode(&__der, &__out_r, &__out_s); \ + ok(_result == DNSSEC_EOK && \ + binary_eq(&__r, &__out_r) && \ + binary_eq(&__s, &__out_s), \ + "decode ok, " message) + +#define DECODE_FAIL(der, message) \ + dnssec_binary_t __der = { .data = der, .size = sizeof(der) }; \ + dnssec_binary_t __out_r = { 0 }; \ + dnssec_binary_t __out_s = { 0 }; \ + int _result = dss_sig_value_decode(&__der, &__out_r, &__out_s); \ + ok(_result != DNSSEC_EOK, \ + "decode fail, " message) + +#define ENCODE_OK(r, s, der, message) \ + dnssec_binary_t __r = { .data = r, .size = sizeof(r) }; \ + dnssec_binary_t __s = { .data = s, .size = sizeof(s) }; \ + dnssec_binary_t __der = { .data = der, .size = sizeof(der) }; \ + dnssec_binary_t __out_der = { 0 }; \ + int _result = dss_sig_value_encode(&__r, &__s, &__out_der); \ + ok(_result == DNSSEC_EOK && \ + binary_eq(&__der, &__out_der), \ + "encode ok, " message); \ + dnssec_binary_free(&__out_der) + +#define ENCODE_FAIL(r, s, message) \ + dnssec_binary_t __r = { .data = r, .size = sizeof(r) }; \ + dnssec_binary_t __s = { .data = s, .size = sizeof(s) }; \ + dnssec_binary_t __out_der = { 0 }; \ + int _result = dss_sig_value_encode(&__r, &__s, &__out_der); \ + ok(_result != DNSSEC_EOK, \ + "encode fail, " message); \ + dnssec_binary_free(&__out_der) + +#define ONE_64_TIMES \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01 + +#define ONE_128_TIMES \ + ONE_64_TIMES, ONE_64_TIMES + +int main(void) +{ + plan_lazy(); + + { + uint8_t der[] = { 0x30,0x08, 0x02,0x02,0x1a,0x2b, 0x02,0x02,0x3c,0x4d }; + uint8_t r[] = { 0x1a, 0x2b }; + uint8_t s[] = { 0x3c, 0x4d }; + DECODE_OK(der, r, s, "simple without MSB"); + } + + { + uint8_t der[] = { 0x30,0x08, 0x02,0x02,0xff,0xff, 0x02,0x02,0x80,0x00 }; + uint8_t r[] = { 0xff, 0xff }; + uint8_t s[] = { 0x80, 0x00 }; + DECODE_OK(der, r, s, "simple with MSB"); + } + + { + uint8_t der[] = { 0x30,0x09, 0x02,0x04,0x00,0x00,0x00,0xfa, 0x02,0x01,0x07 }; + uint8_t r[] = { 0xfa }; + uint8_t s[] = { 0x07 }; + DECODE_OK(der, r, s, "leading zeros"); + } + + { + uint8_t der[] = { 0x30,0x07, 0x02,0x01,0x00, 0x02,0x02,0x00,0x00 }; + uint8_t r[] = { 0x00 }; + uint8_t s[] = { 0x00 }; + DECODE_OK(der, r, s, "zero values" ); + } + + { + uint8_t der[] = { }; + DECODE_FAIL(der, "empty input"); + } + + { + uint8_t der[] = { 0x30,0x04, 0x02,0x01,0x01 }; + DECODE_FAIL(der, "partial sequence"); + } + + { + uint8_t der[] = { 0x30,0x06, 0x02,0x01,0x01, 0x02,0x02,0x01 }; + DECODE_FAIL(der, "partial integer"); + } + + { + uint8_t der[] = { 0x30,0x00 }; + DECODE_FAIL(der, "zero-length sequence"); + } + + { + uint8_t der[] = { 0x30,0x05, 0x02,0x01,0xff, 0x02,0x00 }; + DECODE_FAIL(der, "zero-length integer"); + } + + { + uint8_t der[] = { 0x30,0x84, 0x02,0x40,ONE_64_TIMES, 0x02,0x40,ONE_64_TIMES }; + DECODE_FAIL(der, "unsupported size"); + } + + { + uint8_t r[] = { 0x01, }; + uint8_t s[] = { 0x02,0x03 }; + uint8_t der[] = { 0x30,0x07, 0x02,0x01,0x01, 0x02,0x02,0x02,0x03 }; + ENCODE_OK(r, s, der, "simple"); + } + + { + uint8_t r[] = { 0x00,0x01, }; + uint8_t s[] = { 0x00,0x00,0x02,0x03 }; + uint8_t der[] = { 0x30,0x07, 0x02,0x01,0x01, 0x02,0x02,0x02,0x03 }; + ENCODE_OK(r, s, der, "unnecessary leading zeros"); + } + + { + uint8_t r[] = { 0x00,0x8f }; + uint8_t s[] = { 0x00,0x00,0xff }; + uint8_t der[] = { 0x30,0x08, 0x02,0x02,0x00,0x8f, 0x02,0x02,0x00,0xff }; + ENCODE_OK(r, s, der, "required zero not removed"); + } + + { + uint8_t r[] = { 0x8c }; + uint8_t s[] = { 0xff,0xee }; + uint8_t der[] = { 0x30,0x09, 0x02,0x02,0x00,0x8c, 0x02,0x03,0x00,0xff,0xee }; + ENCODE_OK(r, s, der, "implicitly added zero"); + } + + { + uint8_t r[] = { 0x00 }; + uint8_t s[] = { 0x00,0x00 }; + uint8_t der[] = { 0x30,0x06, 0x02,0x01,0x00, 0x02,0x01,0x00 }; + ENCODE_OK(r, s, der, "zero"); + } + + { + uint8_t r[] = { 0x01 }; + uint8_t s[] = { }; + uint8_t der[] = { 0x30,0x06, 0x02,0x01,0x01, 0x02,0x01,0x00 }; + ENCODE_OK(r, s, der, "zero-length input"); + } + + { + uint8_t r[] = { ONE_128_TIMES }; + uint8_t s[] = { 0x01 }; + ENCODE_FAIL(r, s, "input too long"); + } + + { + uint8_t r[] = { ONE_64_TIMES }; + uint8_t s[] = { ONE_64_TIMES }; + ENCODE_FAIL(r, s, "result too long"); + } + + return 0; +} diff --git a/tests/libdnssec/test_tsig.c b/tests/libdnssec/test_tsig.c new file mode 100644 index 0000000..91674be --- /dev/null +++ b/tests/libdnssec/test_tsig.c @@ -0,0 +1,145 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <string.h> + +#include "binary.h" +#include "dname.h" +#include "tsig.h" + +static const dnssec_binary_t payload = { + .size = 40, + .data = (uint8_t []){ + 0xfd, 0x07, 0xca, 0x30, 0xf9, 0xff, 0x38, 0xb1, 0x32, 0x54, + 0xd1, 0x16, 0x24, 0xaa, 0x81, 0x2c, 0x97, 0xa0, 0x7a, 0xac, + 0x68, 0x7a, 0x3a, 0x60, 0xde, 0xc9, 0xf7, 0x7a, 0x5a, 0x58, + 0xff, 0xc9, 0x0c, 0xef, 0x31, 0xc7, 0x45, 0x2c, 0xee, 0x9d, + } +}; + +static const dnssec_binary_t key = { + .size = 16, + .data = (uint8_t []){ + 0xa8, 0x05, 0x9c, 0x5c, 0x20, 0xc5, 0x00, 0x22, 0x6f, 0xad, + 0xf2, 0x55, 0xdf, 0x89, 0x8a, 0x68 + } +}; + +typedef struct hmac { + int algorithm; + const char *name; + const dnssec_binary_t hmac; +} hmac_t; + +static const hmac_t HMACS[] = { + { DNSSEC_TSIG_HMAC_MD5, "md5", { .size = 16, .data = (uint8_t []) { + 0x12, 0x38, 0x17, 0x4f, 0xa9, 0xc7, 0x5b, 0xcf, 0xd7, 0x08, + 0x19, 0x97, 0xf9, 0x3d, 0x5e, 0xe7 + }}}, + { DNSSEC_TSIG_HMAC_SHA1, "sha1", { .size = 20, .data = (uint8_t []) { + 0xb8, 0x18, 0x2a, 0x5d, 0xf8, 0x2e, 0xa0, 0xb7, 0xcc, 0xcc, + 0xed, 0xc1, 0xaa, 0x34, 0xeb, 0x92, 0x48, 0xf9, 0x65, 0x7b + }}}, + { DNSSEC_TSIG_HMAC_SHA224, "sha224", { .size = 28, .data = (uint8_t []) { + 0xb7, 0x43, 0xcd, 0x0d, 0x9d, 0x51, 0x8c, 0x61, 0xc6, 0x43, + 0x98, 0x73, 0x5c, 0x16, 0x01, 0x1b, 0xfc, 0x82, 0xe9, 0x99, + 0xc2, 0x21, 0xde, 0x16, 0xb1, 0x94, 0x2d, 0xd5 + }}}, + { DNSSEC_TSIG_HMAC_SHA256, "sha256", { .size = 32, .data = (uint8_t []) { + 0x16, 0x5e, 0xf6, 0xed, 0x9b, 0x1a, 0xe5, 0x67, 0x58, 0x7b, + 0xf1, 0x35, 0x9e, 0x59, 0xbd, 0x50, 0x6d, 0x72, 0xf8, 0x87, + 0x0e, 0x22, 0xda, 0x65, 0x00, 0xd6, 0x76, 0x91, 0xde, 0x5f, + 0xec, 0xd8 + }}}, + { DNSSEC_TSIG_HMAC_SHA384, "sha384", { .size = 48, .data = (uint8_t []) { + 0x8a, 0xcf, 0xf3, 0xb7, 0x1c, 0xbe, 0x5c, 0x3e, 0x05, 0x74, + 0x97, 0x46, 0x04, 0x79, 0x3a, 0xe7, 0x8a, 0x5b, 0x7b, 0x12, + 0xca, 0xcd, 0xf2, 0xe2, 0xdf, 0xa9, 0x17, 0xfc, 0x8e, 0x61, + 0xc5, 0x86, 0x3e, 0xdc, 0xad, 0x84, 0x9e, 0x13, 0x0d, 0xa0, + 0x04, 0xb6, 0x6f, 0x7c, 0x85, 0x1b, 0x5c, 0xdf + }}}, + { DNSSEC_TSIG_HMAC_SHA512, "sha512", { .size = 64, .data = (uint8_t []) { + 0xc3, 0x41, 0xd0, 0x96, 0x50, 0xd7, 0xf7, 0xfd, 0x59, 0x73, + 0xde, 0xd6, 0xc7, 0x4c, 0xda, 0xf1, 0x5d, 0xe1, 0x59, 0x34, + 0x79, 0xdc, 0x93, 0x23, 0xcb, 0xf2, 0x1f, 0x25, 0x4e, 0x35, + 0xb0, 0xd0, 0x9f, 0xfc, 0x22, 0xf1, 0xea, 0xbf, 0x9c, 0x18, + 0xd8, 0xcc, 0xcd, 0xb6, 0xb1, 0x4a, 0x06, 0x09, 0xc4, 0x3f, + 0x28, 0x93, 0x71, 0xd6, 0xca, 0xce, 0xf3, 0xa6, 0x08, 0x38, + 0xe3, 0x99, 0xc1, 0xb2 + }}}, + { 0 } +}; + +static void test_lookup_dname(const uint8_t *dname, int algorithm) +{ + dnssec_tsig_algorithm_t alg = dnssec_tsig_algorithm_from_dname(dname); + const char *name = dnssec_tsig_algorithm_to_name(algorithm); + if (name == NULL) name = "invalid"; + ok(alg == algorithm, "dnssec_tsig_algorithm_from_dname(%s)", name); + + const uint8_t *reverse = dnssec_tsig_algorithm_to_dname(algorithm); + ok((algorithm == DNSSEC_TSIG_UNKNOWN && reverse == NULL) || + (algorithm != DNSSEC_TSIG_UNKNOWN && dname_equal(reverse, dname)), + "dnssec_tsig_algorithm_to_dname(%d)", algorithm); +} + +static void test_lookup_name(const char *name, int algorithm) +{ + ok(dnssec_tsig_algorithm_from_name(name) == algorithm, + "dnssec_tsig_algorithm_from_name(%s)", name); + + const char *reverse = dnssec_tsig_algorithm_to_name(algorithm); + ok((algorithm == DNSSEC_TSIG_UNKNOWN && reverse == NULL) || + (algorithm != DNSSEC_TSIG_UNKNOWN && strcasecmp(reverse, name) == 0), + "dnssec_tsig_algorithm_to_name(%d)", algorithm); +} + +static void test_tsig_hmac(const hmac_t *params) +{ + dnssec_tsig_ctx_t *ctx = NULL; + dnssec_tsig_new(&ctx, params->algorithm, &key); + dnssec_tsig_add(ctx, &payload); + + size_t size = dnssec_tsig_size(ctx); + uint8_t hmac[size]; + dnssec_tsig_write(ctx, hmac); + dnssec_tsig_free(ctx); + + ok(size == params->hmac.size && memcmp(hmac, params->hmac.data, size) == 0, + "dnssec_tsig_write(%s)", params->name); +} + +int main(void) +{ + plan_lazy(); + + test_lookup_dname((uint8_t *)"\x08""HMAC-MD5""\x07""SIG-ALG""\x03""REG""\x03""INT", + DNSSEC_TSIG_HMAC_MD5); + test_lookup_dname((uint8_t *)"\x0B""hmac-sha224", DNSSEC_TSIG_HMAC_SHA224); + test_lookup_dname((uint8_t *)"\x06""foobar", DNSSEC_TSIG_UNKNOWN); + + test_lookup_name("hmac-md5", DNSSEC_TSIG_HMAC_MD5); + test_lookup_name("hmac-sha512", DNSSEC_TSIG_HMAC_SHA512); + test_lookup_name("barfoo", DNSSEC_TSIG_UNKNOWN); + test_lookup_name("hmac-foo", DNSSEC_TSIG_UNKNOWN); + + for (const hmac_t *h = HMACS; h->algorithm != 0; h++) { + test_tsig_hmac(h); + } + + return 0; +} diff --git a/tests/libknot/test_control.c b/tests/libknot/test_control.c new file mode 100644 index 0000000..3ec4daf --- /dev/null +++ b/tests/libknot/test_control.c @@ -0,0 +1,221 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <sys/wait.h> +#include <unistd.h> +#include <tap/basic.h> +#include <tap/files.h> + +#define CTL_BUFF_SIZE 18 +#include "libknot/control/control.c" + +#define fake_ok(condition, msg, ...) \ + if (!(condition)) { \ + if (msg != NULL) { \ + printf("error: " msg "\n", ##__VA_ARGS__); \ + } \ + exit(-1); \ + } + +static void ctl_client(const char *socket, size_t argc, knot_ctl_data_t *argv) +{ + knot_ctl_t *ctl = knot_ctl_alloc(); + fake_ok(ctl != NULL, "Allocate control"); + + int ret; + for (int i = 0; i < 20; i++) { + ret = knot_ctl_connect(ctl, socket); + if (ret == KNOT_EOK) { + break; + } + usleep(100000); + } + fake_ok(ret == KNOT_EOK, "Connect to socket"); + + diag("BEGIN: Client -> Server"); + + if (argc > 0) { + for (size_t i = 0; i < argc; i++) { + if (argv[i][KNOT_CTL_IDX_CMD] != NULL && + argv[i][KNOT_CTL_IDX_CMD][0] == '\0') { + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_BLOCK, NULL); + fake_ok(ret == KNOT_EOK, "Client send data block end type"); + } else { + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_DATA, &argv[i]); + fake_ok(ret == KNOT_EOK, "Client send data %zu", i); + } + } + } + + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_END, NULL); + fake_ok(ret == KNOT_EOK, "Client send final data"); + + diag("END: Client -> Server"); + diag("BEGIN: Client <- Server"); + + size_t count = 0; + knot_ctl_data_t data; + knot_ctl_type_t type; + while ((ret = knot_ctl_receive(ctl, &type, &data)) == KNOT_EOK) { + if (type == KNOT_CTL_TYPE_END) { + break; + } + if (argv[count][KNOT_CTL_IDX_CMD] != NULL && + argv[count][KNOT_CTL_IDX_CMD][0] == '\0') { + fake_ok(type == KNOT_CTL_TYPE_BLOCK, "Receive block end type"); + } else { + fake_ok(type == KNOT_CTL_TYPE_DATA, "Check data type"); + for (size_t i = 0; i < KNOT_CTL_IDX__COUNT; i++) { + fake_ok((data[i] == NULL && argv[count][i] == NULL) || + (data[i] != NULL && argv[count][i] != NULL), + "Client compare input item occupation %zu", i); + if (data[i] == NULL) { + continue; + } + + fake_ok(strcmp(data[i], argv[count][i]) == 0, + "Client compare input item '%s", argv[count][i]); + } + } + count++; + } + fake_ok(ret == KNOT_EOK, "Receive OK check"); + fake_ok(type == KNOT_CTL_TYPE_END, "Receive EOF type"); + fake_ok(count == argc, "Client compare input count '%zu'", argc); + + diag("END: Client <- Server"); + + knot_ctl_close(ctl); + knot_ctl_free(ctl); +} + +static void ctl_server(const char *socket, size_t argc, knot_ctl_data_t *argv) +{ + knot_ctl_t *ctl = knot_ctl_alloc(); + ok(ctl != NULL, "Allocate control"); + + int ret = knot_ctl_bind(ctl, socket); + is_int(KNOT_EOK, ret, "Bind control socket"); + + ret = knot_ctl_accept(ctl); + is_int(KNOT_EOK, ret, "Accept a connection"); + + diag("BEGIN: Server <- Client"); + + size_t count = 0; + knot_ctl_data_t data; + knot_ctl_type_t type; + while ((ret = knot_ctl_receive(ctl, &type, &data)) == KNOT_EOK) { + if (type == KNOT_CTL_TYPE_END) { + break; + } + if (argv[count][KNOT_CTL_IDX_CMD] != NULL && + argv[count][KNOT_CTL_IDX_CMD][0] == '\0') { + ok(type == KNOT_CTL_TYPE_BLOCK, "Receive block end type"); + } else { + ok(type == KNOT_CTL_TYPE_DATA, "Check data type"); + for (size_t i = 0; i < KNOT_CTL_IDX__COUNT; i++) { + ok((data[i] == NULL && argv[count][i] == NULL) || + (data[i] != NULL && argv[count][i] != NULL), + "Server compare input item occupation %zu", i); + if (data[i] == NULL) { + continue; + } + + ok(strcmp(data[i], argv[count][i]) == 0, + "Server compare input item '%s", argv[count][i]); + } + } + count++; + } + is_int(KNOT_EOK, ret, "Receive OK check"); + ok(type == KNOT_CTL_TYPE_END, "Receive EOF type"); + ok(count == argc, "Server compare input count '%zu'", argc); + + diag("END: Server <- Client"); + diag("BEGIN: Server -> Client"); + + if (argc > 0) { + for (size_t i = 0; i < argc; i++) { + if (argv[i][KNOT_CTL_IDX_CMD] != NULL && + argv[i][KNOT_CTL_IDX_CMD][0] == '\0') { + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_BLOCK, NULL); + is_int(KNOT_EOK, ret, "Client send data block end type"); + } else { + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_DATA, &argv[i]); + is_int(KNOT_EOK, ret, "Server send data %zu", i); + } + } + } + + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_END, NULL); + is_int(KNOT_EOK, ret, "Server send final data"); + + diag("END: Server -> Client"); + + knot_ctl_close(ctl); + knot_ctl_unbind(ctl); + knot_ctl_free(ctl); +} + +static void test_client_server_client(void) +{ + char *socket = test_mktemp(); + ok(socket != NULL, "Make a temporary socket file '%s'", socket); + + size_t data_len = 5; + knot_ctl_data_t data[] = { + { "command", "error", "section", "item", "identifier", + "zone", "owner", "ttl", "type", "data" }, + { [KNOT_CTL_IDX_DATA] = "\x01\x02" }, + { [KNOT_CTL_IDX_CMD] = "\0" }, // This means block end in this test! + { NULL }, + { [KNOT_CTL_IDX_ERROR] = "Ultra long message" } + }; + + // Fork a client process. + pid_t child_pid = fork(); + if (child_pid == -1) { + ok(child_pid >= 0, "Process fork"); + return; + } + if (child_pid == 0) { + ctl_client(socket, data_len, data); + free(socket); + return; + } else { + ctl_server(socket, data_len, data); + } + + int status = 0; + wait(&status); + ok(WIFEXITED(status), "Wait for client"); + + test_rm_rf(socket); + free(socket); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("Client -> Server -> Client"); + test_client_server_client(); + + return 0; +} diff --git a/tests/libknot/test_cookies.c b/tests/libknot/test_cookies.c new file mode 100644 index 0000000..b50b940 --- /dev/null +++ b/tests/libknot/test_cookies.c @@ -0,0 +1,177 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/cookies.h" +#include "libknot/endian.h" +#include "libknot/errcode.h" +#include "contrib/sockaddr.h" + +static void client_generate(struct sockaddr_storage *c_addr, struct sockaddr_storage *s_addr, + const uint8_t *secret, const char *msg, int code, uint64_t le_cc) +{ + knot_edns_cookie_params_t params = { + .client_addr = (struct sockaddr *)c_addr, + .server_addr = (struct sockaddr *)s_addr, + }; + memcpy(params.secret, secret, sizeof(params.secret)); + + knot_edns_cookie_t cc; + int ret = knot_edns_cookie_client_generate(&cc, ¶ms); + is_int(ret, code, "client_generate ret: %s", msg); + if (ret == KNOT_EOK) { + uint64_t ref = le64toh(le_cc); + ok(cc.len == sizeof(ref) && memcmp(cc.data, &ref, cc.len) == 0, + "client_generate value: %s", msg); + } +} + +static void server_generate(struct sockaddr_storage *c_addr, const uint8_t *secret, + const knot_edns_cookie_t *cc, const char *msg, int code, + uint64_t le_sc) +{ + knot_edns_cookie_params_t params = { + .client_addr = (struct sockaddr *)c_addr, + }; + memcpy(params.secret, secret, sizeof(params.secret)); + + knot_edns_cookie_t sc; + int ret = knot_edns_cookie_server_generate(&sc, cc, ¶ms); + is_int(ret, code, "server_generate ret: %s", msg); + if (ret == KNOT_EOK) { + uint64_t ref = le64toh(le_sc); + ok(sc.len == sizeof(ref) && memcmp(sc.data, &ref, sc.len) == 0, + "server_generate value: %s", msg); + } +} + +static void client_check(struct sockaddr_storage *c_addr, struct sockaddr_storage *s_addr, + const uint8_t *secret, const char *msg, uint16_t le_cc_len, + uint64_t le_cc, int code) +{ + knot_edns_cookie_params_t params = { + .client_addr = (struct sockaddr *)c_addr, + .server_addr = (struct sockaddr *)s_addr, + }; + if (secret != NULL) { + memcpy(params.secret, secret, sizeof(params.secret)); + } + + uint64_t ref = le64toh(le_cc); + knot_edns_cookie_t cc = { + .len = le_cc_len + }; + memcpy(cc.data, &ref, le_cc_len); + + int ret = knot_edns_cookie_client_check(&cc, ¶ms); + is_int(ret, code, "client_check ret: %s", msg); +} + +static void server_check(struct sockaddr_storage *c_addr, const uint8_t *secret, + const char *msg, uint16_t le_cc_len, uint64_t le_cc, + uint16_t le_sc_len, uint64_t le_sc, int code) +{ + knot_edns_cookie_params_t params = { + .client_addr = (struct sockaddr *)c_addr, + }; + if (secret != NULL) { + memcpy(params.secret, secret, sizeof(params.secret)); + } + + uint64_t ref = le64toh(le_cc); + knot_edns_cookie_t cc = { + .len = le_cc_len + }; + memcpy(cc.data, &ref, le_cc_len); + + ref = le64toh(le_sc); + knot_edns_cookie_t sc = { + .len = le_sc_len + }; + memcpy(sc.data, &ref, le_sc_len); + + int ret = knot_edns_cookie_server_check(&sc, &cc, ¶ms); + is_int(ret, code, "server_check ret: %s", msg); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + const uint8_t secret[] = "\xCE\xFA\xEF\xBE\xAD\xDE\x00\x00\xEF\xBE\xAD\xDE\xCE\xFA\x00\x00"; + + struct sockaddr_storage unspec_sa = { 0 }; + + struct sockaddr_storage c4_sa = { 0 }; + struct sockaddr_storage s4_sa = { 0 }; + sockaddr_set(&c4_sa, AF_INET, "127.0.0.1", 0); + sockaddr_set(&s4_sa, AF_INET, "10.0.0.1", 0); + + struct sockaddr_storage c6_sa = { 0 }; + struct sockaddr_storage s6_sa = { 0 }; + sockaddr_set(&c6_sa, AF_INET6, "2001:db8:8714:3a90::12", 0); + sockaddr_set(&s6_sa, AF_INET6, "::1", 0); + + /* Client cookie generate. */ + client_generate(NULL, &s4_sa, secret, "NULL, IPv4", KNOT_EINVAL, 0); + client_generate(&c4_sa, NULL, secret, "IPv4, NULL", KNOT_EINVAL, 0); + client_generate(&c4_sa, &s4_sa, secret, "IPv4, IPv4", KNOT_EOK, 0xde3832f4f59bf5ab); + client_generate(&unspec_sa, &s4_sa, secret, "unspec, IPv4", KNOT_EOK, 0x6b636ff225a1b340); + client_generate(&c4_sa, &unspec_sa, secret, "IPv4, unspec", KNOT_EOK, 0xd713ab1a81179bb3); + + /* Client cookie check. */ + client_check(NULL, &s6_sa, secret, "no client addr", 8, 0xf99dbd02b69ab3c2, KNOT_EINVAL); + client_check(&c6_sa, NULL, secret, "no server addr", 8, 0xf99dbd02b69ab3c2, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, NULL, "no secret", 8, 0xf99dbd02b69ab3c2, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, secret, "no cookie", 0, 0, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, secret, "bad cookie length", 7, 0xf99dbd02b69ab3c2, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, secret, "invalid cookie", 8, 0, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, secret, "good cookie", 8, 0xf99dbd02b69ab3c2, KNOT_EOK); + + const knot_edns_cookie_t cc = { + .data = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + .len = 8 + }; + + /* Server cookie generate. */ + knot_edns_cookie_t cc_part = cc; cc_part.len--; + server_generate(NULL, secret, &cc, "NULL", KNOT_EINVAL, 0); + server_generate(&c4_sa, secret, &cc_part, "cookie part", KNOT_EINVAL, 0); + server_generate(&c4_sa, secret, &cc, "IPv4", KNOT_EOK, 0x52f86bfcc98ded6); + server_generate(&c6_sa, secret, &cc, "IPv6", KNOT_EOK, 0x33ac6c9005acf469); + server_generate(&unspec_sa, secret, &cc, "unspec", KNOT_EOK, 0x96df9dbf28f0f59e); + + /* Server cookie check. */ + server_check(NULL, secret, "no addr", 8, 0x0706050403020100, + 8, 0x33ac6c9005acf469, KNOT_EINVAL); + server_check(&c6_sa, NULL, "no secret", 8, 0x0706050403020100, + 8, 0x33ac6c9005acf469, KNOT_EINVAL); + server_check(&c6_sa, secret, "no client cookie", 0, 0, + 8, 0x33ac6c9005acf469, KNOT_EINVAL); + server_check(&c6_sa, secret, "no server cookie", 8, 0x0706050403020100, + 0, 0, KNOT_EINVAL); + server_check(&c6_sa, secret, "bad client cookie", 8, 0, + 8, 0x33ac6c9005acf469, KNOT_EINVAL); + server_check(&c6_sa, secret, "bad server cookie", 8, 0x0706050403020100, + 8, 0, KNOT_EINVAL); + server_check(&c6_sa, secret, "good cookie 1", 8, 0x0706050403020100, + 8, 0x33ac6c9005acf469, KNOT_EOK); + + return 0; +} diff --git a/tests/libknot/test_db.c b/tests/libknot/test_db.c new file mode 100644 index 0000000..49bd6e4 --- /dev/null +++ b/tests/libknot/test_db.c @@ -0,0 +1,287 @@ +/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <tap/basic.h> +#include <tap/files.h> + +#include "contrib/string.h" +#include "libknot/libknot.h" +#include "contrib/mempattern.h" +#include "contrib/openbsd/strlcpy.h" +#include "contrib/ucw/mempool.h" + +/* UCW array sorting defines. */ +#define ASORT_PREFIX(X) str_key_##X +#define ASORT_KEY_TYPE char* +#define ASORT_LT(x, y) (strcmp((x), (y)) < 0) +#include "contrib/ucw/array-sort.h" + +/* Constants. */ +#define KEY_MAXLEN 64 +#define KEY_SET(key, str) key.data = (str); key.len = strlen(str) + 1 + +/*! \brief Generate random key. */ +static const char *alphabet = "abcdefghijklmn0123456789"; +static char *str_key_rand(size_t len, knot_mm_t *pool) +{ + char *s = mm_alloc(pool, len); + memset(s, 0, len); + for (unsigned i = 0; i < len - 1; ++i) { + s[i] = alphabet[rand() % strlen(alphabet)]; + } + return s; +} + +static void knot_db_test_set(unsigned nkeys, char **keys, void *opts, + const knot_db_api_t *api, knot_mm_t *pool) +{ + if (api == NULL) { + skip("API not compiled in"); + return; + } + + /* Create database */ + knot_db_t *db = NULL; + int ret = api->init(&db, pool, opts); + ok(ret == KNOT_EOK && db != NULL, "%s: create", api->name); + + /* Start WR transaction. */ + knot_db_txn_t txn; + ret = api->txn_begin(db, &txn, 0); + is_int(KNOT_EOK, ret, "%s: txn_begin(WR)", api->name); + + /* Insert keys */ + knot_db_val_t key, val; + bool passed = true; + for (unsigned i = 0; i < nkeys; ++i) { + KEY_SET(key, keys[i]); + val.len = sizeof(void*); + val.data = &key.data; + + ret = api->insert(&txn, &key, &val, 0); + if (ret != KNOT_EOK && ret != KNOT_EEXIST) { + passed = false; + break; + } + } + ok(passed, "%s: insert", api->name); + + /* Commit WR transaction. */ + ret = api->txn_commit(&txn); + is_int(KNOT_EOK, ret, "%s: txn_commit(WR)", api->name); + + /* Start RD transaction. */ + ret = api->txn_begin(db, &txn, KNOT_DB_RDONLY); + is_int(KNOT_EOK, ret, "%s: txn_begin(RD)", api->name); + + /* Lookup all keys */ + passed = true; + for (unsigned i = 0; i < nkeys; ++i) { + KEY_SET(key, keys[i]); + + ret = api->find(&txn, &key, &val, 0); + if (ret != KNOT_EOK) { + passed = false; + break; + } + + const char **stored_key = val.data; + if (strcmp(*stored_key, keys[i]) != 0) { + diag("%s: mismatch on element '%u'", api->name, i); + passed = false; + break; + } + } + ok(passed, "%s: lookup all keys", api->name); + + /* Fetch dataset size. */ + int db_size = api->count(&txn); + ok(db_size > 0 && db_size <= nkeys, "%s: count %d", api->name, db_size); + + /* Unsorted iteration */ + int iterated = 0; + knot_db_iter_t *it = api->iter_begin(&txn, 0); + while (it != NULL) { + ++iterated; + it = api->iter_next(it); + } + api->iter_finish(it); + is_int(db_size, iterated, "%s: unsorted iteration", api->name); + + /* Sorted iteration. */ + char first_key[KEY_MAXLEN] = { '\0' }; + char second_key[KEY_MAXLEN] = { '\0' }; + char last_key[KEY_MAXLEN] = { '\0' }; + char key_buf[KEY_MAXLEN] = {'\0'}; + iterated = 0; + memset(&key, 0, sizeof(key)); + it = api->iter_begin(&txn, KNOT_DB_SORTED); + while (it != NULL) { + api->iter_key(it, &key); + if (iterated > 0) { /* Only if previous exists. */ + if (strcmp(key_buf, key.data) > 0) { + diag("%s: iter_sort '%s' <= '%s' FAIL\n", + api->name, key_buf, (const char *)key.data); + break; + } + if (iterated == 1) { + memcpy(second_key, key.data, key.len); + } + } else { + memcpy(first_key, key.data, key.len); + } + ++iterated; + memcpy(key_buf, key.data, key.len); + it = api->iter_next(it); + } + strlcpy(last_key, key_buf, sizeof(last_key)); + is_int(db_size, iterated, "%s: sorted iteration", api->name); + api->iter_finish(it); + + /* Interactive iteration. */ + it = api->iter_begin(&txn, KNOT_DB_NOOP); + if (it != NULL) { /* If supported. */ + ret = 0; + /* Check if first and last keys are reachable */ + it = api->iter_seek(it, NULL, KNOT_DB_FIRST); + ret += api->iter_key(it, &key); + is_string(first_key, key.data, "%s: iter_set(FIRST)", api->name); + /* Check left/right iteration. */ + it = api->iter_seek(it, &key, KNOT_DB_NEXT); + ret += api->iter_key(it, &key); + is_string(second_key, key.data, "%s: iter_set(NEXT)", api->name); + it = api->iter_seek(it, &key, KNOT_DB_PREV); + ret += api->iter_key(it, &key); + is_string(first_key, key.data, "%s: iter_set(PREV)", api->name); + it = api->iter_seek(it, &key, KNOT_DB_LAST); + ret += api->iter_key(it, &key); + is_string(last_key, key.data, "%s: iter_set(LAST)", api->name); + /* Check if prev(last_key + 1) is the last_key */ + strlcpy(key_buf, last_key, sizeof(key_buf)); + key_buf[0] += 1; + KEY_SET(key, key_buf); + it = api->iter_seek(it, &key, KNOT_DB_LEQ); + ret += api->iter_key(it, &key); + is_string(last_key, key.data, "%s: iter_set(LEQ)", api->name); + /* Check if next(first_key - 1) is the first_key */ + strlcpy(key_buf, first_key, sizeof(key_buf)); + key_buf[0] -= 1; + KEY_SET(key, key_buf); + it = api->iter_seek(it, &key, KNOT_DB_GEQ); + ret += api->iter_key(it, &key); + is_string(first_key, key.data, "%s: iter_set(GEQ)", api->name); + api->iter_finish(it); + is_int(ret, 0, "%s: iter_* error codes", api->name); + } + api->txn_abort(&txn); + + /* Deleting during iteration. */ + const uint8_t DEL_MAX_CNT = 3; + api->txn_begin(db, &txn, 0); + api->clear(&txn); + for (uint8_t i = 0; i < DEL_MAX_CNT; ++i) { + key.data = &i; + key.len = sizeof(i); + val.data = NULL; + val.len = 0; + + ret = api->insert(&txn, &key, &val, 0); + is_int(KNOT_EOK, ret, "%s: add key '%u'", api->name, i); + } + it = api->iter_begin(&txn, KNOT_DB_NOOP); + if (it != NULL) { /* If supported. */ + is_int(DEL_MAX_CNT, api->count(&txn), "%s: key count before", api->name); + it = api->iter_seek(it, NULL, KNOT_DB_FIRST); + uint8_t pos = 0; + while (it != NULL) { + ret = api->iter_key(it, &key); + is_int(KNOT_EOK, ret, "%s: iter key before del", api->name); + is_int(pos, ((uint8_t *)(key.data))[0], "%s: iter compare key '%u'", + api->name, pos); + + ret = knot_db_lmdb_iter_del(it); + is_int(KNOT_EOK, ret, "%s: iter del", api->name); + + it = api->iter_next(it); + + ret = api->iter_key(it, &key); + if (++pos < DEL_MAX_CNT) { + is_int(KNOT_EOK, ret, "%s: iter key after del", api->name); + is_int(pos, ((uint8_t *)key.data)[0], "%s: iter compare key '%u", + api->name, pos); + } else { + is_int(KNOT_EINVAL, ret, "%s: iter key after del", api->name); + } + } + api->iter_finish(it); + is_int(0, api->count(&txn), "%s: key count after", api->name); + } + api->txn_abort(&txn); + + /* Clear database and recheck. */ + ret = api->txn_begin(db, &txn, 0); + ret += api->clear(&txn); + ret += api->txn_commit(&txn); + is_int(0, ret, "%s: clear()", api->name); + + /* Check if the database is empty. */ + api->txn_begin(db, &txn, KNOT_DB_RDONLY); + db_size = api->count(&txn); + is_int(0, db_size, "%s: count after clear = %d", api->name, db_size); + api->txn_abort(&txn); + + api->deinit(db); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_mm_t pool; + mm_ctx_mempool(&pool, MM_DEFAULT_BLKSIZE); + + char *dbid = test_mkdtemp(); + ok(dbid != NULL, "make temporary directory"); + + /* Random keys. */ + unsigned nkeys = 10000; + char **keys = mm_alloc(&pool, sizeof(char*) * nkeys); + for (unsigned i = 0; i < nkeys; ++i) { + keys[i] = str_key_rand(KEY_MAXLEN, &pool); + } + + /* Sort random keys. */ + str_key_sort(keys, nkeys); + + /* Execute test set for all backends. */ + struct knot_db_lmdb_opts lmdb_opts = KNOT_DB_LMDB_OPTS_INITIALIZER; + lmdb_opts.path = dbid; + struct knot_db_trie_opts trie_opts = KNOT_DB_TRIE_OPTS_INITIALIZER; + knot_db_test_set(nkeys, keys, &lmdb_opts, knot_db_lmdb_api(), &pool); + knot_db_test_set(nkeys, keys, &trie_opts, knot_db_trie_api(), &pool); + + /* Cleanup. */ + mp_delete(pool.ctx); + test_rm_rf(dbid); + free(dbid); + + return 0; +} diff --git a/tests/libknot/test_descriptor.c b/tests/libknot/test_descriptor.c new file mode 100644 index 0000000..ecb6797 --- /dev/null +++ b/tests/libknot/test_descriptor.c @@ -0,0 +1,361 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/descriptor.h" + +#define BUF_LEN 256 + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + const knot_rdata_descriptor_t *descr; + char name[BUF_LEN] = { 0 }; + int ret; + uint16_t num; + + // Get descriptor, type num to string: + // 1. TYPE0 + descr = knot_get_rdata_descriptor(0); + ok(descr->type_name == 0, "get TYPE0 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE0 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE0 descriptor 2. item type"); + + ret = knot_rrtype_to_string(0, name, BUF_LEN); + ok(ret != -1, "get TYPE0 ret"); + ok(strcmp(name, "TYPE0") == 0, "get TYPE0 name"); + + // 2. A + descr = knot_get_rdata_descriptor(1); + ok(strcmp(descr->type_name, "A") == 0, "get A descriptor name"); + ok(descr->block_types[0] == 4, + "get A descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get A descriptor 2. item type"); + + ret = knot_rrtype_to_string(1, name, BUF_LEN); + ok(ret != -1, "get A ret"); + ok(strcmp(name, "A") == 0, "get A name"); + + // 3. CNAME + descr = knot_get_rdata_descriptor(5); + ok(strcmp(descr->type_name, "CNAME") == 0, "get CNAME descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_COMPRESSIBLE_DNAME, + "get CNAME descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get CNAME descriptor 2. item type"); + + ret = knot_rrtype_to_string(5, name, BUF_LEN); + ok(ret != -1, "get CNAME ret"); + ok(strcmp(name, "CNAME") == 0, "get CNAME name"); + + // 4. TYPE38 (A6) + descr = knot_get_rdata_descriptor(38); + ok(descr->type_name == 0, "get TYPE38 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE38 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE38 descriptor 2. item type"); + + ret = knot_rrtype_to_string(38, name, BUF_LEN); + ok(ret != -1, "get TYPE38 ret"); + ok(strcmp(name, "TYPE38") == 0, "get TYPE38 name"); + + // 5. ANY + descr = knot_get_rdata_descriptor(255); + ok(strcmp(descr->type_name, "ANY") == 0, "get ANY descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get ANY descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get ANY descriptor 2. item type"); + + ret = knot_rrtype_to_string(255, name, BUF_LEN); + ok(ret != -1, "get ANY ret"); + ok(strcmp(name, "ANY") == 0, "get ANY name"); + + // 6. TYPE65535 + descr = knot_get_rdata_descriptor(65535); + ok(descr->type_name == 0, "get TYPE65535 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE65535 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE65535 descriptor 2. item type"); + + ret = knot_rrtype_to_string(65535, name, BUF_LEN); + ok(ret != -1, "get TYPE65535 ret"); + ok(strcmp(name, "TYPE65535") == 0, "get TYPE65535 name"); + + // Class num to string: + // 7. CLASS0 + ret = knot_rrclass_to_string(0, name, BUF_LEN); + ok(ret != -1, "get CLASS0 ret"); + ok(strcmp(name, "CLASS0") == 0, "get CLASS0 name"); + + // 8. IN + ret = knot_rrclass_to_string(1, name, BUF_LEN); + ok(ret != -1, "get IN ret"); + ok(strcmp(name, "IN") == 0, "get IN name"); + + // 9. ANY + ret = knot_rrclass_to_string(255, name, BUF_LEN); + ok(ret != -1, "get ANY ret"); + ok(strcmp(name, "ANY") == 0, "get ANY name"); + + // 10. CLASS65535 + ret = knot_rrclass_to_string(65535, name, BUF_LEN); + ok(ret != -1, "get CLASS65535 ret"); + ok(strcmp(name, "CLASS65535") == 0, "get CLASS65535 name"); + + // String to type num: + // 11. A + ret = knot_rrtype_from_string("A", &num); + ok(ret != -1, "get A num ret"); + ok(num == 1, "get A num"); + + // 12. a + ret = knot_rrtype_from_string("a", &num); + ok(ret != -1, "get a num ret"); + ok(num == 1, "get a num"); + + // 13. AaAa + ret = knot_rrtype_from_string("AaAa", &num); + ok(ret != -1, "get AaAa num ret"); + ok(num == 28, "get AaAa num"); + + // 14. "" + ret = knot_rrtype_from_string("", &num); + ok(ret == -1, "get "" num ret"); + + // 15. DUMMY + ret = knot_rrtype_from_string("DUMMY", &num); + ok(ret == -1, "get DUMMY num ret"); + + // 16. TypE33 + ret = knot_rrtype_from_string("TypE33", &num); + ok(ret != -1, "get TypE33 num ret"); + ok(num == 33, "get TypE33 num"); + + // 17. TYPE + ret = knot_rrtype_from_string("TYPE", &num); + ok(ret == -1, "get TYPE num ret"); + + // 18. TYPE0 + ret = knot_rrtype_from_string("TYPE0", &num); + ok(ret != -1, "get TYPE0 num ret"); + ok(num == 0, "get TYPE0 num"); + + // 19. TYPE65535 + ret = knot_rrtype_from_string("TYPE65535", &num); + ok(ret != -1, "get TYPE65535 num ret"); + ok(num == 65535, "get TYPE65535 num"); + + // 20. TYPE65536 + ret = knot_rrtype_from_string("TYPE65536", &num); + ok(ret == -1, "get TYPE65536 num ret"); + + // String to class num: + // 21. In + ret = knot_rrclass_from_string("In", &num); + ok(ret != -1, "get In num ret"); + ok(num == 1, "get In num"); + + // 22. ANY + ret = knot_rrclass_from_string("ANY", &num); + ok(ret != -1, "get ANY num ret"); + ok(num == 255, "get ANY num"); + + // 23. "" + ret = knot_rrclass_from_string("", &num); + ok(ret == -1, "get "" num ret"); + + // 24. DUMMY + ret = knot_rrclass_from_string("DUMMY", &num); + ok(ret == -1, "get DUMMY num ret"); + + // 25. CLass33 + ret = knot_rrclass_from_string("CLass33", &num); + ok(ret != -1, "get CLass33 num ret"); + ok(num == 33, "get CLass33 num"); + + // 26. CLASS + ret = knot_rrclass_from_string("CLASS", &num); + ok(ret == -1, "get CLASS num ret"); + + // 27. CLASS0 + ret = knot_rrclass_from_string("CLASS0", &num); + ok(ret != -1, "get CLASS0 num ret"); + ok(num == 0, "get CLASS0 num"); + + // 28. CLASS65535 + ret = knot_rrclass_from_string("CLASS65535", &num); + ok(ret != -1, "get CLASS65535 num ret"); + ok(num == 65535, "get CLASS65535 num"); + + // 29. CLASS65536 + ret = knot_rrclass_from_string("CLASS65536", &num); + ok(ret == -1, "get CLASS65536 num ret"); + + // Get obsolete descriptor: + // 30. TYPE0 + descr = knot_get_obsolete_rdata_descriptor(0); + ok(descr->type_name == 0, "get TYPE0 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE0 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE0 descriptor 2. item type"); + + // 31. MD + descr = knot_get_obsolete_rdata_descriptor(3); + ok(strcmp(descr->type_name, "MD") == 0, "get MD descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_DECOMPRESSIBLE_DNAME, + "get A descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get A descriptor 2. item type"); + + // 32. NXT + descr = knot_get_obsolete_rdata_descriptor(30); + ok(strcmp(descr->type_name, "NXT") == 0, "get NXT descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_DECOMPRESSIBLE_DNAME, + "get CNAME descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_REMAINDER, + "get CNAME descriptor 2. item type"); + ok(descr->block_types[2] == KNOT_RDATA_WF_END, + "get CNAME descriptor 3. item type"); + + // 33. TYPE38 (A6) + descr = knot_get_obsolete_rdata_descriptor(38); + ok(descr->type_name == 0, "get TYPE38 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE38 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE38 descriptor 2. item type"); + + // knot_rrtype_to_string invalid output buffer size + ret = knot_rrtype_to_string(1, NULL, 0); + ok(ret == -1, "knot_rrtype_to_string: invalid output buffer size"); + + // knot_rrclass_to_string invalid output buffer size + ret = knot_rrclass_to_string(1, NULL, 0); + ok(ret == -1, "knot_rrclass_to_string: invalid output buffer size"); + + // knot_rrtype_is_metatype + ok(knot_rrtype_is_metatype(0) == 0, + "rrtype is not metatype"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_SIG) != 0, + "rrtype is SIG"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_OPT) != 0, + "rrtype is OPT"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_TKEY) != 0, + "rrtype is TKEY"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_TSIG) != 0, + "rrtype is TSIG"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_IXFR) != 0, + "rrtype is IXFR"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_AXFR) != 0, + "rrtype is AXFR"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_ANY) != 0, + "rrtype is ANY"); + + // knot_rrtype_is_dnssec + ok(knot_rrtype_is_dnssec(0) == 0, + "rrtype is not DNSSEC"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_DNSKEY) != 0, + "rrtype is DNSKEY"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_RRSIG) != 0, + "rrtype is RRSIG"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_NSEC) != 0, + "rrtype is NSEC"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_NSEC3) != 0, + "rrtype is NSEC3"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_NSEC3PARAM) != 0, + "rrtype is NSEC3PARAM"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_CDNSKEY) != 0, + "rrtype is CDNSKEY"); + + // knot_rrtype_additional_needed + ok(knot_rrtype_additional_needed(0) == 0, + "rrtype is not additional needed"); + ok(knot_rrtype_additional_needed(KNOT_RRTYPE_NS) != 0, + "rrtype is NS"); + ok(knot_rrtype_additional_needed(KNOT_RRTYPE_MX) != 0, + "rrtype is MX"); + ok(knot_rrtype_additional_needed(KNOT_RRTYPE_SRV) != 0, + "rrtype is SRV"); + + // knot_rrtype_should_be_lowercased + ok(knot_rrtype_should_be_lowercased(0) == 0, + "rrtype should not be lowercased"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_NS) != 0, + "rrtype is NS"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MD) != 0, + "rrtype is MD"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MF) != 0, + "rrtype is MF"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_CNAME) != 0, + "rrtype is CNAME"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_SOA) != 0, + "rrtype is SOA"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MB) != 0, + "rrtype is MB"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MG) != 0, + "rrtype is MG"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MR) != 0, + "rrtype is MR"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_PTR) != 0, + "rrtype is PTR"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MINFO) != 0, + "rrtype is MINFO"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MX) != 0, + "rrtype is MX"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_RP) != 0, + "rrtype is RP"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_AFSDB) != 0, + "rrtype is AFSDB"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_RT) != 0, + "rrtype is RT"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_SIG) != 0, + "rrtype is SIG"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_PX) != 0, + "rrtype is PX"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_NXT) != 0, + "rrtype is NXT"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_NAPTR) != 0, + "rrtype is NAPTR"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_KX) != 0, + "rrtype is KX"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_SRV) != 0, + "rrtype is SRV"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_DNAME) != 0, + "rrtype is DNAME"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_RRSIG) != 0, + "rrtype is RRSIG"); + + ret = knot_opt_code_to_string(0, name, BUF_LEN); + ok(ret != -1 && strcmp(name, "CODE0") == 0, "opt to str, code 0"); + ret = knot_opt_code_to_string(10, name, BUF_LEN); + ok(ret != -1 && strcmp(name, "COOKIE") == 0, "opt to str, code 10"); + ret = knot_opt_code_to_string(65535, name, BUF_LEN); + ok(ret != -1 && strcmp(name, "CODE65535") == 0, "opt to str, code 65535"); + + return 0; +} diff --git a/tests/libknot/test_dname.c b/tests/libknot/test_dname.c new file mode 100644 index 0000000..1201d46 --- /dev/null +++ b/tests/libknot/test_dname.c @@ -0,0 +1,584 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/dname.h" + +/* Test dname_parse_from_wire */ +static int test_fw(size_t l, const char *w) { + const uint8_t *np = (const uint8_t *)w + l; + return knot_dname_wire_check((const uint8_t *)w, np, NULL) > 0; +} + +/* Test dname to/from string operations */ +static void test_str(const char *in_str, const char *in_bin, size_t bin_len) { + uint8_t d1[KNOT_DNAME_MAXLEN] = ""; + char s1[4 * KNOT_DNAME_MAXLEN] = ""; + knot_dname_t *d2 = NULL, *aux_d = NULL; + char *s2 = NULL, *aux_s = NULL; + int ret = 0; + + /* dname_from_str */ + aux_d = knot_dname_from_str(d1, in_str, sizeof(d1)); + ok(aux_d != NULL, "dname_from_str: %s", in_str); + if (aux_d == NULL) { + skip_block(10, "dname_from_str: %s", in_str); + return; + } + + /* dname_wire_check */ + ret = knot_dname_wire_check(d1, d1 + sizeof(d1), NULL); + ok(ret == bin_len, "dname_wire_check: %s", in_str); + + /* dname compare */ + ok(memcmp(d1, in_bin, bin_len) == 0, "dname compare: %s", in_str); + + /* dname_to_str */ + aux_s = knot_dname_to_str(s1, d1, sizeof(s1)); + ok(aux_s != NULL, "dname_to_str: %s", in_str); + if (aux_s == NULL) { + skip_block(7, "dname_to_str: %s", in_str); + return; + } + + /* dname_from_str_alloc */ + d2 = knot_dname_from_str_alloc(s1); + ok(d2 != NULL, "dname_from_str_alloc: %s", s1); + if (d2 == NULL) { + skip_block(6, "dname_from_str_alloc: %s", s1); + return; + } + + /* dname_wire_check */ + ret = knot_dname_wire_check(d2, d2 + bin_len, NULL); + ok(ret == bin_len, "dname_wire_check: %s", s1); + + /* dname compare */ + ok(d2 && memcmp(d2, in_bin, bin_len) == 0, "dname compare: %s", s1); + + /* dname_to_str_alloc */ + s2 = knot_dname_to_str_alloc(d2); + knot_dname_free(d2, NULL); + ok(s2 != NULL, "dname_to_str_alloc: %s", s1); + if (s2 == NULL) { + skip_block(3, "dname_to_str_alloc: %s", s1); + return; + } + + /* As the string representation is ambiguous, the following steps + * are just for comparison in wire form. + */ + d2 = knot_dname_from_str_alloc(s2); + ok(d2 != NULL, "dname_from_str_alloc: %s", s2); + if (aux_d == NULL) { + skip_block(2, "dname_from_str_alloc: %s", s2); + free(s2); + return; + } + + /* dname_wire_check */ + ret = knot_dname_wire_check(d2, d2 + bin_len, NULL); + ok(ret == bin_len, "dname_wire_check: %s", s2); + + /* dname compare */ + ok(d2 && memcmp(d2, in_bin, bin_len) == 0, "dname compare: %s", s2); + + knot_dname_free(d2, NULL); + free(s2); +} + +static void test_dname_lf(void) +{ + knot_dname_storage_t storage; + + /* Maximal DNAME length */ + const knot_dname_t *in = (uint8_t *) + "\x3f""iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" + "\x3f""hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh" + "\x3f""ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg" + "\x1f""fffffffffffffffffffffffffffffff" + "\x0f""eeeeeeeeeeeeeee" + "\x07""ddddddd" + "\x03""ccc" + "\x01""b" + "\x00"; + const uint8_t *ref = (uint8_t *) + "\xFE" + "b""\x00" + "ccc""\00" + "ddddddd""\x00" + "eeeeeeeeeeeeeee""\x00" + "fffffffffffffffffffffffffffffff""\x00" + "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg""\x00" + "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh""\x00" + "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii""\x00"; + uint8_t *out = knot_dname_lf(in, storage); + ok(out != NULL && memcmp(ref, out, KNOT_DNAME_MAXLEN) == 0, + "knot_dname_lf: max-length DNAME converted"); + + /* Zero label DNAME*/ + in = (uint8_t *) "\x00"; + out = knot_dname_lf(in, storage); + ok(out != NULL && out[0] == '\x00', "knot_dname_lf: zero-label DNAME converted"); +} + +static void test_dname_storage(void) +{ + const knot_dname_t *dname = (uint8_t *)"\x04""test"; + size_t dname_len = knot_dname_size(dname); + + knot_dname_storage_t storage; + size_t store_len = knot_dname_store(storage, dname); + size_t storage_len = knot_dname_size(storage); + + ok(store_len == dname_len && storage_len == dname_len && + memcmp(storage, dname, dname_len) == 0, + "knot_dname_storage: valid name"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_dname_t *d = NULL, *d2 = NULL; + const char *w = NULL, *t = NULL; + char *s = NULL; + + /* DNAME WIRE CHECKS */ + + /* NULL wire */ + ok(!test_fw(0, NULL), "parsing NULL dname"); + + /* empty label */ + ok(test_fw(1, ""), "parsing empty dname"); + + /* incomplete dname */ + ok(!test_fw(5, "\x08" "dddd"), "parsing incomplete wire"); + + /* non-fqdn */ + ok(!test_fw(3, "\x02" "ab"), "parsing non-fqdn name"); + + /* label length == 63 */ + w = "\x3f" "123456789012345678901234567890123456789012345678901234567890123"; + ok(test_fw(1 + 63 + 1, w), "parsing label length == 63"); + + /* label length > 63 */ + w = "\x40" "1234567890123456789012345678901234567890123456789012345678901234"; + ok(!test_fw(1 + 64 + 1, w), "parsing label length > 63"); + + /* label count == 127 (also maximal dname length) */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"; + ok(test_fw(127 * 2 + 1, w), "parsing label count == 127"); + + /* label count > 127 */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"; + ok(!test_fw(128 * 2 + 1, w), "parsing label count > 127"); + + /* dname length > 255 */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x02\x64\x64"; + ok(!test_fw(126 * 2 + 3 + 1, w), "parsing dname len > 255"); + + /* DNAME STRING CHECKS */ + + /* root dname */ + test_str(".", "\x00", 1); + + /* 1-char dname */ + test_str("a.", "\x01""a", 2 + 1); + + /* 1-char dname - non-fqdn */ + test_str("a", "\x01""a", 2 + 1); + + /* wildcard and asterisks */ + test_str("*.*a.a*a.**.", + "\x01" "*" "\x02" "*a" "\x03" "a*a" "\x02" "**", + 2 + 3 + 4 + 3 + 1); + + /* special label */ + test_str("\\000\\0320\\ \\\\\\\"\\.\\@\\*.", + "\x09" "\x00\x20\x30\x20\x5c\x22.@*", + 10 + 1); + + /* unescaped special characters */ + test_str("_a.b-c./d.", + "\x02" "_a" "\x03" "b-c" "\x02" "/d", + 3 + 4 + 3 + 1); + + /* all possible characters */ + test_str("\\000\\001\\002\\003\\004\\005\\006\\007\\008\\009\\010\\011\\012\\013\\014\\015\\016\\017\\018\\019", + "\x14" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13", + 22); + test_str("\\020\\021\\022\\023\\024\\025\\026\\027\\028\\029\\030\\031\\032\\033\\034\\035\\036\\037\\038\\039", + "\x14" "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27", + 22); + test_str("\\040\\041\\042\\043\\044\\045\\046\\047\\048\\049\\050\\051\\052\\053\\054\\055\\056\\057\\058\\059", + "\x14" "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b", + 22); + test_str("\\060\\061\\062\\063\\064\\065\\066\\067\\068\\069\\070\\071\\072\\073\\074\\075\\076\\077\\078\\079", + "\x14" "\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", + 22); + test_str("\\080\\081\\082\\083\\084\\085\\086\\087\\088\\089\\090\\091\\092\\093\\094\\095\\096\\097\\098\\099", + "\x14" "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63", + 22); + test_str("\\100\\101\\102\\103\\104\\105\\106\\107\\108\\109\\110\\111\\112\\113\\114\\115\\116\\117\\118\\119", + "\x14" "\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77", + 22); + test_str("\\120\\121\\122\\123\\124\\125\\126\\127\\128\\129\\130\\131\\132\\133\\134\\135\\136\\137\\138\\139", + "\x14" "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b", + 22); + test_str("\\140\\141\\142\\143\\144\\145\\146\\147\\148\\149\\150\\151\\152\\153\\154\\155\\156\\157\\158\\159", + "\x14" "\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", + 22); + test_str("\\160\\161\\162\\163\\164\\165\\166\\167\\168\\169\\170\\171\\172\\173\\174\\175\\176\\177\\178\\179", + "\x14" "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3", + 22); + test_str("\\180\\181\\182\\183\\184\\185\\186\\187\\188\\189\\190\\191\\192\\193\\194\\195\\196\\197\\198\\199", + "\x14" "\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", + 22); + test_str("\\200\\201\\202\\203\\204\\205\\206\\207\\208\\209\\210\\211\\212\\213\\214\\215\\216\\217\\218\\219", + "\x14" "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb", + 22); + test_str("\\220\\221\\222\\223\\224\\225\\226\\227\\228\\229\\230\\231\\232\\233\\234\\235\\236\\237\\238\\239", + "\x14" "\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef", + 22); + test_str("\\240\\241\\242\\243\\244\\245\\246\\247\\248\\249\\250\\251\\252\\253\\254\\255", + "\x10" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", + 18); + + /* maximal dname label length */ + test_str("12345678901234567890123456789012345678901234567890123456789012\\063", + "\x3f" "12345678901234567890123456789012345678901234567890123456789012?", + 65); + + /* maximal dname length */ + test_str("1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "\\#234567890123456789012345678901234567890123456789012\\063", + "\x31" "1234567890123456789012345678901234567890123456789" + "\x31" "1234567890123456789012345678901234567890123456789" + "\x31" "1234567890123456789012345678901234567890123456789" + "\x31" "1234567890123456789012345678901234567890123456789" + "\x35" "#234567890123456789012345678901234567890123456789012?", + 255); + + /* NULL output, positive maxlen */ + w = "\x02" "aa"; + s = knot_dname_to_str(NULL, (const uint8_t *)w, 1); + ok(s != NULL, "dname_to_str: null dname"); + if (s != NULL) { + ok(memcmp(s, "aa.", 4) == 0, "dname_to_str: null dname compare"); + free(s); + } else { + skip("dname_to_str: null dname"); + } + + /* non-NULL output, zero maxlen */ + char s_small[2]; + s = knot_dname_to_str(s_small, (const uint8_t *)w, 0); + ok(s == NULL, "dname_to_str: non-NULL output, zero maxlen"); + + /* small buffer */ + s = knot_dname_to_str(s_small, (const uint8_t *)w, 1); + ok(s == NULL, "dname_to_str: small buffer"); + + /* NULL dname */ + s = knot_dname_to_str_alloc(NULL); + ok(s == NULL, "dname_to_str: null dname"); + + /* empty dname is considered as a root dname */ + w = ""; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: empty dname"); + if (s != NULL) { + ok(memcmp(s, ".", 1) == 0, "dname_to_str: empty dname is root dname"); + free(s); + } else { + skip("dname_to_str: empty dname"); + } + + /* incomplete dname */ + /* ASAN: global-buffer-overflow + w = "\x08" "dddd"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: incomplete dname"); + free(s); + */ + + /* non-fqdn */ + w = "\x02" "ab"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: non-fqdn"); + free(s); + + /* label length > 63 */ + w = "\x40" "1234567890123456789012345678901234567890123456789012345678901234"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: label length > 63"); + free(s); + + /* label count > 127 */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: label count > 127"); + free(s); + + /* dname length > 255 */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x02\x64\x64"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: dname length > 255"); + free(s); + + /* output overflow sanity check */ + uint8_t in[4] = "\x02""\x00\x00""\x00"; + for (uint16_t i = 0; i < UINT16_MAX; i++) { + memcpy(in + 1, &i, sizeof(i)); + for (int j = 3; j < 8; j++) { + char tmp[j]; + char *out_static = knot_dname_to_str(tmp, in, sizeof(tmp)); + char *out_dynamic = knot_dname_to_str_alloc(in); + if (out_dynamic == NULL) { + ok(out_dynamic != NULL, "dname_to_str_alloc: invalid input"); + } else if (strlen(out_dynamic) < sizeof(tmp) - 1 && + out_static == NULL) { + ok(out_static != NULL, "dname_to_str: invalid input"); + } + free(out_dynamic); + } + } + + /* NULL output, positive maxlen */ + s = "aa."; + d = knot_dname_from_str(NULL, s, 1); + ok(s != NULL, "dname_from_str: null name"); + if (s != NULL) { + ok(memcmp(d, "\x02" "aa", 4) == 0, "dname_from_str: null name compare"); + free(d); + } else { + skip("dname_from_str: null name"); + } + + /* non-NULL output, zero maxlen */ + uint8_t d_small[2]; + d = knot_dname_from_str(d_small, s, 0); + ok(d == NULL, "dname_from_str: non-NULL output, zero maxlen"); + + /* small buffer */ + d = knot_dname_from_str(d_small, s, 1); + ok(d == NULL, "dname_from_str: small buffer"); + + /* NULL string */ + d = knot_dname_from_str_alloc(NULL); + ok(d == NULL, "dname_from_str: null string"); + + /* empty string */ + t = ""; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: empty string"); + + /* empty label */ + t = ".."; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: empty label"); + + /* leading dot */ + t = ".a"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: leading dot"); + + /* incomplete decimal notation I */ + t = "\\1"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: incomplete decimal I"); + + /* incomplete decimal notation II */ + t = "\\12"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: incomplete decimal II"); + + /* invalid decimal notation I */ + t = "\\256"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: invalid decimal I"); + + /* invalid decimal notation II */ + t = "\\2x6"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: invalid decimal II"); + + /* invalid escape notation */ + t = "\\2"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: invalid escape"); + + /* label length > 63 I */ + t = "1234567890123456789012345678901234567890123456789012345678901234"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: label length > 63 I"); + + /* label length > 63 II */ + t = "123456789012345678901234567890123456789012345678901234567890123\\?"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: label length > 63 II"); + + /* label length > 63 III */ + t = "123456789012345678901234567890123456789012345678901234567890123\\063"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: label length > 63 III"); + + /* dname length > 255 */ + t = "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "123456789012345678901234567890123456789012345678901234.", + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: dname length > 255"); + + /* DNAME SUBDOMAIN CHECKS */ + + /* equal name is subdomain */ + t = "ab.cd.ef"; + d2 = knot_dname_from_str_alloc(t); + t = "ab.cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_in_bailiwick(d, d2) == 0, "dname_subdomain: equal name"); + knot_dname_free(d, NULL); + + /* true subdomain */ + t = "0.ab.cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_in_bailiwick(d, d2) == 1, "dname_subdomain: true subdomain"); + knot_dname_free(d, NULL); + + /* not subdomain */ + t = "cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_in_bailiwick(d, d2) < 0, "dname_subdomain: not subdomain"); + knot_dname_free(d, NULL); + + /* root subdomain */ + t = "."; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_in_bailiwick(d2, d) == 3, "dname_subdomain: root subdomain"); + knot_dname_free(d, NULL); + knot_dname_free(d2, NULL); + + /* DNAME EQUALITY CHECKS */ + + t = "ab.cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_is_equal(d, d), "dname_is_equal: equal names"); + + t = "ab.cd.fe"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: same label count"); + knot_dname_free(d2, NULL); + + t = "ab.cd"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: len(d1) < len(d2)"); + knot_dname_free(d2, NULL); + + t = "ab.cd.ef.gh"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: len(d1) > len(d2)"); + knot_dname_free(d2, NULL); + + t = "ab.cd.efe"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: last label longer"); + knot_dname_free(d2, NULL); + + t = "ab.cd.e"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: last label shorter"); + knot_dname_free(d2, NULL); + + knot_dname_free(d, NULL); + + /* OTHER CHECKS */ + + test_dname_lf(); + + test_dname_storage(); + + return 0; +} diff --git a/tests/libknot/test_edns.c b/tests/libknot/test_edns.c new file mode 100644 index 0000000..0da882c --- /dev/null +++ b/tests/libknot/test_edns.c @@ -0,0 +1,484 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <assert.h> +#include "libknot/libknot.h" +#include "libknot/rrtype/opt.h" +#include "libknot/descriptor.h" +#include "libknot/wire.h" +#include "contrib/sockaddr.h" + +static const uint16_t E_MAX_PLD = 10000; +static const uint16_t E_MAX_PLD2 = 20000; +static const uint8_t E_VERSION = 1; +static const uint8_t E_VERSION2 = 2; +static const uint8_t E_RCODE = 0; +static const uint8_t E_RCODE2 = 200; + +static const char *E_NSID_STR = "FooBar"; +static const uint16_t E_NSID_LEN = 6; + +#define E_NSID_SIZE (4 + E_NSID_LEN) + +static const uint16_t E_OPT3_CODE = 15; +static const char *E_OPT3_FAKE_DATA = "Not used"; +static const char *E_OPT3_DATA = NULL; +static const uint16_t E_OPT3_LEN = 0; +static const uint16_t E_OPT3_FAKE_LEN = 8; + +#define E_OPT3_SIZE (4 + E_OPT3_LEN) + +static const uint16_t E_OPT4_CODE = 30; +static const char *E_OPT4_DATA = NULL; +static const uint16_t E_OPT4_LEN = 0; + +#define E_OPT4_SIZE (4 + E_OPT4_LEN) + +enum offsets { + /*! \brief Offset of Extended RCODE in wire order of TTL. */ + OFFSET_ERCODE = 0, + /*! \brief Offset of Version in wire order of TTL. */ + OFFSET_VER = 1, + /*! \brief Offset of Flags in wire order of TTL. */ + OFFSET_FLAGS = 2, + /*! \brief Offset of OPTION code in one OPTION in RDATA. */ + OFFSET_OPT_CODE = 0, + /*! \brief Offset of OPTION size in one OPTION in RDATA. */ + OFFSET_OPT_SIZE = 2, + /*! \brief Offset of OPTION data in one OPTION in RDATA. */ + OFFSET_OPT_DATA = 4 +}; + +static const uint16_t DO_FLAG = (uint16_t)1 << 15; + +static void check_ttl(knot_rrset_t *rrset, uint8_t ext_rcode, uint8_t ver, + uint16_t flags, char *msg) +{ + if (rrset == NULL) { + return; + } + + /* TTL should be stored in machine byte order. + We need network byte order to compare its parts. */ + uint8_t ttl_wire[4] = { 0, 0, 0, 0 }; + knot_wire_write_u32(ttl_wire, rrset->ttl); + + /* Convert Flags from EDNS parameters to wire format for comparison. */ + uint8_t flags_wire[2] = { 0, 0 }; + knot_wire_write_u16(flags_wire, flags); + + /* TTL = Ext RCODE + Version + Flags */ + bool check = (ttl_wire[OFFSET_ERCODE] == ext_rcode); + ok(check, "%s: extended RCODE", msg); + + check = (ttl_wire[OFFSET_VER] == ver); + ok(check, "%s: version", msg); + + check = (memcmp(flags_wire, ttl_wire + OFFSET_FLAGS, 2) == 0); + ok(check, "%s: flags", msg); +} + +static void check_option(knot_rdata_t *rdata, uint16_t opt_code, + uint16_t opt_len, uint8_t *opt_data, char *msg) +{ + assert(rdata != NULL); + + uint8_t *data = rdata->data; + uint16_t data_len = rdata->len; + + /* Check RDLENGTH according to given data length. */ + bool check = (data_len >= 4 + opt_len); + ok(check, "%s: RDLENGTH (%u)", msg, data_len); + + /* Find the desired option. */ + bool found = false; + int pos = 0; + while (pos <= data_len - 4) { + uint16_t code = knot_wire_read_u16(data + pos + OFFSET_OPT_CODE); + if (code == opt_code) { + found = true; + break; + } + uint16_t len = knot_wire_read_u16(data + pos + OFFSET_OPT_SIZE); + pos += 4 + len; + } + + /* Check that the option is present. */ + ok(found, "%s: find OPTION %u in OPT RR", msg, opt_code); + + /* Check that the first OPTION's size si the size of the option data. */ + uint16_t opt_size = knot_wire_read_u16(data + pos + OFFSET_OPT_SIZE); + check = (opt_size == opt_len); + ok(check, "%s: OPTION data size", msg); + + /* Check the actual NSID data. */ + check = (opt_data == 0 || memcmp(data + pos + OFFSET_OPT_DATA, opt_data, opt_len) == 0); + ok(check, "%s: OPTION data", msg); +} + +static void check_header(knot_rrset_t *opt_rr, uint16_t payload, uint8_t ver, + uint16_t flags, uint8_t ext_rcode, char *msg) +{ + assert(opt_rr != NULL); + bool check; + + /* Check values in OPT RR by hand. */ + /* CLASS == Max UDP payload */ + check = (opt_rr->rclass == payload); + ok(check, "%s: max payload", msg); + + /* The OPT RR should have exactly one RDATA. */ + check = (opt_rr->rrs.count == 1); + ok(check, "%s: RR count == 1", msg); + + knot_rdata_t *rdata = opt_rr->rrs.rdata; + check = (rdata != NULL); + ok(check, "%s: RDATA exists", msg); + + check_ttl(opt_rr, ext_rcode, ver, flags, msg); +} + +static void test_getters(knot_rrset_t *opt_rr) +{ + assert(opt_rr != NULL); + + /* These values should be set from the setters test: + * Max UDP payload: E_MAX_PLD2 + * Version: E_VERSION2 + * RCODE: E_RCODE2 + * Flags: E_FLAGS | KNOT_EDNS_FLAG_DO + * OPTIONs: 1) KNOT_EDNS_OPTION_NSID, E_NSID_LEN, E_NSID_STR + * 2) E_OPT3_CODE, 0, 0 + * 3) E_OPT4_CODE, 0, 0 + */ + + /* Payload */ + bool check = (knot_edns_get_payload(opt_rr) == E_MAX_PLD2); + ok(check, "OPT RR getters: payload"); + + /* Extended RCODE */ + check = (knot_edns_get_ext_rcode(opt_rr) == E_RCODE2); + ok(check, "OPT RR getters: extended RCODE"); + + /* Extended RCODE */ + check = (knot_edns_get_version(opt_rr) == E_VERSION2); + ok(check, "OPT RR getters: version"); + + /* DO bit */ + check = knot_edns_do(opt_rr); + ok(check, "OPT RR getters: DO bit check"); + + /* Wire size */ + size_t total_size = KNOT_EDNS_MIN_SIZE + + E_NSID_SIZE + E_OPT3_SIZE + E_OPT4_SIZE; + size_t actual_size = knot_edns_wire_size(opt_rr); + check = actual_size == total_size; + ok(check, "OPT RR getters: wire size (expected: %zu, actual: %zu)", + total_size, actual_size); + + /* NSID */ + check = knot_edns_get_option(opt_rr, KNOT_EDNS_OPTION_NSID) != NULL; + ok(check, "OPT RR getters: NSID check"); + + /* Other OPTIONs */ + check = knot_edns_get_option(opt_rr, E_OPT3_CODE) != NULL; + ok(check, "OPT RR getters: empty option 1"); + + check = knot_edns_get_option(opt_rr, E_OPT4_CODE) != NULL; + ok(check, "OPT RR getters: empty option 2"); + + uint16_t code = knot_edns_opt_get_code((const uint8_t *)"\x00\x0a" "\x00\x00"); + ok(code == KNOT_EDNS_OPTION_COOKIE, "OPT RR getters: EDNS OPT code"); +} + +static void test_setters(knot_rrset_t *opt_rr) +{ + assert(opt_rr != NULL); + + /* Header-related setters. */ + knot_edns_set_payload(opt_rr, E_MAX_PLD2); + knot_edns_set_ext_rcode(opt_rr, E_RCODE2); + knot_edns_set_version(opt_rr, E_VERSION2); + knot_edns_set_do(opt_rr); + + check_header(opt_rr, E_MAX_PLD2, E_VERSION2, DO_FLAG, E_RCODE2, + "OPT RR setters"); + + /* OPTION(RDATA)-related setters. */ + + /* Proper option. */ + int ret = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_NSID, + E_NSID_LEN, (uint8_t *)E_NSID_STR, NULL); + is_int(KNOT_EOK, ret, "OPT RR setters: add option with data (ret = %s)", + knot_strerror(ret)); + + /* Wrong argument: no OPT RR. */ + ret = knot_edns_add_option(NULL, E_OPT3_CODE, E_OPT3_FAKE_LEN, + (uint8_t *)E_OPT3_FAKE_DATA, NULL); + is_int(KNOT_EINVAL, ret, "OPT RR setters: add option (rr == NULL) " + "(ret = %s)", knot_strerror(ret)); + + /* Wrong argument: option length != 0 && data == NULL. */ + ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_FAKE_LEN, NULL, + NULL); + is_int(KNOT_EINVAL, ret, "OPT RR setters: add option (data == NULL, " + "len != 0) (ret = %s)", knot_strerror(ret)); + + /* Empty OPTION (length 0, data != NULL). */ + ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_LEN, + (uint8_t *)E_OPT3_FAKE_DATA, NULL); + is_int(KNOT_EOK, ret, "OPT RR setters: add empty option 1 (ret = %s)", + knot_strerror(ret)); + + /* Empty OPTION (length 0, data == NULL). */ + ret = knot_edns_add_option(opt_rr, E_OPT4_CODE, E_OPT4_LEN, + (uint8_t *)E_OPT4_DATA, NULL); + is_int(KNOT_EOK, ret, "OPT RR setters: add empty option 2 (ret = %s)", + knot_strerror(ret)); + + knot_rdata_t *rdata = opt_rr->rrs.rdata; + ok(rdata != NULL, "OPT RR setters: non-empty RDATA"); + + /* Check proper option */ + check_option(rdata, KNOT_EDNS_OPTION_NSID, E_NSID_LEN, + (uint8_t *)E_NSID_STR, "OPT RR setters (proper option)"); + + /* Check empty option 1 */ + check_option(rdata, E_OPT3_CODE, E_OPT3_LEN, + (uint8_t *)E_OPT3_DATA, "OPT RR setters (empty option 1)"); + + /* Check empty option 2 */ + check_option(rdata, E_OPT4_CODE, E_OPT4_LEN, + (uint8_t *)E_OPT4_DATA, "OPT RR setters (empty option 2)"); +} + +static void test_alignment(void) +{ + int ret; + + ret = knot_edns_alignment_size(1, 1, 1); + ok(ret == -1, "no alignment"); + + ret = knot_edns_alignment_size(1, 1, 2); + ok(ret == -1, "no alignment"); + + ret = knot_edns_alignment_size(1, 1, 3); + ok(ret == (6 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret); + + ret = knot_edns_alignment_size(1, 1, 4); + ok(ret == (8 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret); + + ret = knot_edns_alignment_size(1, 1, 512); + ok(ret == (512 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret); +} + +static void test_keepalive(void) +{ + typedef struct { + char *msg; + uint16_t opt_len; + char *opt; + uint16_t val; + } test_t; + + // OK tests. + + static const test_t TESTS[] = { + { "ok 0", 0, "", 0 }, + { "ok 1", 2, "\x00\x01", 1 }, + { "ok 258", 2, "\x01\x02", 258 }, + { "ok 65535", 2, "\xFF\xFF", 65535 }, + { NULL } + }; + + for (const test_t *t = TESTS; t->msg != NULL; t++) { + uint16_t len = knot_edns_keepalive_size(t->val); + ok(len == t->opt_len, "%s: %s, size", __func__, t->msg); + + uint8_t wire[8] = { 0 }; + int ret = knot_edns_keepalive_write(wire, sizeof(wire), t->val); + is_int(KNOT_EOK, ret, "%s: %s, write, return", __func__, t->msg); + ok(memcmp(wire, t->opt, t->opt_len) == 0, "%s: %s, write, value", + __func__, t->msg); + + uint16_t timeout = 0; + ret = knot_edns_keepalive_parse(&timeout, (uint8_t *)t->opt, t->opt_len); + is_int(KNOT_EOK, ret, "%s: %s, parse, return", __func__, t->msg); + ok(timeout == t->val, "%s: %s, parse, value", __func__, t->msg); + } + + // Error tests. + + uint8_t wire[8] = { 0 }; + ok(knot_edns_keepalive_write(NULL, 0, 0) == KNOT_EINVAL, + "%s: write, NULL", __func__); + ok(knot_edns_keepalive_write(wire, 1, 1) == KNOT_ESPACE, + "%s: write, no room", __func__); + + uint16_t timeout = 0; + ok(knot_edns_keepalive_parse(NULL, (const uint8_t *)"", 0) == KNOT_EINVAL, + "%s: parse, NULL", __func__); + ok(knot_edns_keepalive_parse(&timeout, NULL, 0) == KNOT_EINVAL, + "%s: parse, NULL", __func__); + ok(knot_edns_keepalive_parse(&timeout, (const uint8_t *)"\x01", 1) == KNOT_EMALF, + "%s: parse, malformed", __func__); +} + +static void test_chain(void) +{ + typedef struct { + char *msg; + uint16_t opt_len; + knot_dname_t *dname; + } test_t; + + // OK tests. + + static const test_t TESTS[] = { + { ".", 1, (knot_dname_t *)"" }, + { "a.", 3, (knot_dname_t *)"\x01" "a" }, + { NULL } + }; + + for (const test_t *t = TESTS; t->msg != NULL; t++) { + uint16_t len = knot_edns_chain_size(t->dname); + ok(len == t->opt_len, "%s: dname %s, size", __func__, t->msg); + + uint8_t wire[8] = { 0 }; + int ret = knot_edns_chain_write(wire, sizeof(wire), t->dname); + is_int(KNOT_EOK, ret, "%s: dname %s, write, return", __func__, t->msg); + ok(memcmp(wire, t->dname, t->opt_len) == 0, "%s: dname %s, write, value", + __func__, t->msg); + + knot_dname_t *dname = NULL; + ret = knot_edns_chain_parse(&dname, (uint8_t *)t->dname, t->opt_len, NULL); + is_int(KNOT_EOK, ret, "%s: dname %s, parse, return", __func__, t->msg); + ok(knot_dname_is_equal(dname, t->dname), "%s: dname %s, parse, value", + __func__, t->msg); + knot_dname_free(dname, NULL); + } + + // Error tests. + + ok(knot_edns_chain_size(NULL) == 0, "%s: size, NULL", __func__); + + uint8_t wire[8] = { 0 }; + ok(knot_edns_chain_write(NULL, 0, wire) == KNOT_EINVAL, + "%s: write, NULL", __func__); + ok(knot_edns_chain_write(wire, 0, NULL) == KNOT_EINVAL, + "%s: write, NULL", __func__); + ok(knot_edns_chain_write(wire, 0, (const knot_dname_t *)"") == KNOT_ESPACE, + "%s: write, no room", __func__); + + knot_dname_t *dname = NULL; + ok(knot_edns_chain_parse(NULL, wire, 0, NULL) == KNOT_EINVAL && dname == NULL, + "%s: parse, NULL", __func__); + ok(knot_edns_chain_parse(&dname, NULL, 0, NULL) == KNOT_EINVAL && dname == NULL, + "%s: parse, NULL", __func__); + ok(knot_edns_chain_parse(&dname, (const uint8_t *)"\x01", 1, NULL) == KNOT_EMALF && + dname == NULL, "%s: parse, malformed", __func__); +} + +static void check_cookie_parse(const char *opt, knot_edns_cookie_t *cc, + knot_edns_cookie_t *sc, int code, const char *msg) +{ + const uint8_t *data = NULL; + uint16_t data_len = 0; + if (opt != NULL) { + data = knot_edns_opt_get_data((uint8_t *)opt); + data_len = knot_edns_opt_get_length((uint8_t *)opt); + } + + int ret = knot_edns_cookie_parse(cc, sc, data, data_len); + is_int(code, ret, "cookie parse ret: %s", msg); +} + +static void ok_cookie_check(const char *opt, knot_edns_cookie_t *cc, + knot_edns_cookie_t *sc, uint16_t cc_len, uint16_t sc_len, + const char *msg) +{ + check_cookie_parse(opt, cc, sc, KNOT_EOK, msg); + + is_int(cc->len, cc_len, "cookie parse cc len: %s", msg); + is_int(sc->len, sc_len, "cookie parse cc len: %s", msg); + + uint16_t size = knot_edns_cookie_size(cc, sc); + is_int(size, cc_len + sc_len, "cookie len: %s", msg); + + uint8_t buf[64]; + int ret = knot_edns_cookie_write(buf, sizeof(buf), cc, sc); + is_int(KNOT_EOK, ret, "cookie write ret: %s", msg); +} + +static void test_cookie(void) +{ + const char *good[] = { + "\x00\x0a" "\x00\x08" "\x00\x01\x02\x03\x04\x05\x06\x07", /* Only client cookie. */ + "\x00\x0a" "\x00\x10" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", /* 8 octets long server cookie. */ + "\x00\x0a" "\x00\x28" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27" /* 32 octets long server cookie. */ + }; + + const char *bad[] = { + "\x00\x0a" "\x00\x00", /* Zero length cookie. */ + "\x00\x0a" "\x00\x01" "\x00", /* Short client cookie. */ + "\x00\x0a" "\x00\x07" "\x00\x01\x02\x03\x04\x05\x06", /* Short client cookie. */ + "\x00\x0a" "\x00\x09" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08", /* Short server cookie. */ + "\x00\x0a" "\x00\x0f" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e", /* Short server cookie. */ + "\x00\x0a" "\x00\x29" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28", /* Long server cookie. */ + }; + + knot_edns_cookie_t cc, sc; + + ok_cookie_check(good[0], &cc, &sc, 8, 0, "good cookie 0"); + ok_cookie_check(good[1], &cc, &sc, 8, 8, "good cookie 1"); + ok_cookie_check(good[2], &cc, &sc, 8, 32, "good cookie 2"); + + check_cookie_parse(NULL, &cc, &sc, KNOT_EINVAL, "no data"); + check_cookie_parse(good[0], NULL, &sc, KNOT_EINVAL, "no client cookie"); + check_cookie_parse(good[1], &cc, NULL, KNOT_EINVAL, "no server cookie"); + + check_cookie_parse(bad[0], &cc, &sc, KNOT_EMALF, "bad cookie 0"); + check_cookie_parse(bad[1], &cc, &sc, KNOT_EMALF, "bad cookie 1"); + check_cookie_parse(bad[2], &cc, &sc, KNOT_EMALF, "bad cookie 2"); + check_cookie_parse(bad[3], &cc, &sc, KNOT_EMALF, "bad cookie 3"); + check_cookie_parse(bad[4], &cc, &sc, KNOT_EMALF, "bad cookie 4"); + check_cookie_parse(bad[5], &cc, &sc, KNOT_EMALF, "bad cookie 5"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_rrset_t opt_rr; + int ret = knot_edns_init(&opt_rr, E_MAX_PLD, E_RCODE, E_VERSION, NULL); + is_int(KNOT_EOK, ret, "OPT RR: init"); + + /* Check initialized values (no NSID yet). */ + check_header(&opt_rr, E_MAX_PLD, E_VERSION, 0, E_RCODE, "OPT RR: check header"); + + test_setters(&opt_rr); + test_getters(&opt_rr); + test_alignment(); + test_keepalive(); + test_chain(); + test_cookie(); + + knot_rrset_clear(&opt_rr, NULL); + + return 0; +} diff --git a/tests/libknot/test_edns_ecs.c b/tests/libknot/test_edns_ecs.c new file mode 100644 index 0000000..6733339 --- /dev/null +++ b/tests/libknot/test_edns_ecs.c @@ -0,0 +1,271 @@ +/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include <tap/basic.h> + +#include <sys/socket.h> +#include <sys/types.h> +#include <netdb.h> + +#include "contrib/sockaddr.h" +#include "libknot/errcode.h" +#include "libknot/rrtype/opt.h" + +#define GARBAGE_BYTE 0xdb + +static void test_size(void) +{ + struct test { + const char *msg; + size_t expected; + knot_edns_client_subnet_t ecs; + }; + + static struct test const TESTS[] = { + // invalid + { "zero family", 0, { 0 } }, + { "zero family & source", 0, { 0, 1 } }, + { "unknown family", 0, { 42, 0 } }, + { "unknown family & source", 0, { 42, 1 } }, + // IPv4 bit ops + { "IPv4, zero source", 4, { 1 } }, + { "IPv4, 7 bits in last byte", 7, { 1, 23 } }, + { "IPv4, 8 bits in last byte", 7, { 1, 24 } }, + { "IPv4, 1 bit in last byte", 8, { 1, 25 } }, + // IPv6 bit ops + { "IPv6, zero source", 4, { 2 } }, + { "IPv6, 7 bits in last byte", 19, { 2, 113 } }, + { "IPv6, 8 bits in last byte", 19, { 2, 120 } }, + { "IPv6, 1 bit in last byte", 20, { 2, 121 } }, + // sources + { "IPv4, source < max", 8, { 1, 31 } }, + { "IPv4, source = max", 8, { 1, 32 } }, + { "IPv4, source > max", 0, { 1, 33 } }, + // scopes + { "IPv6, scope < source", 12, { 2, 64, 48 } }, + { "IPv6, scope = source", 20, { 2, 128, 128 } }, + { "IPv6, scope > max", 0, { 2, 128, 129 } }, + { NULL } + }; + + is_int(0, knot_edns_client_subnet_size(NULL), "%s: null", __func__); + + for (struct test const *t = TESTS; t->msg != NULL; t++) { + int r = knot_edns_client_subnet_size(&t->ecs); + is_int(t->expected, r, "%s: %s", __func__, t->msg); + } +} + +struct test_io { + const char *msg; + int expected; + size_t option_len; + const char *option; + knot_edns_client_subnet_t ecs; +}; + +static void test_write(void) +{ + static struct test_io const TESTS[] = { + // invalid + { "unset family", KNOT_EINVAL, 0, NULL, { 0 } }, + { "invalid family", KNOT_EINVAL, 0, NULL, { 3 } }, + { "small buffer", KNOT_ESPACE, 4, NULL, { 1, 1 } }, + // IPv4 prefix + { "IPv4, zero source", KNOT_EOK, 4, "\x00\x01\x00\x00", { 1 } }, + { "IPv4, 7 bits in LSB", KNOT_EOK, 6, "\x00\x01\x0f\x00\xff\xfe", { 1, 15, 0, "\xff\xff\xff\xff" } }, + { "IPv4, 8 bits in LSB", KNOT_EOK, 6, "\x00\x01\x10\x00\xff\xff", { 1, 16, 0, "\xff\xff\xff\xff" } }, + { "IPv4, 1 bit in LSB", KNOT_EOK, 7, "\x00\x01\x11\x00\xff\xff\x80", { 1, 17, 0, "\xff\xff\xff\xff" } }, + { "IPv4, source = max", KNOT_EOK, 8, "\x00\x01\x20\x00\xaa\xbb\xcc\xdd", { 1, 32, 0, "\xaa\xbb\xcc\xdd" } }, + { "IPv6, source > max", KNOT_EINVAL, 0, NULL, { 2, 129 } }, + // IPv6 scope + { "IPv6, scope < source", KNOT_EOK, 6, "\x00\x02\x10\x0e\xff\xff", { 2, 16, 14, "\xff\xff\xff\xff" } }, + { "IPv6, scope = source", KNOT_EOK, 6, "\x00\x02\x08\x08\xff", { 2, 8, 8, "\xff\xff\xff\xff" } }, + { "IPv6, scope > max", KNOT_EINVAL, 0, NULL, { 2, 128, 129 } }, + // other + { "larger buffer", KNOT_EOK, 7, "\x00\x01\x10\x0e\xff\xff\x00", { 1, 16, 14, "\xff\xff\xff\xff" } }, + { NULL } + }; + + for (struct test_io const *t = TESTS; t->msg != NULL; t++) { + uint8_t option[64]; + assert(sizeof(option) >= t->option_len); + memset(option, GARBAGE_BYTE, sizeof(option)); + + int r = knot_edns_client_subnet_write(option, t->option_len, &t->ecs); + ok(r == t->expected && + (t->expected != KNOT_EOK || memcmp(option, t->option, t->option_len) == 0), + "%s: %s", __func__, t->msg); + } +} + +static void test_parse(void) +{ + static struct test_io const TESTS[] = { + // invalid + { "null", KNOT_EINVAL, 0, NULL }, + { "empty buffer", KNOT_EMALF, 0, "" }, + { "incomplete header", KNOT_EMALF, 3, "\x00\x01\x00" }, + { "incomplete source", KNOT_EMALF, 5, "\x00\x0a\x00\x00\xff\xff" }, + { "zero family", KNOT_EMALF, 4, "\x00\x00\x00\x00" }, + { "unknown family", KNOT_EMALF, 4, "\x00\x03\x00\x00" }, + // IPv4 prefix + { "IPv4, zero source", KNOT_EOK, 4, "\x00\x01\x00\x00", { 1 } }, + { "IPv4, 7 bits in LSB", KNOT_EOK, 6, "\x00\x01\x0f\x00\xff\xfe", { 1, 15, 0, "\xff\xfe" } }, + { "IPv4, 9 bits in LSB", KNOT_EOK, 6, "\x00\x01\x10\x00\xff\xff", { 1, 16, 0, "\xff\xff" } }, + { "IPv4, 1 bit in LSB", KNOT_EOK, 7, "\x00\x01\x11\x00\xff\xff\x80", { 1, 17, 0, "\xff\xff\x80" } }, + { "IPv4, source = max", KNOT_EOK, 8, "\x00\x01\x20\x00\xaa\xbb\xcc\xdd", { 1, 32, 0, "\xaa\xbb\xcc\xdd" } }, + { "IPv4, dirty source", KNOT_EOK, 8, "\x00\x01\x0b\x00\xff\xff\xff\xff", { 1, 11, 0, "\xff\xe0" } }, + { "IPv4, source > max", KNOT_EMALF, 9, "\x00\x01\x21\x00\xaa\xbb\xcc\xdd\xee" }, + // IPv6 scope + { "IPv6 scope < source", KNOT_EOK, 5, "\x00\x02\x07\x05\xff", { 2, 7, 5, "\xfe" } }, + { "IPv6 scope = source", KNOT_EOK, 5, "\x00\x02\x06\x06\xff", { 2, 6, 6, "\xfc" } }, + { "IPv6 scope > max", KNOT_EMALF, 5, "\x00\x02\x06\x81\xff" }, + // extra buffer size + { "extra space", KNOT_EOK, 6, "\x00\x01\x00\x00\xff\x00", { 1 } }, + { "extra space", KNOT_EOK, 6, "\x00\x01\x01\x00\xff\x00", { 1, 1, 0, "\x80" } }, + { NULL } + }; + + for (struct test_io const *t = TESTS; t->msg != NULL; t++) { + knot_edns_client_subnet_t ecs = { 0 }; + memset(&ecs, GARBAGE_BYTE, sizeof(ecs)); + + int r = knot_edns_client_subnet_parse(&ecs, (uint8_t *)t->option, t->option_len); + ok(r == t->expected && + (t->expected != KNOT_EOK || memcmp(&ecs, &t->ecs, sizeof(ecs)) == 0), + "%s: %s", __func__, t->msg); + } +} + +static struct sockaddr_storage addr_init(const char *addr) +{ + struct sockaddr_storage sa = { 0 }; + + struct addrinfo hints = { .ai_flags = AI_NUMERICHOST }; + struct addrinfo *info = NULL; + int r = getaddrinfo(addr, NULL, &hints, &info); + (void)r; + assert(r == 0); + memcpy(&sa, info->ai_addr, info->ai_addrlen); + freeaddrinfo(info); + + return sa; +} + +static void test_set_address(void) +{ + int r; + knot_edns_client_subnet_t ecs = { 0 }; + struct sockaddr_storage ss = { 0 }; + + r = knot_edns_client_subnet_set_addr(NULL, &ss); + is_int(KNOT_EINVAL, r, "%s: missing ECS", __func__); + + r = knot_edns_client_subnet_set_addr(&ecs, NULL); + is_int(KNOT_EINVAL, r, "%s: missing address", __func__); + + memset(&ecs, GARBAGE_BYTE, sizeof(ecs)); + ss = addr_init("198.51.100.42"); + assert(ss.ss_family == AF_INET); + const uint8_t raw4[4] = { 198, 51, 100, 42 }; + + r = knot_edns_client_subnet_set_addr(&ecs, &ss); + ok(r == KNOT_EOK && + ecs.family == 1 && ecs.source_len == 32 && ecs.scope_len == 0 && + memcmp(ecs.address, raw4, sizeof(raw4)) == 0, + "%s: IPv4", __func__); + + memset(&ecs, GARBAGE_BYTE, sizeof(ecs)); + ss = addr_init("2001:db8::dead:beef"); + assert(ss.ss_family == AF_INET6); + const uint8_t raw6[16] = "\x20\x01\x0d\xb8\x00\x00\x00\x00" + "\x00\x00\x00\x00\xde\xad\xbe\xef"; + r = knot_edns_client_subnet_set_addr(&ecs, &ss); + ok(r == KNOT_EOK && + ecs.family == 2 && ecs.source_len == 128 && ecs.scope_len == 0 && + memcmp(ecs.address, raw6, sizeof(raw6)) == 0, + "%s: IPv6", __func__); + + const struct sockaddr_storage ss_unix = { .ss_family = AF_UNIX }; + r = knot_edns_client_subnet_set_addr(&ecs, &ss_unix); + is_int(KNOT_ENOTSUP, r, "%s: UNIX not supported", __func__); +} + +static bool sockaddr_eq(const struct sockaddr_storage *a, const struct sockaddr_storage *b) +{ + return sockaddr_cmp((struct sockaddr *)a, (struct sockaddr *)b) == 0; +} + +static void test_get_address(void) +{ + struct test { + const char *msg; + int expected; + const char *addr_str; + knot_edns_client_subnet_t ecs; + }; + + static struct test const TESTS[] = { + // invalid + { "unset family", KNOT_ENOTSUP, NULL, { 0 } }, + { "unknown family", KNOT_ENOTSUP, NULL, { 3 } }, + // zero source + { "IPv4, any", KNOT_EOK, "0.0.0.0", { 1 } }, + { "IPv6, any", KNOT_EOK, "::0" , { 2 } }, + // IPv4 + { "IPv4, 7 bits in LSB", KNOT_EOK, "198.50.0.0", { 1, 15, 0, "\xc6\x33\xff\xff" } }, + { "IPv4, 8 bits in LSB", KNOT_EOK, "198.51.0.0", { 1, 16, 0, "\xc6\x33\xff\xff" } }, + { "IPv4, 1 bit in LSB", KNOT_EOK, "198.51.128.0", { 1, 17, 0, "\xc6\x33\xff\xff" } }, + { "IPv4, source = max", KNOT_EOK, "198.51.128.1", { 1, 32, 0, "\xc6\x33\x80\x01" } }, + // IPv6 + { "IPv6, 7 bits in LSB", KNOT_EOK, "2001:db8:200::", { 2, 39, 0, "\x20\x01\x0d\xb8\x03\xff" } }, + { "IPv6, 8 bits in LSB", KNOT_EOK, "2001:db8:100::", { 2, 40, 0, "\x20\x01\x0d\xb8\x01\xff" } }, + { "IPv6, 1 bit in LSB", KNOT_EOK, "2001:db8:180::", { 2, 41, 0, "\x20\x01\x0d\xb8\x01\xff" } }, + { "IPv6, source = max", KNOT_EOK, "2001:db8::1", { 2, 128, 0, "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" } }, + { NULL } + }; + + for (struct test const *t = TESTS; t->msg != NULL; t++) { + struct sockaddr_storage result = { 0 }; + int r = knot_edns_client_subnet_get_addr(&result, &t->ecs); + bool valid = false; + + if (t->expected == KNOT_EOK) { + struct sockaddr_storage addr = addr_init(t->addr_str); + assert(addr.ss_family != AF_UNSPEC); + valid = (r == t->expected && sockaddr_eq(&result, &addr)); + } else { + valid = (r == t->expected); + } + + ok(valid, "%s: %s", __func__, t->msg); + } +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_size(); + test_write(); + test_parse(); + test_set_address(); + test_get_address(); + + return 0; +} diff --git a/tests/libknot/test_endian.c b/tests/libknot/test_endian.c new file mode 100644 index 0000000..ef3fb1e --- /dev/null +++ b/tests/libknot/test_endian.c @@ -0,0 +1,70 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/endian.h" + +int main(int argc, char *argv[]) +{ + plan(12); + + typedef union { + uint16_t value; + uint8_t array[2]; + } trafo16_t; + + const uint16_t host16 = 0x0102; + const trafo16_t be16 = { .array = { 0x01, 0x02 } }; + const trafo16_t le16 = { .array = { 0x02, 0x01 } }; + ok(htobe16(host16) == be16.value, "htobe16"); + ok(htole16(host16) == le16.value, "htole16"); + ok(be16toh(be16.value) == host16, "be16toh"); + ok(le16toh(le16.value) == host16, "le16toh"); + + typedef union { + uint32_t value; + uint8_t array[4]; + } trafo32_t; + + const uint32_t host32 = 0x01020304; + const trafo32_t be32 = { .array = { 0x01, 0x02, 0x03, 0x04 } }; + const trafo32_t le32 = { .array = { 0x04, 0x03, 0x02, 0x01 } }; + ok(htobe32(host32) == be32.value, "htobe32"); + ok(htole32(host32) == le32.value, "htole32"); + ok(be32toh(be32.value) == host32, "be32toh"); + ok(le32toh(le32.value) == host32, "le32toh"); + + typedef union { + uint64_t value; + uint8_t array[8]; + } trafo64_t; + + const uint64_t host64 = 0x0102030405060708; + const trafo64_t be64 = { .array = { 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08 } }; + const trafo64_t le64 = { .array = { 0x08, 0x07, 0x06, 0x05, + 0x04, 0x03, 0x02, 0x01 } }; + ok(htobe64(host64) == be64.value, "htobe64"); + ok(htole64(host64) == le64.value, "htole64"); + ok(be64toh(be64.value) == host64, "be64toh"); + ok(le64toh(le64.value) == host64, "le64toh"); + + return 0; +} diff --git a/tests/libknot/test_lookup.c b/tests/libknot/test_lookup.c new file mode 100644 index 0000000..acb612f --- /dev/null +++ b/tests/libknot/test_lookup.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "libknot/lookup.h" + +const knot_lookup_t test_table[] = { + { 0, "test item 0" }, + { 10, "" }, + { 2, "test item 2" }, + { -1, "test item -1" }, + { 0, NULL } +}; + +int main(int argc, char *argv[]) +{ + plan(9); + + /* Lookup by ID. */ + const knot_lookup_t *found = knot_lookup_by_id(test_table, 3); + ok(found == NULL, "lookup table: find by id - non-existent ID"); + + found = knot_lookup_by_id(test_table, 2); + ok(found && found->id == 2 && strcmp(found->name, "test item 2") == 0, + "lookup table: find by id - ID 2 (unordered IDs)"); + + found = knot_lookup_by_id(NULL, 2); + ok(found == NULL, "lookup table: find by id - table == NULL"); + + /* Lookup by name. */ + found = knot_lookup_by_name(test_table, "test item 2"); + ok(found && found->id == 2 && strcmp(found->name, "test item 2") == 0, + "lookup table: find by name - existent"); + + found = knot_lookup_by_name(test_table, ""); + ok(found && found->id == 10 && strcmp(found->name, "") == 0, + "lookup table: find by name - empty string"); + + found = knot_lookup_by_name(test_table, NULL); + ok(found == NULL, "lookup table: find by name - NULL name"); + + found = knot_lookup_by_name(NULL, "test item 2"); + ok(found == NULL, "lookup table: find by name - NULL table"); + + found = knot_lookup_by_name(NULL, NULL); + ok(found == NULL, "lookup table: find by name - NULL table & NULL name"); + + found = knot_lookup_by_name(test_table, "non existent name"); + ok(found == NULL, "lookup table: find by name - non-existent name"); + + return 0; +} diff --git a/tests/libknot/test_pkt.c b/tests/libknot/test_pkt.c new file mode 100644 index 0000000..65458cd --- /dev/null +++ b/tests/libknot/test_pkt.c @@ -0,0 +1,199 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "libknot/libknot.h" +#include "libknot/packet/pkt.c" +#include "contrib/ucw/mempool.h" + +#define TTL 7200 +#define NAMECOUNT 3 +#define DATACOUNT 3 +const char *g_names[NAMECOUNT] = { + "example.com", + "ns1.example.com", + "ns2.example.com" +}; + +const char *g_rdata[DATACOUNT] = { + "\x04" "\xc2\x0c\x00\x01", /* 4B, 194.0.12.1" */ + "\x11" "\x03""ns1""\x07""example""\x03""com""\x00", /* domain name */ + "\x11" "\x03""ns2""\x07""example""\x03""com""\x00", /* domain name */ +}; + +#define RDVAL(i) ((const uint8_t*)(g_rdata[(i)] + 1)) +#define RDLEN(i) ((uint16_t)(g_rdata[(i)][0])) + +/* @note Packet equivalence test, 5 checks. */ +static void packet_match(knot_pkt_t *in, knot_pkt_t *out) +{ + assert(in); + assert(out); + + /* Check counts */ + is_int(knot_wire_get_qdcount(out->wire), + knot_wire_get_qdcount(in->wire), "pkt: QD match"); + is_int(knot_wire_get_ancount(out->wire), + knot_wire_get_ancount(in->wire), "pkt: AN match"); + is_int(knot_wire_get_nscount(out->wire), + knot_wire_get_nscount(in->wire), "pkt: NS match"); + is_int(knot_wire_get_arcount(out->wire), + knot_wire_get_arcount(in->wire), "pkt: AR match"); + + /* Check RRs */ + int rr_matched = 0; + for (unsigned i = 0; i < NAMECOUNT; ++i) { + if (knot_rrset_equal(&out->rr[i], &in->rr[i], KNOT_RRSET_COMPARE_WHOLE) > 0) { + ++rr_matched; + } + } + is_int(NAMECOUNT, rr_matched, "pkt: RR content match"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Create memory pool context. */ + int ret = 0; + knot_mm_t mm; + mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); + + /* Create names and data. */ + knot_dname_t* dnames[NAMECOUNT] = {0}; + knot_rrset_t* rrsets[NAMECOUNT] = {0}; + for (unsigned i = 0; i < NAMECOUNT; ++i) { + dnames[i] = knot_dname_from_str_alloc(g_names[i]); + } + + uint8_t *edns_str = (uint8_t *)"ab"; + /* Create OPT RR. */ + knot_rrset_t opt_rr = { 0 }; + ret = knot_edns_init(&opt_rr, 1024, 0, 0, &mm); + is_int(KNOT_EOK, ret, "initialize OPT RR"); + + /* Add NSID */ + ret = knot_edns_add_option(&opt_rr, KNOT_EDNS_OPTION_NSID, + strlen((char *)edns_str), edns_str, &mm); + is_int(KNOT_EOK, ret, "initialize NSID in OPT RR"); + + /* + * Packet writer tests. + */ + + /* Create packet. */ + knot_pkt_t *out = knot_pkt_new(NULL, MM_DEFAULT_BLKSIZE, &mm); + ok(out != NULL, "pkt: new"); + assert(out); + + /* Mark as response (not part of the test). */ + knot_wire_set_qr(out->wire); + + /* Secure packet. */ + const char *tsig_secret = "abcd"; + knot_tsig_key_t tsig_key; + tsig_key.algorithm = DNSSEC_TSIG_HMAC_MD5; + tsig_key.name = dnames[0]; + tsig_key.secret.data = (uint8_t *)strdup(tsig_secret); + tsig_key.secret.size = strlen(tsig_secret); + ret = knot_pkt_reserve(out, knot_tsig_wire_size(&tsig_key)); + is_int(KNOT_EOK, ret, "pkt: set TSIG key"); + + /* Write question. */ + ret = knot_pkt_put_question(out, dnames[0], KNOT_CLASS_IN, KNOT_RRTYPE_A); + is_int(KNOT_EOK, ret, "pkt: put question"); + + /* Add OPT to packet (empty NSID). */ + ret = knot_pkt_reserve(out, knot_edns_wire_size(&opt_rr)); + is_int(KNOT_EOK, ret, "pkt: reserve OPT RR"); + + /* Begin ANSWER section. */ + ret = knot_pkt_begin(out, KNOT_ANSWER); + is_int(KNOT_EOK, ret, "pkt: begin ANSWER"); + + /* Write ANSWER section. */ + rrsets[0] = knot_rrset_new(dnames[0], KNOT_RRTYPE_A, KNOT_CLASS_IN, TTL, NULL); + knot_dname_free(dnames[0], NULL); + knot_rrset_add_rdata(rrsets[0], RDVAL(0), RDLEN(0), NULL); + ret = knot_pkt_put(out, KNOT_COMPR_HINT_QNAME, rrsets[0], 0); + is_int(KNOT_EOK, ret, "pkt: write ANSWER"); + + /* Begin AUTHORITY. */ + ret = knot_pkt_begin(out, KNOT_AUTHORITY); + is_int(KNOT_EOK, ret, "pkt: begin AUTHORITY"); + + /* Write rest to AUTHORITY. */ + ret = KNOT_EOK; + for (unsigned i = 1; i < NAMECOUNT; ++i) { + rrsets[i] = knot_rrset_new(dnames[i], KNOT_RRTYPE_NS, KNOT_CLASS_IN, TTL, NULL); + knot_dname_free(dnames[i], NULL); + knot_rrset_add_rdata(rrsets[i], RDVAL(i), RDLEN(i), NULL); + ret |= knot_pkt_put(out, KNOT_COMPR_HINT_NONE, rrsets[i], 0); + } + is_int(KNOT_EOK, ret, "pkt: write AUTHORITY(%u)", NAMECOUNT - 1); + + /* Begin ADDITIONALS */ + ret = knot_pkt_begin(out, KNOT_ADDITIONAL); + is_int(KNOT_EOK, ret, "pkt: begin ADDITIONALS"); + + /* Encode OPT RR. */ + ret = knot_pkt_put(out, KNOT_COMPR_HINT_NONE, &opt_rr, 0); + is_int(KNOT_EOK, ret, "pkt: write OPT RR"); + + /* + * Packet reader tests. + */ + + /* Create new packet from query packet. */ + knot_pkt_t *in = knot_pkt_new(out->wire, out->size, &out->mm); + ok(in != NULL, "pkt: create packet for parsing"); + + /* Read packet header. */ + ret = knot_pkt_parse_question(in); + is_int(KNOT_EOK, ret, "pkt: read header"); + + /* Read packet payload. */ + ret = parse_payload(in, 0); + is_int(KNOT_EOK, ret, "pkt: read payload"); + + /* Compare parsed packet to written packet. */ + packet_match(in, out); + + /* + * Copied packet tests. + */ + knot_pkt_t *copy = knot_pkt_new(NULL, in->max_size, &in->mm); + ret = knot_pkt_copy(copy, in); + is_int(KNOT_EOK, ret, "pkt: create packet copy"); + + /* Compare copied packet to original. */ + packet_match(in, copy); + + /* Free packets. */ + knot_pkt_free(copy); + knot_pkt_free(out); + knot_pkt_free(in); + + /* Free extra data. */ + for (unsigned i = 0; i < NAMECOUNT; ++i) { + knot_rrset_free(rrsets[i], NULL); + } + free(tsig_key.secret.data); + mp_delete((struct mempool *)mm.ctx); + + return 0; +} diff --git a/tests/libknot/test_rdata.c b/tests/libknot/test_rdata.c new file mode 100644 index 0000000..094cc4d --- /dev/null +++ b/tests/libknot/test_rdata.c @@ -0,0 +1,60 @@ +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <tap/basic.h> + +#include "libknot/rdata.h" + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test array size + ok(knot_rdata_size(1) == 2 + 1 + 1, "rdata: array size odd."); + ok(knot_rdata_size(2) == 2 + 2, "rdata: array size even."); + + // Test init + const size_t data_size = 16; + uint8_t buf1[knot_rdata_size(data_size)]; + knot_rdata_t *rdata = (knot_rdata_t *)buf1; + uint8_t payload[] = "abcdefghijklmnop"; + knot_rdata_init(rdata, data_size, payload); + const bool set_ok = rdata->len == data_size && + memcmp(rdata->data, payload, data_size) == 0; + ok(set_ok, "rdata: init."); + + // Test compare + rdata->len = data_size; + ok(knot_rdata_cmp(rdata, rdata) == 0, "rdata: cmp eq."); + + knot_rdata_t *lower = rdata; + uint8_t buf2[knot_rdata_size(data_size)]; + knot_rdata_t *greater = (knot_rdata_t *)buf2; + knot_rdata_init(greater, data_size, (uint8_t *)"qrstuvwxyz123456"); + ok(knot_rdata_cmp(lower, greater) < 0, "rdata: cmp lower."); + ok(knot_rdata_cmp(greater, lower) > 0, "rdata: cmp greater."); + + // Payloads will be the same. + memcpy(greater->data, lower->data, data_size); + assert(knot_rdata_cmp(lower, greater) == 0); + + lower->len = data_size - 1; + ok(knot_rdata_cmp(lower, greater) < 0, "rdata: cmp lower size."); + ok(knot_rdata_cmp(greater, lower) > 0, "rdata: cmp greater size."); + + return 0; +} diff --git a/tests/libknot/test_rdataset.c b/tests/libknot/test_rdataset.c new file mode 100644 index 0000000..eb0dcbf --- /dev/null +++ b/tests/libknot/test_rdataset.c @@ -0,0 +1,205 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> +#include <string.h> + +#include "libknot/rdataset.h" +#include "libknot/libknot.h" + +// Inits rdataset with given rdata. +#define RDATASET_INIT_WITH(set, rdata) \ + knot_rdataset_clear(&set, NULL); \ + ret = knot_rdataset_add(&set, rdata, NULL); \ + assert(ret == KNOT_EOK); + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test init + knot_rdataset_t rdataset; + knot_rdataset_init(&rdataset); + ok(rdataset.rdata == NULL && rdataset.count == 0, "rdataset: init."); + + // Test rdata addition + uint8_t buf_gt[knot_rdata_size(4)]; + knot_rdata_t *rdata_gt = (knot_rdata_t *)buf_gt; + knot_rdata_init(rdata_gt, 4, (uint8_t *)"wxyz"); + + int ret = knot_rdataset_add(NULL, NULL, NULL); + is_int(KNOT_EINVAL, ret, "rdataset: add NULL."); + ret = knot_rdataset_add(&rdataset, rdata_gt, NULL); + bool add_ok = ret == KNOT_EOK && rdataset.count == 1 && + knot_rdata_cmp(rdata_gt, rdataset.rdata) == 0; + ok(add_ok, "rdataset: add."); + + uint8_t buf_lo[knot_rdata_size(4)]; + knot_rdata_t *rdata_lo = (knot_rdata_t *)buf_lo; + knot_rdata_init(rdata_lo, 4, (uint8_t *)"abcd"); + ret = knot_rdataset_add(&rdataset, rdata_lo, NULL); + add_ok = ret == KNOT_EOK && rdataset.count == 2 && + knot_rdata_cmp(rdata_lo, rdataset.rdata) == 0; + ok(add_ok, "rdataset: add lower."); + + // Test getters + ok(knot_rdata_cmp(knot_rdataset_at(&rdataset, 0), rdata_lo) == 0 && + knot_rdata_cmp(knot_rdataset_at(&rdataset, 1), rdata_gt) == 0, + "rdataset: at."); + + ok(knot_rdataset_size(&rdataset) == knot_rdata_size(4) * 2, + "rdataset: size."); + + // Test copy + ok(knot_rdataset_copy(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: copy NULL."); + knot_rdataset_t copy; + ret = knot_rdataset_copy(©, &rdataset, NULL); + const bool copy_ok = ret == KNOT_EOK && copy.count == rdataset.count && + knot_rdataset_size(©) == knot_rdataset_size(&rdataset) && + memcmp(rdataset.rdata, copy.rdata, + knot_rdataset_size(&rdataset)) == 0; + ok(copy_ok, "rdataset: copy"); + + // Test eq + ok(knot_rdataset_eq(&rdataset, ©), "rdataset: equal"); + + // Test clear + knot_rdataset_clear(©, NULL); + ok(copy.count == 0 && copy.rdata == NULL, "rdataset: clear."); + + // Test not equal (different count) + ok(!knot_rdataset_eq(&rdataset, ©), "rdataset: not equal - count"); + + // Test member + uint8_t buf_not[knot_rdata_size(1)]; + knot_rdata_t *not_a_member = (knot_rdata_t *)buf_not; + knot_rdata_init(not_a_member, 1, (uint8_t *)"?"); + ok(knot_rdataset_member(&rdataset, rdata_gt), "rdataset: is member."); + ok(!knot_rdataset_member(&rdataset, not_a_member), "rdataset: is not member."); + + // Test merge + ok(knot_rdataset_merge(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: merge NULL."); + knot_rdataset_t empty; + knot_rdataset_init(&empty); + ret = knot_rdataset_merge(&empty, &rdataset, NULL); + bool merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&empty, &rdataset); + ok(merge_ok, "rdataset: merge empty."); + knot_rdata_t *data_before = rdataset.rdata; + ret = knot_rdataset_merge(&rdataset, &rdataset, NULL); + merge_ok = ret == KNOT_EOK && rdataset.count == 2 && + data_before == rdataset.rdata; + ok(merge_ok, "rdataset: merge self."); + + knot_rdataset_clear(&empty, NULL); + + // Init structs for merge sort testing + knot_rdataset_t rdataset_lo; // "Lower" rdataset + knot_rdataset_init(&rdataset_lo); + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + knot_rdataset_t rdataset_gt; // "Greater" rdataset + knot_rdataset_init(&rdataset_gt); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + + // Test not equal - different data + ok(!knot_rdataset_eq(&rdataset_gt, &rdataset_lo), "rdataset: data not equal."); + + // Test that merge keeps the sorted order + ret = knot_rdataset_merge(&rdataset_lo, &rdataset_gt, NULL); + merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset_lo, &rdataset); + ok(merge_ok, "rdataset: merge into lower."); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + ret = knot_rdataset_merge(&rdataset_gt, &rdataset_lo, NULL); + merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset_gt, &rdataset); + ok(merge_ok, "rdataset: merge into greater."); + + // Test intersect + ok(knot_rdataset_intersect(NULL, NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: intersect NULL."); + + knot_rdataset_t intersection; + ret = knot_rdataset_intersect(&rdataset, &rdataset, &intersection, NULL); + bool intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset, &intersection); + ok(intersect_ok, "rdataset: intersect self."); + knot_rdataset_clear(&intersection, NULL); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + ret = knot_rdataset_intersect(&rdataset_lo, &rdataset_gt, &intersection, NULL); + intersect_ok = ret == KNOT_EOK && intersection.count == 0; + ok(intersect_ok, "rdataset: intersect no common."); + + ret = knot_rdataset_intersect(&rdataset, &rdataset_lo, &intersection, NULL); + intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&intersection, &rdataset_lo); + ok(intersect_ok, "rdataset: intersect normal."); + knot_rdataset_clear(&intersection, NULL); + + // Test subtract + ok(knot_rdataset_subtract(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: subtract NULL."); + ret = knot_rdataset_copy(©, &rdataset, NULL); + assert(ret == KNOT_EOK); + ok(knot_rdataset_subtract(©, ©, NULL) == KNOT_EOK && + copy.count == 0, "rdataset: subtract self."); + + ret = knot_rdataset_copy(©, &rdataset, NULL); + assert(ret == KNOT_EOK); + ret = knot_rdataset_subtract(©, &rdataset, NULL); + bool subtract_ok = ret == KNOT_EOK && copy.count == 0; + ok(subtract_ok, "rdataset: subtract identical."); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + data_before = rdataset_lo.rdata; + ret = knot_rdataset_subtract(&rdataset_lo, &rdataset_gt, NULL); + subtract_ok = ret == KNOT_EOK && rdataset_lo.count == 1 && + rdataset_lo.rdata == data_before; + ok(subtract_ok, "rdataset: subtract no common."); + + ret = knot_rdataset_subtract(&rdataset, &rdataset_gt, NULL); + subtract_ok = ret == KNOT_EOK && rdataset.count == 1; + ok(subtract_ok, "rdataset: subtract the second."); + + ret = knot_rdataset_subtract(&rdataset, &rdataset_lo, NULL); + subtract_ok = ret == KNOT_EOK && rdataset.count == 0 && + rdataset.rdata == NULL; + ok(subtract_ok, "rdataset: subtract last."); + + RDATASET_INIT_WITH(rdataset, rdata_gt); + + size_t old_rrs_size = knot_rdataset_size(&rdataset); + size_t rr_size = rdata_lo->len; + ret = knot_rdataset_reserve(&rdataset, rr_size, NULL); + size_t new_rrs_size = knot_rdataset_size(&rdataset); + bool reserve_ok = ret == KNOT_EOK && new_rrs_size == (old_rrs_size + knot_rdata_size(rr_size)); + ok(reserve_ok, "rdataset: reserve normal"); + + RDATASET_INIT_WITH(copy, rdata_lo); + knot_rdataset_add(©, rdata_gt, NULL); + + knot_rdata_init(knot_rdataset_at(&rdataset, 1), 4, (uint8_t *)"abcd"); + + knot_rdataset_clear(©, NULL); + knot_rdataset_clear(&rdataset, NULL); + knot_rdataset_clear(&rdataset_lo, NULL); + knot_rdataset_clear(&rdataset_gt, NULL); + + return EXIT_SUCCESS; +} diff --git a/tests/libknot/test_rrset-wire.c b/tests/libknot/test_rrset-wire.c new file mode 100644 index 0000000..ea1d3c2 --- /dev/null +++ b/tests/libknot/test_rrset-wire.c @@ -0,0 +1,264 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> + +#include "libknot/packet/rrset-wire.h" +#include "libknot/descriptor.h" +#include "libknot/errcode.h" + +// Wire initializers + +#define MESSAGE_HEADER(AN, AUTH, ADD) 0xd4, 0xec, 0x81, 0xa0, 0x00, 0x01, \ + 0x00, AN, 0x00, AUTH, 0x00, ADD + +#define QUERY(qname, type) qname, 0x00, type, 0x00, 0x01 + +#define RR_HEADER(owner, type, rdlength0, rdlength1) owner, 0x00, type, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, rdlength0, rdlength1 + +#define QNAME_POINTER 0xc0, 0x0c + +// Initializers' sizes + +#define QUERY_SIZE 12 + 4 +#define RR_HEADER_SIZE 10 + +// Sample domain names + +#define QNAME 0x03, 0x6e, 0x69, 0x63, 0x02, 0x63, 0x7a, 0x00 +#define QNAME_SIZE 8 +#define QNAME_LONG \ +0x3f,'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', \ +'m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', \ +'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', \ +'m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'w', 'y', \ +'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 0x3f,\ +'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', \ +'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', \ +'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', \ +'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'x', 'y', 'z', \ +'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 0x3f,'a', \ +'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', \ +'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', \ +'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', \ +'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'x', 'y', 'z', 'a', \ +'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'i', 'k', 0x3d,'a', 'b', \ +'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', \ +'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', \ +'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', \ +'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'x', 'y', 'z', 'a', 'b', \ +'c', 'd', 'e', 'f', 'g', 'h', 'i', 0x00 +#define QNAME_LONG_SIZE 255 +#define POINTER_SIZE 2 + +struct wire_data { + uint8_t wire[65535]; + size_t size; + size_t pos; + int code; + const char *msg; +}; + +#define FROM_CASE_COUNT 17 + +static const struct wire_data FROM_CASES[FROM_CASE_COUNT] = { +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A)}, + .size = QUERY_SIZE + QNAME_SIZE, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "No header" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), 0x00, 0x00, 0x01}, + .size = QUERY_SIZE + QNAME_SIZE + 3, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "Partial header" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), + RR_HEADER(QNAME, KNOT_RRTYPE_A, 0x00, 0x04) }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_SIZE * 2, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "No RDATA" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), + RR_HEADER(QNAME, KNOT_RRTYPE_A, 0x00, 0x04), 0x01 }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_SIZE * 2 + 1, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "Partial RDATA" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), + RR_HEADER(QNAME, KNOT_RRTYPE_A, 0x00, 0x04), 0x01, 0x02, 0x03, 0x04 }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_SIZE * 2 + 4, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "OK RDATA" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), + RR_HEADER(QNAME, KNOT_RRTYPE_A, 0x00, 0x05), 0x01, 0x02, 0x03, 0x04, 0x05 }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_SIZE * 2 + 5, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "Trailing RDATA" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME_LONG, KNOT_RRTYPE_SOA), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_SOA, 0x00, 0x18), QNAME_POINTER, QNAME_POINTER, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_LONG_SIZE + 6 + 20, + .pos = QUERY_SIZE + QNAME_LONG_SIZE, + .code = KNOT_EOK, + .msg = "Max DNAME" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_SIG), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_SIG, 0xff, 0xdb), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, QNAME }, + .size = 65535, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "Max RDLENGTH" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME_LONG, KNOT_RRTYPE_SIG), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_SIG, 0xff, 0xff), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, QNAME_POINTER }, + .size = 65535 + QNAME_LONG_SIZE + QUERY_SIZE + RR_HEADER_SIZE + 2, + .pos = QUERY_SIZE + QNAME_LONG_SIZE, + .code = KNOT_EMALF, + .msg = "Max RDLENGTH + compression"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NSEC), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NSEC, 0x00, 0x03), + QNAME_POINTER, 0x00}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 2 + 1, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "DNAME wrong compression"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NAPTR), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NAPTR, 0x00, 0x01), + 0x00}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 1, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "NAPTR missing header"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NAPTR), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NAPTR, 0x00, 0x09), + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, QNAME_POINTER}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 9, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "NAPTR bad offset"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NAPTR), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NAPTR, 0x00, 0x09), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 7, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "NAPTR no DNAME"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NAPTR), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NAPTR, 0x00, 0x0c), + 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, QNAME_POINTER}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 10 + 2, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "NAPTR valid"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_APL), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_APL, 0x00, 0x00) }, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "Valid 0 RDATA"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_TXT), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_TXT, 0x00, 0x00) }, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "Invalid 0 RDATA"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_PX), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_PX, 0x00, 0x06), + 0x00, 0x00, QNAME_POINTER, QNAME_POINTER }, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 6, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "Obsolete RR type"}, +}; + +#define TEST_CASE_FROM(rrset, i) size_t _pos##i = FROM_CASES[i].pos; \ + ok(knot_rrset_rr_from_wire(FROM_CASES[i].wire, &_pos##i, FROM_CASES[i].size, \ + rrset, NULL, true) == FROM_CASES[i].code, "rrset wire: %s", FROM_CASES[i].msg) + +static void test_inputs(void) +{ + for (size_t i = 0; i < FROM_CASE_COUNT; ++i) { + knot_rrset_t rrset; + knot_rrset_init_empty(&rrset); + TEST_CASE_FROM(&rrset, i); + knot_rrset_clear(&rrset, NULL); + } +} + +static void check_canon(uint8_t *wire, size_t size, size_t pos, bool canon, + knot_dname_t *qname, knot_dname_t *dname) +{ + knot_rrset_t rrset; + knot_rrset_init_empty(&rrset); + + int ret = knot_rrset_rr_from_wire(wire, &pos, size, &rrset, NULL, canon); + is_int(KNOT_EOK, ret, "OK %s canonization", canon ? "with" : "without"); + ok(memcmp(rrset.owner, qname, knot_dname_size(qname)) == 0, "compare owner"); + + uint8_t *rdata = rrset.rrs.rdata->data; + ok(memcmp(rdata, dname, knot_dname_size(dname)) == 0, "compare rdata dname"); + + knot_rrset_clear(&rrset, NULL); +} + +static void test_canonization(void) +{ + #define UPP_QNAME_SIZE 5 + #define UPP_QNAME 0x01, 0x41, 0x01, 0x5a, 0x00 // A.Z. + #define LOW_QNAME 0x01, 0x61, 0x01, 0x7a, 0x00 // a.z. + + #define UPP_DNAME_SIZE 3 + #define UPP_DNAME 0x01, 0x58, 0x00 // X. + #define LOW_DNAME 0x01, 0x78, 0x00 // x. + + uint8_t wire[] = { + MESSAGE_HEADER(1, 0, 0), QUERY(UPP_QNAME, KNOT_RRTYPE_NS), + RR_HEADER(UPP_QNAME, KNOT_RRTYPE_NS, 0x00, UPP_DNAME_SIZE), UPP_DNAME + }; + size_t size = QUERY_SIZE + RR_HEADER_SIZE + UPP_QNAME_SIZE * 2 + UPP_DNAME_SIZE; + size_t pos = QUERY_SIZE + UPP_QNAME_SIZE; + + knot_dname_t upp_qname[] = { UPP_QNAME }; + knot_dname_t upp_dname[] = { UPP_DNAME }; + check_canon(wire, size, pos, false, upp_qname, upp_dname); + + knot_dname_t low_qname[] = { LOW_QNAME }; + knot_dname_t low_dname[] = { LOW_DNAME }; + check_canon(wire, size, pos, true, low_qname, low_dname); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("Test NULL parameters"); + int ret = knot_rrset_rr_from_wire(NULL, NULL, 0, NULL, NULL, true); + is_int(KNOT_EINVAL, ret, "rr wire: Invalid params"); + + diag("Test various inputs"); + test_inputs(); + + diag("Test canonization"); + test_canonization(); + + return 0; +} diff --git a/tests/libknot/test_rrset.c b/tests/libknot/test_rrset.c new file mode 100644 index 0000000..a0f1d53 --- /dev/null +++ b/tests/libknot/test_rrset.c @@ -0,0 +1,117 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <inttypes.h> +#include <tap/basic.h> + +#include "libknot/rrset.h" +#include "libknot/descriptor.h" + +static bool check_rrset(const knot_rrset_t *rrset, const knot_dname_t *owner, + uint16_t type, uint16_t rclass, uint32_t ttl) +{ + if (!rrset) { + return false; + } + + const bool dname_cmp = owner == NULL ? rrset->owner == NULL : + knot_dname_is_equal(rrset->owner, owner); + return rrset->type == type && rrset->rclass == rclass && dname_cmp && + rrset->ttl == ttl && rrset->rrs.count == 0; // We do not test rdataset here +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test new + knot_dname_t *dummy_owner = knot_dname_from_str_alloc("test."); + assert(dummy_owner); + + knot_rrset_t *rrset = knot_rrset_new(dummy_owner, KNOT_RRTYPE_TXT, + KNOT_CLASS_IN, 3600, NULL); + ok(rrset != NULL, "rrset: create."); + assert(rrset); + + ok(check_rrset(rrset, dummy_owner, KNOT_RRTYPE_TXT, KNOT_CLASS_IN, 3600), + "rrset: set fields during create."); + + // Test init + knot_dname_free(dummy_owner, NULL); + dummy_owner = knot_dname_from_str_alloc("test2."); + assert(dummy_owner); + + knot_dname_free(rrset->owner, NULL); + knot_rrset_init(rrset, dummy_owner, KNOT_RRTYPE_A, KNOT_CLASS_CH, 7200); + ok(check_rrset(rrset, dummy_owner, KNOT_RRTYPE_A, KNOT_CLASS_CH, 7200), + "rrset: init."); + + // Test copy + knot_rrset_t *copy = knot_rrset_copy(rrset, NULL); + ok(copy != NULL, "rrset: copy."); + ok(check_rrset(copy, rrset->owner, rrset->type, rrset->rclass, 7200), + "rrset: set fields during copy."); + ok(knot_rrset_copy(NULL, NULL) == NULL, "rrset: copy NULL."); + assert(copy); + + // Test equal - pointers + ok(knot_rrset_equal((knot_rrset_t *)0xdeadbeef, (knot_rrset_t *)0xdeadbeef, + KNOT_RRSET_COMPARE_PTR), "rrset: cmp equal pointers"); + ok(!knot_rrset_equal((knot_rrset_t *)0xcafebabe, (knot_rrset_t *)0xdeadbeef, + KNOT_RRSET_COMPARE_PTR), "rrset: cmp different pointers"); + + // Test equal - header + ok(knot_rrset_equal(rrset, copy, KNOT_RRSET_COMPARE_HEADER), + "rrset: cmp equal headers"); + + copy->type = KNOT_RRTYPE_AAAA; + ok(!knot_rrset_equal(rrset, copy, KNOT_RRSET_COMPARE_HEADER), + "rrset: cmp headers - different type"); + + // Test equal - full, rdata empty + copy->type = rrset->type; + ok(knot_rrset_equal(rrset, copy, KNOT_RRSET_COMPARE_WHOLE), + "rrset: cmp headers - rdata"); + + knot_dname_free(rrset->owner, NULL); + rrset->owner = NULL; + ok(!knot_rrset_equal(rrset, copy, KNOT_RRSET_COMPARE_HEADER), + "rrset: cmp NULL owner"); + + ok(knot_rrset_equal(rrset, rrset, KNOT_RRSET_COMPARE_HEADER), + "rrset: cmp NULL owners"); + + // Test clear + knot_rrset_clear(rrset, NULL); + ok(rrset->owner == NULL, "rrset: clear."); + + // Test empty + ok(knot_rrset_empty(rrset), "rrset: empty."); + ok(knot_rrset_empty(NULL), "rrset: empty NULL."); + copy->rrs.count = 1; + ok(!knot_rrset_empty(copy), "rrset: not empty."); + + // Test init empty + knot_rrset_init_empty(rrset); + ok(check_rrset(rrset, NULL, 0, KNOT_CLASS_IN, 0), "rrset: init empty."); + + // "Test" freeing + knot_rrset_free(rrset, NULL); + knot_rrset_free(copy, NULL); + + return 0; +} diff --git a/tests/libknot/test_tsig.c b/tests/libknot/test_tsig.c new file mode 100644 index 0000000..1a861c6 --- /dev/null +++ b/tests/libknot/test_tsig.c @@ -0,0 +1,204 @@ +/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <assert.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> + +#include "libknot/errcode.h" +#include "libknot/tsig.h" + +static bool key_is_eq(const knot_tsig_key_t *a, const knot_tsig_key_t *b) +{ + if (a == NULL && b == NULL) { + return true; + } + + if (a == NULL || b == NULL) { + return false; + } + + return a->algorithm == b->algorithm && + knot_dname_is_equal(a->name, b->name) && + dnssec_binary_cmp(&a->secret, &b->secret) == 0; +} + +#define test_function(function, msg, expected, ...) \ + knot_tsig_key_t key = { 0 }; \ + int r = function(&key, __VA_ARGS__); \ + ok((r != KNOT_EOK && expected == NULL) || \ + (r == KNOT_EOK && key_is_eq(&key, expected)), \ + "%s: %s", #function, msg); \ + knot_tsig_key_deinit(&key); + +static void test_init(const char *msg, const knot_tsig_key_t *expected, + const char *algo, const char *name, const char *secret) +{ + test_function(knot_tsig_key_init, msg, expected, algo, name, secret); +} + +static void test_init_str(const char *msg, const knot_tsig_key_t *expected, + const char *params) +{ + test_function(knot_tsig_key_init_str, msg, expected, params); +} + +static void test_init_file(const char *msg, const knot_tsig_key_t *expected, + const char *filename) +{ + test_function(knot_tsig_key_init_file, msg, expected, filename); +} + +static void test_init_file_content(const char *msg, + const knot_tsig_key_t *expected, + const char *content) +{ + char filename[] = "testkey.XXXXXX"; + + int fd = mkstemp(filename); + if (fd == -1) { + bail("failed to create temporary file"); + return; + } + + ok(write(fd, content, strlen(content)) != -1, "file write"); + close(fd); + + test_init_file(msg, expected, filename); + + unlink(filename); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // initialization from parameters + + test_init("missing name", NULL, "hmac-md5", NULL, "Wg=="); + test_init("missing secret", NULL, "hmac-md5", "name", NULL); + test_init("invalid HMAC", NULL, "hmac-sha11", "name", "Wg=="); + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA256, + .name = (uint8_t *)"\x3""key""\x4""name", + .secret.size = 1, + .secret.data = (uint8_t *)"\x5a" + }; + test_init("default algorithm", &key, NULL, "key.name", "Wg=="); + } + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA1, + .name = (uint8_t *)"\x4""knot""\x3""dns", + .secret.size = 6, + .secret.data = (uint8_t *)"secret" + }; + test_init("sha1", &key, "hmac-sha1", "knot.dns.", "c2VjcmV0"); + } + + // initialization from string + + test_init_str("missing value", NULL, NULL); + test_init_str("malformed", NULL, "this is malformed"); + test_init_str("invalid HMAC", NULL, "hmac-sha51299:key:Wg=="); + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA256, + .name = (uint8_t *)"\x4""tsig""\x3""key", + .secret.size = 9, + .secret.data = (uint8_t *)"bananakey" + }; + test_init_str("default algorithm", &key, "tsig.key:YmFuYW5ha2V5"); + } + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA384, + .name = (uint8_t *)"\x6""strong""\x3""key", + .secret.size = 8, + .secret.data = (uint8_t *)"applekey" + }; + test_init_str("sha384", &key, "hmac-sha384:strong.KEY:YXBwbGVrZXk="); + } + + // initialization from a file + + test_init_file("no filename", NULL, NULL); + test_init_file("not-existing", NULL, "/this-really-should-not-exist"); + test_init_file_content("malformed content", NULL, "malformed\n"); + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA512, + .name = (uint8_t *)"\x6""django""\x3""one", + .secret.size = 40, + .secret.data = (uint8_t *)"Who's that stumbling around in the dark?" + }; + test_init_file_content("sha512", &key, + "hmac-sha512:django.one:V2hvJ3MgdGhhdCB" + "zdHVtYmxpbmcgYXJvdW5kIGluIHRoZSBkYXJrP" + "w==\n\n\n"); + } + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA512, + .name = (uint8_t *)"\x6""django""\x3""two", + .secret.size = 22, + .secret.data = (uint8_t *)"Prepare to get winged!" + }; + test_init_file_content("sha512 without newline", &key, + "hmac-sha512:django.two:UHJlcGFyZSB0byB" + "nZXQgd2luZ2VkIQ=="); + } + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA1, + .name = (uint8_t *)"\x4""test", + .secret.size = 1, + .secret.data = (uint8_t *)"\x5a" + }; + test_init_file_content("leading and trailing white spaces", &key, + "\thmac-sha1:test:Wg== \n"); + } + + // tsig key duplication + + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA1, + .name = (uint8_t *)"\x4""copy""\x2""me", + .secret.size = 6, + .secret.data = (uint8_t *)"orange" + }; + + knot_tsig_key_t copy = { 0 }; + int r; + + r = knot_tsig_key_copy(NULL, &key); + ok(r != KNOT_EOK, "knot_tsig_key_copy: no destination"); + r = knot_tsig_key_copy(©, NULL); + ok(r != KNOT_EOK, "knot_tsig_key_copy: no source"); + r = knot_tsig_key_copy(©, &key); + ok(r == KNOT_EOK && key_is_eq(©, &key) && + copy.secret.data != key.secret.data && copy.name != key.name, + "knot_tsig_key_copy: simple copy"); + + knot_tsig_key_deinit(©); + } + + return 0; +} diff --git a/tests/libknot/test_wire.c b/tests/libknot/test_wire.c new file mode 100644 index 0000000..70617f9 --- /dev/null +++ b/tests/libknot/test_wire.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "libknot/wire.h" + +#define write_test(size, value, ...) { \ + const uint8_t expect[] = { __VA_ARGS__ }; \ + uint8_t wdata[sizeof(expect)] = { 0x00 }; \ + knot_wire_write_u ## size(wdata, value); \ + ok(memcmp(wdata, expect, sizeof(expect)) == 0, "%d-bit write", size); \ +} + +int main(int argc, char *argv[]) +{ + plan(8); + + const uint8_t rdata[] = { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + + is_hex( 0x8899, knot_wire_read_u16(rdata), "16-bit read"); + is_hex( 0x8899aabb, knot_wire_read_u32(rdata), "32-bit read"); + is_hex( 0x8899aabbccdd, knot_wire_read_u48(rdata), "48-bit read"); + is_hex(0x8899aabbccddeeff, knot_wire_read_u64(rdata), "64-bit read"); + + write_test(16, 0x1122, 0x11, 0x22); + write_test(32, 0x66778899, 0x66, 0x77, 0x88, 0x99); + write_test(48, 0xbbccdd778899, 0xbb, 0xcc, 0xdd, 0x77, 0x88, 0x99); + write_test(64, 0xbbccddee66778899, 0xbb, 0xcc, 0xdd, 0xee, + 0x66, 0x77, 0x88, 0x99); + + return 0; +} diff --git a/tests/libknot/test_yparser.c b/tests/libknot/test_yparser.c new file mode 100644 index 0000000..7ee0332 --- /dev/null +++ b/tests/libknot/test_yparser.c @@ -0,0 +1,280 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/yparser/yparser.h" +#include "libknot/libknot.h" + +const char *syntax_ok = + "#comment\n" + " # comment\n" + "a:\n" + "a :\n" + "a : #comment\n" + "\n" + "b: \"b\"\n" + "b: b #comment\n" + "b : b\n" + "b: [ b] # comment\n" + "b: [b ]\n" + "b: [ b ]\n" + "\n" + " f: \"f\"\n" + " f: f #comment\n" + " f : f\n" + " f: [ f] # comment\n" + " f: [f ]\n" + " f: [ f ]\n" + " f: [ \"f\" ]\n" + "\n" + "c: [a,b]\n" + "c: [a, b]\n" + "c: [a ,b]\n" + "c: [a , b]\n" + "c: [ a , b ]\n" + "c: [ \"a\" , \"b\" ]\n" + "\n" + "- d: d\n" + "- d : d # comment\n" + "\n" + "e: \"a#b' c[d,]\"\n" + "\n" + "zone:\n" + "#comment\n" + " # comment\n" + " - domain: example. # comment\n" + " master: bind\n" + " - domain: example.\n" + " master: bind\n" + "zone2:\n" + " - a: b # different indentation"; + +const char *syntax_error1 = + "f:\n" + " - a: b\n" + " - b: c\n"; + +const char *syntax_error2 = + "f:\n" + " - a: b\n" + " c: d\n"; + +const char *syntax_error3 = + "f:\n" + " a: b\n" + " c: d\n"; + +const char *dname_ok = + ".:\n" + "dom-ain:\n" + "\\070-\\071.\\072.:"; + +const char *quotes_ok = + "g: \"\"\n" + "g: a\\ b\n" + "g: \"\\# 1 00\"\n" + "g: \"\\\"\\\"\"\n" + "g: \" a \\\" b \\\" \\\"c\\\" \"\n" + "g: \"\\@ \\[ \\# \\, \\]\"\n"; + +static void test_syntax_ok(yp_parser_t *yp) +{ + // OK input. + int ret = yp_set_input_string(yp, syntax_ok, strlen(syntax_ok)); + is_int(KNOT_EOK, ret, "set input string"); + + size_t line = 3; + for (int i = 0; i < 3; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key0", i); + ok(yp->key_len == 1 && yp->key[0] == 'a' && + yp->data_len == 0 && yp->event == YP_EKEY0 && + yp->line_count == line + i, "compare %i. key0", i); + } + + line += 4; + for (int i = 0; i < 6; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key0 with value", i); + ok(yp->key_len == 1 && yp->key[0] == 'b' && + yp->data_len == 1 && yp->data[0] == 'b' && + yp->event == YP_EKEY0 && yp->line_count == line + i, + "compare %i. key0 with value", i); + } + + line += 7; + for (int i = 0; i < 7; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key1 with value", i); + ok(yp->key_len == 1 && yp->key[0] == 'f' && + yp->data_len == 1 && yp->data[0] == 'f' && + yp->event == YP_EKEY1 && yp->line_count == line + i, + "compare %i. key1 with value", i); + } + + line += 8; + for (int i = 0; i < 6; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key0 with first value", i); + ok(yp->key_len == 1 && yp->key[0] == 'c' && + yp->data_len == 1 && yp->data[0] == 'a' && + yp->event == YP_EKEY0 && yp->line_count == line + i, + "compare %i. key0 with first value", i); + + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key0 with second value", i); + ok(yp->key_len == 1 && yp->key[0] == 'c' && + yp->data_len == 1 && yp->data[0] == 'b' && + yp->event == YP_EKEY0 && yp->line_count == line + i, + "compare %i. key0 with second value", i); + } + + line += 7; + for (int i = 0; i < 2; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. id", i); + ok(yp->key_len == 1 && yp->key[0] == 'd' && + yp->data_len == 1 && yp->data[0] == 'd' && + yp->event == YP_EID && yp->line_count == line + i, + "compare %i. id", i); + } + + line += 3; + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0 with quoted value"); + ok(yp->key_len == 1 && yp->key[0] == 'e' && yp->data_len == 10 && + memcmp(yp->data, "a#b' c[d,]", yp->data_len) == 0 && + yp->event == YP_EKEY0 && yp->line_count == line, + "compare key0 with quoted value"); + + line += 2; + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0"); + ok(yp->key_len == 4 && strcmp(yp->key, "zone") == 0 && + yp->data_len == 0 && + yp->event == YP_EKEY0 && yp->line_count == line, + "compare key0 value"); + + line += 3; + for (int i = 0; i < 2; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. id", i); + ok(yp->key_len == 6 && strcmp(yp->key, "domain") == 0 && + yp->data_len == 8 && strcmp(yp->data, "example.") == 0 && + yp->event == YP_EID && yp->line_count == line + 2 * i, + "compare id"); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key1", i); + ok(yp->key_len == 6 && strcmp(yp->key, "master") == 0 && + yp->data_len == 4 && strcmp(yp->data, "bind") == 0 && + yp->event == YP_EKEY1 && yp->line_count == line + 2 * i + 1, + "compare key1"); + } + + line += 4; + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0"); + ok(yp->key_len == 5 && strcmp(yp->key, "zone2") == 0 && + yp->data_len == 0 && + yp->event == YP_EKEY0 && yp->line_count == line, + "compare key0 value"); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key1"); + ok(yp->key_len == 1 && strcmp(yp->key, "a") == 0 && + yp->data_len == 1 && strcmp(yp->data, "b") == 0 && + yp->event == YP_EID && yp->line_count == line + 1, + "compare key1 value"); + + ret = yp_parse(yp); + is_int(KNOT_EOF, ret, "parse EOF"); +} + +static void test_syntax_error(yp_parser_t *yp, const char *input) +{ + static int count = 1; + + int ret = yp_set_input_string(yp, input, strlen(input)); + is_int(KNOT_EOK, ret, "set error input string %i", count++); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0"); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key1"); + ret = yp_parse(yp); + is_int(KNOT_YP_EINVAL_INDENT, ret, "parse key1 - invalid indentation"); +} + +static void test_dname(yp_parser_t *yp) +{ +#define CHECK_DNAME(str) \ + ret = yp_parse(yp); \ + is_int(KNOT_EOK, ret, "parse dname " str); \ + ok(yp->key_len == strlen(str) && strcmp(yp->key, str) == 0 && yp->data_len == 0 && \ + yp->event == YP_EKEY0 && yp->line_count == line++, "compare " str); + + // Dname key value. + int ret = yp_set_input_string(yp, dname_ok, strlen(dname_ok)); + is_int(KNOT_EOK, ret, "set input string"); + + size_t line = 1; + CHECK_DNAME("."); + CHECK_DNAME("dom-ain"); + CHECK_DNAME("\\070-\\071.\\072."); + +} + +static void test_quotes(yp_parser_t *yp) +{ +#define CHECK_QUOTE(str) \ + ret = yp_parse(yp); \ + is_int(KNOT_EOK, ret, "parse quoted " str); \ + ok(yp->key_len == 1 && yp->key[0] == 'g' && \ + yp->data_len == strlen(str) && strcmp(yp->data, str) == 0 && \ + yp->event == YP_EKEY0 && yp->line_count == line++, "compare " str); + + int ret = yp_set_input_string(yp, quotes_ok, strlen(quotes_ok)); + is_int(KNOT_EOK, ret, "set input string"); + + size_t line = 1; + CHECK_QUOTE(""); + CHECK_QUOTE("a\\ b"); + CHECK_QUOTE("\\# 1 00"); + CHECK_QUOTE("\"\""); + CHECK_QUOTE(" a \" b \" \"c\" "); + CHECK_QUOTE("\\@ \\[ \\# \\, \\]"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + yp_parser_t yp; + yp_init(&yp); + + test_syntax_ok(&yp); + test_syntax_error(&yp, syntax_error1); + test_syntax_error(&yp, syntax_error2); + test_syntax_error(&yp, syntax_error3); + test_dname(&yp); + test_quotes(&yp); + + yp_deinit(&yp); + + return 0; +} diff --git a/tests/libknot/test_ypschema.c b/tests/libknot/test_ypschema.c new file mode 100644 index 0000000..50d56f6 --- /dev/null +++ b/tests/libknot/test_ypschema.c @@ -0,0 +1,417 @@ +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/yparser/ypschema.h" +#include "libknot/yparser/yptrafo.h" +#include "libknot/libknot.h" + +#define C_ID "\x02""id" +#define C_INT "\x07""integer" +#define C_BOOL "\x04""bool" +#define C_OPT "\x06""option" +#define C_STR "\x06""string" +#define C_ADDR "\x07""address" +#define C_DNAME "\x05""dname" +#define C_HEX "\x03""hex" +#define C_BASE64 "\x06""base64" +#define C_DATA "\x04""data" +#define C_REF "\x09""reference" +#define C_GRP "\x05""group" +#define C_MULTIGRP "\x0B""multi-group" + +static const yp_item_t group[] = { + { C_INT, YP_TINT, YP_VINT = { 0, 100, YP_NIL } }, + { C_STR, YP_TSTR, YP_VNONE, YP_FMULTI }, + { NULL } +}; + +static const yp_item_t multi_group[] = { + { C_ID, YP_TSTR, YP_VNONE }, + { C_HEX, YP_THEX, YP_VNONE }, + { C_BASE64, YP_TB64, YP_VNONE }, + { NULL } +}; + +static const knot_lookup_t opts[] = { + { 1, "one" }, + { 10, "ten" }, + { 0, NULL } + }; + +static const yp_item_t static_schema[] = { + { C_OPT, YP_TOPT, YP_VOPT = { opts } }, + { C_BOOL, YP_TBOOL, YP_VNONE }, + { C_DNAME, YP_TDNAME, YP_VNONE }, + { C_GRP, YP_TGRP, YP_VGRP = { group } }, + { C_MULTIGRP, YP_TGRP, YP_VGRP = { multi_group }, YP_FMULTI }, + { C_REF, YP_TREF, YP_VREF = { C_MULTIGRP } }, + { C_DATA, YP_TDATA, YP_VNONE }, + { NULL } +}; + +static void schema_find_test(void) +{ + yp_item_t *schema = NULL; + + int ret = yp_schema_copy(&schema, static_schema); + is_int(KNOT_EOK, ret, "schema copy"); + + const yp_item_t *i = yp_schema_find(C_OPT, NULL, schema); + ok(i != NULL, "schema find"); + if (i == NULL) { + goto error_schema; + } + ok(strcmp(i->name + 1, C_OPT + 1) == 0, "name check"); + + i = yp_schema_find(C_STR, C_GRP, schema); + ok(i != NULL, "schema find with parent"); + if (i == NULL) { + goto error_schema; + } + ok(strcmp(i->name + 1, C_STR + 1) == 0, "name check"); + + i = yp_schema_find(C_ADDR, NULL, schema); + ok(i == NULL, "schema not find"); + + i = yp_schema_find(C_ADDR, C_GRP, schema); + ok(i == NULL, "schema not find with parent"); + +error_schema: + yp_schema_free(schema); +} + +static void schema_merge_test(void) +{ + static const yp_item_t items1[] = { + { "\x01""1", YP_TSTR, YP_VNONE }, + { "\x01""2", YP_TSTR, YP_VNONE }, + { NULL } + }; + + static const yp_item_t items2[] = { + { "\x01""3", YP_TSTR, YP_VNONE }, + { "\x01""4", YP_TSTR, YP_VNONE }, + { NULL } + }; + + yp_item_t *schema = NULL; + yp_item_t *tmp = NULL; + + int ret = yp_schema_copy(&tmp, items1); + is_int(KNOT_EOK, ret, "schema copy"); + + ret = yp_schema_merge(&schema, items1, items2); + is_int(KNOT_EOK, ret, "schema merge"); + + yp_schema_free(tmp); + + for (uint8_t i = 0; i < 4; i++) { + yp_name_t name[3] = { '\x01', '1' + i }; + const yp_item_t *item = yp_schema_find(name, NULL, schema); + ok(item != NULL, "schema find"); + } + + yp_schema_free(schema); +} + +#define SET_INPUT_STR(str) \ + ret = yp_set_input_string(yp, str, strlen(str)); \ + is_int(KNOT_EOK, ret, "set input string"); + +#define PARSER_CHECK(depth) \ + ret = yp_parse(yp); \ + is_int(KNOT_EOK, ret, "parse"); \ + ret = yp_schema_check_parser(ctx, yp); \ + is_int(KNOT_EOK, ret, "check parser"); \ + node = &ctx->nodes[ctx->current]; \ + parent = node->parent; \ + ok(ctx->current == depth, "depth check"); + +#define PARSER_RET_CHECK(code) \ + ret = yp_parse(yp); \ + is_int(KNOT_EOK, ret, "parse"); \ + ret = yp_schema_check_parser(ctx, yp); \ + ok(ret == code, "return check parser"); + +static void parser_test(void) +{ + yp_parser_t yparser; + yp_parser_t *yp = &yparser; + yp_item_t *schema = NULL; + yp_check_ctx_t *ctx = NULL; + + yp_init(yp); + + int ret = yp_schema_copy(&schema, static_schema); + is_int(KNOT_EOK, ret, "schema copy"); + if (ret != KNOT_EOK) { + goto error_parser; + } + + ctx = yp_schema_check_init(&schema); + ok(ctx != NULL, "create check ctx"); + if (ctx == NULL) { + goto error_parser; + } + + yp_node_t *node; + yp_node_t *parent; + const yp_item_t *id; + + diag("parser key0 test"); + SET_INPUT_STR("option: one"); + PARSER_CHECK(0); + ok(strcmp(node->item->name + 1, "option") == 0, "name check"); + ok(node->item->type == YP_TOPT, "type check"); + ok(yp_opt(node->data) == 1, "value check"); + + diag("parser group test"); + SET_INPUT_STR("group:\n integer: 20\n string: [short, \"long string\"]"); + PARSER_CHECK(0); + ok(strcmp(node->item->name + 1, "group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + PARSER_CHECK(1); + ok(strcmp(node->item->name + 1, "integer") == 0, "name check"); + ok(node->item->type == YP_TINT, "type check"); + ok(yp_int(node->data) == 20, "value check"); + PARSER_CHECK(1); + ok(strcmp(node->item->name + 1, "string") == 0, "name check"); + ok(node->item->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->data), "short") == 0, "value check"); + PARSER_CHECK(1); + ok(strcmp(node->item->name + 1, "string") == 0, "name check"); + ok(node->item->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->data), "long string") == 0, "value check"); + + diag("parser multi-group test"); + SET_INPUT_STR("multi-group:\n - id: foo\n base64: Zm9vYmFy\nreference: foo"); + PARSER_CHECK(0); + ok(strcmp(node->item->name + 1, "multi-group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + PARSER_CHECK(0); + ok(node->id_len > 0, "id check"); + ok(strcmp(node->item->name + 1, "multi-group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + id = node->item->var.g.id; + ok(strcmp(id->name + 1, "id") == 0, "name check"); + ok(id->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->id), "foo") == 0, "value check"); + PARSER_CHECK(1); + id = parent->item->var.g.id; + ok(strcmp(parent->item->name + 1, "multi-group") == 0, "name check"); + ok(parent->item->type == YP_TGRP, "type check"); + ok(parent->data_len == 0, "value length check"); + ok(strcmp(yp_str(parent->id), "foo") == 0, "value check"); + ok(strcmp(id->name + 1, "id") == 0, "name check"); + ok(id->type == YP_TSTR, "type check"); + ok(strcmp(node->item->name + 1, "base64") == 0, "name check"); + ok(node->item->type == YP_TB64, "type check"); + ok(memcmp(yp_bin(node->data), "foobar", yp_bin_len(node->data)) == 0, + "value check"); + ok(node->id_len == 0, "id length check"); + PARSER_CHECK(0); + ok(strcmp(node->item->name + 1, "reference") == 0, "name check"); + ok(node->item->type == YP_TREF, "type check"); + ok(strcmp(yp_str(node->data), "foo") == 0, "value check"); + + diag("parser check return"); + SET_INPUT_STR("unknown:"); + PARSER_RET_CHECK(KNOT_YP_EINVAL_ITEM); + + SET_INPUT_STR("group:\n unknown:"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_EINVAL_ITEM); + + SET_INPUT_STR("group:\n - unknown: data"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_EINVAL_ITEM); + + SET_INPUT_STR("group:\n - hex: data"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_EINVAL_ITEM); + + SET_INPUT_STR("dname:"); + PARSER_RET_CHECK(KNOT_EINVAL); + + SET_INPUT_STR("group: data"); + PARSER_RET_CHECK(KNOT_YP_ENOTSUP_DATA); + + SET_INPUT_STR("group:\n integer:"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_EINVAL); + + SET_INPUT_STR("multi-group:\n id:"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_ENODATA); + + SET_INPUT_STR("multi-group:\n hex:"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_ENOID); + +error_parser: + yp_schema_check_deinit(ctx); + yp_schema_free(schema); + yp_deinit(yp); +} + +#define STR_CHECK(depth, key0, key1, id, data) \ + ret = yp_schema_check_str(ctx, key0, key1, id, data); \ + is_int(KNOT_EOK, ret, "check str"); \ + ok(ctx->current == depth, "depth check"); \ + node = &ctx->nodes[ctx->current]; \ + parent = node->parent; + +#define STR_RET_CHECK(code, key0, key1, id, data) \ + ret = yp_schema_check_str(ctx, key0, key1, id, data); \ + ok(ret == code, "return check str"); + +static void str_test(void) +{ + yp_item_t *schema; + yp_check_ctx_t *ctx = NULL; + + int ret = yp_schema_copy(&schema, static_schema); + is_int(KNOT_EOK, ret, "schema copy"); + if (ret != KNOT_EOK) { + goto error_str; + } + + ctx = yp_schema_check_init(&schema); + ok(ctx != NULL, "create check ctx"); + if (ctx == NULL) { + goto error_str; + } + + yp_node_t *node; + yp_node_t *parent; + const yp_item_t *id; + + diag("str key0 test"); + STR_CHECK(0, "option", NULL, NULL, "one"); + ok(strcmp(node->item->name + 1, "option") == 0, "name check"); + ok(node->item->type == YP_TOPT, "type check"); + ok(yp_opt(node->data) == 1, "value check"); + + diag("str group test"); + STR_CHECK(0, "group", NULL, NULL, NULL); + ok(strcmp(node->item->name + 1, "group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + STR_CHECK(1, "group", "integer", NULL, "20"); + ok(strcmp(node->item->name + 1, "integer") == 0, "name check"); + ok(node->item->type == YP_TINT, "type check"); + ok(yp_int(node->data) == 20, "value check"); + STR_CHECK(1, "group", "string", NULL, "short"); + ok(strcmp(node->item->name + 1, "string") == 0, "name check"); + ok(node->item->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->data), "short") == 0, "value check"); + STR_CHECK(1, "group", "string", NULL, "long string"); + ok(strcmp(node->item->name + 1, "string") == 0, "name check"); + ok(node->item->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->data), "long string") == 0, "value check"); + + diag("str multi-group test"); + STR_CHECK(0, "multi-group", NULL, NULL, NULL); + ok(strcmp(node->item->name + 1, "multi-group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + STR_CHECK(0, "multi-group", NULL, "foo", NULL); + ok(node->id_len > 0, "id check"); + ok(strcmp(node->item->name + 1, "multi-group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + id = node->item->var.g.id; + ok(strcmp(id->name + 1, "id") == 0, "name check"); + ok(id->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->id), "foo") == 0, "value check"); + STR_CHECK(1, "multi-group", "base64", "foo", "Zm9vYmFy"); + id = parent->item->var.g.id; + ok(strcmp(parent->item->name + 1, "multi-group") == 0, "name check"); + ok(parent->item->type == YP_TGRP, "type check"); + ok(parent->data_len == 0, "value length check"); + ok(strcmp(yp_str(parent->id), "foo") == 0, "value check"); + ok(strcmp(id->name + 1, "id") == 0, "name check"); + ok(id->type == YP_TSTR, "type check"); + ok(strcmp(node->item->name + 1, "base64") == 0, "name check"); + ok(node->item->type == YP_TB64, "type check"); + ok(memcmp(yp_bin(node->data), "foobar", yp_bin_len(node->data)) == 0, + "value check"); + ok(node->id_len == 0, "id length check"); + STR_CHECK(0, "reference", NULL, NULL, "foo"); + ok(strcmp(node->item->name + 1, "reference") == 0, "name check"); + ok(node->item->type == YP_TREF, "type check"); + ok(strcmp(yp_str(node->data), "foo") == 0, "value check"); + + diag("str check return"); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, "", "", "", ""); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, NULL, NULL, NULL, NULL); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, "unknown", NULL, NULL, NULL); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, NULL, "unknown", NULL, NULL); + STR_RET_CHECK(KNOT_EINVAL, "dname", "", "", ""); + STR_RET_CHECK(KNOT_EOK, "dname", NULL, NULL, NULL); + STR_RET_CHECK(KNOT_EOK, "dname", NULL, NULL, "."); + STR_RET_CHECK(KNOT_EINVAL, "dname", NULL, NULL, ".."); + STR_RET_CHECK(KNOT_YP_ENOTSUP_ID, "dname", NULL, "id", NULL); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, "dname", "unknown", NULL, NULL); + + STR_RET_CHECK(KNOT_EOK, "group", "", "", ""); + STR_RET_CHECK(KNOT_EOK, "group", NULL, NULL, NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_DATA, "group", "", "", "data"); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, "group", "unknown", NULL, NULL); + STR_RET_CHECK(KNOT_EOK, "group", "string", NULL, NULL); + STR_RET_CHECK(KNOT_EOK, "group", "string", NULL, "data"); + STR_RET_CHECK(KNOT_EOK, "group", "string", NULL, ""); + STR_RET_CHECK(KNOT_YP_ENOTSUP_ID, "group", "", "id", NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_ID, "group", "string", "id", NULL); + + STR_RET_CHECK(KNOT_EOK, "multi-group", "", "", ""); + STR_RET_CHECK(KNOT_EOK, "multi-group", NULL, NULL, NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_DATA, "multi-group", NULL, NULL, "data"); + STR_RET_CHECK(KNOT_EOK, "multi-group", NULL, "idval", NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_DATA, "multi-group", NULL, "idval", "data"); + STR_RET_CHECK(KNOT_EOK, "multi-group", "hex", "idval", NULL); + STR_RET_CHECK(KNOT_EOK, "multi-group", "hex", "idval", "data"); + STR_RET_CHECK(KNOT_EOK, "multi-group", "hex", NULL, NULL); + STR_RET_CHECK(KNOT_EOK, "multi-group", "hex", NULL, "data"); + STR_RET_CHECK(KNOT_EOK, "multi-group", "id", "", NULL); + STR_RET_CHECK(KNOT_EOK, "multi-group", "id", NULL, "idval"); + STR_RET_CHECK(KNOT_EOK, "multi-group", "id", "idval", NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_DATA, "multi-group", "id", "idval", "data"); + +error_str: + yp_schema_check_deinit(ctx); + yp_schema_free(schema); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + schema_find_test(); + schema_merge_test(); + parser_test(); + str_test(); + + return 0; +} diff --git a/tests/libknot/test_yptrafo.c b/tests/libknot/test_yptrafo.c new file mode 100644 index 0000000..3014a27 --- /dev/null +++ b/tests/libknot/test_yptrafo.c @@ -0,0 +1,403 @@ +/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/socket.h> +#include <tap/basic.h> + +#include "libknot/yparser/yptrafo.h" +#include "libknot/libknot.h" + +static void int_test(const char *txt, int64_t num, yp_style_t s, + int64_t min, int64_t max) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TINT, YP_VINT = { min, max, YP_NIL, s } }; + + diag("integer \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(yp_int(b) == num, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, s | YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void int_bad_test(const char *txt, int code, yp_style_t s, + int64_t min, int64_t max) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TINT, YP_VINT = { min, max, YP_NIL, s } }; + + diag("integer \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void bool_test(const char *txt, bool val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TBOOL, YP_VNONE }; + + diag("boolean \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(yp_bool(b) == val, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void bool_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TBOOL, YP_VNONE }; + + diag("boolean \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void opt_test(const char *txt, unsigned val, const knot_lookup_t *opts) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TOPT, YP_VOPT = { opts } }; + + diag("option \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(b_len == 1, "compare length"); + ok(yp_opt(b) == val, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void opt_bad_test(const char *txt, int code, const knot_lookup_t *opts) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TOPT, YP_VOPT = { opts } }; + + diag("option \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void str_test(const char *txt, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TSTR, YP_VNONE }; + + diag("string \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(b_len == strlen(txt) + 1, "compare length"); + ok(memcmp(yp_str(b), val, b_len) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void addr_test(const char *txt, bool port) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TADDR, YP_VNONE }; + + diag("address \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + bool no_port; + yp_addr(b, &no_port); + ok(no_port == port, "compare port presence"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void addr_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TADDR, YP_VNONE }; + + diag("address \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void addr_range_test(const char *txt) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TNET, YP_VNONE }; + + diag("address range \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void addr_range_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TNET, YP_VNONE }; + + diag("address range \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void dname_test(const char *txt, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TDNAME, YP_VNONE }; + + diag("dname \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(memcmp(yp_dname(b), val, b_len) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void hex_test(const char *txt, const char *val, const char *txt_out) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_THEX, YP_VNONE }; + + if (txt_out == NULL) { + txt_out = txt; + } + + diag("hex \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(memcmp(yp_bin(b), val, yp_bin_len(b)) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt_out) == t_len, "txt length"); + ok(memcmp(txt_out, t, t_len) == 0, "compare"); +} + +static void hex_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_THEX, YP_VNONE }; + + diag("hex \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void base64_test(const char *txt, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TB64, YP_VNONE }; + + diag("base64 \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(memcmp(yp_bin(b), val, yp_bin_len(b)) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void ref_test(const char *txt, bool val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t id = { NULL, YP_TBOOL, YP_VNONE }; + yp_item_t ref = { NULL, YP_TGRP, YP_VNONE }; + yp_item_t i = { NULL, YP_TREF, YP_VNONE }; + ref.var.g.id = &id; + i.var.r.ref = &ref; + + diag("reference to boolean \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(yp_bool(b) == val, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Integer tests. */ + int64_t min = -20000000000, max = 20000000000; + int_test("5", 5, YP_SNONE, min, max); + int_test("0", 0, YP_SNONE, min, max); + int_test("-5", -5, YP_SNONE, min, max); + int_test("20000000000", max, YP_SNONE, min, max); + int_test("-20000000000", min, YP_SNONE, min, max); + int_test("11B", 11LL * 1, YP_SSIZE, min, max); + int_test("11K", 11LL * 1024, YP_SSIZE, min, max); + int_test("11M", 11LL * 1024 * 1024, YP_SSIZE, min, max); + int_test("11G", 11LL * 1024 * 1024 * 1024, YP_SSIZE, min, max); + int_test("11s", 11LL * 1, YP_STIME, min, max); + int_test("11m", 11LL * 60, YP_STIME, min, max); + int_test("11h", 11LL * 3600, YP_STIME, min, max); + int_test("11d", 11LL * 24 * 3600, YP_STIME, min, max); + int_test("1025B", 1025LL, YP_SSIZE, min, max); + int_test("61s", 61LL, YP_STIME, min, max); + int_bad_test("20000000001", KNOT_ERANGE, YP_SNONE, min, max); + int_bad_test("-20000000001", KNOT_ERANGE, YP_SNONE, min, max); + int_bad_test("1x", KNOT_EINVAL, YP_SNONE, min, max); + int_bad_test("1sx", KNOT_EINVAL, YP_STIME, min, max); + + /* Boolean tests. */ + bool_test("on", true); + bool_test("off", false); + bool_bad_test("onx", KNOT_EINVAL); + bool_bad_test("enable", KNOT_EINVAL); + + /* Option tests. */ + static const knot_lookup_t opts[] = { + { 1, "one" }, + { 10, "ten" }, + { 255, "max" }, + { 0, NULL } + }; + opt_test("one", 1, opts); + opt_test("ten", 10, opts); + opt_test("max", 255, opts); + opt_bad_test("onex", KNOT_EINVAL, opts); + opt_bad_test("word", KNOT_EINVAL, opts); + + /* String tests. */ + str_test("Test string!", "Test string!"); + + /* Address tests. */ + addr_test("192.168.123.1", true); + addr_test("192.168.123.1@12345", false); + addr_test("2001:db8::1", true); + addr_test("::1@12345", false); + addr_test("/tmp/test.sock", true); + addr_bad_test("192.168.123.x", KNOT_EINVAL); + addr_bad_test("192.168.123.1@", KNOT_EINVAL); + addr_bad_test("192.168.123.1@1x", KNOT_EINVAL); + addr_bad_test("192.168.123.1@65536", KNOT_ERANGE); + + /* Address range tests. */ + addr_range_test("1.1.1.1"); + addr_range_test("1.1.1.1/0"); + addr_range_test("1.1.1.1/32"); + addr_range_test("1.1.1.1-1.2.3.4"); + addr_range_test("::1"); + addr_range_test("::1/0"); + addr_range_test("::1/32"); + addr_range_test("1::-5::"); + addr_range_bad_test("unix", KNOT_EINVAL); + addr_range_bad_test("1.1.1", KNOT_EINVAL); + addr_range_bad_test("1.1.1.1/", KNOT_EINVAL); + addr_range_bad_test("1.1.1.1/33", KNOT_ERANGE); + addr_range_bad_test("1.1.1.1-", KNOT_EINVAL); + addr_range_bad_test("1.1.1.1-::1", KNOT_EINVAL); + + /* Dname tests. */ + dname_test("example.com.", "\x07""example""\x03""com""\x00"); + + /* Hex tests. */ + hex_test("", "", NULL); + hex_test("0x", "", ""); + hex_test("Hello World!", "Hello World!", NULL); + hex_test("0x0155FF", "\x01\x55\xFF", NULL); + hex_bad_test("0xA", KNOT_EINVAL); + + /* Base64 tests. */ + base64_test("Zm9vYmFy", "foobar"); + + /* Ref tests. */ + ref_test("on", true); + + return 0; +} diff --git a/tests/libzscanner/TESTS b/tests/libzscanner/TESTS new file mode 100644 index 0000000..f26b858 --- /dev/null +++ b/tests/libzscanner/TESTS @@ -0,0 +1,80 @@ +00-0_general +00-1_general +00-2_general +00-3_general +00-4_general +01_owner +02_class +03_rrttl +04-0_ORIGIN +04-1_ORIGIN +04-2_ORIGIN +04-3_ORIGIN +04-4_ORIGIN +04-5_ORIGIN +04-6_ORIGIN +04-7_ORIGIN +04-8_ORIGIN +04-9_ORIGIN +05-0_TTL +05-1_TTL +05-2_TTL +05-3_TTL +05-4_TTL +06-0_INCLUDE +06-1_INCLUDE +06-2_INCLUDE +06-3_INCLUDE +06-4_INCLUDE +06-5_INCLUDE +06-6_INCLUDE +06-7_INCLUDE +06-8_INCLUDE +07-0-rdata +07-1-rdata +07-2-rdata +07-3-rdata +07-4-rdata +10_A +11_AAAA +12_TXT +13_SPF +14_NS +15_CNAME +16_PTR +17_DNAME +18_MX +19_AFSDB +20_RT +21_KX +22_HINFO +23_MINFO +24_RP +25_SOA +26_SRV +27_NAPTR +28_TYPE +29_CERT +30_KEY +31_DNSKEY +32_APL +33_DS +34_SSHFP +35_IPSECKEY +36_RRSIG +37_NSEC +38_DHCID +39_NSEC3 +40_NSEC3PARAM +41_TLSA +42_LOC +43_EUI48 +44_EUI64 +45_NID +46_L32 +47_L64 +48_LP +49_CDS +50_CDNSKEY +51_URI +52_CAA diff --git a/tests/libzscanner/data/00-0_general.in b/tests/libzscanner/data/00-0_general.in new file mode 100644 index 0000000..de9c3f0 --- /dev/null +++ b/tests/libzscanner/data/00-0_general.in @@ -0,0 +1,24 @@ +$ORIGIN . +$TTL 1 + +; OK +t01 IN 10 NS @ ; All items are mentioned + IN 10 NS @ ; Same as above without OWNER +t02 20 IN NS @ ; Switched CLASS and TTL + 20 IN NS @ ; Same as above without OWNER +t03 30 NS @ ; Missing CLASS + 30 NS @ ; Same as above without OWNER +t04 IN NS @ ; Missing TTL + IN NS @ ; Same as above without OWNER +t05 NS @ ; Missing CLASS and TTL + NS @ ; Same as above without OWNER + +@ ( ) NS ( ; Multiline 1/5 + ) () ( ; Multiline 2/5 + + @ ; Multiline 4/5 + ) ( +) ; Multiline 6/6 + +; KO +@ NS ((@)) ; Nested parentheses - ERROR = STOP PROCESSING! diff --git a/tests/libzscanner/data/00-0_general.out b/tests/libzscanner/data/00-0_general.out new file mode 100644 index 0000000..9acf1cb --- /dev/null +++ b/tests/libzscanner/data/00-0_general.out @@ -0,0 +1,68 @@ +OWNER=0374303100 +CLASS=0001 +RRTTL=0000000A +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303100 +CLASS=0001 +RRTTL=0000000A +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303200 +CLASS=0001 +RRTTL=00000014 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303200 +CLASS=0001 +RRTTL=00000014 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303300 +CLASS=0001 +RRTTL=0000001E +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303300 +CLASS=0001 +RRTTL=0000001E +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303500 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303500 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +ERROR=ZS_LEFT_PARENTHESIS +------ diff --git a/tests/libzscanner/data/00-1_general.in b/tests/libzscanner/data/00-1_general.in new file mode 100644 index 0000000..2423909 --- /dev/null +++ b/tests/libzscanner/data/00-1_general.in @@ -0,0 +1,7 @@ +$ORIGIN . +$TTL 1 + +; KO +@ TXT ( "text" ; Unclosed multiline block + +;comment diff --git a/tests/libzscanner/data/00-1_general.out b/tests/libzscanner/data/00-1_general.out new file mode 100644 index 0000000..85b0653 --- /dev/null +++ b/tests/libzscanner/data/00-1_general.out @@ -0,0 +1,2 @@ +ERROR=ZS_UNCLOSED_MULTILINE +------ diff --git a/tests/libzscanner/data/00-2_general.in b/tests/libzscanner/data/00-2_general.in new file mode 100644 index 0000000..460eeb5 --- /dev/null +++ b/tests/libzscanner/data/00-2_general.in @@ -0,0 +1 @@ +$ORIGIN .
diff --git a/tests/libzscanner/data/00-2_general.out b/tests/libzscanner/data/00-2_general.out new file mode 100644 index 0000000..79776a7 --- /dev/null +++ b/tests/libzscanner/data/00-2_general.out @@ -0,0 +1,2 @@ +ERROR=ZS_DOS_NEWLINE +------ diff --git a/tests/libzscanner/data/00-3_general.in b/tests/libzscanner/data/00-3_general.in new file mode 100644 index 0000000..6ce107c --- /dev/null +++ b/tests/libzscanner/data/00-3_general.in @@ -0,0 +1,4 @@ +$ORIGIN . +$TTL 1 + +. NS @ ; No newline
\ No newline at end of file diff --git a/tests/libzscanner/data/00-3_general.out b/tests/libzscanner/data/00-3_general.out new file mode 100644 index 0000000..bc06672 --- /dev/null +++ b/tests/libzscanner/data/00-3_general.out @@ -0,0 +1,6 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ diff --git a/tests/libzscanner/data/00-4_general.in b/tests/libzscanner/data/00-4_general.in new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/libzscanner/data/00-4_general.in diff --git a/tests/libzscanner/data/00-4_general.out b/tests/libzscanner/data/00-4_general.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/libzscanner/data/00-4_general.out diff --git a/tests/libzscanner/data/01_owner.in b/tests/libzscanner/data/01_owner.in new file mode 100644 index 0000000..0108be3 --- /dev/null +++ b/tests/libzscanner/data/01_owner.in @@ -0,0 +1,37 @@ +$ORIGIN . +$TTL 1 + +; OK +. NS @ ; The simplest owner +tld. NS @ ; FQD tld owner +tld NS @ ; Relative form + NS @ ; The previous owner +*. NS @ ; FQD with asterisk +* NS @ ; Alone asterisk +*.* NS @ ; More asterisks +*a.a*a.** NS @ ; Also possible +@ NS @ ; Use origin +0123456789 NS @ ; Digits +0/25.2.0.192.in-addr.arpa. NS @ ; CIDR notation +_a_.-b-c-./d/. NS @ ; Allowed characters '_' '-' '/' anywhere +ABCDEFGHIJKLMNOPQRSTUVWXYZ NS @ ; All upper-case letters +abcdefghijklmnopqrstuvwxyz NS @ ; All lower-case letters +\000\0320\ \\\"\.\@\*.tld. NS @ ; Label with special chars +b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. NS @ ; IPv6 reverse +12345678901234567890123456789012345678901234567890123456789012\051.tld. NS @ ; Label of maximal length +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901. NS @ ; Domain name of maximal length +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901 NS @ ; Domain name of maximal length (after appending origin) + +; KO +& NS @ ; Bad (unslashed) character + NS @ ; Bad previous +.a NS @ ; Leading dot +@@ NS @ ; Double @@ +.. NS @ ; Missing label between dots +\1 NS @ ; Slash notation requires 3 digits +\12 NS @ ; Slash notation requires 3 digits +12345678901234567890123456789012345678901234567890123456789012\0514.tld. NS @ ; Label exceeded maximal length +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012. NS @ ; Domain name exceeded maximal length +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012 NS @ ; Domain name exceeded maximal length (after appending origin) +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.1 NS @ ; Domain name exceeded maximal length (maximal dname length check is after each valid label) +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.123456789012345678901234567890123456789012345678901234567890123 NS @ ; Domain name exceeded maximal length (maximal dname length check is after each valid label) diff --git a/tests/libzscanner/data/01_owner.out b/tests/libzscanner/data/01_owner.out new file mode 100644 index 0000000..26a8454 --- /dev/null +++ b/tests/libzscanner/data/01_owner.out @@ -0,0 +1,138 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=012A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=012A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=012A012A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=022A6103612A61022A2A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0A3031323334353637383900 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=04302F3235013201300331393207696E2D61646472046172706100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=035F615F052D622D632D032F642F00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=1A4142434445464748494A4B4C4D4E4F505152535455565758595A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=1A6162636465666768696A6B6C6D6E6F707172737475767778797A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=09002030205C222E402A03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_BAD_OWNER +------ +WARNG=ZS_BAD_PREVIOUS_OWNER +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_LABEL_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ diff --git a/tests/libzscanner/data/02_class.in b/tests/libzscanner/data/02_class.in new file mode 100644 index 0000000..c4347e7 --- /dev/null +++ b/tests/libzscanner/data/02_class.in @@ -0,0 +1,10 @@ +$ORIGIN . +$TTL 1 + +; OK +@ IN NS @ ; The only accepted class IN +@ in NS @ ; Class in lower-case + +; KO +@ CH NS @ ; Unsupported class +@ CLASS1 NS @ ; Unsupported notation diff --git a/tests/libzscanner/data/02_class.out b/tests/libzscanner/data/02_class.out new file mode 100644 index 0000000..69daae3 --- /dev/null +++ b/tests/libzscanner/data/02_class.out @@ -0,0 +1,16 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ diff --git a/tests/libzscanner/data/03_rrttl.in b/tests/libzscanner/data/03_rrttl.in new file mode 100644 index 0000000..7c57d73 --- /dev/null +++ b/tests/libzscanner/data/03_rrttl.in @@ -0,0 +1,26 @@ +$ORIGIN . +$TTL 1 + +; OK +@ 0 NS @ ; Minimal ttl +@ 3600 NS @ ; Inner value +@ 4294967295 NS @ ; Maximal ttl +@ 1S NS @ ; 1 second (upper-case) +@ 1s NS @ ; 1 second (lower-case) +@ 1M NS @ ; 1 minute (upper-case) +@ 1m NS @ ; 1 minute (lower-case) +@ 1H NS @ ; 1 hour (upper-case) +@ 1h NS @ ; 1 hour (lower-case) +@ 1D NS @ ; 1 day (upper-case) +@ 1d NS @ ; 1 day (lower-case) +@ 1W NS @ ; 1 week (upper-case) +@ 1w NS @ ; 1 week (lower-case) +@ 1w1d1h1m1s NS @ ; More time units +@ 1s1m1m NS @ ; Same time units, non decreasing order + +; KO +@ -1 NS @ ; Negative ttl +@ 4294967296 NS @ ; 32bit overflow +@ 100000000W NS @ ; 32bit overflow +@ 4294967295s1w NS @ ; 32bit overflow +@ 1x NS @ ; Unknown time unit diff --git a/tests/libzscanner/data/03_rrttl.out b/tests/libzscanner/data/03_rrttl.out new file mode 100644 index 0000000..f5cc907 --- /dev/null +++ b/tests/libzscanner/data/03_rrttl.out @@ -0,0 +1,100 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=FFFFFFFF +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=0000003C +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=0000003C +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00015180 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00015180 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00093A80 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00093A80 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=000A9A4D +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000079 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_BAD_TIME_UNIT +------ diff --git a/tests/libzscanner/data/04-0_ORIGIN.in b/tests/libzscanner/data/04-0_ORIGIN.in new file mode 100644 index 0000000..4d65ec4 --- /dev/null +++ b/tests/libzscanner/data/04-0_ORIGIN.in @@ -0,0 +1,29 @@ +$TTL 1 + +; OK +$ORIGIN . ; Root domain +@ NS @ ; Use origin +a. NS @ ; Absolute dname +a NS @ ; Relative dname +$ORIGIN tld. ; 1. level domain +@ NS @ ; Use origin +a. NS @ ; Absolute dname +a NS @ ; Relative dname +$ORIGIN second.tld. ; 2. level domain +@ NS @ ; Use origin +a. NS @ ; Absolute dname +a NS @ ; Relative dname +$ORIGIN \0320\ \\\"\.\@\*.tld. ; Label with special chars +@ NS @ ; Use origin +$ORIGIN b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. ; IPv6 reverse +@ NS @ ; Use origin +$ORIGIN 12345678901234567890123456789012345678901234567890123456789012\051.tld. ; Label of maximal length +@ NS @ ; Use origin +$ORIGIN 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901. ; Domain name of maximal length +@ NS @ ; Use origin +$origin . ; Lower-case +@ NS @ ; Use origin + +; KO +$ORIGIN ; Empty input +. NS . ; Is OK, but shouldn't be processed due to previous error stop! diff --git a/tests/libzscanner/data/04-0_ORIGIN.out b/tests/libzscanner/data/04-0_ORIGIN.out new file mode 100644 index 0000000..92dc459 --- /dev/null +++ b/tests/libzscanner/data/04-0_ORIGIN.out @@ -0,0 +1,86 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=016103746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=067365636F6E6403746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=067365636F6E6403746C6400 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=067365636F6E6403746C6400 +------ +OWNER=0161067365636F6E6403746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=067365636F6E6403746C6400 +------ +OWNER=082030205C222E402A03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=082030205C222E402A03746C6400 +------ +OWNER=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100 +------ +OWNER=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400 +------ +OWNER=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +ERROR=ZS_BAD_ORIGIN +------ diff --git a/tests/libzscanner/data/04-1_ORIGIN.in b/tests/libzscanner/data/04-1_ORIGIN.in new file mode 100644 index 0000000..871c064 --- /dev/null +++ b/tests/libzscanner/data/04-1_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN tld ; Not FQD diff --git a/tests/libzscanner/data/04-1_ORIGIN.out b/tests/libzscanner/data/04-1_ORIGIN.out new file mode 100644 index 0000000..467de10 --- /dev/null +++ b/tests/libzscanner/data/04-1_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_ORIGIN +------ diff --git a/tests/libzscanner/data/04-2_ORIGIN.in b/tests/libzscanner/data/04-2_ORIGIN.in new file mode 100644 index 0000000..8dd2e20 --- /dev/null +++ b/tests/libzscanner/data/04-2_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN % ; Bad (unslashed) character diff --git a/tests/libzscanner/data/04-2_ORIGIN.out b/tests/libzscanner/data/04-2_ORIGIN.out new file mode 100644 index 0000000..467de10 --- /dev/null +++ b/tests/libzscanner/data/04-2_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_ORIGIN +------ diff --git a/tests/libzscanner/data/04-3_ORIGIN.in b/tests/libzscanner/data/04-3_ORIGIN.in new file mode 100644 index 0000000..26d1872 --- /dev/null +++ b/tests/libzscanner/data/04-3_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN .. ; Missing label between dots diff --git a/tests/libzscanner/data/04-3_ORIGIN.out b/tests/libzscanner/data/04-3_ORIGIN.out new file mode 100644 index 0000000..b7d67e5 --- /dev/null +++ b/tests/libzscanner/data/04-3_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/04-4_ORIGIN.in b/tests/libzscanner/data/04-4_ORIGIN.in new file mode 100644 index 0000000..0be4721 --- /dev/null +++ b/tests/libzscanner/data/04-4_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN \1 ; Slash notation requires 3 digits diff --git a/tests/libzscanner/data/04-4_ORIGIN.out b/tests/libzscanner/data/04-4_ORIGIN.out new file mode 100644 index 0000000..03a0738 --- /dev/null +++ b/tests/libzscanner/data/04-4_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/04-5_ORIGIN.in b/tests/libzscanner/data/04-5_ORIGIN.in new file mode 100644 index 0000000..170d465 --- /dev/null +++ b/tests/libzscanner/data/04-5_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN \12 ; Slash notation requires 3 digits diff --git a/tests/libzscanner/data/04-5_ORIGIN.out b/tests/libzscanner/data/04-5_ORIGIN.out new file mode 100644 index 0000000..03a0738 --- /dev/null +++ b/tests/libzscanner/data/04-5_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/04-6_ORIGIN.in b/tests/libzscanner/data/04-6_ORIGIN.in new file mode 100644 index 0000000..db9652d --- /dev/null +++ b/tests/libzscanner/data/04-6_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN .tld ; Leading dot diff --git a/tests/libzscanner/data/04-6_ORIGIN.out b/tests/libzscanner/data/04-6_ORIGIN.out new file mode 100644 index 0000000..b7d67e5 --- /dev/null +++ b/tests/libzscanner/data/04-6_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/04-7_ORIGIN.in b/tests/libzscanner/data/04-7_ORIGIN.in new file mode 100644 index 0000000..556646c --- /dev/null +++ b/tests/libzscanner/data/04-7_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN tld. x ; Unexpected item diff --git a/tests/libzscanner/data/04-7_ORIGIN.out b/tests/libzscanner/data/04-7_ORIGIN.out new file mode 100644 index 0000000..b7d67e5 --- /dev/null +++ b/tests/libzscanner/data/04-7_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/04-8_ORIGIN.in b/tests/libzscanner/data/04-8_ORIGIN.in new file mode 100644 index 0000000..445cbec --- /dev/null +++ b/tests/libzscanner/data/04-8_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN 12345678901234567890123456789012345678901234567890123456789012\0514.tld. ; Label exceeded maximal length diff --git a/tests/libzscanner/data/04-8_ORIGIN.out b/tests/libzscanner/data/04-8_ORIGIN.out new file mode 100644 index 0000000..788a495 --- /dev/null +++ b/tests/libzscanner/data/04-8_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_LABEL_OVERFLOW +------ diff --git a/tests/libzscanner/data/04-9_ORIGIN.in b/tests/libzscanner/data/04-9_ORIGIN.in new file mode 100644 index 0000000..e0a4b95 --- /dev/null +++ b/tests/libzscanner/data/04-9_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012. ; Domain name exceeded maximal length diff --git a/tests/libzscanner/data/04-9_ORIGIN.out b/tests/libzscanner/data/04-9_ORIGIN.out new file mode 100644 index 0000000..eef0ab5 --- /dev/null +++ b/tests/libzscanner/data/04-9_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_DNAME_OVERFLOW +------ diff --git a/tests/libzscanner/data/05-0_TTL.in b/tests/libzscanner/data/05-0_TTL.in new file mode 100644 index 0000000..baa8f38 --- /dev/null +++ b/tests/libzscanner/data/05-0_TTL.in @@ -0,0 +1,36 @@ +$ORIGIN . + +; OK +$TTL 0 ; Minimal ttl +@ NS @ ; Use ttl +$TTL 3600 ; Inner value +@ NS @ ; Use ttl +$TTL 4294967295 ; Maximal ttl +@ NS @ ; Use ttl +$TTL 1S ; 1 second (upper-case) +@ NS @ ; Use ttl +$TTL 1s ; 1 second (lower-case) +@ NS @ ; Use ttl +$TTL 1M ; 1 minute (upper-case) +@ NS @ ; Use ttl +$TTL 1m ; 1 minute (lower-case) +@ NS @ ; Use ttl +$TTL 1H ; 1 hour (upper-case) +@ NS @ ; Use ttl +$TTL 1h ; 1 hour (lower-case) +@ NS @ ; Use ttl +$TTL 1D ; 1 day (upper-case) +@ NS @ ; Use ttl +$TTL 1d ; 1 day (lower-case) +@ NS @ ; Use ttl +$TTL 1W ; 1 week (upper-case) +@ NS @ ; Use ttl +$TTL 1w ; 1 week (lower-case) +@ NS @ ; Use ttl +$TTL 1w1d1h1m1s ; More time units +@ NS @ ; Use ttl +$TTL 1s1m1m ; Same time units, non decreasing order +@ NS @ ; Use ttl + +; KO +$TTL -1 ; Negative ttl diff --git a/tests/libzscanner/data/05-0_TTL.out b/tests/libzscanner/data/05-0_TTL.out new file mode 100644 index 0000000..93c7651 --- /dev/null +++ b/tests/libzscanner/data/05-0_TTL.out @@ -0,0 +1,92 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=FFFFFFFF +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=0000003C +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=0000003C +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00015180 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00015180 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00093A80 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00093A80 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=000A9A4D +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000079 +RTYPE=0002 +RDATA=00 +------ +ERROR=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/05-1_TTL.in b/tests/libzscanner/data/05-1_TTL.in new file mode 100644 index 0000000..519fe79 --- /dev/null +++ b/tests/libzscanner/data/05-1_TTL.in @@ -0,0 +1,4 @@ +$ORIGIN . + +; KO +$TTL 4294967296 ; 32bit overflow diff --git a/tests/libzscanner/data/05-1_TTL.out b/tests/libzscanner/data/05-1_TTL.out new file mode 100644 index 0000000..1849267 --- /dev/null +++ b/tests/libzscanner/data/05-1_TTL.out @@ -0,0 +1,2 @@ +ERROR=ZS_NUMBER32_OVERFLOW +------ diff --git a/tests/libzscanner/data/05-2_TTL.in b/tests/libzscanner/data/05-2_TTL.in new file mode 100644 index 0000000..ed112da --- /dev/null +++ b/tests/libzscanner/data/05-2_TTL.in @@ -0,0 +1,4 @@ +$ORIGIN . + +; KO +$TTL 100000000W ; 32bit overflow diff --git a/tests/libzscanner/data/05-2_TTL.out b/tests/libzscanner/data/05-2_TTL.out new file mode 100644 index 0000000..1849267 --- /dev/null +++ b/tests/libzscanner/data/05-2_TTL.out @@ -0,0 +1,2 @@ +ERROR=ZS_NUMBER32_OVERFLOW +------ diff --git a/tests/libzscanner/data/05-3_TTL.in b/tests/libzscanner/data/05-3_TTL.in new file mode 100644 index 0000000..d96c9ba --- /dev/null +++ b/tests/libzscanner/data/05-3_TTL.in @@ -0,0 +1,4 @@ +$ORIGIN . + +; KO +$TTL 4294967295s1w ; 32bit overflow diff --git a/tests/libzscanner/data/05-3_TTL.out b/tests/libzscanner/data/05-3_TTL.out new file mode 100644 index 0000000..1849267 --- /dev/null +++ b/tests/libzscanner/data/05-3_TTL.out @@ -0,0 +1,2 @@ +ERROR=ZS_NUMBER32_OVERFLOW +------ diff --git a/tests/libzscanner/data/05-4_TTL.in b/tests/libzscanner/data/05-4_TTL.in new file mode 100644 index 0000000..efaf4d0 --- /dev/null +++ b/tests/libzscanner/data/05-4_TTL.in @@ -0,0 +1,4 @@ +$ORIGIN . + +; KO +$TTL 1x ; Unknown time unit diff --git a/tests/libzscanner/data/05-4_TTL.out b/tests/libzscanner/data/05-4_TTL.out new file mode 100644 index 0000000..d4bef98 --- /dev/null +++ b/tests/libzscanner/data/05-4_TTL.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_TIME_UNIT +------ diff --git a/tests/libzscanner/data/06-0_INCLUDE.in b/tests/libzscanner/data/06-0_INCLUDE.in new file mode 100644 index 0000000..962e6c9 --- /dev/null +++ b/tests/libzscanner/data/06-0_INCLUDE.in @@ -0,0 +1,29 @@ +$ORIGIN . +$TTL 1 + +; OK +0. NS @ + +$INCLUDE ./includes/include1 ; Relative path without origin +1. NS @ + +$INCLUDE "./includes/include2" . ; Quoted filename and the simplest origin +2. NS @ + +$INCLUDE ./includes/include\050 tld. ; Simple origin +3. NS @ + +$INCLUDE \./includes/include2 _a_.-b-c-./d/. ; Slashed character in file name, allowed characters in origin +4. NS @ + +$INCLUDE ./includes/include2 \0320\ \\\"\.\@\*.tld. ; Origin with special chars +5. NS @ + +$INCLUDE @TMPDIR@/includes/include2 ; Absolute path without origin +6. NS @ + +$INCLUDE @TMPDIR@/includes/include2 tld. ; Absolute path with origin +7. NS @ + +; KO (DISABLED - different results) +;$INCLUDE ; Empty parameters diff --git a/tests/libzscanner/data/06-0_INCLUDE.out b/tests/libzscanner/data/06-0_INCLUDE.out new file mode 100644 index 0000000..2536f72 --- /dev/null +++ b/tests/libzscanner/data/06-0_INCLUDE.out @@ -0,0 +1,138 @@ +OWNER=013000 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016105746C64316100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=016105746C64316200 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=05746C64316200 +------ +OWNER=013100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016200 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013200 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016203746C6400 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013300 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0162035F615F052D622D632D032F642F00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=035F615F052D622D632D032F642F00 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0162082030205C222E402A03746C6400 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=082030205C222E402A03746C6400 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013500 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016200 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013600 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016203746C6400 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013700 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ diff --git a/tests/libzscanner/data/06-1_INCLUDE.in b/tests/libzscanner/data/06-1_INCLUDE.in new file mode 100644 index 0000000..194fb52 --- /dev/null +++ b/tests/libzscanner/data/06-1_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include1 a ; Origin is not FQDN diff --git a/tests/libzscanner/data/06-1_INCLUDE.out b/tests/libzscanner/data/06-1_INCLUDE.out new file mode 100644 index 0000000..6634921 --- /dev/null +++ b/tests/libzscanner/data/06-1_INCLUDE.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_INCLUDE_ORIGIN +------ diff --git a/tests/libzscanner/data/06-2_INCLUDE.in b/tests/libzscanner/data/06-2_INCLUDE.in new file mode 100644 index 0000000..21bcf05 --- /dev/null +++ b/tests/libzscanner/data/06-2_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include1 % ; Bad origin diff --git a/tests/libzscanner/data/06-2_INCLUDE.out b/tests/libzscanner/data/06-2_INCLUDE.out new file mode 100644 index 0000000..6634921 --- /dev/null +++ b/tests/libzscanner/data/06-2_INCLUDE.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_INCLUDE_ORIGIN +------ diff --git a/tests/libzscanner/data/06-3_INCLUDE.in b/tests/libzscanner/data/06-3_INCLUDE.in new file mode 100644 index 0000000..f7079b4 --- /dev/null +++ b/tests/libzscanner/data/06-3_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE @TMPDIR@/ ; Given file is a directory diff --git a/tests/libzscanner/data/06-3_INCLUDE.out b/tests/libzscanner/data/06-3_INCLUDE.out new file mode 100644 index 0000000..6823154 --- /dev/null +++ b/tests/libzscanner/data/06-3_INCLUDE.out @@ -0,0 +1,2 @@ +ERROR=ZS_FILE_INVALID +------ diff --git a/tests/libzscanner/data/06-4_INCLUDE.in b/tests/libzscanner/data/06-4_INCLUDE.in new file mode 100644 index 0000000..3cdc79d --- /dev/null +++ b/tests/libzscanner/data/06-4_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE @TMPDIR@/file-doesnt-exist ; File doesn't exist diff --git a/tests/libzscanner/data/06-4_INCLUDE.out b/tests/libzscanner/data/06-4_INCLUDE.out new file mode 100644 index 0000000..e09e5d1 --- /dev/null +++ b/tests/libzscanner/data/06-4_INCLUDE.out @@ -0,0 +1,2 @@ +ERROR=ZS_FILE_OPEN +------ diff --git a/tests/libzscanner/data/06-5_INCLUDE.in b/tests/libzscanner/data/06-5_INCLUDE.in new file mode 100644 index 0000000..1d65812 --- /dev/null +++ b/tests/libzscanner/data/06-5_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include3 ; Blank include file diff --git a/tests/libzscanner/data/06-5_INCLUDE.out b/tests/libzscanner/data/06-5_INCLUDE.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/libzscanner/data/06-5_INCLUDE.out diff --git a/tests/libzscanner/data/06-6_INCLUDE.in b/tests/libzscanner/data/06-6_INCLUDE.in new file mode 100644 index 0000000..cbfda64 --- /dev/null +++ b/tests/libzscanner/data/06-6_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include4 ; Include file contains warning diff --git a/tests/libzscanner/data/06-6_INCLUDE.out b/tests/libzscanner/data/06-6_INCLUDE.out new file mode 100644 index 0000000..a9c0259 --- /dev/null +++ b/tests/libzscanner/data/06-6_INCLUDE.out @@ -0,0 +1,4 @@ +WARNG=ZS_BAD_RDATA +------ +ERROR=ZS_UNPROCESSED_INCLUDE +------ diff --git a/tests/libzscanner/data/06-7_INCLUDE.in b/tests/libzscanner/data/06-7_INCLUDE.in new file mode 100644 index 0000000..24deef7 --- /dev/null +++ b/tests/libzscanner/data/06-7_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include5 ; Include file contains error diff --git a/tests/libzscanner/data/06-7_INCLUDE.out b/tests/libzscanner/data/06-7_INCLUDE.out new file mode 100644 index 0000000..cbbb0c1 --- /dev/null +++ b/tests/libzscanner/data/06-7_INCLUDE.out @@ -0,0 +1,4 @@ +ERROR=ZS_BAD_NUMBER +------ +ERROR=ZS_UNPROCESSED_INCLUDE +------ diff --git a/tests/libzscanner/data/06-8_INCLUDE.in b/tests/libzscanner/data/06-8_INCLUDE.in new file mode 100644 index 0000000..c856668 --- /dev/null +++ b/tests/libzscanner/data/06-8_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include6 ; Include file contains include diff --git a/tests/libzscanner/data/06-8_INCLUDE.out b/tests/libzscanner/data/06-8_INCLUDE.out new file mode 100644 index 0000000..4581388 --- /dev/null +++ b/tests/libzscanner/data/06-8_INCLUDE.out @@ -0,0 +1,12 @@ +OWNER=016200 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ diff --git a/tests/libzscanner/data/07-0-rdata.in b/tests/libzscanner/data/07-0-rdata.in new file mode 100644 index 0000000..a79403f --- /dev/null +++ b/tests/libzscanner/data/07-0-rdata.in @@ -0,0 +1 @@ +@ A \
\ No newline at end of file diff --git a/tests/libzscanner/data/07-0-rdata.out b/tests/libzscanner/data/07-0-rdata.out new file mode 100644 index 0000000..ed303f6 --- /dev/null +++ b/tests/libzscanner/data/07-0-rdata.out @@ -0,0 +1,2 @@ +WARNG=ZS_BAD_ADDRESS_CHAR +------ diff --git a/tests/libzscanner/data/07-1-rdata.in b/tests/libzscanner/data/07-1-rdata.in new file mode 100644 index 0000000..7a5a11a --- /dev/null +++ b/tests/libzscanner/data/07-1-rdata.in @@ -0,0 +1 @@ +@ TXT \
\ No newline at end of file diff --git a/tests/libzscanner/data/07-1-rdata.out b/tests/libzscanner/data/07-1-rdata.out new file mode 100644 index 0000000..1702677 --- /dev/null +++ b/tests/libzscanner/data/07-1-rdata.out @@ -0,0 +1,2 @@ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/07-2-rdata.in b/tests/libzscanner/data/07-2-rdata.in new file mode 100644 index 0000000..7a4c8fe --- /dev/null +++ b/tests/libzscanner/data/07-2-rdata.in @@ -0,0 +1 @@ +@ TXT \092
\ No newline at end of file diff --git a/tests/libzscanner/data/07-2-rdata.out b/tests/libzscanner/data/07-2-rdata.out new file mode 100644 index 0000000..3f52437 --- /dev/null +++ b/tests/libzscanner/data/07-2-rdata.out @@ -0,0 +1,6 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0010 +RDATA=015C +------ diff --git a/tests/libzscanner/data/07-3-rdata.in b/tests/libzscanner/data/07-3-rdata.in new file mode 100644 index 0000000..338b212 --- /dev/null +++ b/tests/libzscanner/data/07-3-rdata.in @@ -0,0 +1 @@ +@ TXT \\
\ No newline at end of file diff --git a/tests/libzscanner/data/07-3-rdata.out b/tests/libzscanner/data/07-3-rdata.out new file mode 100644 index 0000000..3f52437 --- /dev/null +++ b/tests/libzscanner/data/07-3-rdata.out @@ -0,0 +1,6 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0010 +RDATA=015C +------ diff --git a/tests/libzscanner/data/07-4-rdata.in b/tests/libzscanner/data/07-4-rdata.in new file mode 100644 index 0000000..74a45dd --- /dev/null +++ b/tests/libzscanner/data/07-4-rdata.in @@ -0,0 +1 @@ +@ TXT \# 2 015C
\ No newline at end of file diff --git a/tests/libzscanner/data/07-4-rdata.out b/tests/libzscanner/data/07-4-rdata.out new file mode 100644 index 0000000..3f52437 --- /dev/null +++ b/tests/libzscanner/data/07-4-rdata.out @@ -0,0 +1,6 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0010 +RDATA=015C +------ diff --git a/tests/libzscanner/data/10_A.in b/tests/libzscanner/data/10_A.in new file mode 100644 index 0000000..6c7c90a --- /dev/null +++ b/tests/libzscanner/data/10_A.in @@ -0,0 +1,19 @@ +$ORIGIN . +$TTL 1 + +; OK +@ A 0.0.0.0 ; Minimal ipv4 address +@ A 255.255.255.255 ; Maximal ipv4 address +@ A \# 4 00000000 ; Hexadecimal rdata +@ TYPE1 \# 4 00000000 ; TYPE + Hexadecimal rdata +@ TYPE1 0.0.0.0 ; TYPE +@ a 0.0.0.0 ; Type in lower-case + +; KO +@ A +@ A ; Empty rdata +@ A \# 0 ; Hex empty rdata +@ A 0.0.0.256 ; 8bit overflow +@ A 0.0.0 ; Short address +@ A 0.0.0.A ; Bad character +@ A 0.0.0.0 1.1.1.1 ; Unexpected item diff --git a/tests/libzscanner/data/10_A.out b/tests/libzscanner/data/10_A.out new file mode 100644 index 0000000..dda68ab --- /dev/null +++ b/tests/libzscanner/data/10_A.out @@ -0,0 +1,50 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/11_AAAA.in b/tests/libzscanner/data/11_AAAA.in new file mode 100644 index 0000000..48c4b37 --- /dev/null +++ b/tests/libzscanner/data/11_AAAA.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ AAAA 0:0:0:0:0:0:0:0 ; Minimal ipv6 address +@ AAAA FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF ; Maximal ipv6 address +@ AAAA \# 16 00000000 00000000 00000000 00000000 ; Hexadecimal rdata +@ TYPE28 \# 16 00000000 00000000 00000000 00000000 ; TYPE + Hexadecimal rdata +@ TYPE28 0:0:0:0:0:0:0:0 ; TYPE +@ AAAA 0::1.2.3.4 ; ipv6 address based on ipv4 address +@ AAAA :: ; Double colon +@ aaAA :: ; Type in lower-case + +; KO +@ AAAA +@ AAAA ; Empty rdata +@ AAAA \# 0 ; Hex empty rdata +@ AAAA 0::FFFFF ; 16bit overflow +@ AAAA 0:0:0:0:0:0:0 ; Short address +@ AAAA 0:0:0:0:0:0:0:X ; Bad character +@ AAAA :: :: ; Unexpected item diff --git a/tests/libzscanner/data/11_AAAA.out b/tests/libzscanner/data/11_AAAA.out new file mode 100644 index 0000000..0cb174a --- /dev/null +++ b/tests/libzscanner/data/11_AAAA.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000001020304 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_IPV6 +------ +WARNG=ZS_BAD_IPV6 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/12_TXT.in b/tests/libzscanner/data/12_TXT.in new file mode 100644 index 0000000..cdd0eaa --- /dev/null +++ b/tests/libzscanner/data/12_TXT.in @@ -0,0 +1,37 @@ +$ORIGIN . +$TTL 1 + +; OK +@ TXT "" ; Blank string +@ TXT a ; One char string +@ TXT \ ; One space char +@ TXT "\ " ; One space char in quotes +@ TXT \021 ; One unprintable char +@ TXT "\\ \"" ; Special chars +@ TXT "" "test1" "\255" test2 ; Array of text strings +@ TXT "" "" "" ; Array of blank strings +@ TXT first \# "\#" ; Array with special string +@ TXT \0320\ \\\"\;\.\@\*.tld. ; Special domain as a string +@ TXT " !\"#$%&'()*+,-./0123456789:;<=>?@" ; First part of all printables +@ TXT "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" ; Second part of all printables +@ TXT "abcdefghijklmnopqrstuvwxyz{|}~" ; Third part of all printables +@ TXT \# 1 00 ; Hexadecimal rdata +@ TYPE16 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE16 "" ; TYPE +@ TXT ( ; Special multi-line string +"first +second" +third ; Second string +) +@ TXT "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053" ; Text string of maximal length (255 chars) +@ TXT "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\0536" ; Minimum overflowed text string which should be divided into two strings. +@ TXT "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053\054" ; Minimum overflowed text string which should be divided into two strings (decimal version). +@ txt "" ; Type in lower-case + +; KO +@ TXT +@ TXT ; Empty rdata +@ TXT \# 0 ; Hex empty rdata +@ TXT \01 ; Missing digit in decimal notation +@ TXT \256 ; 8bit overflow in decimal notation +@ TXT """ ; '"' char without forward slash diff --git a/tests/libzscanner/data/12_TXT.out b/tests/libzscanner/data/12_TXT.out new file mode 100644 index 0000000..283b1e0 --- /dev/null +++ b/tests/libzscanner/data/12_TXT.out @@ -0,0 +1,138 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0120 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0120 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0115 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=035C2022 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0005746573743101FF057465737432 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=05666972737401230123 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0E2030205C223B2E402A2E746C642E +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=21202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F40 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=204142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=1E6162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0C66697273740A7365636F6E64057468697264 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E3132333435 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E31323334350136 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E31323334350136 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_TEXT +------ diff --git a/tests/libzscanner/data/13_SPF.in b/tests/libzscanner/data/13_SPF.in new file mode 100644 index 0000000..0ad6c84 --- /dev/null +++ b/tests/libzscanner/data/13_SPF.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The SPF is the same as the TXT, so there are the differences and basics only. + +; OK +@ SPF "" "test1" "\255" test2 ; Array of text strings +@ SPF \# 1 00 ; Hexadecimal rdata +@ TYPE99 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE99 "" ; TYPE +@ spf "" ; Type in lower-case + +; KO +@ SPF diff --git a/tests/libzscanner/data/13_SPF.out b/tests/libzscanner/data/13_SPF.out new file mode 100644 index 0000000..be7fb35 --- /dev/null +++ b/tests/libzscanner/data/13_SPF.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=0005746573743101FF057465737432 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/14_NS.in b/tests/libzscanner/data/14_NS.in new file mode 100644 index 0000000..b56a579 --- /dev/null +++ b/tests/libzscanner/data/14_NS.in @@ -0,0 +1,38 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NS . ; The simplest owner +@ NS tld. ; FQD tld owner +@ NS tld ; Relative form +@ NS *. ; FQD with asterisk +@ NS * ; Alone asterisk +@ NS *.* ; More asterisks +@ NS *a.a*a.** ; Also possible +@ NS @ ; Use origin +@ NS 0123456789 ; Digits +@ NS _a_.-b-c-./d/. ; Allowed characters '_' '-' '/' anywhere +@ NS ABCDEFGHIJKLMNOPQRSTUVWXYZ ; All upper-case letters +@ NS abcdefghijklmnopqrstuvwxyz ; All lower-case letters +@ NS \0320\ \\\"\.\@\*.tld. ; Label with special chars +@ NS b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. ; IPv6 reverse +@ NS 123456789012345678901234567890123456789012345678901234567890123.tld. ; Label of maximal length +@ NS 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901. ; Domain name of maximal length +@ NS 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901 ; Domain name of maximal length (after appending origin) +@ TYPE2 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE2 @ ; TYPE +@ ns @ ; Type in lower-case + +; KO +@ NS +@ NS ; Empty rdata +@ NS \# 0 ; Hex empty rdata +@ NS & ; Bad (unslashed) character +@ NS @@ ; Double @@ +@ NS .. ; Missing label between dots +@ NS \1 ; Slash notation requires 3 digits +@ NS \12 ; Slash notation requires 3 digits +@ NS 1234567890123456789012345678901234567890123456789012345678901234.tld. ; Label exceeded maximal length +@ NS 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012. ; Domain name exceeded maximal length +@ NS 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012 ; Domain name exceeded maximal length (after appending origin) +@ NS . x ; Unexpected item diff --git a/tests/libzscanner/data/14_NS.out b/tests/libzscanner/data/14_NS.out new file mode 100644 index 0000000..08d739a --- /dev/null +++ b/tests/libzscanner/data/14_NS.out @@ -0,0 +1,144 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=012A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=012A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=012A012A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=022A6103612A61022A2A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=0A3031323334353637383900 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=035F615F052D622D632D032F642F00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=1A4142434445464748494A4B4C4D4E4F505152535455565758595A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=1A6162636465666768696A6B6C6D6E6F707172737475767778797A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_LABEL_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/15_CNAME.in b/tests/libzscanner/data/15_CNAME.in new file mode 100644 index 0000000..806b8f9 --- /dev/null +++ b/tests/libzscanner/data/15_CNAME.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The CNAME is the same as the NS, so there are the differences and basics only. + +; OK +@ CNAME test.example.com ; Relative dname +@ CNAME \# 1 00 ; Hexadecimal rdata +@ TYPE5 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE5 @ ; TYPE +@ cname @ ; Type in lower-case + +; KO +@ CNAME diff --git a/tests/libzscanner/data/15_CNAME.out b/tests/libzscanner/data/15_CNAME.out new file mode 100644 index 0000000..3c3a55d --- /dev/null +++ b/tests/libzscanner/data/15_CNAME.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=0474657374076578616D706C6503636F6D00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/16_PTR.in b/tests/libzscanner/data/16_PTR.in new file mode 100644 index 0000000..3694e7d --- /dev/null +++ b/tests/libzscanner/data/16_PTR.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The PTR is the same as the NS, so there are the differences and basics only. + +; OK +@ PTR test.example.com ; Relative dname +@ PTR \# 1 00 ; Hexadecimal rdata +@ TYPE12 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE12 @ ; TYPE +@ ptr @ ; Type in lower-case + +; KO +@ PTR diff --git a/tests/libzscanner/data/16_PTR.out b/tests/libzscanner/data/16_PTR.out new file mode 100644 index 0000000..55d94b9 --- /dev/null +++ b/tests/libzscanner/data/16_PTR.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=0474657374076578616D706C6503636F6D00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/17_DNAME.in b/tests/libzscanner/data/17_DNAME.in new file mode 100644 index 0000000..5e9ba71 --- /dev/null +++ b/tests/libzscanner/data/17_DNAME.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The DNAME is the same as the NS, so there are the differences and basics only. + +; OK +@ DNAME test.example.com ; Relative dname +@ DNAME \# 1 00 ; Hexadecimal rdata +@ TYPE39 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE39 @ ; TYPE +@ dname @ ; Type in lower-case + +; KO +@ DNAME diff --git a/tests/libzscanner/data/17_DNAME.out b/tests/libzscanner/data/17_DNAME.out new file mode 100644 index 0000000..35f11d8 --- /dev/null +++ b/tests/libzscanner/data/17_DNAME.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=0474657374076578616D706C6503636F6D00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/18_MX.in b/tests/libzscanner/data/18_MX.in new file mode 100644 index 0000000..61e6afb --- /dev/null +++ b/tests/libzscanner/data/18_MX.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; For more tests on dname see NS test (same processing) + +; OK +@ MX 0 @ ; Minimal priority +@ MX 65535 @ ; Maximal priority +@ MX 1 mail ; Relative dname +@ MX 1 mail.tld. ; Absolute dname +@ MX \# 3 0001 00 ; Hexadecimal rdata +@ TYPE15 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE15 1 @ ; TYPE +@ mx 1 @ ; Type in lower-case + +; KO +@ MX +@ MX ; Empty rdata +@ MX \# 0 ; Hex empty rdata +@ MX -1 @ ; Negative number +@ MX 65536 @ ; 16bit overflow +@ MX 1 $ ; Bad dname +@ MX 0 @ x ; Unexpected item diff --git a/tests/libzscanner/data/18_MX.out b/tests/libzscanner/data/18_MX.out new file mode 100644 index 0000000..0a50038 --- /dev/null +++ b/tests/libzscanner/data/18_MX.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=FFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=0001046D61696C03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/19_AFSDB.in b/tests/libzscanner/data/19_AFSDB.in new file mode 100644 index 0000000..be569e4 --- /dev/null +++ b/tests/libzscanner/data/19_AFSDB.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The AFSDB is the same as the MX, so there are the differences and basics only. + +; OK +@ AFSDB 1 mail ; Relative dname +@ AFSDB \# 3 0001 00 ; Hexadecimal rdata +@ TYPE18 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE18 1 @ ; TYPE +@ afsdb 1 @ ; Type in lower-case + +; KO +@ AFSDB diff --git a/tests/libzscanner/data/19_AFSDB.out b/tests/libzscanner/data/19_AFSDB.out new file mode 100644 index 0000000..b5c77eb --- /dev/null +++ b/tests/libzscanner/data/19_AFSDB.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/20_RT.in b/tests/libzscanner/data/20_RT.in new file mode 100644 index 0000000..3bc774d --- /dev/null +++ b/tests/libzscanner/data/20_RT.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The RT is the same as the MX, so there are the differences and basics only. + +; OK +@ RT 1 mail ; Relative dname +@ RT \# 3 0001 00 ; Hexadecimal rdata +@ TYPE21 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE21 1 @ ; TYPE +@ rt 1 @ ; Type in lower-case + +; KO +@ RT diff --git a/tests/libzscanner/data/20_RT.out b/tests/libzscanner/data/20_RT.out new file mode 100644 index 0000000..8be89a3 --- /dev/null +++ b/tests/libzscanner/data/20_RT.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/21_KX.in b/tests/libzscanner/data/21_KX.in new file mode 100644 index 0000000..529480d --- /dev/null +++ b/tests/libzscanner/data/21_KX.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The KX is the same as the MX, so there are the differences and basics only. + +; OK +@ KX 1 mail ; Relative dname +@ KX \# 3 0001 00 ; Hexadecimal rdata +@ TYPE36 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE36 1 @ ; TYPE +@ kx 1 @ ; Type in lower-case + +; KO +@ KX diff --git a/tests/libzscanner/data/21_KX.out b/tests/libzscanner/data/21_KX.out new file mode 100644 index 0000000..1bc91e6 --- /dev/null +++ b/tests/libzscanner/data/21_KX.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/22_HINFO.in b/tests/libzscanner/data/22_HINFO.in new file mode 100644 index 0000000..4cd5ab8 --- /dev/null +++ b/tests/libzscanner/data/22_HINFO.in @@ -0,0 +1,26 @@ +$ORIGIN . +$TTL 1 + +; OK +@ HINFO "" "" ; Blank string +@ HINFO a b ; One char string +@ HINFO \ \ ; One space char +@ HINFO "\ " "\ " ; One space char in quotes +@ HINFO \021 \022 ; One unprintable char +@ HINFO "\\ \"" "\\ \"" ; Special chars +@ HINFO first \# ; Array with special string +@ HINFO \# 2 00 00 ; Hexadecimal rdata +@ TYPE13 \# 2 00 00 ; TYPE + Hexadecimal rdata +@ TYPE13 "" "" ; TYPE +@ HINFO "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053" "" ; Text string of maximal length (255 chars) +@ hinfo "" "" ; Type in lower-case + +; KO +@ HINFO +@ HINFO ; Empty rdata +@ HINFO \# 0 ; Hex empty rdata +@ HINFO \01 "" ; Missing digit in decimal notation +@ HINFO \256 "" ; 8bit overflow in decimal notation +@ HINFO """ "" ; '"' char without forward slash +@ HINFO "" "" "" ; Unexpected item +@ HINFO "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\0536" "" ; Maximal length overflow diff --git a/tests/libzscanner/data/22_HINFO.out b/tests/libzscanner/data/22_HINFO.out new file mode 100644 index 0000000..fa66729 --- /dev/null +++ b/tests/libzscanner/data/22_HINFO.out @@ -0,0 +1,88 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=01610162 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=01200120 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=01200120 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=01150116 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=035C2022035C2022 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0566697273740123 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E313233343500 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_TEXT +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_ITEM_OVERFLOW +------ diff --git a/tests/libzscanner/data/23_MINFO.in b/tests/libzscanner/data/23_MINFO.in new file mode 100644 index 0000000..7b34c60 --- /dev/null +++ b/tests/libzscanner/data/23_MINFO.in @@ -0,0 +1,18 @@ +$ORIGIN . +$TTL 1 + +; For more tests on dname see NS test (same processing) + +; OK +@ MINFO . . ; The simplest dnames +@ MINFO @ @ ; Use origin +@ MINFO mail mail.tld. ; Relative and absolute dnames +@ MINFO \# 2 00 00 ; Hexadecimal rdata +@ TYPE14 \# 2 00 00 ; TYPE + Hexadecimal rdata +@ TYPE14 @ @ ; TYPE +@ minfo @ @ ; Type in lower-case + +; KO +@ MINFO +@ MINFO ; Empty rdata +@ MINFO \# 0 ; Hex empty rdata diff --git a/tests/libzscanner/data/23_MINFO.out b/tests/libzscanner/data/23_MINFO.out new file mode 100644 index 0000000..8154c0c --- /dev/null +++ b/tests/libzscanner/data/23_MINFO.out @@ -0,0 +1,48 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=046D61696C00046D61696C03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/24_RP.in b/tests/libzscanner/data/24_RP.in new file mode 100644 index 0000000..a70d792 --- /dev/null +++ b/tests/libzscanner/data/24_RP.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The RP is the same as the MINFO, so there are the differences and basics only. + +; OK +@ RP mail mail.tld. ; Relative and absolute dnames +@ RP \# 2 00 00 ; Hexadecimal rdata +@ TYPE17 \# 2 00 00 ; TYPE + Hexadecimal rdata +@ TYPE17 @ @ ; TYPE +@ rp @ @ ; Type in lower-case + +; KO +@ RP diff --git a/tests/libzscanner/data/24_RP.out b/tests/libzscanner/data/24_RP.out new file mode 100644 index 0000000..d13b1ba --- /dev/null +++ b/tests/libzscanner/data/24_RP.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=046D61696C00046D61696C03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=0000 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/25_SOA.in b/tests/libzscanner/data/25_SOA.in new file mode 100644 index 0000000..bf093d4 --- /dev/null +++ b/tests/libzscanner/data/25_SOA.in @@ -0,0 +1,31 @@ +$ORIGIN . +$TTL 1 + +; OK +@ SOA @ @ 0 0 0 0 0 ; The simplest variant +@ SOA tld. tld 0 0 0 0 0 ; Absolute and relative dnames. +@ SOA @ @ 4294967295 0 0 0 0 ; Maximal serial +@ SOA @ @ 0 4294967295 4294967295 4294967295 4294967295 ; Maximal times +@ SOA @ @ 0 1d 1h 1m 1s ; Time units +@ TYPE6 \# 22 00 00 0000000000000000000000000000000000000000 ; TYPE + Hexadecimal rdata +@ TYPE6 @ @ 0 0 0 0 0 ; TYPE +@ SOA ns.tld. first\.second.tld. ( ; Multiline record + 2007120710 + 1w2d3h4m5s + 2h + 3m + 4s +) +@ soa @ @ 0 0 0 0 0 ; Type in lower-case + +; KO +@ SOA +@ SOA ; Empty rdata +@ SOA \# 0 ; Hex empty rdata +@ SOA @ @ 1h 0 0 0 0 ; Bad number +@ SOA @ @ 4294967296 0 0 0 0 ; Serial overflow +@ SOA @ @ 0 4294967296 0 0 0 ; Refresh overflow +@ SOA @ @ 0 0 4294967296 0 0 ; Retry overflow +@ SOA @ @ 0 0 0 4294967296 0 ; Expire overflow +@ SOA @ @ 0 0 0 0 4294967296 ; Minimum overflow +@ SOA @ @ 0 0 0 0 0 x ; Unexpected item diff --git a/tests/libzscanner/data/25_SOA.out b/tests/libzscanner/data/25_SOA.out new file mode 100644 index 0000000..f658442 --- /dev/null +++ b/tests/libzscanner/data/25_SOA.out @@ -0,0 +1,74 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=00000000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=03746C640003746C64000000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=0000FFFFFFFF00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=0000000000000001518000000E100000003C00000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=00000000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=00000000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=026E7303746C64000C66697273742E7365636F6E6403746C640077A23B46000C08A500001C20000000B400000004 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=00000000000000000000000000000000000000000000 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/26_SRV.in b/tests/libzscanner/data/26_SRV.in new file mode 100644 index 0000000..001e1e6 --- /dev/null +++ b/tests/libzscanner/data/26_SRV.in @@ -0,0 +1,25 @@ +$ORIGIN . +$TTL 1 + +; OK +@ SRV 0 0 0 @ ; The simplest variant +_ldap._tcp.test.tld. SRV 0 0 0 @ ; Underscores in owner +@ SRV 65535 65535 65535 @ ; Maximal numbers +@ SRV 0 0 0 \0320\ \\\"\.\@\*.tld. ; Dname with specials +@ TYPE33 \# 7 000000000000 00 ; TYPE + Hexadecimal rdata +@ TYPE33 0 0 0 @ ; TYPE +@ srv 0 0 0 @ ; Type in lower-case + +; KO +@ SRV +@ SRV ; Empty rdata +@ SRV \# 0 ; Hex empty rdata +@ SRV 1h 0 0 @ ; Bad priority +@ SRV 0 1h 0 @ ; Bad weight +@ SRV 0 0 1h @ ; Bad port +@ SRV 0 0 0 % ; Bad target +@ SRV 65536 0 0 @ ; Priority overflow +@ SRV 0 65536 0 @ ; Weight overflow +@ SRV 0 0 65536 @ ; Port overflow +@ SRV 0 0 0 @ x ; Unexpected item +@ SRV 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/26_SRV.out b/tests/libzscanner/data/26_SRV.out new file mode 100644 index 0000000..eadb804 --- /dev/null +++ b/tests/libzscanner/data/26_SRV.out @@ -0,0 +1,66 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +OWNER=055F6C646170045F746370047465737403746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=FFFFFFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=000000000000082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/27_NAPTR.in b/tests/libzscanner/data/27_NAPTR.in new file mode 100644 index 0000000..44fd346 --- /dev/null +++ b/tests/libzscanner/data/27_NAPTR.in @@ -0,0 +1,20 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NAPTR 0 0 "" "" "" @ ; The simplest variant +@ NAPTR 65535 65535 "" "" "" @ ; Maximal numbers +@ NAPTR 65535 65535 "" "" "!^urn:cid:.+@([^\.]+\.)(.*)$!\\2!i" @ ; Regexp example +@ NAPTR 0 0 "" "" "" \0320\ \\\"\.\@\*.tld. ; Dname with specials +@ TYPE35 \# 8 00000000000000 00 ; TYPE + Hexadecimal rdata +@ TYPE35 0 0 "" "" "" @ ; TYPE +@ naptr 0 0 "" "" "" @ ; Type in lower-case + +; KO +@ NAPTR +@ NAPTR ; Empty rdata +@ NAPTR \# 0 ; Hex empty rdata +@ NAPTR 65536 0 "" "" "" @ ; Order overflow +@ NAPTR 0 65536 "" "" "" @ ; Preference overflow +@ NAPTR 0 0 "" "" "" @ x ; Unexpected item +@ NAPTR 0 0 "" "" "" ; Missing item diff --git a/tests/libzscanner/data/27_NAPTR.out b/tests/libzscanner/data/27_NAPTR.out new file mode 100644 index 0000000..cc34e26 --- /dev/null +++ b/tests/libzscanner/data/27_NAPTR.out @@ -0,0 +1,56 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=FFFFFFFF00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=FFFFFFFF00001F215E75726E3A6369643A2E2B40285B5E2E5D2B2E29282E2A2924215C32216900 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=00000000000000082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=0000000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/28_TYPE.in b/tests/libzscanner/data/28_TYPE.in new file mode 100644 index 0000000..f8189e8 --- /dev/null +++ b/tests/libzscanner/data/28_TYPE.in @@ -0,0 +1,27 @@ +$ORIGIN . +$TTL 1 + +; OK +@ TYPE0 \# 0 ; Minimal type number +@ TYPE65535 \# 0 ; Maximal type number +@ TYPE55555 \# 0 ; Without hex rdata +@ TYPE55555 \# 1 00 ; Without hex rdata +@ TYPE1 \# 4 00000000 ; Known type +@ TYPE1 0.0.0.0 ; Known type in text format +@ TYPE55555 ( ; Multiline begin + \# + 5 + 0102 03 + 04 05 + ) ; Multiline end +@ type55555 \# 0 ; Type in lower-case + +; KO +@ TYPE55555 +@ TYPE55555 ; Without text rdata +@ TYPE65536 ; Type number overflow +@ TYPE65535x ; Bad type +@ TYPE55555 \# ; Missing hex length +@ TYPE55555 \# 1 0000 ; Too long rdata +@ TYPE55555 \# 2 00 ; Bad rdata length +@ TYPE55555 \# 1 00 x ; Unexpected data diff --git a/tests/libzscanner/data/28_TYPE.out b/tests/libzscanner/data/28_TYPE.out new file mode 100644 index 0000000..0aa409a --- /dev/null +++ b/tests/libzscanner/data/28_TYPE.out @@ -0,0 +1,64 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0000 +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=FFFF +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=D903 +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=D903 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=D903 +RDATA=0102030405 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=D903 +RDATA= +------ +WARNG=ZS_CANNOT_TEXT_DATA +------ +WARNG=ZS_CANNOT_TEXT_DATA +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_RDATA_LENGTH +------ +WARNG=ZS_BAD_RDATA_LENGTH +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/29_CERT.in b/tests/libzscanner/data/29_CERT.in new file mode 100644 index 0000000..ee70ce2 --- /dev/null +++ b/tests/libzscanner/data/29_CERT.in @@ -0,0 +1,58 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CERT 0 0 0 AA== ; The simplest variant +@ CERT 65535 65535 255 AA== ; Maximal numbers +@ CERT PKIX 0 0 AA== ; Certificate type mnemo +@ CERT SPKI 0 0 AA== ; Certificate type mnemo +@ CERT PGP 0 0 AA== ; Certificate type mnemo +@ CERT IPKIX 0 0 AA== ; Certificate type mnemo +@ CERT ISPKI 0 0 AA== ; Certificate type mnemo +@ CERT IPGP 0 0 AA== ; Certificate type mnemo +@ CERT ACPKIX 0 0 AA== ; Certificate type mnemo +@ CERT IACPKIX 0 0 AA== ; Certificate type mnemo +@ CERT URI 0 0 AA== ; Certificate type mnemo +@ CERT OID 0 0 AA== ; Certificate type mnemo +@ CERT 0 0 RSAMD5 AA== ; Algorithm mnemo +@ CERT 0 0 DH AA== ; Algorithm mnemo +@ CERT 0 0 DSA AA== ; Algorithm mnemo +@ CERT 0 0 RSASHA1 AA== ; Algorithm mnemo +@ CERT 0 0 DSA-NSEC3-SHA1 AA== ; Algorithm mnemo +@ CERT 0 0 RSASHA1-NSEC3-SHA1 AA== ; Algorithm mnemo +@ CERT 0 0 RSASHA256 AA== ; Algorithm mnemo +@ CERT 0 0 RSASHA512 AA== ; Algorithm mnemo +@ CERT 0 0 ECC-GOST AA== ; Algorithm mnemo +@ CERT 0 0 ECDSAP256SHA256 AA== ; Algorithm mnemo +@ CERT 0 0 ECDSAP384SHA384 AA== ; Algorithm mnemo +@ CERT 0 0 ED25519 AA== ; Algorithm mnemo +@ CERT 0 0 ED448 AA== ; Algorithm mnemo +@ CERT 0 0 INDIRECT AA== ; Algorithm mnemo +@ CERT 0 0 PRIVATEDNS AA== ; Algorithm mnemo +@ CERT 0 0 PRIVATEOID AA== ; Algorithm mnemo +@ CERT 0 0 0 Zm8= ; One char padding +@ CERT 0 0 0 Zm9v ; Without padding +@ CERT 0 0 0 Zm9vYg== ; Two base64 blocks +@ CERT 0 0 0 Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE37 \# 6 000000000000 ; TYPE + Hexadecimal rdata +@ TYPE37 0 0 0 AA== ; TYPE +@ cert 0 0 0 AA== ; Type in lower-case + +; KO +@ CERT +@ CERT ; Empty rdata +@ CERT \# 0 ; Hex empty rdata +@ CERT 65536 0 0 AA== ; Type overflow +@ CERT X 0 0 AA== ; Bad type mnemonic +@ CERT 0 65536 0 AA== ; Key tag overflow +@ CERT 0 0 256 AA== ; Algorithm overflow +@ CERT 0 0 0 A ; Continuous block length must be multiple of 4 +@ CERT 0 0 0 AB ; Continuous block length must be multiple of 4 +@ CERT 0 0 0 ABC ; Continuous block length must be multiple of 4 +@ CERT 0 0 0 AA == ; Continuous block length must be multiple of 4 +@ CERT 0 0 0 A=== ; Bad padding +@ CERT 0 0 0 = ; Bad padding +@ CERT 0 0 0 == ; Bad padding +@ CERT 0 0 0 === ; Bad padding +@ CERT 0 0 0 ==== ; Bad padding +@ CERT 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/29_CERT.out b/tests/libzscanner/data/29_CERT.out new file mode 100644 index 0000000..da2c897 --- /dev/null +++ b/tests/libzscanner/data/29_CERT.out @@ -0,0 +1,244 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=FFFFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000100000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000200000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000300000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000400000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000500000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000600000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000700000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000800000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00FD00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00FE00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000200 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000300 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000500 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000600 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000700 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000800 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000D00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000E00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000F00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000001000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00000000FC00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00000000FD00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00000000FE00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=0000000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=0000000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=0000000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=0000000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000000 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_CERT_TYPE +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/30_KEY.in b/tests/libzscanner/data/30_KEY.in new file mode 100644 index 0000000..263fa03 --- /dev/null +++ b/tests/libzscanner/data/30_KEY.in @@ -0,0 +1,31 @@ +$ORIGIN . +$TTL 1 + +; OK +@ KEY 0 0 0 AA== ; The simplest variant +@ KEY 65535 255 255 AA== ; Maximal numbers +@ KEY 0 0 0 Zm8= ; One char padding +@ KEY 0 0 0 Zm9v ; Without padding +@ KEY 0 0 0 Zm9vYg== ; Two base64 blocks +@ KEY 0 0 0 Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE25 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE25 0 0 0 AA== ; TYPE +@ key 0 0 0 AA== ; Type in lower-case + +; KO +@ KEY +@ KEY ; Empty rdata +@ KEY \# 0 ; Hex empty rdata +@ KEY 65536 0 0 AA== ; Type overflow +@ KEY 0 256 0 AA== ; Key tag overflow +@ KEY 0 0 256 AA== ; Algorithm overflow +@ KEY 0 0 0 A ; Continuous block length must be multiple of 4 +@ KEY 0 0 0 AB ; Continuous block length must be multiple of 4 +@ KEY 0 0 0 ABC ; Continuous block length must be multiple of 4 +@ KEY 0 0 0 AA == ; Continuous block length must be multiple of 4 +@ KEY 0 0 0 A=== ; Bad padding +@ KEY 0 0 0 = ; Bad padding +@ KEY 0 0 0 == ; Bad padding +@ KEY 0 0 0 === ; Bad padding +@ KEY 0 0 0 ==== ; Bad padding +@ KEY 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/30_KEY.out b/tests/libzscanner/data/30_KEY.out new file mode 100644 index 0000000..1ec998b --- /dev/null +++ b/tests/libzscanner/data/30_KEY.out @@ -0,0 +1,86 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=00000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=00000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=00000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=00000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/31_DNSKEY.in b/tests/libzscanner/data/31_DNSKEY.in new file mode 100644 index 0000000..871de97 --- /dev/null +++ b/tests/libzscanner/data/31_DNSKEY.in @@ -0,0 +1,32 @@ +$ORIGIN . +$TTL 1 + +; OK +@ DNSKEY 0 0 0 AA== ; The simplest variant +@ DNSKEY 65535 255 255 AA== ; Maximal numbers +@ DNSKEY 0 0 RSAMD5 AA== ; Algorithm mnemonic +@ DNSKEY 0 0 0 Zm8= ; One char padding +@ DNSKEY 0 0 0 Zm9v ; Without padding +@ DNSKEY 0 0 0 Zm9vYg== ; Two base64 blocks +@ DNSKEY 0 0 0 Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE48 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE48 0 0 0 AA== ; TYPE +@ dnskey 0 0 0 AA== ; Type in lower-case + +; KO +@ DNSKEY +@ DNSKEY ; Empty rdata +@ DNSKEY \# 0 ; Hex empty rdata +@ DNSKEY 65536 0 0 AA== ; Type overflow +@ DNSKEY 0 256 0 AA== ; Key tag overflow +@ DNSKEY 0 0 256 AA== ; Algorithm overflow +@ DNSKEY 0 0 0 A ; Continuous block length must be multiple of 4 +@ DNSKEY 0 0 0 AB ; Continuous block length must be multiple of 4 +@ DNSKEY 0 0 0 ABC ; Continuous block length must be multiple of 4 +@ DNSKEY 0 0 0 AA == ; Continuous block length must be multiple of 4 +@ DNSKEY 0 0 0 A=== ; Bad padding +@ DNSKEY 0 0 0 = ; Bad padding +@ DNSKEY 0 0 0 == ; Bad padding +@ DNSKEY 0 0 0 === ; Bad padding +@ DNSKEY 0 0 0 ==== ; Bad padding +@ DNSKEY 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/31_DNSKEY.out b/tests/libzscanner/data/31_DNSKEY.out new file mode 100644 index 0000000..fa034c5 --- /dev/null +++ b/tests/libzscanner/data/31_DNSKEY.out @@ -0,0 +1,92 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=00000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=00000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=00000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=00000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/32_APL.in b/tests/libzscanner/data/32_APL.in new file mode 100644 index 0000000..ea9a747 --- /dev/null +++ b/tests/libzscanner/data/32_APL.in @@ -0,0 +1,30 @@ +$ORIGIN . +$TTL 1 + +; OK +@ APL ; The simplest variant - blank list +@ APL 1:0.0.0.0/0 ; Minimal ipv4 prefix length +@ APL 1:255.255.255.255/32 ; Maximal ipv4 prefix length +@ APL 1:255.255.255.255/30 ; Prefix length isn't multiple of 8 +@ APL 2:::/0 ; Minimal ipv6 address +@ APL 2:0::0/0 ; Minimal ipv6 prefix length +@ APL 2:0::0/128 ; Maximal ipv6 prefix length +@ APL 2:FFFF:FFFF:FFFF::/2 ; Trailing zeroes test +@ APL !1:0.0.0.0/0 ; Negation flag +@ APL 1:0.0.0.0/0 1:255.255.255.255/32 ; More APLs +@ TYPE42 \# 4 00010000 ; TYPE + Hexadecimal rdata +@ TYPE42 1:0.0.0.0/0 ; TYPE +@ APL \# 0 ; Zero length rdata +@ apl 1:0.0.0.0/0 ; Type in lower-case + +; KO +@ APL 0:0.0.0.0/32 ; Bad address family +@ APL x:0.0.0.0/32 ; Bad address family +@ APL !x:0.0.0.0/32 ; Bad address family +@ APL 2:0.0.0.0/32 ; Address family mismatch +@ APL 1:0::0/32 ; Address family mismatch +@ APL 1:0.0.0.0/33 ; Prefix length is too long +@ APL 2:0::0/129 ; Prefix length is too long +@ APL 2::/0 ; Bad ipv6 address +@ APL 2:0::0/x ; Bad prefix length +@ APL 1:0.0.0.0/ ; Missing prefix length diff --git a/tests/libzscanner/data/32_APL.out b/tests/libzscanner/data/32_APL.out new file mode 100644 index 0000000..50ec101 --- /dev/null +++ b/tests/libzscanner/data/32_APL.out @@ -0,0 +1,104 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00012004FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00011E04FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00020000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00020000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00028000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00020206FFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010080 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=0001000000012004FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010000 +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_IPV6 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_IPV6 +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_APL +------ diff --git a/tests/libzscanner/data/33_DS.in b/tests/libzscanner/data/33_DS.in new file mode 100644 index 0000000..a5d805c --- /dev/null +++ b/tests/libzscanner/data/33_DS.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ DS 0 0 0 00 ; The simplest variant +@ DS 65535 255 255 00 ; Maximal numbers +@ DS 0 RSAMD5 0 00 ; Algorithm mnemonic +@ DS 0 0 0 01 02 0304 ; Hex block with blank spaces between them +@ TYPE43 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE43 0 0 0 00 ; TYPE +@ ds 0 0 0 00 ; Type in lower-case + +; KO +@ DS +@ DS ; Empty rdata +@ DS \# 0 ; Hex empty rdata +@ DS 65536 0 0 00 ; Key tag overflow +@ DS 0 256 0 00 ; Algorithm overflow +@ DS 0 0 256 00 ; Digest type overflow +@ DS 0 0 0 0 ; Continuous block length must be multiple of 2 +@ DS 0 0 0 00 0 ; Continuous block length must be multiple of 2 +@ DS 0 0 0 XX ; Bad hex character +@ DS 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/33_DS.out b/tests/libzscanner/data/33_DS.out new file mode 100644 index 0000000..2257119 --- /dev/null +++ b/tests/libzscanner/data/33_DS.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000001020304 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/34_SSHFP.in b/tests/libzscanner/data/34_SSHFP.in new file mode 100644 index 0000000..89c4de3 --- /dev/null +++ b/tests/libzscanner/data/34_SSHFP.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ SSHFP 0 0 00 ; The simplest variant +@ SSHFP 255 255 00 ; Maximal numbers +@ SSHFP 0 0 01 02 0304 ; Hex block with blank spaces between them +@ TYPE44 \# 3 000000 ; TYPE + Hexadecimal rdata +@ TYPE44 0 0 00 ; TYPE +@ sshfp 0 0 00 ; Type in lower-case + +; KO +@ SSHFP +@ SSHFP ; Empty rdata +@ SSHFP \# 0 ; Hex empty rdata +@ SSHFP 256 0 00 ; Algorithm overflow +@ SSHFP 0 256 00 ; Fp type overflow +@ SSHFP 0 0 0 ; Continuous block length must be multiple of 2 +@ SSHFP 0 0 00 0 ; Continuous block length must be multiple of 2 +@ SSHFP 0 0 XX ; Bad hex character +@ SSHFP 0 0 ; Missing item diff --git a/tests/libzscanner/data/34_SSHFP.out b/tests/libzscanner/data/34_SSHFP.out new file mode 100644 index 0000000..da8ce6d --- /dev/null +++ b/tests/libzscanner/data/34_SSHFP.out @@ -0,0 +1,54 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=FFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000001020304 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/35_IPSECKEY.in b/tests/libzscanner/data/35_IPSECKEY.in new file mode 100644 index 0000000..dc56bd7 --- /dev/null +++ b/tests/libzscanner/data/35_IPSECKEY.in @@ -0,0 +1,29 @@ +$ORIGIN . +$TTL 1 + +; OK +@ IPSECKEY 0 0 0 . ; The simplest variant - no gw, no key +@ IPSECKEY 255 3 255 . AA== ; Maximal numbers +@ IPSECKEY 0 1 0 0.0.0.0 ; IPv4 address +@ IPSECKEY 0 2 0 :: ; IPv6 address +@ IPSECKEY 0 3 0 \0320\ \\\"\.\@\*.tld. ; Special chars in domain name +@ IPSECKEY 0 0 1 . Zm8= ; One char padding +@ IPSECKEY 0 0 1 . Zm9v ; Without padding +@ IPSECKEY 0 0 1 . Zm9vYg== ; Two base64 blocks +@ IPSECKEY 0 0 1 . Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE45 \# 3 000000 ; TYPE + Hexadecimal rdata +@ TYPE45 0 0 1 . AA== ; TYPE +@ ipseckey 0 0 1 . AA== ; Type in lower-case + +; KO +@ IPSECKEY +@ IPSECKEY ; Empty rdata +@ IPSECKEY \# 0 ; Hex empty rdata +@ IPSECKEY 256 0 0 . ; Precedence overflow +@ IPSECKEY 0 4 0 . ; Unknown gateway +@ IPSECKEY 0 0 256 . AA== ; Algorithm overflow +@ IPSECKEY 0 0 0 . AA== ; If alg is 0 then key shouldn't be given +@ IPSECKEY 0 0 0 a% ; Bad domain name char +@ IPSECKEY 0 0 1 . A ; Continuous block length must be multiple of 4 +@ IPSECKEY 0 0 1 . = ; Bad padding +@ IPSECKEY 0 0 ; Missing item diff --git a/tests/libzscanner/data/35_IPSECKEY.out b/tests/libzscanner/data/35_IPSECKEY.out new file mode 100644 index 0000000..718ce22 --- /dev/null +++ b/tests/libzscanner/data/35_IPSECKEY.out @@ -0,0 +1,94 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=FF03FF0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=00010000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=00020000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000300082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000001666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000001666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000001666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000001666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=00000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=00000100 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_GATEWAY +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_GATEWAY_KEY +------ +WARNG=ZS_BAD_GATEWAY +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_GATEWAY_KEY +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/36_RRSIG.in b/tests/libzscanner/data/36_RRSIG.in new file mode 100644 index 0000000..e970fc5 --- /dev/null +++ b/tests/libzscanner/data/36_RRSIG.in @@ -0,0 +1,45 @@ +$ORIGIN . +$TTL 1 + +; OK +@ RRSIG TYPE0 0 0 0 0 0 0 . AA== ; The simplest variant +@ RRSIG A 2 3 4 5 6 7 \008. CQ== ; Human visual test - block numbering +@ RRSIG TYPE65535 255 255 4294967295 4294967295 4294967295 65535 . AA== ; Maximal numbers +@ RRSIG TYPE0 RSAMD5 0 0 0 0 0 . AA== ; Algorithm mnemonic +@ RRSIG A 0 0 0 19700101000000 0 0 . AA== ; Minimal date format +@ RRSIG A 0 0 0 0 21051231235959 0 . AA== ; Maximal date format (zscanner limit) +@ RRSIG TYPE0 0 0 0 0 0 0 \0320\ \\\"\.\@\*.tld. AA== ; Special chars in domain name +@ RRSIG A 0 0 0 0 0 0 . Zm8= ; One char padding +@ RRSIG A 0 0 0 0 0 0 . Zm9v ; Without padding +@ RRSIG A 0 0 0 0 0 0 . Zm9vYg== ; Two base64 blocks +@ RRSIG A 0 0 0 0 0 0 . Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE46 \# 20 000100000000000000000000000000000000 00 00 ; TYPE + Hexadecimal rdata +@ TYPE46 A 0 0 0 0 0 0 . AA== ; TYPE +@ rrsig A 0 0 0 0 0 0 . AA== ; Type in lower-case + +; KO +@ RRSIG +@ RRSIG ; Empty rdata +@ RRSIG \# 0 ; Hex empty rdata +@ RRSIG X 0 0 0 0 0 0 . AA== ; Unknown type +@ RRSIG TYPE65536 0 0 0 0 0 0 . AA== ; Type overflow +@ RRSIG A 256 0 0 0 0 0 . AA== ; Algorithm overflow +@ RRSIG A 0 256 0 0 0 0 . AA== ; Labels overflow +@ RRSIG A 0 0 4294967296 0 0 0 . AA== ; TTL overflow +@ RRSIG A 0 0 0 9294967296 0 0 . AA== ; Sig. exp. overflow +@ RRSIG A 0 0 0 0 4294967296 0 . AA== ; Sig. inc. overflow +@ RRSIG A 0 0 0 0 0 65536 . AA== ; Key tag overflow +@ RRSIG A 0 0 0 0 21060101000000 0 . AA== ; Date overflow +@ RRSIG A 0 0 0 0 2106010100000x 0 . AA== ; Bad timestamp char +@ RRSIG A 0 0 0 0 210601010000000 0 . AA== ; Bad timestamp length +@ RRSIG A 0 0 0 0 0 0 a% AA== ; Bad domain char +@ RRSIG A 0 0 0 0 0 0 . A ; Continuous block length must be multiple of 4 +@ RRSIG A 0 0 0 0 0 0 . AB ; Continuous block length must be multiple of 4 +@ RRSIG A 0 0 0 0 0 0 . ABC ; Continuous block length must be multiple of 4 +@ RRSIG A 0 0 0 0 0 0 . AA == ; Continuous block length must be multiple of 4 +@ RRSIG A 0 0 0 0 0 0 . A=== ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . = ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . == ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . === ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . ==== ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . ; Missing item diff --git a/tests/libzscanner/data/36_RRSIG.out b/tests/libzscanner/data/36_RRSIG.out new file mode 100644 index 0000000..b3d48be --- /dev/null +++ b/tests/libzscanner/data/36_RRSIG.out @@ -0,0 +1,134 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010203000000040000000500000006000701080009 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0000010000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0001000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=000100000000000000000000FFCEDD7F00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=000000000000000000000000000000000000082030205C222E402A03746C640000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010000000000000000000000000000000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010000000000000000000000000000000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010000000000000000000000000000000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010000000000000000000000000000000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0001000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0001000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0001000000000000000000000000000000000000 +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_DATE +------ +WARNG=ZS_BAD_TIMESTAMP_CHAR +------ +WARNG=ZS_BAD_TIMESTAMP_LENGTH +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/37_NSEC.in b/tests/libzscanner/data/37_NSEC.in new file mode 100644 index 0000000..1efa4ea --- /dev/null +++ b/tests/libzscanner/data/37_NSEC.in @@ -0,0 +1,20 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NSEC . ; The simplest variant - without bitmap +@ NSEC \0320\ \\\"\.\@\*.tld. ; Special chars in domain name +@ NSEC . TYPE0 ; Minimal type number +@ NSEC . TYPE65535 ; Maximal type number +@ NSEC . TYPE0 A NS ; First bitmap window +@ NSEC . TYPE0 TYPE256 TYPE512 TYPE32768 ; First, second, third and 128. bitmap window +@ TYPE47 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE47 . ; TYPE +@ nsec . ; Type in lower-case + +; KO +@ NSEC +@ NSEC ; Empty rdata +@ NSEC \# 0 ; Hex empty rdata +@ NSEC . TYPE65536 ; Type number overflow +@ NSEC . X ; Unknown type diff --git a/tests/libzscanner/data/37_NSEC.out b/tests/libzscanner/data/37_NSEC.out new file mode 100644 index 0000000..7a62def --- /dev/null +++ b/tests/libzscanner/data/37_NSEC.out @@ -0,0 +1,64 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00000180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00FF200000000000000000000000000000000000000000000000000000000000000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=000001E0 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00000180010180020180800180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_BITMAP +------ diff --git a/tests/libzscanner/data/38_DHCID.in b/tests/libzscanner/data/38_DHCID.in new file mode 100644 index 0000000..4c0642a --- /dev/null +++ b/tests/libzscanner/data/38_DHCID.in @@ -0,0 +1,26 @@ +$ORIGIN . +$TTL 1 + +; OK +@ DHCID AA== ; The simplest variant +@ DHCID Zm8= ; One char padding +@ DHCID Zm9v ; Without padding +@ DHCID Zm9vYg== ; Two base64 blocks +@ DHCID Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE49 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE49 AA== ; TYPE +@ dhcid AA== ; Type in lower-case + +; KO +@ DHCID +@ DHCID ; Empty rdata +@ DHCID \# 0 ; Hex empty rdata +@ DHCID A ; Continuous block length must be multiple of 4 +@ DHCID AB ; Continuous block length must be multiple of 4 +@ DHCID ABC ; Continuous block length must be multiple of 4 +@ DHCID AA == ; Continuous block length must be multiple of 4 +@ DHCID A=== ; Bad padding +@ DHCID = ; Bad padding +@ DHCID == ; Bad padding +@ DHCID === ; Bad padding +@ DHCID ==== ; Bad padding diff --git a/tests/libzscanner/data/38_DHCID.out b/tests/libzscanner/data/38_DHCID.out new file mode 100644 index 0000000..8dc8ec9 --- /dev/null +++ b/tests/libzscanner/data/38_DHCID.out @@ -0,0 +1,72 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/39_NSEC3.in b/tests/libzscanner/data/39_NSEC3.in new file mode 100644 index 0000000..cadbfa9 --- /dev/null +++ b/tests/libzscanner/data/39_NSEC3.in @@ -0,0 +1,46 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NSEC3 0 0 0 - 00====== ; The simplest variant - without bitmap +@ NSEC3 255 255 65535 - 00====== ; Maximal numbers +@ NSEC3 0 0 0 00FF 00====== ; Hex string +@ NSEC3 0 0 0 - 00====== ; Eight char padding +@ NSEC3 0 0 0 - CPNG==== ; Four char padding +@ NSEC3 0 0 0 - CPNMU=== ; Three char padding +@ NSEC3 0 0 0 - CPNMUOG= ; One char padding +@ NSEC3 0 0 0 - CPNMUOJ1 ; Without padding +@ NSEC3 0 0 0 - CPNMUOJ1E8====== ; Two base32hex blocks +@ NSEC3 0 0 0 - 00====== TYPE0 ; Minimal type number +@ NSEC3 0 0 0 - 00====== TYPE65535 ; Maximal type number +@ NSEC3 0 0 0 - 00====== TYPE0 A NS ; First bitmap window +@ NSEC3 0 0 0 - 00====== TYPE0 TYPE256 TYPE512 TYPE32768 ; First, second, third and 128. bitmap window +@ TYPE50 \# 7 00000000000100 ; TYPE + Hexadecimal rdata +@ TYPE50 0 0 0 - 00====== ; TYPE +@ nsec3 0 0 0 - 00====== ; Type in lower-case + +; KO +@ NSEC3 +@ NSEC3 ; Empty rdata +@ NSEC3 \# 0 ; Hex empty rdata +@ NSEC3 256 0 0 - 00====== ; Algorithm overflow +@ NSEC3 0 256 0 - 00====== ; Flags overflow +@ NSEC3 0 0 65536 - 00====== ; Iterations overflow +@ NSEC3 0 0 0 0 00====== ; Hex block must be multiple of 2 +@ NSEC3 0 0 0 0X 00====== ; Bad hex char +@ NSEC3 0 0 0 00 FF 00====== ; Hex string with blank space inside +@ NSEC3 0 0 0 - 1 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 12 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 123 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 1234 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 12345 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 123456 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 1234567 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 123456 78 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - ======== ; Bad padding +@ NSEC3 0 0 0 - 1======= ; Bad padding +@ NSEC3 0 0 0 - 123===== ; Bad padding +@ NSEC3 0 0 0 - 123456== ; Bad padding +@ NSEC3 0 0 0 - CPNMUOJ1 E8====== ; Two base32hex blocks with blank space between them +@ NSEC3 0 0 0 - 00====== TYPE65536 ; Type number overflow +@ NSEC3 0 0 0 - 00====== X ; Unknown type diff --git a/tests/libzscanner/data/39_NSEC3.out b/tests/libzscanner/data/39_NSEC3.out new file mode 100644 index 0000000..1aaec4f --- /dev/null +++ b/tests/libzscanner/data/39_NSEC3.out @@ -0,0 +1,144 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=FFFFFFFF000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000200FF0100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000002666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000003666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000004666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000005666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000006666F6F626172 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100000180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100FF200000000000000000000000000000000000000000000000000000000000000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000001000001E0 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100000180010180020180800180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BITMAP +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_BITMAP +------ diff --git a/tests/libzscanner/data/40_NSEC3PARAM.in b/tests/libzscanner/data/40_NSEC3PARAM.in new file mode 100644 index 0000000..694e3f7 --- /dev/null +++ b/tests/libzscanner/data/40_NSEC3PARAM.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NSEC3PARAM 0 0 0 - ; The simplest variant +@ NSEC3PARAM 255 255 65535 - ; Maximal numbers +@ NSEC3PARAM 0 0 0 0102FF ; Hex string +@ TYPE51 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE51 0 0 0 - ; TYPE +@ nsec3param 0 0 0 - ; Type in lower-case + +; KO +@ NSEC3PARAM +@ NSEC3PARAM ; Empty rdata +@ NSEC3PARAM \# 0 ; Hex empty rdata +@ NSEC3PARAM 256 0 0 00 ; Algorithm overflow +@ NSEC3PARAM 0 256 0 00 ; Flags overflow +@ NSEC3PARAM 0 0 65536 00 ; Iterations overflow +@ NSEC3PARAM 0 0 0 0 ; Hex block length must be multiple of 2 +@ NSEC3PARAM 0 0 0 0x ; Bad hex char +@ NSEC3PARAM 0 0 0 00 00 ; Hex block must not contain blank spaces +@ NSEC3PARAM 0 0 0 00 x ; Unexpected item +@ NSEC3PARAM 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/40_NSEC3PARAM.out b/tests/libzscanner/data/40_NSEC3PARAM.out new file mode 100644 index 0000000..83b9bb1 --- /dev/null +++ b/tests/libzscanner/data/40_NSEC3PARAM.out @@ -0,0 +1,58 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=00000000030102FF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/41_TLSA.in b/tests/libzscanner/data/41_TLSA.in new file mode 100644 index 0000000..927498e --- /dev/null +++ b/tests/libzscanner/data/41_TLSA.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ TLSA 0 0 0 00 ; The simplest variant +@ TLSA 255 255 255 00 ; Maximal numbers +@ TLSA 0 0 0 0102 00 FF ; Hex string with blank spaces inside +@ TYPE52 \# 4 00000000 ; TYPE + Hexadecimal rdata +@ TYPE52 0 0 0 00 ; TYPE +@ tlsa 0 0 0 00 ; Type in lower-case + +; KO +@ TLSA +@ TLSA ; Empty rdata +@ TLSA \# 0 ; Hex empty rdata +@ TLSA 256 0 0 00 ; Algorithm overflow +@ TLSA 0 256 0 00 ; Flags overflow +@ TLSA 0 0 256 00 ; Iterations overflow +@ TLSA 0 0 0 0 ; Hex block length must be multiple of 2 +@ TLSA 0 0 0 0x ; Bad hex char +@ TLSA 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/41_TLSA.out b/tests/libzscanner/data/41_TLSA.out new file mode 100644 index 0000000..6f5b6a1 --- /dev/null +++ b/tests/libzscanner/data/41_TLSA.out @@ -0,0 +1,54 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=FFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=000000010200FF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=00000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/42_LOC.in b/tests/libzscanner/data/42_LOC.in new file mode 100644 index 0000000..9eaae1d --- /dev/null +++ b/tests/libzscanner/data/42_LOC.in @@ -0,0 +1,64 @@ +$ORIGIN . +$TTL 1 + +; OK +@ LOC 1 N 1 E 0 ; The simplest case +@ LOC 0 1 N 1 E 0 ; Combination of parameters +@ LOC 0 0 1 N 1 E 0 ; Combination of parameters +@ LOC 1 N 0 1 E 0 ; Combination of parameters +@ LOC 1 N 0 0 1 E 0 ; Combination of parameters +@ LOC 1 N 0 0 1 E 0m ; Combination of parameters +@ LOC 1 N 1 E 0 1 ; Combination of parameters +@ LOC 1 N 1 E 0 1m ; Combination of parameters +@ LOC 1 N 1 E 0 0 1 ; Combination of parameters +@ LOC 1 N 1 E 0 0 1m ; Combination of parameters +@ LOC 1 N 1 E 0 0 0 1 ; Combination of parameters +@ LOC 1 N 1 E 0 0 0 1m ; Combination of parameters +@ LOC 0 0 0 N 0 0 0 E -100000.00 0 0 0 ; Minimal values +@ LOC 90 59 59.999 S 180 59 59.999 W 42849672.95m 90000000.00m 90000000.00m 90000000.00m ; Maximal values +@ LOC 0 S 0 0 0.001 W 0 ; Float dd.ddd test +@ LOC 0 S 0 0 0.01 W 0 ; Float dd.ddd test +@ LOC 0 S 0 0 0.1 W 0 ; Float dd.ddd test +@ LOC 0 S 0 0 1.0 W 0 ; Float dd.ddd test +@ LOC 0 S 0 0 10 W 0 ; Float dd.ddd test +@ LOC 0 S 0 W 0 0.01 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 0.10 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 1.0 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 10 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 100 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 1000 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 10000 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 100000 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 1000000 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 10000000 ; Number to [mantisa,exponent] test +@ LOC \# 16 00 00 00 00 00000000 00000000 00000000 ; Hexadecimal rdata +@ TYPE29 \# 16 00 00 00 00 00000000 00000000 00000000 ; TYPE + Hexadecimal rdata +@ TYPE29 0 N 0 E 0 ; TYPE +@ loc 0 N 0 E 0 ; Type in lower-case + +; KO +@ LOC +@ LOC ; Empty rdata +@ LOC \# 0 ; Hex empty rdata +@ LOC 91 0 0 N 0 0 0 E 0 0 0 0 ; Degree overflow +@ LOC 0 60 0 N 0 0 0 E 0 0 0 0 ; Minute overflow +@ LOC 0 0 60 0 N 0 0 0 E 0 0 0 0 ; Second overflow +@ LOC 0 0 0 N 181 0 0 E 0 0 0 0 ; Degree overflow +@ LOC 0 0 0 N 0 60 0 E 0 0 0 0 ; Minute overflow +@ LOC 0 0 0 N 0 0 60 E 0 0 0 0 ; Second overflow +@ LOC 0 0 0 N 0 0 0 E 42849672.96 0 0 0 ; Altitude overflow +@ LOC 0 0 0 N 0 0 0 E 42849673 0 0 0 ; Altitude overflow +@ LOC 0 0 0 N 0 0 0 E -100000.01 0 0 0 ; Altitude underflow +@ LOC 0 0 0 N 0 0 0 E -100001 0 0 0 ; Altitude underflow +@ LOC 0 0 0 N 0 0 0 E 0 90000000.01 0 0 ; Size overflow +@ LOC 0 0 0 N 0 0 0 E 0 90000001 0 0 ; Size overflow +@ LOC 0 0 0 N 0 0 0 E 0 0 90000000.01 0 ; HP overflow +@ LOC 0 0 0 N 0 0 0 E 0 0 90000001 0 ; HP overflow +@ LOC 0 0 0 N 0 0 0 E 0 0 0 90000000.01 ; VP overflow +@ LOC 0 0 0 N 0 0 0 E 0 0 0 90000001 ; VP overflow +@ LOC 1 1 E 0 ; Missing N or S +@ LOC 1 x 1 E 0 ; Bad letter +@ LOC 1 N 1 0 ; Missing E or W +@ LOC 1 N 1 x 0 ; Bad letter +@ LOC 1 N 1 E ; Missing altitude +@ LOC 0 0 0 N 0 0 0 E 0 0 0 0 x ; Unexpected item diff --git a/tests/libzscanner/data/42_LOC.out b/tests/libzscanner/data/42_LOC.out new file mode 100644 index 0000000..730cc3b --- /dev/null +++ b/tests/libzscanner/data/42_LOC.out @@ -0,0 +1,248 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138000EA608036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800003E88036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE808000EA6000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE80800003E800989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE80800003E800989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=000012138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=000012138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=000000128036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=000000128036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00000000800000008000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=009999996C79388159295F81FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFFFFF00989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFFFF600989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFFF9C00989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFFC1800989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFD8F000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00101613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00111613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00131613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00141613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00151613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00161613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00171613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00181613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00191613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000008000000000989680 +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ diff --git a/tests/libzscanner/data/43_EUI48.in b/tests/libzscanner/data/43_EUI48.in new file mode 100644 index 0000000..a2abbec --- /dev/null +++ b/tests/libzscanner/data/43_EUI48.in @@ -0,0 +1,22 @@ +$ORIGIN . +$TTL 1 + +; OK +@ EUI48 00-00-00-00-00-00 ; The simplest case +@ EUI48 FF-FF-FF-FF-FF-FF ; The maximal case +@ EUI48 aa-bb-cc-dd-ee-ff ; Lower-case +@ EUI48 \# 6 000000000000 ; Hexadecimal rdata +@ TYPE108 \# 6 000000000000 ; TYPE + Hexadecimal rdata +@ TYPE108 00-00-00-00-00-00 ; TYPE +@ eui48 00-00-00-00-00-00 ; Type in lower-case + +; KO +@ EUI48 +@ EUI48 ; Empty rdata +@ EUI48 \# 0 ; Hex empty rdata +@ EUI48 00-00-00-00-00 ; Too few hex pairs +@ EUI48 00-00-00-00-00-00-00 ; Too many hex pairs +@ EUI48 00-00-00-00-00-0 ; Missing char in a hex pair +@ EUI48 00:00-00-00-00-00 ; Bad separator +@ EUI48 00-00-00-x0-00-00 ; Bad character +@ EUI48 00-00-00-00-00-00 x ; Unexpected item diff --git a/tests/libzscanner/data/43_EUI48.out b/tests/libzscanner/data/43_EUI48.out new file mode 100644 index 0000000..a54a314 --- /dev/null +++ b/tests/libzscanner/data/43_EUI48.out @@ -0,0 +1,60 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=FFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=AABBCCDDEEFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_EUI_LENGTH +------ +WARNG=ZS_BAD_EUI_LENGTH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_CHAR_DASH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/44_EUI64.in b/tests/libzscanner/data/44_EUI64.in new file mode 100644 index 0000000..10f6346 --- /dev/null +++ b/tests/libzscanner/data/44_EUI64.in @@ -0,0 +1,22 @@ +$ORIGIN . +$TTL 1 + +; OK +@ EUI64 00-00-00-00-00-00-00-00 ; The simplest case +@ EUI64 FF-FF-FF-FF-FF-FF-FF-FF ; The maximal case +@ EUI64 aa-bb-cc-dd-ee-ff-01-02 ; Lower-case +@ EUI64 \# 8 0000000000000000 ; Hexadecimal rdata +@ TYPE109 \# 8 0000000000000000 ; TYPE + Hexadecimal rdata +@ TYPE109 00-00-00-00-00-00-00-00 ; TYPE +@ eui64 00-00-00-00-00-00-00-00 ; Type in lower-case + +; KO +@ EUI64 +@ EUI64 ; Empty rdata +@ EUI64 \# 0 ; Hex empty rdata +@ EUI64 00-00-00-00-00-00-00 ; Too few hex pairs +@ EUI64 00-00-00-00-00-00-00-00-00 ; Too many hex pairs +@ EUI64 00-00-00-00-00-00-00-0 ; Missing char in a hex pair +@ EUI64 00:00-00-00-00-00-00-00 ; Bad separator +@ EUI64 00-00-00-x0-00-00-00-00 ; Bad character +@ EUI64 00-00-00-00-00-00-00-00 x ; Unexpected item diff --git a/tests/libzscanner/data/44_EUI64.out b/tests/libzscanner/data/44_EUI64.out new file mode 100644 index 0000000..4cce5f5 --- /dev/null +++ b/tests/libzscanner/data/44_EUI64.out @@ -0,0 +1,60 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=FFFFFFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=AABBCCDDEEFF0102 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_EUI_LENGTH +------ +WARNG=ZS_BAD_EUI_LENGTH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_CHAR_DASH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/45_NID.in b/tests/libzscanner/data/45_NID.in new file mode 100644 index 0000000..a85f9c3 --- /dev/null +++ b/tests/libzscanner/data/45_NID.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The NID is the same as the L64, so there are the differences and basics only. + +; OK +@ NID 0 0000:0000:0000:0000 ; The simplest case +@ NID \# 10 00000000000000000000 ; Hexadecimal rdata +@ TYPE104 \# 10 00000000000000000000 ; TYPE + Hexadecimal rdata +@ TYPE104 0 0000:0000:0000:0000 ; TYPE +@ nid 0 0000:0000:0000:0000 ; Type in lower-case + +; KO +@ NID diff --git a/tests/libzscanner/data/45_NID.out b/tests/libzscanner/data/45_NID.out new file mode 100644 index 0000000..a2bfb4c --- /dev/null +++ b/tests/libzscanner/data/45_NID.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/46_L32.in b/tests/libzscanner/data/46_L32.in new file mode 100644 index 0000000..866e953 --- /dev/null +++ b/tests/libzscanner/data/46_L32.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ L32 0 0.0.0.0 ; The simplest case +@ L32 65535 255.255.255.255 ; The maximal case +@ L32 \# 6 000000000000 ; Hexadecimal rdata +@ TYPE105 \# 6 000000000000 ; TYPE + Hexadecimal rdata +@ TYPE105 0 0.0.0.0 ; TYPE +@ l32 0 0.0.0.0 ; Type in lower-case + +; KO +@ L32 +@ L32 ; Empty rdata +@ L32 \# 0 ; Hex empty rdata +@ L32 65536 0.0.0.0 ; Too big preference +@ L32 0 0.0.0.256 ; 8-bit overflow +@ L32 0 0.0.0 ; Short address +@ L32 0 0.0.0.0.0 ; Long address +@ L32 0 0.0.0.x ; Bad character +@ L32 0 0.0.0.0 x ; Unexpected item diff --git a/tests/libzscanner/data/46_L32.out b/tests/libzscanner/data/46_L32.out new file mode 100644 index 0000000..e9c77b5 --- /dev/null +++ b/tests/libzscanner/data/46_L32.out @@ -0,0 +1,54 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=FFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/47_L64.in b/tests/libzscanner/data/47_L64.in new file mode 100644 index 0000000..b4aabf3 --- /dev/null +++ b/tests/libzscanner/data/47_L64.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ L64 0 0000:0000:0000:0000 ; The simplest case +@ L64 65535 FFFF:FFFF:FFFF:FFFF ; The maximal case +@ L64 0 abcd:ef00:0000:0000 ; Lower-case +@ L64 \# 10 00000000000000000000 ; Hexadecimal rdata +@ TYPE106 \# 10 00000000000000000000 ; TYPE + Hexadecimal rdata +@ TYPE106 0 0000:0000:0000:0000 ; TYPE +@ l64 0 0000:0000:0000:0000 ; Type in lower-case + +; KO +@ L64 +@ L64 ; Empty rdata +@ L64 \# 0 ; Hex empty rdata +@ L64 65536 ; Too big preference +@ L64 0 0000:0000:0000 ; Missing label +@ L64 0 0000:0000:0000:0000:0000 ; Too many labels +@ L64 0 0000:0000:0000:000 ; Missing hex character +@ L64 0 0000:0000:0000-0000 ; Bad separator +@ L64 0 0000:0000:0000:x000 ; Bad hex character +@ L64 0 0000:0000:0000:0000 x ; Unexpected item diff --git a/tests/libzscanner/data/47_L64.out b/tests/libzscanner/data/47_L64.out new file mode 100644 index 0000000..106ee58 --- /dev/null +++ b/tests/libzscanner/data/47_L64.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=FFFFFFFFFFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=0000ABCDEF0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_L64_LENGTH +------ +WARNG=ZS_BAD_L64_LENGTH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_CHAR_COLON +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/48_LP.in b/tests/libzscanner/data/48_LP.in new file mode 100644 index 0000000..bc537d0 --- /dev/null +++ b/tests/libzscanner/data/48_LP.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The LP is the same as the MX, so there are the differences and basics only. + +; OK +@ LP 1 mail ; Relative dname +@ LP \# 3 0001 00 ; Hexadecimal rdata +@ TYPE107 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE107 1 @ ; TYPE +@ lp 1 @ ; Type in lower-case + +; KO +@ LP diff --git a/tests/libzscanner/data/48_LP.out b/tests/libzscanner/data/48_LP.out new file mode 100644 index 0000000..4961c7e --- /dev/null +++ b/tests/libzscanner/data/48_LP.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/49_CDS.in b/tests/libzscanner/data/49_CDS.in new file mode 100644 index 0000000..7b6c347 --- /dev/null +++ b/tests/libzscanner/data/49_CDS.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CDS 0 0 0 00 ; The simplest variant +@ CDS 65535 255 255 00 ; Maximal numbers +@ CDS 0 RSAMD5 0 00 ; Algorithm mnemonic +@ CDS 0 0 0 01 02 0304 ; Hex block with blank spaces between them +@ TYPE59 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE59 0 0 0 00 ; TYPE +@ cds 0 0 0 00 ; Type in lower-case + +; KO +@ CDS +@ CDS ; Empty rdata +@ CDS \# 0 ; Hex empty rdata +@ CDS 65536 0 0 00 ; Key tag overflow +@ CDS 0 256 0 00 ; Algorithm overflow +@ CDS 0 0 256 00 ; Digest type overflow +@ CDS 0 0 0 0 ; Continuous block length must be multiple of 2 +@ CDS 0 0 0 00 0 ; Continuous block length must be multiple of 2 +@ CDS 0 0 0 XX ; Bad hex character +@ CDS 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/49_CDS.out b/tests/libzscanner/data/49_CDS.out new file mode 100644 index 0000000..de40722 --- /dev/null +++ b/tests/libzscanner/data/49_CDS.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000001020304 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/50_CDNSKEY.in b/tests/libzscanner/data/50_CDNSKEY.in new file mode 100644 index 0000000..dc91462 --- /dev/null +++ b/tests/libzscanner/data/50_CDNSKEY.in @@ -0,0 +1,32 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CDNSKEY 0 0 0 AA== ; The simplest variant +@ CDNSKEY 65535 255 255 AA== ; Maximal numbers +@ CDNSKEY 0 0 RSAMD5 AA== ; Algorithm mnemonic +@ CDNSKEY 0 0 0 Zm8= ; One char padding +@ CDNSKEY 0 0 0 Zm9v ; Without padding +@ CDNSKEY 0 0 0 Zm9vYg== ; Two base64 blocks +@ CDNSKEY 0 0 0 Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE60 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE60 0 0 0 AA== ; TYPE +@ cdnskey 0 0 0 AA== ; Type in lower-case + +; KO +@ CDNSKEY +@ CDNSKEY ; Empty rdata +@ CDNSKEY \# 0 ; Hex empty rdata +@ CDNSKEY 65536 0 0 AA== ; Type overflow +@ CDNSKEY 0 256 0 AA== ; Key tag overflow +@ CDNSKEY 0 0 256 AA== ; Algorithm overflow +@ CDNSKEY 0 0 0 A ; Continuous block length must be multiple of 4 +@ CDNSKEY 0 0 0 AB ; Continuous block length must be multiple of 4 +@ CDNSKEY 0 0 0 ABC ; Continuous block length must be multiple of 4 +@ CDNSKEY 0 0 0 AA == ; Continuous block length must be multiple of 4 +@ CDNSKEY 0 0 0 A=== ; Bad padding +@ CDNSKEY 0 0 0 = ; Bad padding +@ CDNSKEY 0 0 0 == ; Bad padding +@ CDNSKEY 0 0 0 === ; Bad padding +@ CDNSKEY 0 0 0 ==== ; Bad padding +@ CDNSKEY 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/50_CDNSKEY.out b/tests/libzscanner/data/50_CDNSKEY.out new file mode 100644 index 0000000..3100313 --- /dev/null +++ b/tests/libzscanner/data/50_CDNSKEY.out @@ -0,0 +1,92 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=00000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=00000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=00000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=00000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/51_URI.in b/tests/libzscanner/data/51_URI.in new file mode 100644 index 0000000..8d18f42 --- /dev/null +++ b/tests/libzscanner/data/51_URI.in @@ -0,0 +1,22 @@ +$ORIGIN . +$TTL 1 + +; OK +@ URI 0 0 a ; The simplest variant +@ URI 65535 65535 ftp://a ; Maximal priority and weight +@ URI 0 0 "ftp://a" ; Quoted target +@ URI 0 0 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 ; Target longer than 255 +@ TYPE256 \# 5 0000000061 ; TYPE + Hexadecimal rdata +@ TYPE256 0 0 a ; TYPE +@ uri 0 0 a ; Type in lower-case + +; OK extensions +@ URI 0 0 "" ; Empty target + +; KO +@ URI +@ URI ; Empty rdata +@ URI \# 0 ; Hex empty rdata +@ URI 65536 0 a ; Priority overflow +@ URI 0 65536 a ; Weight overflow +@ URI 0 0 a a ; Unexpected item diff --git a/tests/libzscanner/data/51_URI.out b/tests/libzscanner/data/51_URI.out new file mode 100644 index 0000000..9dcf933 --- /dev/null +++ b/tests/libzscanner/data/51_URI.out @@ -0,0 +1,60 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=0000000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=FFFFFFFF6674703A2F2F61 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=000000006674703A2F2F61 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=00000000303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=0000000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=0000000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=0000000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=00000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/52_CAA.in b/tests/libzscanner/data/52_CAA.in new file mode 100644 index 0000000..7043ce5 --- /dev/null +++ b/tests/libzscanner/data/52_CAA.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CAA 0 a a ; The simplest variant +@ CAA 255 a a ; Maximal flags +@ CAA 0 a "a ; b" ; Quoted value +@ CAA 0 a 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 ; Value longer than 255 +@ TYPE257 \# 4 00016161 ; TYPE + Hexadecimal rdata +@ TYPE257 0 a a ; TYPE +@ caa 0 a a ; Type in lower-case + +; OK fallbacks and extensions +@ CAA 0 "" a ; Empty tag +@ CAA 0 "a" a ; Quoted tag +@ CAA 0 abcdefghijklmnopqrstuvwxyz0123456789 a ; All allowed characters, longer than 15 + +; KO +@ CAA +@ CAA ; Empty rdata +@ CAA \# 0 ; Hex empty rdata +@ CAA 256 a a ; Flags overflow +@ CAA 0 a a a ; Unexpected item diff --git a/tests/libzscanner/data/52_CAA.out b/tests/libzscanner/data/52_CAA.out new file mode 100644 index 0000000..e5eefdf --- /dev/null +++ b/tests/libzscanner/data/52_CAA.out @@ -0,0 +1,70 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=FF016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161203B2062 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=000161303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00246162636465666768696A6B6C6D6E6F707172737475767778797A3031323334353637383961 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/includes/include1 b/tests/libzscanner/data/includes/include1 new file mode 100644 index 0000000..9de1859 --- /dev/null +++ b/tests/libzscanner/data/includes/include1 @@ -0,0 +1,9 @@ +$TTL 1 + +a NS @ + +$ORIGIN tld1a. +a NS @ + +$ORIGIN tld1b. +a NS @ diff --git a/tests/libzscanner/data/includes/include2 b/tests/libzscanner/data/includes/include2 new file mode 100644 index 0000000..1e14e96 --- /dev/null +++ b/tests/libzscanner/data/includes/include2 @@ -0,0 +1,6 @@ +$TTL 1H + +b NS @ + +$ORIGIN tld1a. +b NS @ diff --git a/tests/libzscanner/data/includes/include3 b/tests/libzscanner/data/includes/include3 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/libzscanner/data/includes/include3 diff --git a/tests/libzscanner/data/includes/include4 b/tests/libzscanner/data/includes/include4 new file mode 100644 index 0000000..7e8d5e2 --- /dev/null +++ b/tests/libzscanner/data/includes/include4 @@ -0,0 +1 @@ +a NS ; Missing data diff --git a/tests/libzscanner/data/includes/include5 b/tests/libzscanner/data/includes/include5 new file mode 100644 index 0000000..ac98e01 --- /dev/null +++ b/tests/libzscanner/data/includes/include5 @@ -0,0 +1 @@ +$TTL x ; Bad number diff --git a/tests/libzscanner/data/includes/include6 b/tests/libzscanner/data/includes/include6 new file mode 100644 index 0000000..b5e8cb8 --- /dev/null +++ b/tests/libzscanner/data/includes/include6 @@ -0,0 +1 @@ +$INCLUDE include2 ; Include in include diff --git a/tests/libzscanner/processing.c b/tests/libzscanner/processing.c new file mode 100644 index 0000000..a5ddeaa --- /dev/null +++ b/tests/libzscanner/processing.c @@ -0,0 +1,173 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <inttypes.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#include "libzscanner/scanner.h" +#include "libzscanner/functions.c" +#include "libzscanner/processing.h" +#include "libknot/descriptor.c" + +const char *separator = "------\n"; + +static void print_wire_dname(const uint8_t *dname, uint32_t dname_length) +{ + uint32_t label_length = 0, i = 0; + + for (i = 0; i < dname_length; i++) { + if (label_length == 0) { + label_length = dname[i]; + printf("(%u)", label_length); + continue; + } + printf("%c", (char)dname[i]); + label_length--; + } +} + +void debug_process_error(zs_scanner_t *s) +{ + if (s->error.fatal) { + printf("LINE(%03"PRIu64") ERROR(%s) FILE(%s) NEAR(%s)\n", + s->line_counter, + zs_strerror(s->error.code), + s->file.name, + s->buffer); + } else { + printf("LINE(%03"PRIu64") WARNING(%s) FILE(%s) NEAR(%s)\n", + s->line_counter, + zs_strerror(s->error.code), + s->file.name, + s->buffer); + } + fflush(stdout); +} + +void debug_process_record(zs_scanner_t *s) +{ + uint32_t i; + + char rclass[32]; + char rtype[32]; + + if (knot_rrclass_to_string(s->r_class, rclass, sizeof(rclass)) > 0 && + knot_rrtype_to_string(s->r_type, rtype, sizeof(rtype)) > 0) { + printf("LINE(%03"PRIu64") %s %6u %*s ", + s->line_counter, rclass, s->r_ttl, 5, rtype); + } else { + printf("LINE(%03"PRIu64") %u %6u %*u ", + s->line_counter, s->r_class, s->r_ttl, 5, s->r_type); + } + + print_wire_dname(s->r_owner, s->r_owner_length); + + printf(" \\# %u ", s->r_data_length); + + for (i = 0; i < s->r_data_length; i++) { + printf("%02X", (s->r_data)[i]); + } + printf("\n"); + fflush(stdout); +} + +void test_process_error(zs_scanner_t *s) +{ + if (s->error.fatal) { + printf("ERROR=%s\n%s", zs_errorname(s->error.code), separator); + } else { + printf("WARNG=%s\n%s", zs_errorname(s->error.code), separator); + } + fflush(stdout); +} + +void test_process_record(zs_scanner_t *s) +{ + uint32_t i; + + printf("OWNER="); + for (i = 0; i < s->r_owner_length; i++) { + printf("%02X", s->r_owner[i]); + } + printf("\n"); + printf("CLASS=%04X\n", s->r_class); + printf("RRTTL=%08X\n", s->r_ttl); + printf("RTYPE=%04X\n", s->r_type); + printf("RDATA="); + for (i = 0; i < s->r_data_length; i++) { + printf("%02X", (s->r_data)[i]); + } + printf("\n%s", separator); + fflush(stdout); +} + +int test_date_to_timestamp(void) +{ + time_t ref_timestamp, max_timestamp; + uint32_t test_timestamp; + uint8_t buffer[16]; + uint64_t val1, val2; // For time_t type unification. + struct tm tm; + + // Set UTC for strftime. + putenv("TZ=UTC"); + tzset(); + + // Get maximal allowed timestamp. + strptime("21051231235959", "%Y%m%d%H%M%S", &tm); + max_timestamp = mktime(&tm); + + // Testing loop over whole input interval. + for (ref_timestamp = 0; + ref_timestamp < max_timestamp; + ref_timestamp += 1) { + struct tm result; + // Get reference (correct) timestamp. + strftime((char*)buffer, sizeof(buffer), "%Y%m%d%H%M%S", + gmtime_r(&ref_timestamp, &result)); + + // Get testing timestamp. + test_timestamp = 0U; // prevents Wunitialized + date_to_timestamp(buffer, &test_timestamp); + + // Some continuous loging. + if (ref_timestamp % 10000000 == 0) { + val1 = ref_timestamp; + printf("%s = %"PRIu64"\n", buffer, val1); + } + + // Comparing results. + if (ref_timestamp != test_timestamp) { + val1 = ref_timestamp; + + if (ref_timestamp > test_timestamp) { + val2 = ref_timestamp - test_timestamp; + printf("%s = %"PRIu64", in - out = %"PRIu64"\n", + buffer, val1, val2); + } else { + val2 = test_timestamp - ref_timestamp; + printf("%s = %"PRIu64", out - in = %"PRIu64"\n", + buffer, val1, val2); + } + + return -1; + } + } + + return 0; +} diff --git a/tests/libzscanner/processing.h b/tests/libzscanner/processing.h new file mode 100644 index 0000000..fe66737 --- /dev/null +++ b/tests/libzscanner/processing.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "libzscanner/scanner.h" + +void debug_process_error(zs_scanner_t *scanner); + +void debug_process_record(zs_scanner_t *scanner); + +void test_process_error(zs_scanner_t *scanner); + +void test_process_record(zs_scanner_t *scanner); + +int test_date_to_timestamp(void); diff --git a/tests/libzscanner/test_zscanner.in b/tests/libzscanner/test_zscanner.in new file mode 100644 index 0000000..2c0c275 --- /dev/null +++ b/tests/libzscanner/test_zscanner.in @@ -0,0 +1,41 @@ +#!/bin/sh + +SOURCE=@top_srcdir@/tests/libzscanner +BUILD=@top_builddir@/tests/libzscanner + +. @top_srcdir@/tests/tap/libtap.sh + +cd "$BUILD" + +TMPDIR=$(test_tmpdir) +TESTS_DIR="$SOURCE"/data +ZSCANNER_TOOL="$BUILD"/zscanner-tool + +plan 80 + +mkdir -p "$TMPDIR"/includes/ +for a in 1 2 3 4 5 6; do + cat "$TESTS_DIR"/includes/include"$a" > "$TMPDIR"/includes/include"$a"; +done + +for case in $(cat "$SOURCE"/TESTS); do + casein=$(test_file_path data/"$case".in) + caseout=$(test_file_path data/"$case".out) + filein="$TMPDIR"/"$case".in + fileout="$TMPDIR"/"$case".out + + sed -e "s|@TMPDIR@|$TMPDIR|;" < "$casein" > "$filein" + + "$ZSCANNER_TOOL" -m 2 . "$filein" > "$fileout" + + if cmp -s "$fileout" "$caseout"; then + ok "$case: output matches" true + rm "$filein" + rm "$fileout" + else + ok "$case: output differs" false + diff -urNap "$caseout" "$fileout" | while read line; do diag "$line"; done + fi +done + +rm -rf "$TMPDIR"/includes/ diff --git a/tests/libzscanner/zscanner-tool.c b/tests/libzscanner/zscanner-tool.c new file mode 100644 index 0000000..06b795c --- /dev/null +++ b/tests/libzscanner/zscanner-tool.c @@ -0,0 +1,251 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <getopt.h> +#include <inttypes.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#include "libzscanner/processing.h" +#include "libzscanner/scanner.h" + +#define DEFAULT_MODE 1 +#define DEFAULT_CLASS 1 +#define DEFAULT_TTL 0 + +static void *timestamp_worker(void *data) +{ + int *ret = (int *)data; + *ret = test_date_to_timestamp(); + return NULL; +} + +static void help(void) +{ + printf("\nZone scanner testing tool.\n" + "Usage: zscanner-tool [parameters] origin zonefile\n" + "\n" + "Parameters:\n" + " -m [0,1,2] Processing mode.\n" + " 0 Empty output.\n" + " 1 Debug output (DEFAULT).\n" + " 2 Test output.\n" + " -s State parsing mode.\n" + " -t Launch unit tests.\n" + " -h Print this help.\n"); +} + +static int time_test(void) +{ + pthread_t t1, t2, t3; + int ret1, ret2, ret3; + + pthread_create(&t1, NULL, timestamp_worker, &ret1); + pthread_create(&t2, NULL, timestamp_worker, &ret2); + pthread_create(&t3, NULL, timestamp_worker, &ret3); + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + pthread_join(t3, NULL); + + if (ret1 != 0 || ret2 != 0 || ret3 != 0) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static int include(zs_scanner_t *s); + +static int state_parsing(zs_scanner_t *s) +{ + while (zs_parse_record(s) == 0) { + switch (s->state) { + case ZS_STATE_DATA: + if (s->process.record != NULL) { + s->process.record(s); + } + break; + case ZS_STATE_ERROR: + if (s->process.error != NULL) { + s->process.error(s); + } + if (s->error.fatal) { + return -1; + } + break; + case ZS_STATE_INCLUDE: + if (include(s) != 0) { + return -1; + } + break; + default: + return (s->error.counter == 0) ? 0 : -1; + } + } + + return -1; +} + +static int include(zs_scanner_t *s) +{ + zs_scanner_t *ss; + int ret = 0; + + if ((ss = malloc(sizeof(zs_scanner_t))) == NULL || + zs_init(ss, (char *)s->buffer, s->default_class, s->default_ttl) != 0 || + zs_set_input_file(ss, (char *)(s->include_filename)) != 0 || + zs_set_processing(ss, s->process.record, s->process.error, s->process.data) != 0 || + state_parsing(ss) != 0) { + if (ss == NULL) { + s->error.code = ZS_ENOMEM; + } else if (ss->error.counter > 0) { + s->error.counter += ss->error.counter; + s->error.code = ZS_UNPROCESSED_INCLUDE; + } else { + s->error.code = ss->error.code; + } + + if (s->process.error != NULL) { + s->buffer[0] = '\0'; // Clear unrelated content. + s->buffer_length = 0; + s->error.counter++; + s->error.fatal = true; + s->process.error(s); + } + + ret = -1; + } + + zs_deinit(ss); + free(ss); + + return ret; +} + +int main(int argc, char *argv[]) +{ + int mode = DEFAULT_MODE, state = 0, test = 0; + + // Command line long options. + struct option opts[] = { + { "mode", required_argument, NULL, 'm' }, + { "state", no_argument, NULL, 's' }, + { "test", no_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, + { NULL } + }; + + // Parsed command line arguments. + int opt = 0, li = 0; + while ((opt = getopt_long(argc, argv, "m:sth", opts, &li)) != -1) { + switch (opt) { + case 'm': + mode = atoi(optarg); + break; + case 's': + state = 1; + break; + case 't': + test = 1; + break; + case 'h': + help(); + return EXIT_SUCCESS; + default: + help(); + return EXIT_FAILURE; + } + } + + if (test == 1) { + return time_test(); + } + + // Check if there are 2 remaining non-options. + if (argc - optind != 2) { + help(); + return EXIT_FAILURE; + } + + const char *origin = argv[optind]; + const char *zone_file = argv[optind + 1]; + + // Create a zone scanner. + zs_scanner_t *s = malloc(sizeof(zs_scanner_t)); + if (s == NULL) { + printf("Scanner create error!\n"); + return EXIT_FAILURE; + } + if (zs_init(s, origin, DEFAULT_CLASS, DEFAULT_TTL) != 0) { + printf("Scanner init error!\n"); + free(s); + return EXIT_FAILURE; + } + if (zs_set_input_file(s, zone_file) != 0) { + printf("Scanner file error!\n"); + zs_deinit(s); + free(s); + return EXIT_FAILURE; + } + + // Set the processing mode. + int ret; + switch (mode) { + case 0: + ret = 0; + break; + case 1: + ret = zs_set_processing(s, debug_process_record, debug_process_error, NULL); + break; + case 2: + ret = zs_set_processing(s, test_process_record, test_process_error, NULL); + break; + default: + printf("Bad mode number!\n"); + help(); + return EXIT_FAILURE; + } + if (ret != 0) { + printf("Processing setup error!\n"); + return EXIT_FAILURE; + } + + // Parse the file. + ret = state ? state_parsing(s) : zs_parse_all(s); + if (ret == 0) { + if (mode == DEFAULT_MODE) { + printf("Zone file has been processed successfully\n"); + } + + zs_deinit(s); + free(s); + return EXIT_SUCCESS; + } else { + if (s->error.counter > 0 && mode == DEFAULT_MODE) { + printf("Zone processing has stopped with " + "%"PRIu64" warnings/errors!\n", + s->error.counter); + } else if (mode == DEFAULT_MODE) { + printf("%s\n", zs_strerror(s->error.code)); + } + + zs_deinit(s); + free(s); + return EXIT_FAILURE; + } +} diff --git a/tests/modules/test_onlinesign.c b/tests/modules/test_onlinesign.c new file mode 100644 index 0000000..e2b3e89 --- /dev/null +++ b/tests/modules/test_onlinesign.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <tap/basic.h> +#include <assert.h> + +#include "knot/modules/onlinesign/nsec_next.h" +#include "libknot/consts.h" +#include "libknot/dname.h" +#include "libknot/errcode.h" + +/*! + * \brief Assert that a domain name in a static buffer is valid. + */ +#define _assert_dname(name) \ + assert(knot_dname_wire_check(name, name + KNOT_DNAME_MAXLEN, NULL) > 0) + +static void _test_nsec_next(const char *msg, + const knot_dname_t *input, + const knot_dname_t *apex, + const knot_dname_t *expected) +{ + knot_dname_t *next = online_nsec_next(input, apex); + ok(next != NULL && knot_dname_is_equal(next, expected), + "nsec_next, %s", msg); + knot_dname_free(next, NULL); +} + +/*! + * \brief Check \a online_nsec_next. + * + * Intentionally implemented as a macro. The input domain names are copied + * into static buffers and validated. + */ +#define test_nsec_next(msg, _input, _apex, _expected) \ +{ \ + uint8_t input[KNOT_DNAME_MAXLEN] = _input; \ + uint8_t apex[KNOT_DNAME_MAXLEN] = _apex; \ + uint8_t expected[KNOT_DNAME_MAXLEN] = _expected; \ + \ + _assert_dname(input); \ + _assert_dname(apex); \ + _assert_dname(expected); \ + \ + _test_nsec_next(msg, input, apex, expected); \ +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // adding a single zero-byte label + + test_nsec_next( + "zero-byte label, apex", + "\x7""example""\x3""com", + "\x7""example""\x3""com", + "\x01\x00""\x07""example""\x03""com" + ); + + test_nsec_next( + "zero-byte label, subdomain", + "\x02""nx""\x7""example""\x3""com", + "\x7""example""\x3""com", + "\x01\x00""\x02""nx""\x07""example""\x03""com" + ); + + test_nsec_next( + "zero-byte label, binary", + "\x02\xff\xff""\x7""example""\x3""com", + "\x07""example""\x3""com", + "\x01\x00""\x02\xff\xff""\x7""example""\x3""com" + ); + + // zero byte label won't fit, increment + #define APEX \ + "\x05""bacon""\x05""salad" + + #define LONG_SUFFIX \ + "\x2e""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ + "\x2e""iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" \ + "\x2e""mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm" \ + "\x2e""qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" \ + "\x2c""zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" \ + APEX + assert(sizeof(LONG_SUFFIX) == 245 + 1); + + test_nsec_next( + "increment first label (simple)", + "\x08""icecream" LONG_SUFFIX, + APEX, + "\x08""icecrean" LONG_SUFFIX + ); + + test_nsec_next( + "increment first label (binary)", + "\x08""walrus\xff\xff" LONG_SUFFIX, + APEX, + "\x08""walrut\x00\x00" LONG_SUFFIX + ); + + test_nsec_next( + "increment first label (in place)", + "\x07""lobster" LONG_SUFFIX, + APEX, + "\x07""lobstes" LONG_SUFFIX + ); + + test_nsec_next( + "increment first label (extend)", + "\x07""\xff\xff\xff\xff\xff\xff\xff" LONG_SUFFIX, + APEX, + "\x08""\xff\xff\xff\xff\xff\xff\xff\x00" LONG_SUFFIX + ); + + // name too long + + test_nsec_next( + "name to long, strip label and increase next (simple)", + "\x03""\xff\xff\xff""\x04""newt" LONG_SUFFIX, + APEX, + "\x04""newu" LONG_SUFFIX + ); + + test_nsec_next( + "name to long, strip label and increase next (binary)", + "\x03""\xff\xff\xff""\x04""cc\xff\xff" LONG_SUFFIX, + APEX, + "\x04""cd\x00\x00" LONG_SUFFIX + ); + + test_nsec_next( + "name to long, strip label and increase next (extend)", + "\x04""\xff\xff\xff\xff""\x03""\xff\xff\xff" LONG_SUFFIX, + APEX, + "\x04""\xff\xff\xff\x00" LONG_SUFFIX + ); + + // label too long + + #define MAX_LABEL "\x3f" /* 63 */ \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff" + assert(sizeof(MAX_LABEL) == 64 + 1); + + #define PAD_LABEL "\x28" /* 40 */ \ + "iiiiiiiiiioooooooooottttttttttssssssssss" + assert(sizeof(PAD_LABEL) == 41 + 1); + + test_nsec_next( + "label too long, strip and increase next (simple)", + MAX_LABEL "\x08""mandrill" MAX_LABEL MAX_LABEL PAD_LABEL APEX, + APEX, + "\x08""mandrilm" MAX_LABEL MAX_LABEL PAD_LABEL APEX + ); + + test_nsec_next( + "label too long, strip and increase next (extend)", + MAX_LABEL "\x07""\xff\xff\xff\xff\xff\xff\xff" MAX_LABEL MAX_LABEL PAD_LABEL APEX, + APEX, + "\x08""\xff\xff\xff\xff\xff\xff\xff\x00" MAX_LABEL MAX_LABEL PAD_LABEL APEX + ); + + test_nsec_next( + "label too long, strip multiple", + MAX_LABEL MAX_LABEL "\x08""flamingo" MAX_LABEL PAD_LABEL APEX, + APEX, + "\x08""flamingp" MAX_LABEL PAD_LABEL APEX + ); + + test_nsec_next( + "label too long, wrap around to apex", + "\x31" /* 49 */ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff" + MAX_LABEL MAX_LABEL MAX_LABEL APEX, + APEX, + APEX + ); + + return 0; +} diff --git a/tests/modules/test_rrl.c b/tests/modules/test_rrl.c new file mode 100644 index 0000000..b7aef4e --- /dev/null +++ b/tests/modules/test_rrl.c @@ -0,0 +1,167 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "libdnssec/crypto.h" +#include "libdnssec/random.h" +#include "libknot/libknot.h" +#include "contrib/sockaddr.h" +#include "knot/modules/rrl/functions.c" + +/* Enable time-dependent tests. */ +//#define ENABLE_TIMED_TESTS +#define RRL_SIZE 196613 +#define RRL_THREADS 8 +#define RRL_INSERTS (RRL_SIZE/(5*RRL_THREADS)) /* lf = 1/5 */ + +/* Disabled as default as it depends on random input. + * Table may be consistent even if some collision occur (and they may occur). + * Note: Disabled due to reported problems when running on VMs due to time + * flow inconsistencies. Should work alright on a host machine. + */ +#ifdef ENABLE_TIMED_TESTS +struct bucketmap { + unsigned i; + uint64_t x; +}; + +/*! \brief Unit runnable. */ +struct runnable_data { + int passed; + rrl_table_t *rrl; + struct sockaddr_storage *addr; + rrl_req_t *rq; + knot_dname_t *zone; +}; + +static void* rrl_runnable(void *arg) +{ + struct runnable_data *d = (struct runnable_data *)arg; + struct sockaddr_storage addr; + memcpy(&addr, d->addr, sizeof(struct sockaddr_storage)); + int lock = -1; + uint32_t now = time(NULL); + struct bucketmap *m = malloc(RRL_INSERTS * sizeof(struct bucketmap)); + for (unsigned i = 0; i < RRL_INSERTS; ++i) { + m[i].i = dnssec_random_uint32_t(); + ((struct sockaddr_in *) &addr)->sin_addr.s_addr = m[i].i; + rrl_item_t *b = rrl_hash(d->rrl, &addr, d->rq, d->zone, now, &lock); + rrl_unlock(d->rrl, lock); + m[i].x = b->netblk; + } + for (unsigned i = 0; i < RRL_INSERTS; ++i) { + ((struct sockaddr_in *) &addr)->sin_addr.s_addr = m[i].i; + rrl_item_t *b = rrl_hash(d->rrl, &addr, d->rq, d->zone, now, &lock); + rrl_unlock(d->rrl, lock); + if (b->netblk != m[i].x) { + d->passed = 0; + } + } + free(m); + return NULL; +} + +static void rrl_hopscotch(struct runnable_data* rd) +{ + rd->passed = 1; + pthread_t thr[RRL_THREADS]; + for (unsigned i = 0; i < RRL_THREADS; ++i) { + pthread_create(thr + i, NULL, &rrl_runnable, rd); + } + for (unsigned i = 0; i < RRL_THREADS; ++i) { + pthread_join(thr[i], NULL); + } +} +#endif + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + dnssec_crypto_init(); + + /* Prepare query. */ + knot_pkt_t *query = knot_pkt_new(NULL, 512, NULL); + if (query == NULL) { + return KNOT_ERROR; /* Fatal */ + } + + knot_dname_t *qname = knot_dname_from_str_alloc("beef."); + int ret = knot_pkt_put_question(query, qname, KNOT_CLASS_IN, KNOT_RRTYPE_A); + knot_dname_free(qname, NULL); + if (ret != KNOT_EOK) { + knot_pkt_free(query); + return KNOT_ERROR; /* Fatal */ + } + + /* Prepare response */ + uint8_t rbuf[65535]; + size_t rlen = sizeof(rbuf); + memcpy(rbuf, query->wire, query->size); + knot_wire_flags_set_qr(rbuf); + + rrl_req_t rq; + rq.w = rbuf; + rq.len = rlen; + rq.query = query; + rq.flags = 0; + + /* 1. create rrl table */ + const uint32_t rate = 10; + rrl_table_t *rrl = rrl_create(RRL_SIZE, rate); + ok(rrl != NULL, "rrl: create"); + + /* 4. N unlimited requests. */ + knot_dname_t *zone = knot_dname_from_str_alloc("rrl."); + + struct sockaddr_storage addr; + struct sockaddr_storage addr6; + sockaddr_set(&addr, AF_INET, "1.2.3.4", 0); + sockaddr_set(&addr6, AF_INET6, "1122:3344:5566:7788::aabb", 0); + ret = 0; + for (unsigned i = 0; i < rate * RRL_CAPACITY; ++i) { + if (rrl_query(rrl, &addr, &rq, zone, NULL) != KNOT_EOK || + rrl_query(rrl, &addr6, &rq, zone, NULL) != KNOT_EOK) { + ret = KNOT_ELIMIT; + break; + } + } + is_int(0, ret, "rrl: unlimited IPv4/v6 requests"); + +#ifdef ENABLE_TIMED_TESTS + /* 5. limited request */ + ret = rrl_query(rrl, &addr, &rq, zone, NULL); + is_int(KNOT_ELIMIT, ret, "rrl: throttled IPv4 request"); + + /* 6. limited IPv6 request */ + ret = rrl_query(rrl, &addr6, &rq, zone, NULL); + is_int(KNOT_ELIMIT, ret, "rrl: throttled IPv6 request"); + + /* 8. hopscotch test */ + struct runnable_data rd = { + 1, rrl, &addr, &rq, zone + }; + rrl_hopscotch(&rd); + ok(rd.passed, "rrl: hashtable is ~ consistent"); +#endif + + knot_dname_free(zone, NULL); + knot_pkt_free(query); + rrl_destroy(rrl); + dnssec_crypto_cleanup(); + return 0; +} diff --git a/tests/tap/basic.c b/tests/tap/basic.c new file mode 100644 index 0000000..23b595c --- /dev/null +++ b/tests/tap/basic.c @@ -0,0 +1,605 @@ +/* + * Some utility routines for writing tests. + * + * Here are a variety of utility routines for writing tests compatible with + * the TAP protocol. All routines of the form ok() or is*() take a test + * number and some number of appropriate arguments, check to be sure the + * results match the expected output using the arguments, and print out + * something appropriate for that test number. Other utility routines help in + * constructing more complex tests, skipping tests, reporting errors, setting + * up the TAP output format, or finding things in the test environment. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu> + * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013 + * The Board of Trustees of the Leland Stanford Junior University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef _WIN32 +# include <direct.h> +#else +# include <sys/stat.h> +#endif +#include <sys/types.h> +#include <unistd.h> + +#include "basic.h" + +/* Windows provides mkdir and rmdir under different names. */ +#ifdef _WIN32 +# define mkdir(p, m) _mkdir(p) +# define rmdir(p) _rmdir(p) +#endif + +/* + * The test count. Always contains the number that will be used for the next + * test status. + */ +unsigned long testnum = 1; + +/* + * Status information stored so that we can give a test summary at the end of + * the test case. We store the planned final test and the count of failures. + * We can get the highest test count from testnum. + * + * We also store the PID of the process that called plan() and only summarize + * results when that process exits, so as to not misreport results in forked + * processes. + * + * If _lazy is true, we're doing lazy planning and will print out the plan + * based on the last test number at the end of testing. + */ +static unsigned long _planned = 0; +static unsigned long _failed = 0; +static pid_t _process = 0; +static int _lazy = 0; + +/* + * Our exit handler. Called on completion of the test to report a summary of + * results provided we're still in the original process. This also handles + * printing out the plan if we used plan_lazy(), although that's suppressed if + * we never ran a test (due to an early bail, for example). + */ +static void +finish(void) +{ + unsigned long highest = testnum - 1; + + if (_planned == 0 && !_lazy) + return; + fflush(stderr); + if (_process != 0 && getpid() == _process) { + if (_lazy && highest > 0) { + printf("1..%lu\n", highest); + _planned = highest; + } + if (_planned > highest) + printf("# Looks like you planned %lu test%s but only ran %lu\n", + _planned, (_planned > 1 ? "s" : ""), highest); + else if (_planned < highest) + printf("# Looks like you planned %lu test%s but ran %lu extra\n", + _planned, (_planned > 1 ? "s" : ""), highest - _planned); + else if (_failed > 0) + printf("# Looks like you failed %lu test%s of %lu\n", _failed, + (_failed > 1 ? "s" : ""), _planned); + else if (_planned > 1) + printf("# All %lu tests successful or skipped\n", _planned); + else + printf("# %lu test successful or skipped\n", _planned); + } +} + +/* + * Initialize things. Turns on line buffering on stdout and then prints out + * the number of tests in the test suite. + */ +void +plan(unsigned long count) +{ + if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0) + fprintf(stderr, "# cannot set stdout to line buffered: %s\n", + strerror(errno)); + fflush(stderr); + printf("1..%lu\n", count); + testnum = 1; + _planned = count; + _process = getpid(); + atexit(finish); +} + +/* + * Initialize things for lazy planning, where we'll automatically print out a + * plan at the end of the program. Turns on line buffering on stdout as well. + */ +void +plan_lazy(void) +{ + if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0) + fprintf(stderr, "# cannot set stdout to line buffered: %s\n", + strerror(errno)); + testnum = 1; + _process = getpid(); + _lazy = 1; + atexit(finish); +} + +/* + * Skip the entire test suite and exits. Should be called instead of plan(), + * not after it, since it prints out a special plan line. + */ +void +skip_all(const char *format, ...) +{ + fflush(stderr); + printf("1..0 # skip"); + if (format != NULL) { + va_list args; + + putchar(' '); + va_start(args, format); + vprintf(format, args); + va_end(args); + } + putchar('\n'); + exit(0); +} + +/* + * Print the test description. + */ +static void +print_desc(const char *format, va_list args) +{ + printf(" - "); + vprintf(format, args); +} + +/* + * Takes a boolean success value and assumes the test passes if that value + * is true and fails if that value is false. + */ +void +ok(int success, const char *format, ...) +{ + fflush(stderr); + printf("%sok %lu", success ? "" : "not ", testnum++); + if (!success) + _failed++; + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Same as ok(), but takes the format arguments as a va_list. + */ +void +okv(int success, const char *format, va_list args) +{ + fflush(stderr); + printf("%sok %lu", success ? "" : "not ", testnum++); + if (!success) + _failed++; + if (format != NULL) + print_desc(format, args); + putchar('\n'); +} + +/* + * Skip a test. + */ +void +skip(const char *reason, ...) +{ + fflush(stderr); + printf("ok %lu # skip", testnum++); + if (reason != NULL) { + va_list args; + + va_start(args, reason); + putchar(' '); + vprintf(reason, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Report the same status on the next count tests. + */ +void +ok_block(unsigned long count, int status, const char *format, ...) +{ + unsigned long i; + + fflush(stderr); + for (i = 0; i < count; i++) { + printf("%sok %lu", status ? "" : "not ", testnum++); + if (!status) + _failed++; + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); + } +} + +/* + * Skip the next count tests. + */ +void +skip_block(unsigned long count, const char *reason, ...) +{ + unsigned long i; + + fflush(stderr); + for (i = 0; i < count; i++) { + printf("ok %lu # skip", testnum++); + if (reason != NULL) { + va_list args; + + va_start(args, reason); + putchar(' '); + vprintf(reason, args); + va_end(args); + } + putchar('\n'); + } +} + +/* + * Takes an expected integer and a seen integer and assumes the test passes + * if those two numbers match. + */ +void +is_int(long long wanted, long long seen, const char *format, ...) +{ + fflush(stderr); + if (wanted == seen) + printf("ok %lu", testnum++); + else { + printf("# wanted: %lld\n# seen: %lld\n", wanted, seen); + printf("not ok %lu", testnum++); + _failed++; + } + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Takes a string and what the string should be, and assumes the test passes + * if those strings match (using strcmp). + */ +void +is_string(const char *wanted, const char *seen, const char *format, ...) +{ + if (wanted == NULL) + wanted = "(null)"; + if (seen == NULL) + seen = "(null)"; + fflush(stderr); + if (strcmp(wanted, seen) == 0) + printf("ok %lu", testnum++); + else { + printf("# wanted: %s\n# seen: %s\n", wanted, seen); + printf("not ok %lu", testnum++); + _failed++; + } + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Takes an expected unsigned long and a seen unsigned long and assumes the + * test passes if the two numbers match. Otherwise, reports them in hex. + */ +void +is_hex(unsigned long long wanted, unsigned long long seen, + const char *format, ...) +{ + fflush(stderr); + if (wanted == seen) + printf("ok %lu", testnum++); + else { + printf("# wanted: %llx\n# seen: %llx\n", + (unsigned long long) wanted, + (unsigned long long) seen); + printf("not ok %lu", testnum++); + _failed++; + } + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Bail out with an error. + */ +void +bail(const char *format, ...) +{ + va_list args; + + fflush(stderr); + fflush(stdout); + printf("Bail out! "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); + exit(255); +} + +/* + * Bail out with an error, appending strerror(errno). + */ +void +sysbail(const char *format, ...) +{ + va_list args; + int oerrno = errno; + + fflush(stderr); + fflush(stdout); + printf("Bail out! "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf(": %s\n", strerror(oerrno)); + exit(255); +} + +/* + * Report a diagnostic to stderr. + */ +void +diag(const char *format, ...) +{ + va_list args; + + fflush(stderr); + fflush(stdout); + printf("# "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); +} + +/* + * Report a diagnostic to stderr, appending strerror(errno). + */ +void +sysdiag(const char *format, ...) +{ + va_list args; + int oerrno = errno; + + fflush(stderr); + fflush(stdout); + printf("# "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf(": %s\n", strerror(oerrno)); +} + +/* + * Allocate cleared memory, reporting a fatal error with bail on failure. + */ +void * +bcalloc(size_t n, size_t size) +{ + void *p; + + p = calloc(n, size); + if (p == NULL) + sysbail("failed to calloc %lu", (unsigned long)(n * size)); + return p; +} + +/* + * Allocate memory, reporting a fatal error with bail on failure. + */ +void * +bmalloc(size_t size) +{ + void *p; + + p = malloc(size); + if (p == NULL) + sysbail("failed to malloc %lu", (unsigned long) size); + return p; +} + +/* + * Reallocate memory, reporting a fatal error with bail on failure. + */ +void * +brealloc(void *p, size_t size) +{ + p = realloc(p, size); + if (p == NULL) + sysbail("failed to realloc %lu bytes", (unsigned long) size); + return p; +} + +/* + * Copy a string, reporting a fatal error with bail on failure. + */ +char * +bstrdup(const char *s) +{ + char *p; + size_t len; + + len = strlen(s) + 1; + p = malloc(len); + if (p == NULL) + sysbail("failed to strdup %lu bytes", (unsigned long) len); + memcpy(p, s, len); + return p; +} + +/* + * Copy up to n characters of a string, reporting a fatal error with bail on + * failure. Don't use the system strndup function, since it may not exist and + * the TAP library doesn't assume any portability support. + */ +char * +bstrndup(const char *s, size_t n) +{ + const char *p; + char *copy; + size_t length; + + /* Don't assume that the source string is nul-terminated. */ + for (p = s; (size_t) (p - s) < n && *p != '\0'; p++) + ; + length = p - s; + copy = malloc(length + 1); + if (p == NULL) + sysbail("failed to strndup %lu bytes", (unsigned long) length); + memcpy(copy, s, length); + copy[length] = '\0'; + return copy; +} + +/* + * Locate a test file. Given the partial path to a file, look under BUILD and + * then SOURCE for the file and return the full path to the file. Returns + * NULL if the file doesn't exist. A non-NULL return should be freed with + * test_file_path_free(). + * + * This function uses sprintf because it attempts to be independent of all + * other portability layers. The use immediately after a memory allocation + * should be safe without using snprintf or strlcpy/strlcat. + */ +char * +test_file_path(const char *file) +{ + char *base; + char *path = NULL; + size_t length; + const char *envs[] = { "BUILD", "SOURCE", NULL }; + int i; + + for (i = 0; envs[i] != NULL; i++) { + base = getenv(envs[i]); + if (base == NULL) + continue; + length = strlen(base) + 1 + strlen(file) + 1; + path = bmalloc(length); + snprintf(path, length, "%s/%s", base, file); + if (access(path, R_OK) == 0) + break; + free(path); + path = NULL; + } + return path; +} + +/* + * Free a path returned from test_file_path(). This function exists primarily + * for Windows, where memory must be freed from the same library domain that + * it was allocated from. + */ +void +test_file_path_free(char *path) +{ + if (path != NULL) + free(path); +} + +/* + * Create a temporary directory, tmp, under BUILD if set and the current + * directory if it does not. Returns the path to the temporary directory in + * newly allocated memory, and calls bail on any failure. The return value + * should be freed with test_tmpdir_free. + * + * This function uses sprintf because it attempts to be independent of all + * other portability layers. The use immediately after a memory allocation + * should be safe without using snprintf or strlcpy/strlcat. + */ +char * +test_tmpdir(void) +{ + const char *build; + char *path = NULL; + size_t length; + + build = getenv("BUILD"); + if (build == NULL) + build = "."; + length = strlen(build) + strlen("/tmp") + 1; + path = bmalloc(length); + snprintf(path, length, "%s/tmp", build); + if (access(path, X_OK) < 0) + if (mkdir(path, 0777) < 0) + sysbail("error creating temporary directory %s", path); + return path; +} + +/* + * Free a path returned from test_tmpdir() and attempt to remove the + * directory. If we can't delete the directory, don't worry; something else + * that hasn't yet cleaned up may still be using it. + */ +void +test_tmpdir_free(char *path) +{ + rmdir(path); + if (path != NULL) + free(path); +} diff --git a/tests/tap/basic.h b/tests/tap/basic.h new file mode 100644 index 0000000..2e1b7e3 --- /dev/null +++ b/tests/tap/basic.h @@ -0,0 +1,132 @@ +/* + * Basic utility routines for the TAP protocol. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu> + * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012 + * The Board of Trustees of the Leland Stanford Junior University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "macros.h" +#include <stdarg.h> /* va_list */ +#include <sys/types.h> /* size_t */ + +/* + * Used for iterating through arrays. ARRAY_SIZE returns the number of + * elements in the array (useful for a < upper bound in a for loop) and + * ARRAY_END returns a pointer to the element past the end (ISO C99 makes it + * legal to refer to such a pointer as long as it's never dereferenced). + */ +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +#define ARRAY_END(array) (&(array)[ARRAY_SIZE(array)]) + +BEGIN_DECLS + +/* + * The test count. Always contains the number that will be used for the next + * test status. + */ +extern unsigned long testnum; + +/* Print out the number of tests and set standard output to line buffered. */ +void plan(unsigned long count); + +/* + * Prepare for lazy planning, in which the plan will be printed automatically + * at the end of the test program. + */ +void plan_lazy(void); + +/* Skip the entire test suite. Call instead of plan. */ +void skip_all(const char *format, ...) + __attribute__((__noreturn__, __format__(printf, 1, 2))); + +/* + * Basic reporting functions. The okv() function is the same as ok() but + * takes the test description as a va_list to make it easier to reuse the + * reporting infrastructure when writing new tests. + */ +void ok(int success, const char *format, ...) + __attribute__((__format__(printf, 2, 3))); +void okv(int success, const char *format, va_list args); +void skip(const char *reason, ...) + __attribute__((__format__(printf, 1, 2))); + +/* Report the same status on, or skip, the next count tests. */ +void ok_block(unsigned long count, int success, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +void skip_block(unsigned long count, const char *reason, ...) + __attribute__((__format__(printf, 2, 3))); + +/* Check an expected value against a seen value. */ +void is_int(long long wanted, long long seen, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +void is_string(const char *wanted, const char *seen, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +void is_hex(unsigned long long wanted, unsigned long long seen, + const char *format, ...) + __attribute__((__format__(printf, 3, 4))); + +/* Bail out with an error. sysbail appends strerror(errno). */ +void bail(const char *format, ...) + __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2))); +void sysbail(const char *format, ...) + __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2))); + +/* Report a diagnostic to stderr prefixed with #. */ +void diag(const char *format, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +void sysdiag(const char *format, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); + +/* Allocate memory, reporting a fatal error with bail on failure. */ +void *bcalloc(size_t, size_t) + __attribute__((__alloc_size__(1, 2), __malloc__)); +void *bmalloc(size_t) + __attribute__((__alloc_size__(1), __malloc__)); +void *brealloc(void *, size_t) + __attribute__((__alloc_size__(2), __malloc__)); +char *bstrdup(const char *) + __attribute__((__malloc__, __nonnull__)); +char *bstrndup(const char *, size_t) + __attribute__((__malloc__, __nonnull__)); + +/* + * Find a test file under BUILD or SOURCE, returning the full path. The + * returned path should be freed with test_file_path_free(). + */ +char *test_file_path(const char *file) + __attribute__((__malloc__, __nonnull__)); +void test_file_path_free(char *path); + +/* + * Create a temporary directory relative to BUILD and return the path. The + * returned path should be freed with test_tmpdir_free. + */ +char *test_tmpdir(void) + __attribute__((__malloc__)); +void test_tmpdir_free(char *path); + +END_DECLS diff --git a/tests/tap/files.c b/tests/tap/files.c new file mode 100644 index 0000000..2e67e9e --- /dev/null +++ b/tests/tap/files.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "files.h" + +#include "../../src/contrib/string.c" +#include "../../src/contrib/files.c" + +#include <stdlib.h> + +static char *make_temp(bool is_directory) +{ + char *tmpdir = getenv("TMPDIR"); + if (!tmpdir) { + tmpdir = "/tmp"; + } + + char tmp[4096] = { 0 }; + int r = snprintf(tmp, sizeof(tmp), "%s/knot_unit.XXXXXX", tmpdir); + if (r <= 0 || r >= sizeof(tmp)) { + return NULL; + } + + if (is_directory) { + char *ret = mkdtemp(tmp); + if (ret == NULL) { + return NULL; + } + } else { + int ret = mkstemp(tmp); + if (ret == -1) { + return NULL; + } + close(ret); + } + + return strdup(tmp); +} + +char *test_mktemp(void) +{ + return make_temp(false); +} + +char *test_mkdtemp(void) +{ + return make_temp(true); +} + +bool test_rm_rf(const char *path) +{ + return remove_path(path); +} diff --git a/tests/tap/files.h b/tests/tap/files.h new file mode 100644 index 0000000..bfc6090 --- /dev/null +++ b/tests/tap/files.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <stdbool.h> + +/*! + * \brief Create a temporary file. + * + * If TMPDIR environment variable is set, the file is created within + * that directory. If the variable is not set, the file is created + * within /tmp. + */ +char *test_mktemp(void); + +/*! + * \brief Create a temporary directory. + * + * If TMPDIR environment variable is set, the directory is created within + * that directory. If the variable is not set, the directory is created + * within /tmp. + */ +char *test_mkdtemp(void); + +/*! + * \brief Delete file or directory (recursive). + * + * \return true on success, false when one or more files failed to be removed. + */ +bool test_rm_rf(const char *path); diff --git a/tests/tap/float.c b/tests/tap/float.c new file mode 100644 index 0000000..5c0c643 --- /dev/null +++ b/tests/tap/float.c @@ -0,0 +1,67 @@ +/* + * Utility routines for writing floating point tests. + * + * Currently provides only one function, which checks whether a double is + * equal to an expected value within a given epsilon. This is broken into a + * separate source file from the rest of the basic C TAP library because it + * may require linking with -lm on some platforms, and the package may not + * otherwise care about floating point. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2008, 2010, 2012 Russ Allbery <rra@stanford.edu> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Required for isnan() and isinf(). */ +#if defined(__STRICT_ANSI__) || defined(PEDANTIC) +# ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 600 +# endif +#endif + +#include <math.h> +#include <stdarg.h> +#include <stdio.h> + +#include "basic.h" +#include "float.h" + +/* + * Takes an expected double and a seen double and assumes the test passes if + * those two numbers are within delta of each other. + */ +void +is_double(double wanted, double seen, double epsilon, const char *format, ...) +{ + va_list args; + + va_start(args, format); + fflush(stderr); + if ((isnan(wanted) && isnan(seen)) + || (isinf(wanted) && isinf(seen) && wanted == seen) + || fabs(wanted - seen) <= epsilon) + okv(1, format, args); + else { + printf("# wanted: %g\n# seen: %g\n", wanted, seen); + okv(0, format, args); + } +} diff --git a/tests/tap/float.h b/tests/tap/float.h new file mode 100644 index 0000000..5c58b5b --- /dev/null +++ b/tests/tap/float.h @@ -0,0 +1,39 @@ +/* + * Floating point check function for the TAP protocol. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2008, 2010, 2012 Russ Allbery <rra@stanford.edu> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "macros.h" + +BEGIN_DECLS + +/* Check an expected value against a seen value within epsilon. */ +void is_double(double wanted, double seen, double epsilon, + const char *format, ...) + __attribute__((__format__(printf, 4, 5))); + +END_DECLS diff --git a/tests/tap/libtap.sh b/tests/tap/libtap.sh new file mode 100644 index 0000000..0ffab2d --- /dev/null +++ b/tests/tap/libtap.sh @@ -0,0 +1,246 @@ +# Shell function library for test cases. +# +# Note that while many of the functions in this library could benefit from +# using "local" to avoid possibly hammering global variables, Solaris /bin/sh +# doesn't support local and this library aspires to be portable to Solaris +# Bourne shell. Instead, all private variables are prefixed with "tap_". +# +# This file provides a TAP-compatible shell function library useful for +# writing test cases. It is part of C TAP Harness, which can be found at +# <http://www.eyrie.org/~eagle/software/c-tap-harness/>. +# +# Written by Russ Allbery <rra@stanford.edu> +# Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu> +# Copyright 2006, 2007, 2008, 2013 +# The Board of Trustees of the Leland Stanford Junior University +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Print out the number of test cases we expect to run. +plan () { + count=1 + planned="$1" + failed=0 + echo "1..$1" + trap finish 0 +} + +# Prepare for lazy planning. +plan_lazy () { + count=1 + planned=0 + failed=0 + trap finish 0 +} + +# Report the test status on exit. +finish () { + tap_highest=`expr "$count" - 1` + if [ "$planned" = 0 ] ; then + echo "1..$tap_highest" + planned="$tap_highest" + fi + tap_looks='# Looks like you' + if [ "$planned" -gt 0 ] ; then + if [ "$planned" -gt "$tap_highest" ] ; then + if [ "$planned" -gt 1 ] ; then + echo "$tap_looks planned $planned tests but only ran" \ + "$tap_highest" + else + echo "$tap_looks planned $planned test but only ran" \ + "$tap_highest" + fi + elif [ "$planned" -lt "$tap_highest" ] ; then + tap_extra=`expr "$tap_highest" - "$planned"` + if [ "$planned" -gt 1 ] ; then + echo "$tap_looks planned $planned tests but ran" \ + "$tap_extra extra" + else + echo "$tap_looks planned $planned test but ran" \ + "$tap_extra extra" + fi + elif [ "$failed" -gt 0 ] ; then + if [ "$failed" -gt 1 ] ; then + echo "$tap_looks failed $failed tests of $planned" + else + echo "$tap_looks failed $failed test of $planned" + fi + elif [ "$planned" -gt 1 ] ; then + echo "# All $planned tests successful or skipped" + else + echo "# $planned test successful or skipped" + fi + fi +} + +# Skip the entire test suite. Should be run instead of plan. +skip_all () { + tap_desc="$1" + if [ -n "$tap_desc" ] ; then + echo "1..0 # skip $tap_desc" + else + echo "1..0 # skip" + fi + exit 0 +} + +# ok takes a test description and a command to run and prints success if that +# command is successful, false otherwise. The count starts at 1 and is +# updated each time ok is printed. +ok () { + tap_desc="$1" + if [ -n "$tap_desc" ] ; then + tap_desc=" - $tap_desc" + fi + shift + if "$@" ; then + echo ok "$count$tap_desc" + else + echo not ok "$count$tap_desc" + failed=`expr $failed + 1` + fi + count=`expr $count + 1` +} + +# Skip the next test. Takes the reason why the test is skipped. +skip () { + echo "ok $count # skip $*" + count=`expr $count + 1` +} + +# Report the same status on a whole set of tests. Takes the count of tests, +# the description, and then the command to run to determine the status. +ok_block () { + tap_i=$count + tap_end=`expr $count + $1` + shift + while [ "$tap_i" -lt "$tap_end" ] ; do + ok "$@" + tap_i=`expr $tap_i + 1` + done +} + +# Skip a whole set of tests. Takes the count and then the reason for skipping +# the test. +skip_block () { + tap_i=$count + tap_end=`expr $count + $1` + shift + while [ "$tap_i" -lt "$tap_end" ] ; do + skip "$@" + tap_i=`expr $tap_i + 1` + done +} + +# Portable variant of printf '%s\n' "$*". In the majority of cases, this +# function is slower than printf, because the latter is often implemented +# as a builtin command. The value of the variable IFS is ignored. +# +# This macro must not be called via backticks inside double quotes, since this +# will result in bizarre escaping behavior and lots of extra backslashes on +# Solaris. +puts () { + cat << EOH +$@ +EOH +} + +# Run a program expected to succeed, and print ok if it does and produces the +# correct output. Takes the description, expected exit status, the expected +# output, the command to run, and then any arguments for that command. +# Standard output and standard error are combined when analyzing the output of +# the command. +# +# If the command may contain system-specific error messages in its output, +# add strip_colon_error before the command to post-process its output. +ok_program () { + tap_desc="$1" + shift + tap_w_status="$1" + shift + tap_w_output="$1" + shift + tap_output=`"$@" 2>&1` + tap_status=$? + if [ $tap_status = $tap_w_status ] \ + && [ x"$tap_output" = x"$tap_w_output" ] ; then + ok "$tap_desc" true + else + echo "# saw: ($tap_status) $tap_output" + echo "# not: ($tap_w_status) $tap_w_output" + ok "$tap_desc" false + fi +} + +# Strip a colon and everything after it off the output of a command, as long +# as that colon comes after at least one whitespace character. (This is done +# to avoid stripping the name of the program from the start of an error +# message.) This is used to remove system-specific error messages (coming +# from strerror, for example). +strip_colon_error() { + tap_output=`"$@" 2>&1` + tap_status=$? + tap_output=`puts "$tap_output" | sed 's/^\([^ ]* [^:]*\):.*/\1/'` + puts "$tap_output" + return $tap_status +} + +# Bail out with an error message. +bail () { + echo 'Bail out!' "$@" + exit 255 +} + +# Output a diagnostic on standard error, preceded by the required # mark. +diag () { + echo '#' "$@" +} + +# Search for the given file first in $BUILD and then in $SOURCE and echo the +# path where the file was found, or the empty string if the file wasn't +# found. +# +# This macro uses puts, so don't run it using backticks inside double quotes +# or bizarre quoting behavior will happen with Solaris sh. +test_file_path () { + if [ -n "$BUILD" ] && [ -f "$BUILD/$1" ] ; then + puts "$BUILD/$1" + elif [ -n "$SOURCE" ] && [ -f "$SOURCE/$1" ] ; then + puts "$SOURCE/$1" + else + echo '' + fi +} + +# Create $BUILD/tmp for use by tests for storing temporary files and return +# the path (via standard output). +# +# This macro uses puts, so don't run it using backticks inside double quotes +# or bizarre quoting behavior will happen with Solaris sh. +test_tmpdir () { + if [ -z "$BUILD" ] ; then + tap_tmpdir="./tmp" + else + tap_tmpdir="$BUILD"/tmp + fi + if [ ! -d "$tap_tmpdir" ] ; then + mkdir "$tap_tmpdir" || bail "Error creating $tap_tmpdir" + fi + puts "$tap_tmpdir" +} diff --git a/tests/tap/macros.h b/tests/tap/macros.h new file mode 100644 index 0000000..31081a4 --- /dev/null +++ b/tests/tap/macros.h @@ -0,0 +1,85 @@ +/* + * Helpful macros for TAP header files. + * + * This is not, strictly speaking, related to TAP, but any TAP add-on is + * probably going to need these macros, so define them in one place so that + * everyone can pull them in. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2008, 2012 Russ Allbery <rra@stanford.edu> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/* + * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7 + * could you use the __format__ form of the attributes, which is what we use + * (to avoid confusion with other macros), and only with gcc 2.96 can you use + * the attribute __malloc__. 2.96 is very old, so don't bother trying to get + * the other attributes to work with GCC versions between 2.7 and 2.96. + */ +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) +# define __attribute__(spec) /* empty */ +# endif +#endif + +/* + * We use __alloc_size__, but it was only available in fairly recent versions + * of GCC. Suppress warnings about the unknown attribute if GCC is too old. + * We know that we're GCC at this point, so we can use the GCC variadic macro + * extension, which will still work with versions of GCC too old to have C99 + * variadic macro support. + */ +#if !defined(__attribute__) && !defined(__alloc_size__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define __alloc_size__(spec, args...) /* empty */ +# endif +#endif + +/* + * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ + * settings that GCC does. For them, suppress warnings about unknown + * attributes on declarations. This unfortunately will affect the entire + * compilation context, but there's no push and pop available. + */ +#if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__)) +# pragma GCC diagnostic ignored "-Wattributes" +#endif + +/* Used for unused parameters to silence gcc warnings. */ +/* #define UNUSED __attribute__((__unused__)) */ + +/* + * BEGIN_DECLS is used at the beginning of declarations so that C++ + * compilers don't mangle their names. END_DECLS is used at the end. + */ +#undef BEGIN_DECLS +#undef END_DECLS +#ifdef __cplusplus +# define BEGIN_DECLS extern "C" { +# define END_DECLS } +#else +# define BEGIN_DECLS /* empty */ +# define END_DECLS /* empty */ +#endif diff --git a/tests/tap/runtests.c b/tests/tap/runtests.c new file mode 100644 index 0000000..0464fbb --- /dev/null +++ b/tests/tap/runtests.c @@ -0,0 +1,1393 @@ +/* + * Run a set of tests, reporting results. + * + * Usage: + * + * runtests [-b <build-dir>] [-s <source-dir>] <test-list> + * runtests -o [-b <build-dir>] [-s <source-dir>] <test> + * + * In the first case, expects a list of executables located in the given file, + * one line per executable. For each one, runs it as part of a test suite, + * reporting results. Test output should start with a line containing the + * number of tests (numbered from 1 to this number), optionally preceded by + * "1..", although that line may be given anywhere in the output. Each + * additional line should be in the following format: + * + * ok <number> + * not ok <number> + * ok <number> # skip + * not ok <number> # todo + * + * where <number> is the number of the test. An optional comment is permitted + * after the number if preceded by whitespace. ok indicates success, not ok + * indicates failure. "# skip" and "# todo" are a special cases of a comment, + * and must start with exactly that formatting. They indicate the test was + * skipped for some reason (maybe because it doesn't apply to this platform) + * or is testing something known to currently fail. The text following either + * "# skip" or "# todo" and whitespace is the reason. + * + * As a special case, the first line of the output may be in the form: + * + * 1..0 # skip some reason + * + * which indicates that this entire test case should be skipped and gives a + * reason. + * + * Any other lines are ignored, although for compliance with the TAP protocol + * all lines other than the ones in the above format should be sent to + * standard error rather than standard output and start with #. + * + * This is a subset of TAP as documented in Test::Harness::TAP or + * TAP::Parser::Grammar, which comes with Perl. + * + * If the -o option is given, instead run a single test and display all of its + * output. This is intended for use with failing tests so that the person + * running the test suite can get more details about what failed. + * + * If built with the C preprocessor symbols SOURCE and BUILD defined, C TAP + * Harness will export those values in the environment so that tests can find + * the source and build directory and will look for tests under both + * directories. These paths can also be set with the -b and -s command-line + * options, which will override anything set at build time. + * + * Any bug reports, bug fixes, and improvements are very much welcome and + * should be sent to the e-mail address below. This program is part of C TAP + * Harness <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011 + * Russ Allbery <rra@stanford.edu> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +/* Required for fdopen(), getopt(), and putenv(). */ +#if defined(__STRICT_ANSI__) || defined(PEDANTIC) +# ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +# endif +#endif + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <time.h> +#include <unistd.h> + +/* sys/time.h must be included before sys/resource.h on some platforms. */ +#include <sys/resource.h> + +/* AIX doesn't have WCOREDUMP. */ +#ifndef WCOREDUMP +# define WCOREDUMP(status) ((unsigned)(status) & 0x80) +#endif + +/* + * Used for iterating through arrays. Returns the number of elements in the + * array (useful for a < upper bound in a for loop). + */ +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +/* + * The source and build versions of the tests directory. This is used to set + * the SOURCE and BUILD environment variables and find test programs, if set. + * Normally, this should be set as part of the build process to the test + * subdirectories of $(abs_top_srcdir) and $(abs_top_builddir) respectively. + */ +#ifndef SOURCE +# define SOURCE NULL +#endif +#ifndef BUILD +# define BUILD NULL +#endif + +/* Test status codes. */ +enum test_status { + TEST_FAIL, + TEST_PASS, + TEST_SKIP, + TEST_INVALID +}; + +/* Indicates the state of our plan. */ +enum plan_status { + PLAN_INIT, /* Nothing seen yet. */ + PLAN_FIRST, /* Plan seen before any tests. */ + PLAN_PENDING, /* Test seen and no plan yet. */ + PLAN_FINAL /* Plan seen after some tests. */ +}; + +/* Error exit statuses for test processes. */ +#define CHILDERR_DUP 100 /* Couldn't redirect stderr or stdout. */ +#define CHILDERR_EXEC 101 /* Couldn't exec child process. */ +#define CHILDERR_STDERR 102 /* Couldn't open stderr file. */ + +/* Structure to hold data for a set of tests. */ +struct testset { + char *file; /* The file name of the test. */ + char *path; /* The path to the test program. */ + enum plan_status plan; /* The status of our plan. */ + unsigned long count; /* Expected count of tests. */ + unsigned long current; /* The last seen test number. */ + unsigned int length; /* The length of the last status message. */ + unsigned long passed; /* Count of passing tests. */ + unsigned long failed; /* Count of failing lists. */ + unsigned long skipped; /* Count of skipped tests (passed). */ + unsigned long allocated; /* The size of the results table. */ + enum test_status *results; /* Table of results by test number. */ + unsigned int aborted; /* Whether the set was aborted. */ + int reported; /* Whether the results were reported. */ + int status; /* The exit status of the test. */ + unsigned int all_skipped; /* Whether all tests were skipped. */ + char *reason; /* Why all tests were skipped. */ +}; + +/* Structure to hold a linked list of test sets. */ +struct testlist { + struct testset *ts; + struct testlist *next; +}; + +/* + * Usage message. Should be used as a printf format with four arguments: the + * path to runtests, given three times, and the usage_description. This is + * split into variables to satisfy the pedantic ISO C90 limit on strings. + */ +static const char usage_message[] = "\ +Usage: %s [-b <build-dir>] [-s <source-dir>] <test> ...\n\ + %s [-b <build-dir>] [-s <source-dir>] -l <test-list> -L <log-file>\n\ + %s -o [-b <build-dir>] [-s <source-dir>] <test>\n\ +\n%s"; +static const char usage_extra[] = "\ +Options:\n\ + -b <build-dir> Set the build directory to <build-dir>\n\ + -l <list> Take the list of tests to run from <test-list>\n\ + -o Run a single test rather than a list of tests\n\ + -s <source-dir> Set the source directory to <source-dir>\n\ + -L <log-file> Set log file for a list of tests\n\ +\n\ +runtests normally runs each test listed on the command line. With the -l\n\ +option, it instead runs every test listed in a file. With the -o option,\n\ +it instead runs a single test and shows its complete output.\n"; + +/* + * Header used for test output. %s is replaced by the file name of the list + * of tests. + */ +static const char banner[] = "\n\ +Running all tests listed in %s. If any tests fail, run the failing\n\ +test program with runtests -o to see more details.\n\n"; + +/* Header for reports of failed tests. */ +static const char header[] = "\n\ +Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ +-------------------------- -------------- ---- ---- ------------------------"; + +/* Include the file name and line number in malloc failures. */ +#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__) +#define xmalloc(size) x_malloc((size), __FILE__, __LINE__) +#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__) +#define xstrdup(p) x_strdup((p), __FILE__, __LINE__) + +/* + * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7 + * could you use the __format__ form of the attributes, which is what we use + * (to avoid confusion with other macros). + */ +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __attribute__(spec) /* empty */ +# endif +#endif + +/* + * We use __alloc_size__, but it was only available in fairly recent versions + * of GCC. Suppress warnings about the unknown attribute if GCC is too old. + * We know that we're GCC at this point, so we can use the GCC variadic macro + * extension, which will still work with versions of GCC too old to have C99 + * variadic macro support. + */ +#if !defined(__attribute__) && !defined(__alloc_size__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define __alloc_size__(spec, args...) /* empty */ +# endif +#endif + +/* + * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ + * settings that GCC does. For them, suppress warnings about unknown + * attributes on declarations. This unfortunately will affect the entire + * compilation context, but there's no push and pop available. + */ +#if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__)) +# pragma GCC diagnostic ignored "-Wattributes" +#endif + +/* Declare internal functions that benefit from compiler attributes. */ +static void sysdie(const char *, ...) + __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2))); +static void *x_calloc(size_t, size_t, const char *, int) + __attribute__((__alloc_size__(1, 2), __malloc__, __nonnull__)); +static void *x_malloc(size_t, const char *, int) + __attribute__((__alloc_size__(1), __malloc__, __nonnull__)); +static void *x_realloc(void *, size_t, const char *, int) + __attribute__((__alloc_size__(2), __malloc__, __nonnull__(3))); +static char *x_strdup(const char *, const char *, int) + __attribute__((__malloc__, __nonnull__)); + +/* + * Report a fatal error, including the results of strerror, and exit. + */ +static void +sysdie(const char *format, ...) +{ + int oerrno; + va_list args; + + oerrno = errno; + fflush(stdout); + fprintf(stderr, "runtests: "); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, ": %s\n", strerror(oerrno)); + exit(1); +} + +/* + * Allocate zeroed memory, reporting a fatal error and exiting on failure. + */ +static void * +x_calloc(size_t n, size_t size, const char *file, int line) +{ + void *p; + + n = (n > 0) ? n : 1; + size = (size > 0) ? size : 1; + p = calloc(n, size); + if (p == NULL) + sysdie("failed to calloc %lu bytes at %s line %d", + (unsigned long) size, file, line); + return p; +} + +/* + * Allocate memory, reporting a fatal error and exiting on failure. + */ +static void * +x_malloc(size_t size, const char *file, int line) +{ + void *p; + + p = malloc(size); + if (p == NULL) + sysdie("failed to malloc %lu bytes at %s line %d", + (unsigned long) size, file, line); + return p; +} + +/* + * Reallocate memory, reporting a fatal error and exiting on failure. + */ +static void * +x_realloc(void *p, size_t size, const char *file, int line) +{ + p = realloc(p, size); + if (p == NULL) + sysdie("failed to realloc %lu bytes at %s line %d", + (unsigned long) size, file, line); + return p; +} + +/* + * Copy a string, reporting a fatal error and exiting on failure. + */ +static char * +x_strdup(const char *s, const char *file, int line) +{ + char *p; + size_t len; + + len = strlen(s) + 1; + p = malloc(len); + if (p == NULL) + sysdie("failed to strdup %lu bytes at %s line %d", + (unsigned long) len, file, line); + memcpy(p, s, len); + return p; +} + +/* + * Given a struct timeval, return the number of seconds it represents as a + * double. Use difftime() to convert a time_t to a double. + */ +static double +tv_seconds(const struct timeval *tv) +{ + return difftime(tv->tv_sec, 0) + tv->tv_usec * 1e-6; +} + +/* + * Given two struct timevals, return the difference in seconds. + */ +static double +tv_diff(const struct timeval *tv1, const struct timeval *tv0) +{ + return tv_seconds(tv1) - tv_seconds(tv0); +} + +/* + * Given two struct timevals, return the sum in seconds as a double. + */ +static double +tv_sum(const struct timeval *tv1, const struct timeval *tv2) +{ + return tv_seconds(tv1) + tv_seconds(tv2); +} + +/* + * Given a pointer to a string, skip any leading whitespace and return a + * pointer to the first non-whitespace character. + */ +static const char * +skip_whitespace(const char *p) +{ + while (isspace((unsigned char)(*p))) + p++; + return p; +} + +/* + * Start a program, connecting its stdout to a pipe on our end and its stderr + * to /dev/null, and storing the file descriptor to read from in the two + * argument. Returns the PID of the new process. Errors are fatal. + */ +static pid_t +test_start(const char *path, int *fd) +{ + int fds[2], errfd; + pid_t child; + + if (pipe(fds) == -1) { + puts("ABORTED"); + fflush(stdout); + sysdie("can't create pipe"); + } + child = fork(); + if (child == (pid_t) -1) { + puts("ABORTED"); + fflush(stdout); + sysdie("can't fork"); + } else if (child == 0) { + /* In child. Set up our stdout and stderr. */ + errfd = open("/dev/null", O_WRONLY); + if (errfd < 0) + _exit(CHILDERR_STDERR); + if (dup2(errfd, 2) == -1) + _exit(CHILDERR_DUP); + close(fds[0]); + if (dup2(fds[1], 1) == -1) + _exit(CHILDERR_DUP); + + /* Now, exec our process. */ + if (execl(path, path, (char *) 0) == -1) + _exit(CHILDERR_EXEC); + } else { + /* In parent. Close the extra file descriptor. */ + close(fds[1]); + } + *fd = fds[0]; + return child; +} + +/* + * Back up over the output saying what test we were executing. + */ +static void +test_backspace(struct testset *ts) +{ + unsigned int i; + + if (!isatty(STDOUT_FILENO)) + return; + for (i = 0; i < ts->length; i++) + putchar('\b'); + for (i = 0; i < ts->length; i++) + putchar(' '); + for (i = 0; i < ts->length; i++) + putchar('\b'); + ts->length = 0; +} + +/* + * Read the plan line of test output, which should contain the range of test + * numbers. We may initialize the testset structure here if we haven't yet + * seen a test. Return true if initialization succeeded and the test should + * continue, false otherwise. + */ +static int +test_plan(const char *line, struct testset *ts) +{ + unsigned long i; + long n; + + /* + * Accept a plan without the leading 1.. for compatibility with older + * versions of runtests. This will only be allowed if we've not yet seen + * a test result. + */ + line = skip_whitespace(line); + if (strncmp(line, "1..", 3) == 0) + line += 3; + + /* + * Get the count, check it for validity, and initialize the struct. If we + * have something of the form "1..0 # skip foo", the whole file was + * skipped; record that. If we do skip the whole file, zero out all of + * our statistics, since they're no longer relevant. strtol is called + * with a second argument to advance the line pointer past the count to + * make it simpler to detect the # skip case. + */ + n = strtol(line, (char **) &line, 10); + if (n == 0) { + line = skip_whitespace(line); + if (*line == '#') { + line = skip_whitespace(line + 1); + if (strncasecmp(line, "skip", 4) == 0) { + line = skip_whitespace(line + 4); + if (*line != '\0') { + ts->reason = xstrdup(line); + ts->reason[strlen(ts->reason) - 1] = '\0'; + } + ts->all_skipped = 1; + ts->aborted = 1; + ts->count = 0; + ts->passed = 0; + ts->skipped = 0; + ts->failed = 0; + return 0; + } + } + } + if (n <= 0) { + puts("ABORTED (invalid test count)"); + ts->aborted = 1; + ts->reported = 1; + return 0; + } + if (ts->plan == PLAN_INIT && ts->allocated == 0) { + ts->count = n; + ts->allocated = n; + ts->plan = PLAN_FIRST; + ts->results = xmalloc(ts->count * sizeof(enum test_status)); + for (i = 0; i < ts->count; i++) + ts->results[i] = TEST_INVALID; + } else if (ts->plan == PLAN_PENDING) { + if ((unsigned long) n < ts->count) { + test_backspace(ts); + printf("ABORTED (invalid test number %lu)\n", ts->count); + ts->aborted = 1; + ts->reported = 1; + return 0; + } + ts->count = n; + if ((unsigned long) n > ts->allocated) { + ts->results = xrealloc(ts->results, n * sizeof(enum test_status)); + for (i = ts->allocated; i < ts->count; i++) + ts->results[i] = TEST_INVALID; + ts->allocated = n; + } + ts->plan = PLAN_FINAL; + } + return 1; +} + +/* + * Given a single line of output from a test, parse it and return the success + * status of that test. Anything printed to stdout not matching the form + * /^(not )?ok \d+/ is ignored. Sets ts->current to the test number that just + * reported status. + */ +static void +test_checkline(const char *line, struct testset *ts) +{ + enum test_status status = TEST_PASS; + const char *bail; + char *end; + long number; + unsigned long i, current; + int outlen; + + /* Before anything, check for a test abort. */ + bail = strstr(line, "Bail out!"); + if (bail != NULL) { + bail = skip_whitespace(bail + strlen("Bail out!")); + if (*bail != '\0') { + size_t length; + + length = strlen(bail); + if (bail[length - 1] == '\n') + length--; + test_backspace(ts); + printf("ABORTED (%.*s)\n", (int) length, bail); + ts->reported = 1; + } + ts->aborted = 1; + return; + } + + /* + * If the given line isn't newline-terminated, it was too big for an + * fgets(), which means ignore it. + */ + if (line[strlen(line) - 1] != '\n') + return; + + /* If the line begins with a hash mark, ignore it. */ + if (line[0] == '#') + return; + + /* If we haven't yet seen a plan, look for one. */ + if (ts->plan == PLAN_INIT && isdigit((unsigned char)(*line))) { + if (!test_plan(line, ts)) + return; + } else if (strncmp(line, "1..", 3) == 0) { + if (ts->plan == PLAN_PENDING) { + if (!test_plan(line, ts)) + return; + } else { + test_backspace(ts); + puts("ABORTED (multiple plans)"); + ts->aborted = 1; + ts->reported = 1; + return; + } + } + + /* Parse the line, ignoring something we can't parse. */ + if (strncmp(line, "not ", 4) == 0) { + status = TEST_FAIL; + line += 4; + } + if (strncmp(line, "ok", 2) != 0) + return; + line = skip_whitespace(line + 2); + errno = 0; + number = strtol(line, &end, 10); + if (errno != 0 || end == line) + number = ts->current + 1; + current = number; + if (number <= 0 || (current > ts->count && ts->plan == PLAN_FIRST)) { + test_backspace(ts); + printf("ABORTED (invalid test number %lu)\n", current); + ts->aborted = 1; + ts->reported = 1; + return; + } + + /* We have a valid test result. Tweak the results array if needed. */ + if (ts->plan == PLAN_INIT || ts->plan == PLAN_PENDING) { + ts->plan = PLAN_PENDING; + if (current > ts->count) + ts->count = current; + if (current > ts->allocated) { + unsigned long n; + + n = (ts->allocated == 0) ? 32 : ts->allocated * 2; + if (n < current) + n = current; + ts->results = xrealloc(ts->results, n * sizeof(enum test_status)); + for (i = ts->allocated; i < n; i++) + ts->results[i] = TEST_INVALID; + ts->allocated = n; + } + } + + /* + * Handle directives. We should probably do something more interesting + * with unexpected passes of todo tests. + */ + while (isdigit((unsigned char)(*line))) + line++; + line = skip_whitespace(line); + if (*line == '#') { + line = skip_whitespace(line + 1); + if (strncasecmp(line, "skip", 4) == 0) + status = TEST_SKIP; + if (strncasecmp(line, "todo", 4) == 0) + status = (status == TEST_FAIL) ? TEST_SKIP : TEST_FAIL; + } + + /* Make sure that the test number is in range and not a duplicate. */ + if (ts->results[current - 1] != TEST_INVALID) { + test_backspace(ts); + printf("ABORTED (duplicate test number %lu)\n", current); + ts->aborted = 1; + ts->reported = 1; + return; + } + + /* Good results. Increment our various counters. */ + switch (status) { + case TEST_PASS: ts->passed++; break; + case TEST_FAIL: ts->failed++; break; + case TEST_SKIP: ts->skipped++; break; + case TEST_INVALID: break; + } + ts->current = current; + ts->results[current - 1] = status; + if (isatty(STDOUT_FILENO)) { + test_backspace(ts); + if (ts->plan == PLAN_PENDING) + outlen = printf("%lu/?", current); + else + outlen = printf("%lu/%lu", current, ts->count); + ts->length = (outlen >= 0) ? outlen : 0; + fflush(stdout); + } +} + +/* + * Print out a range of test numbers, returning the number of characters it + * took up. Takes the first number, the last number, the number of characters + * already printed on the line, and the limit of number of characters the line + * can hold. Add a comma and a space before the range if chars indicates that + * something has already been printed on the line, and print ... instead if + * chars plus the space needed would go over the limit (use a limit of 0 to + * disable this). + */ +static unsigned int +test_print_range(unsigned long first, unsigned long last, unsigned int chars, + unsigned int limit) +{ + unsigned int needed = 0; + unsigned long n; + + for (n = first; n > 0; n /= 10) + needed++; + if (last > first) { + for (n = last; n > 0; n /= 10) + needed++; + needed++; + } + if (chars > 0) + needed += 2; + if (limit > 0 && chars + needed > limit) { + needed = 0; + if (chars <= limit) { + if (chars > 0) { + printf(", "); + needed += 2; + } + printf("..."); + needed += 3; + } + } else { + if (chars > 0) + printf(", "); + if (last > first) + printf("%lu-", first); + printf("%lu", last); + } + return needed; +} + +/* + * Summarize a single test set. The second argument is 0 if the set exited + * cleanly, a positive integer representing the exit status if it exited + * with a non-zero status, and a negative integer representing the signal + * that terminated it if it was killed by a signal. + */ +static void +test_summarize(struct testset *ts, int status) +{ + unsigned long i; + unsigned long missing = 0; + unsigned long failed = 0; + unsigned long first = 0; + unsigned long last = 0; + + if (ts->aborted) { + fputs("ABORTED", stdout); + if (ts->count > 0) + printf(" (passed %lu/%lu)", ts->passed, ts->count - ts->skipped); + } else { + for (i = 0; i < ts->count; i++) { + if (ts->results[i] == TEST_INVALID) { + if (missing == 0) + fputs("MISSED ", stdout); + if (first && i == last) + last = i + 1; + else { + if (first) + test_print_range(first, last, missing - 1, 0); + missing++; + first = i + 1; + last = i + 1; + } + } + } + if (first) + test_print_range(first, last, missing - 1, 0); + first = 0; + last = 0; + for (i = 0; i < ts->count; i++) { + if (ts->results[i] == TEST_FAIL) { + if (missing && !failed) + fputs("; ", stdout); + if (failed == 0) + fputs("FAILED ", stdout); + if (first && i == last) + last = i + 1; + else { + if (first) + test_print_range(first, last, failed - 1, 0); + failed++; + first = i + 1; + last = i + 1; + } + } + } + if (first) + test_print_range(first, last, failed - 1, 0); + if (!missing && !failed) { + fputs(!status ? "ok" : "dubious", stdout); + if (ts->skipped > 0) { + if (ts->skipped == 1) + printf(" (skipped %lu test)", ts->skipped); + else + printf(" (skipped %lu tests)", ts->skipped); + } + } + } + if (status > 0) + printf(" (exit status %d)", status); + else if (status < 0) + printf(" (killed by signal %d%s)", -status, + WCOREDUMP(ts->status) ? ", core dumped" : ""); + putchar('\n'); +} + +/* + * Given a test set, analyze the results, classify the exit status, handle a + * few special error messages, and then pass it along to test_summarize() for + * the regular output. Returns true if the test set ran successfully and all + * tests passed or were skipped, false otherwise. + */ +static int +test_analyze(struct testset *ts) +{ + if (ts->reported) + return 0; + if (ts->all_skipped) { + if (ts->reason == NULL) + puts("skipped"); + else + printf("skipped (%s)\n", ts->reason); + return 1; + } else if (WIFEXITED(ts->status) && WEXITSTATUS(ts->status) != 0) { + switch (WEXITSTATUS(ts->status)) { + case CHILDERR_DUP: + if (!ts->reported) + puts("ABORTED (can't dup file descriptors)"); + break; + case CHILDERR_EXEC: + if (!ts->reported) + puts("ABORTED (execution failed -- not found?)"); + break; + case CHILDERR_STDERR: + if (!ts->reported) + puts("ABORTED (can't open /dev/null)"); + break; + default: + test_summarize(ts, WEXITSTATUS(ts->status)); + break; + } + return 0; + } else if (WIFSIGNALED(ts->status)) { + test_summarize(ts, -WTERMSIG(ts->status)); + return 0; + } else if (ts->plan != PLAN_FIRST && ts->plan != PLAN_FINAL) { + puts("ABORTED (no valid test plan)"); + ts->aborted = 1; + return 0; + } else { + test_summarize(ts, 0); + return (ts->failed == 0); + } +} + +static void +cond_fputs(const char *buffer, FILE *stream) +{ + if (!stream) { + return; + } + + fputs(buffer, stream); +} + +/* + * Runs a single test set, accumulating and then reporting the results. + * Returns true if the test set was successfully run and all tests passed, + * false otherwise. + */ +static int +test_run(struct testset *ts, FILE *logfile) +{ + pid_t testpid, child; + int outfd, status; + unsigned long i; + FILE *output; + char buffer[BUFSIZ]; + + /* Run the test program. */ + testpid = test_start(ts->path, &outfd); + output = fdopen(outfd, "r"); + if (!output) { + puts("ABORTED"); + fflush(stdout); + sysdie("fdopen failed"); + } + + /* Pass each line of output to test_checkline(). */ + while (!ts->aborted && fgets(buffer, sizeof(buffer), output)) { + cond_fputs(buffer, logfile); + test_checkline(buffer, ts); + } + if (ferror(output) || ts->plan == PLAN_INIT) + ts->aborted = 1; + test_backspace(ts); + + /* + * Consume the rest of the test output, close the output descriptor, + * retrieve the exit status, and pass that information to test_analyze() + * for eventual output. + */ + while (fgets(buffer, sizeof(buffer), output)) + ; + fclose(output); + child = waitpid(testpid, &ts->status, 0); + if (child == (pid_t) -1) { + if (!ts->reported) { + puts("ABORTED"); + fflush(stdout); + } + sysdie("waitpid for %u failed", (unsigned int) testpid); + } + if (ts->all_skipped) + ts->aborted = 0; + if (WEXITSTATUS(ts->status) > 0) + ts->failed++; + status = test_analyze(ts); + + /* Convert missing tests to failed tests. */ + for (i = 0; i < ts->count; i++) { + if (ts->results[i] == TEST_INVALID) { + ts->failed++; + ts->results[i] = TEST_FAIL; + status = 0; + } + } + return status; +} + +/* Summarize a list of test failures. */ +static void +test_fail_summary(const struct testlist *fails) +{ + struct testset *ts; + unsigned int chars; + unsigned long i, first, last, total; + + puts(header); + + /* Failed Set Fail/Total (%) Skip Stat Failing (25) + -------------------------- -------------- ---- ---- -------------- */ + for (; fails; fails = fails->next) { + ts = fails->ts; + total = ts->count - ts->skipped; + printf("%-26.26s %4lu/%-4lu %3.0f%% %4lu ", ts->file, ts->failed, + total, total ? (ts->failed * 100.0) / total : 0, + ts->skipped); + if (WIFEXITED(ts->status)) + printf("%4d ", WEXITSTATUS(ts->status)); + else + printf(" -- "); + if (ts->aborted) { + puts("aborted"); + continue; + } + chars = 0; + first = 0; + last = 0; + for (i = 0; i < ts->count; i++) { + if (ts->results[i] == TEST_FAIL) { + if (first != 0 && i == last) + last = i + 1; + else { + if (first != 0) + chars += test_print_range(first, last, chars, 19); + first = i + 1; + last = i + 1; + } + } + } + if (first != 0) + test_print_range(first, last, chars, 19); + putchar('\n'); + } +} + +/* + * Check whether a given file path is a valid test. Currently, this checks + * whether it is executable and is a regular file. Returns true or false. + */ +static int +is_valid_test(const char *path) +{ + struct stat st; + + if (access(path, X_OK) < 0) + return 0; + if (stat(path, &st) < 0) + return 0; + if (!S_ISREG(st.st_mode)) + return 0; + return 1; +} + +/* + * Given the name of a test, a pointer to the testset struct, and the source + * and build directories, find the test. We try first relative to the current + * directory, then in the build directory (if not NULL), then in the source + * directory. In each of those directories, we first try a "-t" extension and + * then a ".t" extension. When we find an executable program, we return the + * path to that program. If none of those paths are executable, just fill in + * the name of the test as is. + * + * The caller is responsible for freeing the path member of the testset + * struct. + */ +static char * +find_test(const char *name, const char *source, const char *build) +{ + char *path; + const char *bases[3], *suffix, *base; + unsigned int i, j; + const char *suffixes[3] = { "-t", ".t", "" }; + + /* Possible base directories. */ + bases[0] = "."; + bases[1] = build; + bases[2] = source; + + /* Try each suffix with each base. */ + for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + suffix = suffixes[i]; + for (j = 0; j < ARRAY_SIZE(bases); j++) { + unsigned int path_len; + + base = bases[j]; + if (base == NULL) + continue; + path_len = strlen(base) + strlen(name) + strlen(suffix) + 2; + path = xmalloc(path_len); + snprintf(path, path_len, "%s/%s%s", base, name, suffix); + if (is_valid_test(path)) + return path; + free(path); + path = NULL; + } + } + if (path == NULL) + path = xstrdup(name); + return path; +} + +/* + * Read a list of tests from a file, returning the list of tests as a struct + * testlist. Reports an error to standard error and exits if the list of + * tests cannot be read. + */ +static struct testlist * +read_test_list(const char *filename) +{ + FILE *file; + unsigned int line; + size_t length; + char buffer[BUFSIZ]; + struct testlist *listhead, *current; + + /* Create the initial container list that will hold our results. */ + listhead = xmalloc(sizeof(struct testlist)); + listhead->ts = NULL; + listhead->next = NULL; + current = NULL; + + /* + * Open our file of tests to run and read it line by line, creating a new + * struct testlist and struct testset for each line. + */ + file = fopen(filename, "r"); + if (file == NULL) + sysdie("can't open %s", filename); + line = 0; + while (fgets(buffer, sizeof(buffer), file)) { + line++; + length = strlen(buffer) - 1; + if (buffer[length] != '\n') { + fprintf(stderr, "%s:%u: line too long\n", filename, line); + exit(1); + } + buffer[length] = '\0'; + if (current == NULL) + current = listhead; + else { + current->next = xmalloc(sizeof(struct testlist)); + current = current->next; + current->next = NULL; + } + current->ts = xcalloc(1, sizeof(struct testset)); + current->ts->plan = PLAN_INIT; + current->ts->file = xstrdup(buffer); + current->ts->reason = NULL; + } + fclose(file); + + /* Return the results. */ + return listhead; +} + +/* + * Build a list of tests from command line arguments. Takes the argv and argc + * representing the command line arguments and returns a newly allocated test + * list. The caller is responsible for freeing. + */ +static struct testlist * +build_test_list(char *argv[], int argc) +{ + int i; + struct testlist *listhead, *current; + + /* Create the initial container list that will hold our results. */ + listhead = xmalloc(sizeof(struct testlist)); + listhead->ts = NULL; + listhead->next = NULL; + current = NULL; + + /* Walk the list of arguments and create test sets for them. */ + for (i = 0; i < argc; i++) { + if (current == NULL) + current = listhead; + else { + current->next = xmalloc(sizeof(struct testlist)); + current = current->next; + current->next = NULL; + } + current->ts = xcalloc(1, sizeof(struct testset)); + current->ts->plan = PLAN_INIT; + current->ts->file = xstrdup(argv[i]); + current->ts->reason = NULL; + } + + /* Return the results. */ + return listhead; +} + +/* Free a struct testset. */ +static void +free_testset(struct testset *ts) +{ + free(ts->file); + free(ts->path); + free(ts->results); + if (ts->reason != NULL) + free(ts->reason); + free(ts); +} + +/* + * Run a batch of tests. Takes two additional parameters: the root of the + * source directory and the root of the build directory. Test programs will + * be first searched for in the current directory, then the build directory, + * then the source directory. Returns true iff all tests passed, and always + * frees the test list that's passed in. + */ +static int +test_batch(struct testlist *tests, const char *source, const char *build, + const char *logfile_name) +{ + size_t length; + unsigned int i; + unsigned int longest = 0; + unsigned int count = 0; + struct testset *ts; + struct timeval start, end; + struct rusage stats; + struct testlist *failhead = NULL; + struct testlist *failtail = NULL; + struct testlist *current, *next; + int succeeded; + FILE *logfile = NULL; + unsigned long total = 0; + unsigned long passed = 0; + unsigned long skipped = 0; + unsigned long failed = 0; + unsigned long aborted = 0; + + /* Walk the list of tests to find the longest name. */ + for (current = tests; current != NULL; current = current->next) { + length = strlen(current->ts->file); + if (length > longest) + longest = length; + } + + /* + * Add two to longest and round up to the nearest tab stop. This is how + * wide the column for printing the current test name will be. + */ + longest += 2; + if (longest % 8) + longest += 8 - (longest % 8); + + /* Start the wall clock timer. */ + gettimeofday(&start, NULL); + + /* Open the log (soft error). */ + if (logfile_name != NULL) { + logfile = fopen(logfile_name, "w+"); + if (!logfile) { + fprintf(stderr, "Could not open the log file.\n"); + } + } + + /* Now, plow through our tests again, running each one. */ + for (current = tests; current != NULL; current = current->next) { + ts = current->ts; + + /* Print out the name of the test file. */ + fputs(ts->file, stdout); + for (i = strlen(ts->file); i < longest; i++) + putchar('.'); + if (isatty(STDOUT_FILENO)) + fflush(stdout); + + /* Run the test. */ + ts->path = find_test(ts->file, source, build); + succeeded = test_run(ts, logfile); + fflush(stdout); + + /* Record cumulative statistics. */ + aborted += ts->aborted; + total += ts->count + ts->all_skipped; + passed += ts->passed; + skipped += ts->skipped + ts->all_skipped; + failed += ts->failed; + count++; + + /* If the test fails, we shuffle it over to the fail list. */ + if (!succeeded) { + if (failhead == NULL) { + failhead = xmalloc(sizeof(struct testset)); + failtail = failhead; + } else { + failtail->next = xmalloc(sizeof(struct testset)); + failtail = failtail->next; + } + failtail->ts = ts; + failtail->next = NULL; + } + } + total -= skipped; + + /* Close the log. */ + if (logfile) { + fclose(logfile); + } + + /* Stop the timer and get our child resource statistics. */ + gettimeofday(&end, NULL); + getrusage(RUSAGE_CHILDREN, &stats); + + /* Summarize the failures and free the failure list. */ + if (failhead != NULL) { + test_fail_summary(failhead); + while (failhead != NULL) { + next = failhead->next; + free(failhead); + failhead = next; + } + } + + /* Free the memory used by the test lists. */ + while (tests != NULL) { + next = tests->next; + free_testset(tests->ts); + free(tests); + tests = next; + } + + /* Print out the final test summary. */ + putchar('\n'); + if (aborted != 0) { + if (aborted == 1) + printf("Aborted %lu test set", aborted); + else + printf("Aborted %lu test sets", aborted); + printf(", passed %lu/%lu tests", passed, total); + } + else if (failed == 0) + fputs("All tests successful", stdout); + else + printf("Failed %lu/%lu tests, %.2f%% okay", failed, total, + (total - failed) * 100.0 / total); + if (skipped != 0) { + if (skipped == 1) + printf(", %lu test skipped", skipped); + else + printf(", %lu tests skipped", skipped); + } + puts("."); + printf("Files=%u, Tests=%lu", count, total); + printf(", %.2f seconds", tv_diff(&end, &start)); + printf(" (%.2f usr + %.2f sys = %.2f CPU)\n", + tv_seconds(&stats.ru_utime), tv_seconds(&stats.ru_stime), + tv_sum(&stats.ru_utime, &stats.ru_stime)); + return (failed == 0 && aborted == 0); +} + +/* + * Run a single test case. This involves just running the test program after + * having done the environment setup and finding the test program. + */ +static void +test_single(const char *program, const char *source, const char *build) +{ + char *path; + + path = find_test(program, source, build); + if (execl(path, path, (char *) 0) == -1) + sysdie("cannot exec %s", path); +} + +/* + * Main routine. Set the SOURCE and BUILD environment variables and then, + * given a file listing tests, run each test listed. + */ +int +main(int argc, char *argv[]) +{ + int option; + int status = 0; + int single = 0; + char *source_env = NULL; + char *build_env = NULL; + const char *shortlist; + const char *list = NULL; + const char *source = SOURCE; + const char *build = BUILD; + const char *logfile = NULL; + struct testlist *tests; + + while ((option = getopt(argc, argv, "b:hl:os:L:")) != EOF) { + switch (option) { + case 'b': + build = optarg; + break; + case 'h': + printf(usage_message, argv[0], argv[0], argv[0], usage_extra); + exit(0); + break; + case 'l': + list = optarg; + break; + case 'o': + single = 1; + break; + case 's': + source = optarg; + break; + case 'L': + logfile = optarg; + break; + default: + exit(1); + } + } + argv += optind; + argc -= optind; + if ((list == NULL && argc < 1) || (list != NULL && argc > 0)) { + fprintf(stderr, usage_message, argv[0], argv[0], argv[0], usage_extra); + exit(1); + } + + /* Set SOURCE and BUILD environment variables. */ + if (source != NULL) { + unsigned int len = strlen("SOURCE=") + strlen(source) + 1; + source_env = xmalloc(len); + snprintf(source_env, len, "SOURCE=%s", source); + if (putenv(source_env) != 0) + sysdie("cannot set SOURCE in the environment"); + } + if (build != NULL) { + unsigned int len = strlen("BUILD=") + strlen(build) + 1; + build_env = xmalloc(len); + snprintf(build_env, len, "BUILD=%s", build); + if (putenv(build_env) != 0) + sysdie("cannot set BUILD in the environment"); + } + + /* Run the tests as instructed. */ + if (single) + test_single(argv[0], source, build); + else if (list != NULL) { + shortlist = strrchr(list, '/'); + if (shortlist == NULL) + shortlist = list; + else + shortlist++; + printf(banner, shortlist); + tests = read_test_list(list); + status = test_batch(tests, source, build, logfile) ? 0 : 1; + } else { + tests = build_test_list(argv, argc); + status = test_batch(tests, source, build, logfile) ? 0 : 1; + } + + /* For valgrind cleanliness, free all our memory. */ + if (source_env != NULL) { + putenv((char *) "SOURCE="); + free(source_env); + } + if (build_env != NULL) { + putenv((char *) "BUILD="); + free(build_env); + } + exit(status); +} diff --git a/tests/utils/test_cert.c b/tests/utils/test_cert.c new file mode 100644 index 0000000..3089116 --- /dev/null +++ b/tests/utils/test_cert.c @@ -0,0 +1,223 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/common/cert.h" +#include "libknot/error.h" + +#include <tap/basic.h> +#include <string.h> + +static const uint8_t CERT_DER[] = { + 0x30, 0x82, 0x06, 0xad, 0x30, 0x82, 0x05, 0x95, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x07, 0x06, 0xdb, 0x97, 0x5f, 0xf1, 0xa8, 0x9b, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, + 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, + 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, + 0x6e, 0x67, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x2f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x33, 0x30, 0x36, 0x30, 0x38, + 0x31, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x30, + 0x36, 0x30, 0x38, 0x31, 0x33, 0x31, 0x33, 0x5a, 0x30, 0x81, 0xa2, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x5a, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x48, + 0x6c, 0x61, 0x76, 0x6e, 0x69, 0x20, 0x6d, 0x65, 0x73, 0x74, 0x6f, 0x20, + 0x50, 0x72, 0x61, 0x68, 0x61, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x13, 0x11, 0x50, 0x72, 0x61, 0x68, 0x61, 0x20, 0x2d, 0x20, + 0x56, 0x69, 0x6e, 0x6f, 0x68, 0x72, 0x61, 0x64, 0x79, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x43, 0x5a, 0x2e, 0x4e, + 0x49, 0x43, 0x2c, 0x20, 0x7a, 0x2e, 0x73, 0x2e, 0x70, 0x2e, 0x6f, 0x2e, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x77, + 0x77, 0x77, 0x2e, 0x6b, 0x6e, 0x6f, 0x74, 0x2d, 0x64, 0x6e, 0x73, 0x2e, + 0x63, 0x7a, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x16, 0x68, 0x6f, 0x73, 0x74, 0x6d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x40, 0x6b, 0x6e, 0x6f, 0x74, 0x2d, 0x64, + 0x6e, 0x73, 0x2e, 0x63, 0x7a, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, + 0x01, 0x00, 0x9d, 0xa9, 0x87, 0x3b, 0x2e, 0xfa, 0xfd, 0xf6, 0x0b, 0x63, + 0xa8, 0x23, 0xc6, 0x66, 0x3d, 0x02, 0x9e, 0xf0, 0xa0, 0x83, 0x44, 0xbd, + 0x1a, 0xea, 0xee, 0xdd, 0xb3, 0x8d, 0xe6, 0xbd, 0xe1, 0xdc, 0xff, 0xf6, + 0xa9, 0x10, 0xdd, 0x0e, 0x3e, 0x6b, 0xb2, 0x8d, 0xa7, 0x52, 0x2b, 0xd4, + 0xff, 0xc6, 0x7a, 0x65, 0x23, 0x34, 0x02, 0x09, 0xc0, 0x17, 0xcc, 0x5d, + 0x47, 0x29, 0x9a, 0xac, 0x40, 0xdc, 0x8a, 0x3a, 0x65, 0xa3, 0xf5, 0x9f, + 0x1b, 0xaa, 0xaf, 0xdf, 0xab, 0xa7, 0xd3, 0x14, 0x86, 0xcc, 0xb8, 0x28, + 0x9a, 0x65, 0x33, 0xda, 0x22, 0xae, 0x62, 0x1a, 0x6b, 0xb7, 0x67, 0xdc, + 0xf0, 0x8c, 0xa3, 0xc1, 0x84, 0x1e, 0xf2, 0xcc, 0xf3, 0xe5, 0xfe, 0xf4, + 0xd8, 0x90, 0x50, 0xbc, 0x9d, 0x77, 0xc9, 0x4d, 0xb9, 0x8c, 0xfe, 0xff, + 0x33, 0x02, 0x7c, 0x4f, 0xb1, 0x3d, 0x66, 0x30, 0x97, 0xa3, 0xe0, 0x54, + 0xc1, 0x3f, 0x4a, 0xd8, 0x3a, 0xa7, 0xcb, 0xe8, 0x16, 0x37, 0x72, 0xb3, + 0x36, 0x90, 0x75, 0x1a, 0x2f, 0x95, 0x55, 0xb5, 0x10, 0x18, 0x29, 0xb0, + 0xee, 0x32, 0x8b, 0x3e, 0x02, 0x38, 0x5f, 0x53, 0xd6, 0x73, 0x41, 0x4c, + 0x1e, 0xae, 0xcf, 0x4f, 0x50, 0xa9, 0x71, 0xbc, 0x79, 0xa5, 0x9e, 0xd6, + 0x13, 0x07, 0xa3, 0xaa, 0x89, 0x0d, 0x31, 0x8c, 0x3a, 0x80, 0xe1, 0x53, + 0x22, 0x29, 0x43, 0xb9, 0xdf, 0xf6, 0xfb, 0x6d, 0xad, 0xbd, 0xf8, 0xc3, + 0xee, 0xbe, 0x59, 0xd0, 0x06, 0x45, 0x35, 0x95, 0xce, 0xcb, 0x61, 0xd9, + 0x74, 0x9e, 0x90, 0x96, 0xb8, 0xd6, 0xb2, 0xc9, 0x29, 0xfd, 0x45, 0xaf, + 0xea, 0xbe, 0x7b, 0x96, 0x76, 0x59, 0xe8, 0x04, 0x05, 0x5c, 0x8e, 0xc1, + 0xb3, 0x7c, 0xeb, 0xd8, 0xc8, 0x3d, 0x84, 0x13, 0x50, 0x07, 0x6f, 0xff, + 0x27, 0x69, 0xcb, 0x33, 0x62, 0x87, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x02, 0xfa, 0x30, 0x82, 0x02, 0xf6, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xa8, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x86, 0x4e, 0x14, 0x78, 0x0e, 0x5d, 0x44, 0x21, 0xe0, 0x80, 0x23, + 0x6b, 0x1f, 0x9b, 0xf2, 0xd6, 0x09, 0xc5, 0x50, 0xa6, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x11, 0xdb, + 0x23, 0x45, 0xfd, 0x54, 0xcc, 0x6a, 0x71, 0x6f, 0x84, 0x8a, 0x03, 0xd7, + 0xbe, 0xf7, 0x01, 0x2f, 0x26, 0x86, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, + 0x11, 0x04, 0x2f, 0x30, 0x2d, 0x82, 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x6b, + 0x6e, 0x6f, 0x74, 0x2d, 0x64, 0x6e, 0x73, 0x2e, 0x63, 0x7a, 0x82, 0x0b, + 0x6b, 0x6e, 0x6f, 0x74, 0x2d, 0x64, 0x6e, 0x73, 0x2e, 0x63, 0x7a, 0x82, + 0x0d, 0x2a, 0x2e, 0x6b, 0x6e, 0x6f, 0x74, 0x2d, 0x64, 0x6e, 0x73, 0x2e, + 0x63, 0x7a, 0x30, 0x82, 0x01, 0x56, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x82, 0x01, 0x4d, 0x30, 0x82, 0x01, 0x49, 0x30, 0x08, 0x06, 0x06, 0x67, + 0x81, 0x0c, 0x01, 0x02, 0x02, 0x30, 0x82, 0x01, 0x3b, 0x06, 0x0b, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x81, 0xb5, 0x37, 0x01, 0x02, 0x03, 0x30, 0x82, + 0x01, 0x2a, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x02, 0x01, 0x16, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, + 0x64, 0x66, 0x30, 0x81, 0xf7, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x02, 0x30, 0x81, 0xea, 0x30, 0x27, 0x16, 0x20, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x03, 0x02, 0x01, 0x01, 0x1a, + 0x81, 0xbe, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, + 0x41, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2c, 0x20, 0x72, 0x65, + 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, + 0x6e, 0x64, 0x65, 0x64, 0x20, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, + 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, + 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, + 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, + 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, + 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x74, 0x32, 0x2d, + 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0x8e, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0x81, 0x30, + 0x7f, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, + 0x73, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x75, 0x62, 0x2f, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x32, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x63, 0x61, + 0x30, 0x42, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, + 0x86, 0x36, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x69, 0x61, + 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x2e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x32, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x23, 0x06, 0x03, + 0x55, 0x1d, 0x12, 0x04, 0x1c, 0x30, 0x1a, 0x86, 0x18, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0xae, 0xea, 0xec, 0xe0, 0x6e, 0xe1, 0x5e, + 0xe3, 0x06, 0xe6, 0x09, 0xff, 0xf2, 0xea, 0xeb, 0xbd, 0xc2, 0xf9, 0xa2, + 0x79, 0xbb, 0xd1, 0xc3, 0x9c, 0x9f, 0xbd, 0x74, 0x0c, 0x9c, 0xeb, 0x73, + 0xf1, 0x5c, 0x57, 0x98, 0x8c, 0xaf, 0xaa, 0xfb, 0xcf, 0xfb, 0x55, 0x31, + 0x54, 0x71, 0x07, 0xdd, 0x7c, 0x83, 0x70, 0xcb, 0x12, 0xbf, 0x05, 0xd8, + 0x62, 0xf1, 0xe0, 0x9d, 0x1c, 0x35, 0xb2, 0x42, 0xb1, 0x37, 0xe8, 0x73, + 0x4c, 0xe5, 0xda, 0xd9, 0xcb, 0xe6, 0x5a, 0x50, 0x31, 0x14, 0xce, 0x50, + 0xc0, 0xfb, 0x68, 0xb9, 0xe6, 0x48, 0x24, 0xdd, 0x4f, 0xbe, 0x34, 0x28, + 0xba, 0x21, 0x53, 0x86, 0x86, 0x91, 0x6f, 0xb0, 0x8e, 0x34, 0x20, 0x4d, + 0xdf, 0xef, 0xf3, 0x6f, 0xb0, 0x78, 0x89, 0x4b, 0x80, 0x36, 0xe9, 0x75, + 0x3a, 0xd6, 0x18, 0xc6, 0x84, 0xe3, 0x0c, 0xa9, 0x24, 0xcb, 0x49, 0xaf, + 0x72, 0x09, 0x3a, 0xb5, 0xdd, 0x59, 0xb9, 0xe0, 0xb6, 0x7e, 0xc2, 0x3c, + 0xd0, 0xea, 0xeb, 0x39, 0x06, 0x3f, 0xc6, 0xe9, 0x1f, 0x37, 0x25, 0x3c, + 0xdf, 0x0d, 0x95, 0xcc, 0x9f, 0xa3, 0x68, 0x15, 0x3b, 0x80, 0x9b, 0x17, + 0x1a, 0x54, 0x65, 0x61, 0xb0, 0xcf, 0xb5, 0x76, 0x7c, 0xc2, 0x7e, 0x54, + 0x4d, 0x03, 0xe6, 0x90, 0xa0, 0x59, 0xa9, 0x1c, 0x6d, 0x4b, 0x34, 0x03, + 0xc3, 0xbb, 0xcd, 0x77, 0x60, 0x0e, 0xb1, 0x4e, 0x22, 0x81, 0xe4, 0x17, + 0xf4, 0xd2, 0x58, 0x2c, 0x72, 0x4e, 0xde, 0xd0, 0x24, 0x25, 0xfb, 0xd8, + 0x3f, 0xc8, 0x0f, 0x3b, 0x0d, 0xec, 0x75, 0x81, 0x37, 0x08, 0xd0, 0x0a, + 0x29, 0x28, 0x9f, 0x7f, 0x35, 0x83, 0x70, 0x18, 0x6c, 0x4b, 0x24, 0x8e, + 0xc0, 0xe5, 0xc1, 0xbb, 0x5b, 0x24, 0xb4, 0x5c, 0x8e, 0xbc, 0x79, 0xc0, + 0xad, 0x47, 0x17, 0xdd, 0x7a, 0xf2, 0x26, 0x6e, 0xe4 +}; + +static gnutls_x509_crt_t get_cert(void) +{ + gnutls_x509_crt_t cert = NULL; + if (gnutls_x509_crt_init(&cert) != 0) { + return NULL; + } + + const gnutls_datum_t der = { + .data = (uint8_t *)CERT_DER, + .size = sizeof(CERT_DER) + }; + if (gnutls_x509_crt_import(cert, &der, GNUTLS_X509_FMT_DER) != 0) { + gnutls_x509_crt_deinit(cert); + return NULL; + } + + return cert; +} + +void test_get_pin(void) +{ + gnutls_x509_crt_t cert = get_cert(); + ok(cert != NULL, "create testing certificate"); + + static const uint8_t expected[] = { + 0x35, 0xa2, 0x1a, 0x6b, 0x95, 0x34, 0x53, 0xed, 0xf7, 0xf7, + 0x08, 0x76, 0x08, 0x17, 0x9c, 0x4a, 0x16, 0x6e, 0xcf, 0xd5, + 0xff, 0x46, 0x71, 0x1d, 0xa8, 0x08, 0xb7, 0xef, 0x75, 0xaf, + 0xfd, 0xa0 + }; + + uint8_t pin[CERT_PIN_LEN] = { 0 }; + + int r = cert_get_pin(cert, NULL, 0); + ok(r == KNOT_EINVAL, "cert_get_pin(), no target buffer"); + + r = cert_get_pin(cert, pin, sizeof(pin) - 1); + ok(r == KNOT_EINVAL, "cert_get_pin(), invalid buffer size"); + + r = cert_get_pin(cert, pin, sizeof(pin)); + ok(r == KNOT_EOK && sizeof(pin) == sizeof(expected) && + memcmp(pin, expected, sizeof(pin)) == 0, + "cert_get_pin(), valid input"); + + gnutls_x509_crt_deinit(cert); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_get_pin(); + + return 0; +} diff --git a/tests/utils/test_lookup.c b/tests/utils/test_lookup.c new file mode 100644 index 0000000..111eb26 --- /dev/null +++ b/tests/utils/test_lookup.c @@ -0,0 +1,136 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/error.h" +#include "utils/common/lookup.h" + +static void check_search_ok(lookup_t *l, const char *in, const char *out) +{ + diag("Search for '%s'", in); + int ret = lookup_search(l, in, strlen(in)); + is_int(KNOT_EOK, ret, "Check found"); + ok(strcmp(out, l->found.key) == 0, "Compare key"); + ok(strcmp(out, l->found.data) == 0, "Compare data"); + ok(l->iter.first_key == NULL, "Compare no first key"); + ok(l->iter.count == 1, "Compare 1 count"); +} + +static void check_search_multi(lookup_t *l, const char *in, const char *out, + const char *first, size_t count) +{ + diag("Search for '%s'", in); + int ret = lookup_search(l, in, strlen(in)); + is_int(KNOT_EFEWDATA, ret, "Check found multi"); + ok(strcmp(out, l->found.key) == 0, "Compare key"); + ok(l->found.data == NULL, "Compare no data"); + ok(strcmp(first, l->iter.first_key) == 0, "Compare first key"); + ok(l->iter.count == count, "Compare count"); +} + +static void check_search_none(lookup_t *l, const char *in) +{ + diag("Search for '%s'", in); + int ret = lookup_search(l, in, strlen(in)); + is_int(KNOT_ENOENT, ret, "Check not found"); + ok(l->found.key == NULL, "Check no key"); + ok(l->found.data == NULL, "Check no data"); +} + +static void init(lookup_t *l, const char **table) +{ + int ret = lookup_init(l); + is_int(KNOT_EOK, ret, "Init"); + + while (*table != NULL) { + ret = lookup_insert(l, *table, (void *)*table); + is_int(KNOT_EOK, ret, "Insert '%s'", *table); + table++; + } +} + +static void test_search_basic(void) +{ + const char* table[] = { + "aa", + "bb", + NULL + }; + + lookup_t l; + init(&l, table); + + check_search_ok(&l, "a", "aa"); + check_search_ok(&l, "aa", "aa"); + check_search_ok(&l, "b", "bb"); + check_search_ok(&l, "bb", "bb"); + + check_search_none(&l, "0"); + check_search_none(&l, "000"); + check_search_none(&l, "00000000000000000000000000000000000000000000"); + check_search_none(&l, "a0"); + check_search_none(&l, "ab"); + check_search_none(&l, "aaa"); + check_search_none(&l, "bbb"); + check_search_none(&l, "cc"); + check_search_none(&l, "ccc"); + check_search_none(&l, "cccccccccccccccccccccccccccccccccccccccccccc"); + + check_search_multi(&l, "", "", "aa", 2); + + lookup_deinit(&l); +} + +static void test_search_iter(void) +{ + const char* table[] = { + "0", + "ab", + "abc", + "abcd", + "abc-1", + "abc-99", + "z", + NULL + }; + + lookup_t l; + init(&l, table); + + check_search_multi(&l, "", "", "0", 7); + check_search_multi(&l, "a", "ab", "ab", 5); + check_search_multi(&l, "ab", "ab", "ab", 5); + check_search_multi(&l, "abc", "abc", "abc", 4); + check_search_multi(&l, "abc-", "abc-", "abc-1", 2); + + lookup_deinit(&l); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("Search tests basic"); + test_search_basic(); + + diag("Search tests multi-result"); + test_search_iter(); + + return 0; +} |