diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2018-05-12 11:54:35 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2018-05-12 11:54:35 +0000 |
commit | 15de2de8449b4f5063f93578ae68aa0bc79a205c (patch) | |
tree | f0a7e3230212205e7ff88a2900de97026940f63c /testcode | |
parent | 689b65913bba5320ef50befddf4743c6dafde873 (diff) |
Diffstat (limited to 'testcode')
-rwxr-xr-x | testcode/do-tests.sh | 2 | ||||
-rw-r--r-- | testcode/replay.c | 1 | ||||
-rw-r--r-- | testcode/streamtcp.c | 4 | ||||
-rw-r--r-- | testcode/testbound.c | 12 | ||||
-rw-r--r-- | testcode/unitauth.c | 858 | ||||
-rw-r--r-- | testcode/unitmain.c | 21 | ||||
-rw-r--r-- | testcode/unitmain.h | 2 | ||||
-rw-r--r-- | testcode/unitverify.c | 5 |
8 files changed, 902 insertions, 3 deletions
diff --git a/testcode/do-tests.sh b/testcode/do-tests.sh index e356d4fc312ca..dcf93907e3882 100755 --- a/testcode/do-tests.sh +++ b/testcode/do-tests.sh @@ -9,7 +9,7 @@ NEED_CURL='06-ianaports.tpkg root_anchor.tpkg' NEED_WHOAMI='07-confroot.tpkg' NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg stub_udp6.tpkg edns_cache.tpkg' NEED_NOMINGW='tcp_sigpipe.tpkg 07-confroot.tpkg 08-host-lib.tpkg fwd_ancil.tpkg' -NEED_DNSCRYPT_PROXY='dnscrypt_queries.tpkg' +NEED_DNSCRYPT_PROXY='dnscrypt_queries.tpkg dnscrypt_queries_chacha.tpkg' # test if dig and ldns-testns are available. test_tool_avail "dig" diff --git a/testcode/replay.c b/testcode/replay.c index b45bde8067298..085c314759fdf 100644 --- a/testcode/replay.c +++ b/testcode/replay.c @@ -488,6 +488,7 @@ replay_scenario_read(FILE* in, const char* name, int* lineno) return scen; } } + log_err("scenario read failed at line %d (no SCENARIO_END?)", *lineno); replay_scenario_delete(scen); return NULL; } diff --git a/testcode/streamtcp.c b/testcode/streamtcp.c index 34b5c02813692..f5eb8fc48b1da 100644 --- a/testcode/streamtcp.c +++ b/testcode/streamtcp.c @@ -143,7 +143,9 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id, edns.edns_present = 1; edns.bits = EDNS_DO; edns.udp_size = 4096; - attach_edns_record(buf, &edns); + if(sldns_buffer_capacity(buf) >= + sldns_buffer_limit(buf)+calc_edns_field_size(&edns)) + attach_edns_record(buf, &edns); } /* send it */ diff --git a/testcode/testbound.c b/testcode/testbound.c index 180b2c256a49f..20c99608fdd7f 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -78,6 +78,7 @@ testbound_usage(void) printf("-g detect GOST support (exit code 0 or 1)\n"); printf("-e detect ECDSA support (exit code 0 or 1)\n"); printf("-c detect CLIENT_SUBNET support (exit code 0 or 1)\n"); + printf("-i detect IPSECMOD support (exit code 0 or 1)\n"); printf("-s testbound self-test - unit test of testbound parts.\n"); printf("-o str unbound commandline options separated by spaces.\n"); printf("Version %s\n", PACKAGE_VERSION); @@ -281,7 +282,7 @@ main(int argc, char* argv[]) pass_argc = 1; pass_argv[0] = "unbound"; add_opts("-d", &pass_argc, pass_argv); - while( (c=getopt(argc, argv, "12egho:p:s")) != -1) { + while( (c=getopt(argc, argv, "12egciho:p:s")) != -1) { switch(c) { case 's': free(pass_argv[1]); @@ -337,6 +338,15 @@ main(int argc, char* argv[]) exit(1); #endif break; + case 'i': +#ifdef USE_IPSECMOD + printf("IPSECMOD supported\n"); + exit(0); +#else + printf("IPSECMOD not supported\n"); + exit(1); +#endif + break; case 'p': playback_file = optarg; break; diff --git a/testcode/unitauth.c b/testcode/unitauth.c new file mode 100644 index 0000000000000..f6c022aa03d70 --- /dev/null +++ b/testcode/unitauth.c @@ -0,0 +1,858 @@ +/* + * testcode/unitauth.c - unit test for authzone authoritative zone code. + * + * Copyright (c) 2017, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/** + * \file + * Unit test for auth zone code. + */ +#include "config.h" +#include "services/authzone.h" +#include "testcode/unitmain.h" +#include "util/regional.h" +#include "util/net_help.h" +#include "util/data/msgreply.h" +#include "services/cache/dns.h" +#include "sldns/str2wire.h" +#include "sldns/wire2str.h" +#include "sldns/sbuffer.h" + +/** verbosity for this test */ +static int vbmp = 0; + +/** struct for query and answer checks */ +struct q_ans { + /** zone to query (delegpt) */ + const char* zone; + /** query name, class, type */ + const char* query; + /** additional flags or "" */ + const char* flags; + /** expected answer to check against, multi-line string */ + const char* answer; +}; + +/** auth zone for test */ +static const char* zone_example_com = +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" +"example.com. 3600 IN A 10.0.0.1\n" +"example.com. 3600 IN NS ns.example.com.\n" +"example.com. 3600 IN MX 50 mail.example.com.\n" +"deep.ent.example.com. 3600 IN A 10.0.0.9\n" +"mail.example.com. 3600 IN A 10.0.0.4\n" +"ns.example.com. 3600 IN A 10.0.0.5\n" +"out.example.com. 3600 IN CNAME www.example.com.\n" +"plan.example.com. 3600 IN CNAME nonexist.example.com.\n" +"redir.example.com. 3600 IN DNAME redir.example.org.\n" +"sub.example.com. 3600 IN NS ns1.sub.example.com.\n" +"sub.example.com. 3600 IN NS ns2.sub.example.com.\n" +"ns1.sub.example.com. 3600 IN A 10.0.0.6\n" +"ns2.sub.example.com. 3600 IN AAAA 2001::7\n" +"*.wild.example.com. 3600 IN A 10.0.0.8\n" +"*.wild2.example.com. 3600 IN CNAME www.example.com.\n" +"*.wild3.example.com. 3600 IN A 10.0.0.8\n" +"*.wild3.example.com. 3600 IN MX 50 mail.example.com.\n" +"www.example.com. 3600 IN A 10.0.0.2\n" +"www.example.com. 3600 IN A 10.0.0.3\n" +"yy.example.com. 3600 IN TXT \"a\"\n" +"yy.example.com. 3600 IN TXT \"b\"\n" +"yy.example.com. 3600 IN TXT \"c\"\n" +"yy.example.com. 3600 IN TXT \"d\"\n" +"yy.example.com. 3600 IN TXT \"e\"\n" +"yy.example.com. 3600 IN TXT \"f\"\n" + +/* and some tests for RRSIGs (rrsig is www.nlnetlabs.nl copy) */ +/* normal: domain and 1 rrsig */ +"z1.example.com. 3600 IN A 10.0.0.10\n" +"z1.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +/* normal: domain and 2 rrsigs */ +"z2.example.com. 3600 IN A 10.0.0.10\n" +"z2.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +"z2.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n" +/* normal: domain and 3 rrsigs */ +"z3.example.com. 3600 IN A 10.0.0.10\n" +"z3.example.com. 3600 IN A 10.0.0.11\n" +"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n" +"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12356 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12356}\n" +/* just an RRSIG rrset with nothing else */ +"z4.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +/* just an RRSIG rrset with nothing else, 2 rrsigs */ +"z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +"z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n" +#if 0 /* comparison of file does not work on this part because duplicates */ + /* are removed and the rrsets are reordered */ +/* first rrsig, then A record */ +"z6.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +"z6.example.com. 3600 IN A 10.0.0.10\n" +/* first two rrsigs, then A record */ +"z7.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +"z7.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n" +"z7.example.com. 3600 IN A 10.0.0.10\n" +/* first two rrsigs, then two A records */ +"z8.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +"z8.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n" +"z8.example.com. 3600 IN A 10.0.0.10\n" +"z8.example.com. 3600 IN A 10.0.0.11\n" +/* duplicate RR, duplicate RRsig */ +"z9.example.com. 3600 IN A 10.0.0.10\n" +"z9.example.com. 3600 IN A 10.0.0.11\n" +"z9.example.com. 3600 IN A 10.0.0.10\n" +"z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +"z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n" +#endif /* if0 for duplicates and reordering */ +; + +/** queries for example.com: zone, query, flags, answer. end with NULL */ +static struct q_ans example_com_queries[] = { + { "example.com", "www.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"www.example.com. 3600 IN A 10.0.0.2\n" +"www.example.com. 3600 IN A 10.0.0.3\n" + }, + + { "example.com", "example.com. SOA", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"example.com. 3600 IN A 10.0.0.1\n" + }, + + { "example.com", "example.com. AAAA", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "example.com. NS", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"example.com. 3600 IN NS ns.example.com.\n" +";additional section\n" +"ns.example.com. 3600 IN A 10.0.0.5\n" + }, + + { "example.com", "example.com. MX", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"example.com. 3600 IN MX 50 mail.example.com.\n" +";additional section\n" +"mail.example.com. 3600 IN A 10.0.0.4\n" + }, + + { "example.com", "example.com. IN ANY", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" +"example.com. 3600 IN MX 50 mail.example.com.\n" +"example.com. 3600 IN A 10.0.0.1\n" + }, + + { "example.com", "nonexist.example.com. A", "", +";flags QR AA rcode NXDOMAIN\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "deep.ent.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"deep.ent.example.com. 3600 IN A 10.0.0.9\n" + }, + + { "example.com", "ent.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "below.deep.ent.example.com. A", "", +";flags QR AA rcode NXDOMAIN\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "mail.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"mail.example.com. 3600 IN A 10.0.0.4\n" + }, + + { "example.com", "ns.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"ns.example.com. 3600 IN A 10.0.0.5\n" + }, + + { "example.com", "out.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"out.example.com. 3600 IN CNAME www.example.com.\n" +"www.example.com. 3600 IN A 10.0.0.2\n" +"www.example.com. 3600 IN A 10.0.0.3\n" + }, + + { "example.com", "out.example.com. CNAME", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"out.example.com. 3600 IN CNAME www.example.com.\n" + }, + + { "example.com", "plan.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"plan.example.com. 3600 IN CNAME nonexist.example.com.\n" + }, + + { "example.com", "plan.example.com. CNAME", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"plan.example.com. 3600 IN CNAME nonexist.example.com.\n" + }, + + { "example.com", "redir.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "redir.example.com. DNAME", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"redir.example.com. 3600 IN DNAME redir.example.org.\n" + }, + + { "example.com", "abc.redir.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"redir.example.com. 3600 IN DNAME redir.example.org.\n" +"abc.redir.example.com. 0 IN CNAME abc.redir.example.org.\n" + }, + + { "example.com", "foo.abc.redir.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"redir.example.com. 3600 IN DNAME redir.example.org.\n" +"foo.abc.redir.example.com. 0 IN CNAME foo.abc.redir.example.org.\n" + }, + + { "example.com", "sub.example.com. NS", "", +";flags QR rcode NOERROR\n" +";authority section\n" +"sub.example.com. 3600 IN NS ns1.sub.example.com.\n" +"sub.example.com. 3600 IN NS ns2.sub.example.com.\n" +";additional section\n" +"ns1.sub.example.com. 3600 IN A 10.0.0.6\n" +"ns2.sub.example.com. 3600 IN AAAA 2001::7\n" + }, + + { "example.com", "sub.example.com. DS", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "www.sub.example.com. NS", "", +";flags QR rcode NOERROR\n" +";authority section\n" +"sub.example.com. 3600 IN NS ns1.sub.example.com.\n" +"sub.example.com. 3600 IN NS ns2.sub.example.com.\n" +";additional section\n" +"ns1.sub.example.com. 3600 IN A 10.0.0.6\n" +"ns2.sub.example.com. 3600 IN AAAA 2001::7\n" + }, + + { "example.com", "foo.abc.sub.example.com. NS", "", +";flags QR rcode NOERROR\n" +";authority section\n" +"sub.example.com. 3600 IN NS ns1.sub.example.com.\n" +"sub.example.com. 3600 IN NS ns2.sub.example.com.\n" +";additional section\n" +"ns1.sub.example.com. 3600 IN A 10.0.0.6\n" +"ns2.sub.example.com. 3600 IN AAAA 2001::7\n" + }, + + { "example.com", "ns1.sub.example.com. A", "", +";flags QR rcode NOERROR\n" +";authority section\n" +"sub.example.com. 3600 IN NS ns1.sub.example.com.\n" +"sub.example.com. 3600 IN NS ns2.sub.example.com.\n" +";additional section\n" +"ns1.sub.example.com. 3600 IN A 10.0.0.6\n" +"ns2.sub.example.com. 3600 IN AAAA 2001::7\n" + }, + + { "example.com", "ns1.sub.example.com. AAAA", "", +";flags QR rcode NOERROR\n" +";authority section\n" +"sub.example.com. 3600 IN NS ns1.sub.example.com.\n" +"sub.example.com. 3600 IN NS ns2.sub.example.com.\n" +";additional section\n" +"ns1.sub.example.com. 3600 IN A 10.0.0.6\n" +"ns2.sub.example.com. 3600 IN AAAA 2001::7\n" + }, + + { "example.com", "ns2.sub.example.com. A", "", +";flags QR rcode NOERROR\n" +";authority section\n" +"sub.example.com. 3600 IN NS ns1.sub.example.com.\n" +"sub.example.com. 3600 IN NS ns2.sub.example.com.\n" +";additional section\n" +"ns1.sub.example.com. 3600 IN A 10.0.0.6\n" +"ns2.sub.example.com. 3600 IN AAAA 2001::7\n" + }, + + { "example.com", "ns2.sub.example.com. AAAA", "", +";flags QR rcode NOERROR\n" +";authority section\n" +"sub.example.com. 3600 IN NS ns1.sub.example.com.\n" +"sub.example.com. 3600 IN NS ns2.sub.example.com.\n" +";additional section\n" +"ns1.sub.example.com. 3600 IN A 10.0.0.6\n" +"ns2.sub.example.com. 3600 IN AAAA 2001::7\n" + }, + + { "example.com", "wild.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "*.wild.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"*.wild.example.com. 3600 IN A 10.0.0.8\n" + }, + + { "example.com", "*.wild.example.com. AAAA", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "abc.wild.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"abc.wild.example.com. 3600 IN A 10.0.0.8\n" + }, + + { "example.com", "abc.wild.example.com. AAAA", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "foo.abc.wild.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"foo.abc.wild.example.com. 3600 IN A 10.0.0.8\n" + }, + + { "example.com", "foo.abc.wild.example.com. AAAA", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "wild2.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";authority section\n" +"example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" + }, + + { "example.com", "*.wild2.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"*.wild2.example.com. 3600 IN CNAME www.example.com.\n" +"www.example.com. 3600 IN A 10.0.0.2\n" +"www.example.com. 3600 IN A 10.0.0.3\n" + }, + + { "example.com", "abc.wild2.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"abc.wild2.example.com. 3600 IN CNAME www.example.com.\n" +"www.example.com. 3600 IN A 10.0.0.2\n" +"www.example.com. 3600 IN A 10.0.0.3\n" + }, + + { "example.com", "foo.abc.wild2.example.com. A", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"foo.abc.wild2.example.com. 3600 IN CNAME www.example.com.\n" +"www.example.com. 3600 IN A 10.0.0.2\n" +"www.example.com. 3600 IN A 10.0.0.3\n" + }, + + { "example.com", "abc.wild2.example.com. CNAME", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"abc.wild2.example.com. 3600 IN CNAME www.example.com.\n" + }, + + { "example.com", "abc.wild3.example.com. IN ANY", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"abc.wild3.example.com. 3600 IN MX 50 mail.example.com.\n" +"abc.wild3.example.com. 3600 IN A 10.0.0.8\n" + }, + + { "example.com", "yy.example.com. TXT", "", +";flags QR AA rcode NOERROR\n" +";answer section\n" +"yy.example.com. 3600 IN TXT \"a\"\n" +"yy.example.com. 3600 IN TXT \"b\"\n" +"yy.example.com. 3600 IN TXT \"c\"\n" +"yy.example.com. 3600 IN TXT \"d\"\n" +"yy.example.com. 3600 IN TXT \"e\"\n" +"yy.example.com. 3600 IN TXT \"f\"\n" + }, + + {NULL, NULL, NULL, NULL} +}; + +/** number of tmpfiles */ +static int tempno = 0; +/** number of deleted files */ +static int delno = 0; + +/** cleanup tmp files at exit */ +static void +tmpfilecleanup(void) +{ + int i; + char buf[256]; + for(i=0; i<tempno; i++) { + snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d", + (unsigned)getpid(), i); + if(vbmp) printf("cleanup: unlink %s\n", buf); + unlink(buf); + } +} + +/** create temp file, return (malloced) name string, write contents to it */ +static char* +create_tmp_file(const char* s) +{ + char buf[256]; + char *fname; + FILE *out; + size_t r; + snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d", + (unsigned)getpid(), tempno++); + fname = strdup(buf); + if(!fname) fatal_exit("out of memory"); + /* if no string, just make the name */ + if(!s) return fname; + /* if string, write to file */ + out = fopen(fname, "w"); + if(!out) fatal_exit("cannot open %s: %s", fname, strerror(errno)); + r = fwrite(s, 1, strlen(s), out); + if(r == 0) { + fatal_exit("write failed: %s", strerror(errno)); + } else if(r < strlen(s)) { + fatal_exit("write failed: too short (disk full?)"); + } + fclose(out); + return fname; +} + +/** delete temp file and free name string */ +static void +del_tmp_file(char* fname) +{ + unlink(fname); + free(fname); + delno++; + if(delno == tempno) { + /* deleted all outstanding files, back to start condition */ + tempno = 0; + delno = 0; + } +} + +/** Add zone from file for testing */ +static struct auth_zone* +addzone(struct auth_zones* az, const char* name, char* fname) +{ + struct auth_zone* z; + size_t nmlen; + uint8_t* nm = sldns_str2wire_dname(name, &nmlen); + if(!nm) fatal_exit("out of memory"); + lock_rw_wrlock(&az->lock); + z = auth_zone_create(az, nm, nmlen, LDNS_RR_CLASS_IN); + lock_rw_unlock(&az->lock); + if(!z) fatal_exit("cannot find zone"); + auth_zone_set_zonefile(z, fname); + + if(!auth_zone_read_zonefile(z)) { + fatal_exit("parse failure for auth zone %s", name); + } + lock_rw_unlock(&z->lock); + free(nm); + return z; +} + +/** check that file is the same as other file */ +static void +checkfile(char* f1, char *f2) +{ + char buf1[10240], buf2[10240]; + int line = 0; + FILE* i1, *i2; + i1 = fopen(f1, "r"); + if(!i1) fatal_exit("cannot open %s: %s", f1, strerror(errno)); + i2 = fopen(f2, "r"); + if(!i2) fatal_exit("cannot open %s: %s", f2, strerror(errno)); + + while(!feof(i1) && !feof(i2)) { + char* cp1, *cp2; + line++; + cp1 = fgets(buf1, (int)sizeof(buf1), i1); + cp2 = fgets(buf2, (int)sizeof(buf2), i2); + if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2))) + fatal_exit("fgets failed: %s", strerror(errno)); + if(strcmp(buf1, buf2) != 0) { + log_info("in files %s and %s:%d", f1, f2, line); + log_info("'%s'", buf1); + log_info("'%s'", buf2); + fatal_exit("files are not eqaul"); + } + } + unit_assert(feof(i1) && feof(i2)); + + fclose(i1); + fclose(i2); +} + +/** check that a zone (in string) can be read and reproduced */ +static void +check_read_exact(const char* name, const char* zone) +{ + struct auth_zones* az; + struct auth_zone* z; + char* fname, *outf; + if(vbmp) printf("check read zone %s\n", name); + fname = create_tmp_file(zone); + + az = auth_zones_create(); + unit_assert(az); + z = addzone(az, name, fname); + unit_assert(z); + outf = create_tmp_file(NULL); + if(!auth_zone_write_file(z, outf)) { + fatal_exit("write file failed for %s", fname); + } + checkfile(fname, outf); + + del_tmp_file(fname); + del_tmp_file(outf); + auth_zones_delete(az); +} + +/** parse q_ans structure for making query */ +static void +q_ans_parse(struct q_ans* q, struct regional* region, + struct query_info** qinfo, int* fallback, uint8_t** dp_nm, + size_t* dp_nmlen) +{ + int ret; + uint8_t buf[65535]; + size_t len, dname_len; + + /* parse flags */ + *fallback = 0; /* default fallback value */ + if(strstr(q->flags, "fallback")) + *fallback = 1; + + /* parse zone */ + *dp_nmlen = sizeof(buf); + if((ret=sldns_str2wire_dname_buf(q->zone, buf, dp_nmlen))!=0) + fatal_exit("cannot parse query dp zone %s : %s", q->zone, + sldns_get_errorstr_parse(ret)); + *dp_nm = regional_alloc_init(region, buf, *dp_nmlen); + if(!dp_nm) fatal_exit("out of memory"); + + /* parse query */ + len = sizeof(buf); + dname_len = 0; + if((ret=sldns_str2wire_rr_question_buf(q->query, buf, &len, &dname_len, + *dp_nm, *dp_nmlen, NULL, 0))!=0) + fatal_exit("cannot parse query %s : %s", q->query, + sldns_get_errorstr_parse(ret)); + *qinfo = (struct query_info*)regional_alloc_zero(region, + sizeof(**qinfo)); + if(!*qinfo) fatal_exit("out of memory"); + (*qinfo)->qname = regional_alloc_init(region, buf, dname_len); + if(!(*qinfo)->qname) fatal_exit("out of memory"); + (*qinfo)->qname_len = dname_len; + (*qinfo)->qtype = sldns_wirerr_get_type(buf, len, dname_len); + (*qinfo)->qclass = sldns_wirerr_get_class(buf, len, dname_len); +} + +/** print flags to string */ +static void +pr_flags(sldns_buffer* buf, uint16_t flags) +{ + char rcode[32]; + sldns_buffer_printf(buf, ";flags"); + if((flags&BIT_QR)!=0) sldns_buffer_printf(buf, " QR"); + if((flags&BIT_AA)!=0) sldns_buffer_printf(buf, " AA"); + if((flags&BIT_TC)!=0) sldns_buffer_printf(buf, " TC"); + if((flags&BIT_RD)!=0) sldns_buffer_printf(buf, " RD"); + if((flags&BIT_CD)!=0) sldns_buffer_printf(buf, " CD"); + if((flags&BIT_RA)!=0) sldns_buffer_printf(buf, " RA"); + if((flags&BIT_AD)!=0) sldns_buffer_printf(buf, " AD"); + if((flags&BIT_Z)!=0) sldns_buffer_printf(buf, " Z"); + sldns_wire2str_rcode_buf((int)(FLAGS_GET_RCODE(flags)), + rcode, sizeof(rcode)); + sldns_buffer_printf(buf, " rcode %s", rcode); + sldns_buffer_printf(buf, "\n"); +} + +/** print RRs to string */ +static void +pr_rrs(sldns_buffer* buf, struct reply_info* rep) +{ + char s[65536]; + size_t i, j; + struct packed_rrset_data* d; + log_assert(rep->rrset_count == rep->an_numrrsets + rep->ns_numrrsets + + rep->ar_numrrsets); + for(i=0; i<rep->rrset_count; i++) { + /* section heading */ + if(i == 0 && rep->an_numrrsets != 0) + sldns_buffer_printf(buf, ";answer section\n"); + else if(i == rep->an_numrrsets && rep->ns_numrrsets != 0) + sldns_buffer_printf(buf, ";authority section\n"); + else if(i == rep->an_numrrsets+rep->ns_numrrsets && + rep->ar_numrrsets != 0) + sldns_buffer_printf(buf, ";additional section\n"); + /* spool RRset */ + d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data; + for(j=0; j<d->count+d->rrsig_count; j++) { + if(!packed_rr_to_string(rep->rrsets[i], j, 0, + s, sizeof(s))) { + fatal_exit("could not rr_to_string %d", + (int)i); + } + sldns_buffer_printf(buf, "%s", s); + } + } +} + +/** create string for message */ +static char* +msgtostr(struct dns_msg* msg) +{ + char* str; + sldns_buffer* buf = sldns_buffer_new(65535); + if(!buf) fatal_exit("out of memory"); + pr_flags(buf, msg->rep->flags); + pr_rrs(buf, msg->rep); + + str = strdup((char*)sldns_buffer_begin(buf)); + if(!str) fatal_exit("out of memory"); + sldns_buffer_free(buf); + return str; +} + +/** find line diff between strings */ +static void +line_diff(const char* p, const char* q, const char* pdesc, const char* qdesc) +{ + char* pdup, *qdup, *pl, *ql; + int line = 1; + pdup = strdup(p); + qdup = strdup(q); + if(!pdup || !qdup) fatal_exit("out of memory"); + pl=pdup; + ql=qdup; + printf("linediff (<%s, >%s)\n", pdesc, qdesc); + while(pl && ql && *pl && *ql) { + char* ep = strchr(pl, '\n'); + char* eq = strchr(ql, '\n'); + /* terminate lines */ + if(ep) *ep = 0; + if(eq) *eq = 0; + /* printout */ + if(strcmp(pl, ql) == 0) { + printf("%3d %s\n", line, pl); + } else { + printf("%3d < %s\n", line, pl); + printf("%3d > %s\n", line, ql); + } + if(ep) *ep = '\n'; + if(eq) *eq = '\n'; + if(ep) pl = ep+1; + else pl = NULL; + if(eq) ql = eq+1; + else ql = NULL; + line++; + } + if(pl && *pl) { + printf("%3d < %s\n", line, pl); + } + if(ql && *ql) { + printf("%3d > %s\n", line, ql); + } + free(pdup); + free(qdup); +} + +/** make q_ans query */ +static void +q_ans_query(struct q_ans* q, struct auth_zones* az, struct query_info* qinfo, + struct regional* region, int expected_fallback, uint8_t* dp_nm, + size_t dp_nmlen) +{ + int ret, fallback = 0; + struct dns_msg* msg = NULL; + char* ans_str; + int oldv = verbosity; + /* increase verbosity to printout logic in authzone */ + if(vbmp) verbosity = 4; + ret = auth_zones_lookup(az, qinfo, region, &msg, &fallback, dp_nm, + dp_nmlen); + if(vbmp) verbosity = oldv; + + /* check the answer */ + ans_str = msgtostr(msg); + /* printout if vbmp */ + if(vbmp) printf("got (ret=%s%s):\n%s", + (ret?"ok":"fail"), (fallback?" fallback":""), ans_str); + /* check expected value for ret */ + if(expected_fallback && ret != 0) { + /* ret is zero on fallback */ + if(vbmp) printf("fallback expected, but " + "return value is not false\n"); + unit_assert(expected_fallback && ret == 0); + } + if(ret == 0) { + if(!expected_fallback) { + if(vbmp) printf("return value is false, " + "(unexpected)\n"); + } + unit_assert(expected_fallback); + } + /* check expected value for fallback */ + if(expected_fallback && !fallback) { + if(vbmp) printf("expected fallback, but fallback is no\n"); + } else if(!expected_fallback && fallback) { + if(vbmp) printf("expected no fallback, but fallback is yes\n"); + } + unit_assert( (expected_fallback&&fallback) || + (!expected_fallback&&!fallback)); + /* check answer string */ + if(strcmp(q->answer, ans_str) != 0) { + if(vbmp) printf("wanted:\n%s", q->answer); + line_diff(q->answer, ans_str, "wanted", "got"); + } + unit_assert(strcmp(q->answer, ans_str) == 0); + if(vbmp) printf("query ok\n\n"); + free(ans_str); +} + +/** check queries on a loaded zone */ +static void +check_az_q_ans(struct auth_zones* az, struct q_ans* queries) +{ + struct q_ans* q; + struct regional* region = regional_create(); + struct query_info* qinfo; + int fallback; + uint8_t* dp_nm; + size_t dp_nmlen; + for(q=queries; q->zone; q++) { + if(vbmp) printf("query %s: %s %s\n", q->zone, q->query, + q->flags); + q_ans_parse(q, region, &qinfo, &fallback, &dp_nm, &dp_nmlen); + q_ans_query(q, az, qinfo, region, fallback, dp_nm, dp_nmlen); + regional_free_all(region); + } + regional_destroy(region); +} + +/** check queries for a zone are returned as specified */ +static void +check_queries(const char* name, const char* zone, struct q_ans* queries) +{ + struct auth_zones* az; + struct auth_zone* z; + char* fname; + if(vbmp) printf("check queries %s\n", name); + fname = create_tmp_file(zone); + az = auth_zones_create(); + if(!az) fatal_exit("out of memory"); + z = addzone(az, name, fname); + if(!z) fatal_exit("could not read zone for queries test"); + del_tmp_file(fname); + + /* run queries and test them */ + check_az_q_ans(az, queries); + + auth_zones_delete(az); +} + +/** Test authzone read from file */ +static void +authzone_read_test(void) +{ + if(vbmp) printf("Testing read auth zone\n"); + check_read_exact("example.com", zone_example_com); +} + +/** Test authzone query from zone */ +static void +authzone_query_test(void) +{ + if(vbmp) printf("Testing query auth zone\n"); + check_queries("example.com", zone_example_com, example_com_queries); +} + +/** test authzone code */ +void +authzone_test(void) +{ + unit_show_feature("authzone"); + atexit(tmpfilecleanup); + authzone_read_test(); + authzone_query_test(); +} diff --git a/testcode/unitmain.c b/testcode/unitmain.c index fd56e64d3f5d8..d662991bab5de 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -403,6 +403,8 @@ config_tag_test(void) } #include "util/rtt.h" +#include "util/timehist.h" +#include "libunbound/unbound.h" /** test RTT code */ static void rtt_test(void) @@ -426,6 +428,8 @@ rtt_test(void) unit_assert( rtt_timeout(&r) > RTT_MIN_TIMEOUT-1); unit_assert( rtt_timeout(&r) < RTT_MAX_TIMEOUT+1); } + /* must be the same, timehist bucket is used in stats */ + unit_assert(UB_STATS_BUCKET_NUM == NUM_BUCKETS_HIST); } #include "services/cache/infra.h" @@ -623,6 +627,9 @@ respip_conf_actions_test(void) } unit_assert(respip_global_apply_cfg(set, &cfg)); verify_respip_set_actions(set, config_response_ip, clen); + + respip_set_delete(set); + config_deldblstrlist(cfg.respip_actions); } /** Per-view respip actions test; apply raw configuration with two views @@ -690,6 +697,12 @@ respip_view_conf_actions_test(void) unit_assert(v); verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2); lock_rw_unlock(&v->lock); + + views_delete(views); + free(cv1->name); + free(cv1); + free(cv2->name); + free(cv2); } typedef struct addr_data {char* ip; char* data;} addr_data_t; @@ -774,6 +787,8 @@ respip_conf_data_test(void) verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A); verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME); verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA); + + respip_set_delete(set); } /** Test per-view respip redirect w/ data directives */ @@ -810,6 +825,11 @@ respip_view_conf_data_test(void) 0, LDNS_RR_TYPE_CNAME); verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA); + lock_rw_unlock(&v->lock); + + views_delete(views); + free(cv->name); + free(cv); } /** respip unit tests */ @@ -865,6 +885,7 @@ main(int argc, char* argv[]) fatal_exit("could not init NSS"); #endif /* HAVE_SSL or HAVE_NSS*/ checklock_start(); + authzone_test(); neg_test(); rnd_test(); respip_test(); diff --git a/testcode/unitmain.h b/testcode/unitmain.h index d81b603b2f6b8..e5c6109a2aae0 100644 --- a/testcode/unitmain.h +++ b/testcode/unitmain.h @@ -78,5 +78,7 @@ void ecs_test(void); #endif /* CLIENT_SUBNET */ /** unit test for ldns functions */ void ldns_test(void); +/** unit test for auth zone functions */ +void authzone_test(void); #endif /* TESTCODE_UNITMAIN_H */ diff --git a/testcode/unitverify.c b/testcode/unitverify.c index 37994a377c28e..e5e5b0f7bacb0 100644 --- a/testcode/unitverify.c +++ b/testcode/unitverify.c @@ -537,6 +537,11 @@ verify_test(void) } dstest_file("testdata/test_ds.sha384"); #endif +#ifdef USE_ED25519 + if(dnskey_algo_id_is_supported(LDNS_ED25519)) { + verifytest_file("testdata/test_sigs.ed25519", "20170530140439"); + } +#endif #ifdef USE_SHA1 dstest_file("testdata/test_ds.sha1"); #endif |