1 /*
2  * testcode/unitauth.c - unit test for authzone authoritative zone code.
3  *
4  * Copyright (c) 2017, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36 /**
37  * \file
38  * Unit test for auth zone code.
39  */
40 #include "config.h"
41 #include "services/authzone.h"
42 #include "testcode/unitmain.h"
43 #include "util/regional.h"
44 #include "util/net_help.h"
45 #include "util/config_file.h"
46 #include "util/data/msgreply.h"
47 #include "services/cache/dns.h"
48 #include "sldns/str2wire.h"
49 #include "sldns/wire2str.h"
50 #include "sldns/sbuffer.h"
51 
52 /** verbosity for this test */
53 static int vbmp = 0;
54 
55 /** struct for query and answer checks */
56 struct q_ans {
57 	/** zone to query (delegpt) */
58 	const char* zone;
59 	/** query name, class, type */
60 	const char* query;
61 	/** additional flags or "" */
62 	const char* flags;
63 	/** expected answer to check against, multi-line string */
64 	const char* answer;
65 };
66 
67 /** auth zone for test */
68 static const char* zone_example_com =
69 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
70 "example.com.	3600	IN	A	10.0.0.1\n"
71 "example.com.	3600	IN	NS	ns.example.com.\n"
72 "example.com.	3600	IN	MX	50 mail.example.com.\n"
73 "deep.ent.example.com.	3600	IN	A	10.0.0.9\n"
74 "mail.example.com.	3600	IN	A	10.0.0.4\n"
75 "ns.example.com.	3600	IN	A	10.0.0.5\n"
76 "out.example.com.	3600	IN	CNAME	www.example.com.\n"
77 "plan.example.com.	3600	IN	CNAME	nonexist.example.com.\n"
78 "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
79 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
80 "obscured.redir2.example.com.	3600	IN	A	10.0.0.12\n"
81 "under2.redir2.example.com.	3600	IN	DNAME	redir3.example.net.\n"
82 "doubleobscured.under2.redir2.example.com.	3600	IN	A	10.0.0.13\n"
83 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
84 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
85 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
86 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
87 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
88 "obscured.sub2.example.com.	3600	IN	A	10.0.0.10\n"
89 "under.sub2.example.com.	3600	IN	NS	ns.under.sub2.example.com.\n"
90 "doubleobscured.under.sub2.example.com.	3600	IN	A	10.0.0.11\n"
91 "*.wild.example.com.	3600	IN	A	10.0.0.8\n"
92 "*.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
93 "*.wild3.example.com.	3600	IN	A	10.0.0.8\n"
94 "*.wild3.example.com.	3600	IN	MX	50 mail.example.com.\n"
95 "www.example.com.	3600	IN	A	10.0.0.2\n"
96 "www.example.com.	3600	IN	A	10.0.0.3\n"
97 "yy.example.com.	3600	IN	TXT	\"a\"\n"
98 "yy.example.com.	3600	IN	TXT	\"b\"\n"
99 "yy.example.com.	3600	IN	TXT	\"c\"\n"
100 "yy.example.com.	3600	IN	TXT	\"d\"\n"
101 "yy.example.com.	3600	IN	TXT	\"e\"\n"
102 "yy.example.com.	3600	IN	TXT	\"f\"\n"
103 
104 /* and some tests for RRSIGs (rrsig is www.nlnetlabs.nl copy) */
105 /* normal: domain and 1 rrsig */
106 "z1.example.com.	3600	IN	A	10.0.0.10\n"
107 "z1.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
108 /* normal: domain and 2 rrsigs */
109 "z2.example.com.	3600	IN	A	10.0.0.10\n"
110 "z2.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
111 "z2.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
112 /* normal: domain and 3 rrsigs */
113 "z3.example.com.	3600	IN	A	10.0.0.10\n"
114 "z3.example.com.	3600	IN	A	10.0.0.11\n"
115 "z3.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
116 "z3.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
117 "z3.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 12356 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
118 /* just an RRSIG rrset with nothing else */
119 "z4.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
120 /* just an RRSIG rrset with nothing else, 2 rrsigs */
121 "z5.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
122 "z5.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
123 #if 1 /* comparison of file does not work on this part because duplicates */
124       /* are removed and the rrsets are reordered */
125 "end_of_check.z6.example.com. 3600 IN 	A	10.0.0.10\n"
126 /* first rrsig, then A record */
127 "z6.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
128 "z6.example.com.	3600	IN	A	10.0.0.10\n"
129 /* first two rrsigs, then A record */
130 "z7.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
131 "z7.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
132 "z7.example.com.	3600	IN	A	10.0.0.10\n"
133 /* first two rrsigs, then two A records */
134 "z8.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
135 "z8.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
136 "z8.example.com.	3600	IN	A	10.0.0.10\n"
137 "z8.example.com.	3600	IN	A	10.0.0.11\n"
138 /* duplicate RR, duplicate RRsig */
139 "z9.example.com.	3600	IN	A	10.0.0.10\n"
140 "z9.example.com.	3600	IN	A	10.0.0.11\n"
141 "z9.example.com.	3600	IN	A	10.0.0.10\n"
142 "z9.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
143 "z9.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
144 /* different covered types, first RRSIGs then, RRs, then another RRSIG */
145 "zz10.example.com.	3600	IN	RRSIG	AAAA 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
146 "zz10.example.com.	3600	IN	RRSIG	A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
147 "zz10.example.com.	3600	IN	A	10.0.0.10\n"
148 "zz10.example.com.	3600	IN	RRSIG	CNAME 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
149 "zz10.example.com.	3600	IN	AAAA	::11\n"
150 #endif /* if0 for duplicates and reordering */
151 ;
152 
153 /** queries for example.com: zone, query, flags, answer. end with NULL */
154 static struct q_ans example_com_queries[] = {
155 	{ "example.com", "www.example.com. A", "",
156 ";flags QR AA rcode NOERROR\n"
157 ";answer section\n"
158 "www.example.com.	3600	IN	A	10.0.0.2\n"
159 "www.example.com.	3600	IN	A	10.0.0.3\n"
160 	},
161 
162 	{ "example.com", "example.com. SOA", "",
163 ";flags QR AA rcode NOERROR\n"
164 ";answer section\n"
165 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
166 	},
167 
168 	{ "example.com", "example.com. A", "",
169 ";flags QR AA rcode NOERROR\n"
170 ";answer section\n"
171 "example.com.	3600	IN	A	10.0.0.1\n"
172 	},
173 
174 	{ "example.com", "example.com. AAAA", "",
175 ";flags QR AA rcode NOERROR\n"
176 ";authority section\n"
177 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
178 	},
179 
180 	{ "example.com", "example.com. NS", "",
181 ";flags QR AA rcode NOERROR\n"
182 ";answer section\n"
183 "example.com.	3600	IN	NS	ns.example.com.\n"
184 ";additional section\n"
185 "ns.example.com.	3600	IN	A	10.0.0.5\n"
186 	},
187 
188 	{ "example.com", "example.com. MX", "",
189 ";flags QR AA rcode NOERROR\n"
190 ";answer section\n"
191 "example.com.	3600	IN	MX	50 mail.example.com.\n"
192 ";additional section\n"
193 "mail.example.com.	3600	IN	A	10.0.0.4\n"
194 	},
195 
196 	{ "example.com", "example.com. IN ANY", "",
197 ";flags QR AA rcode NOERROR\n"
198 ";answer section\n"
199 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
200 "example.com.	3600	IN	MX	50 mail.example.com.\n"
201 "example.com.	3600	IN	A	10.0.0.1\n"
202 	},
203 
204 	{ "example.com", "nonexist.example.com. A", "",
205 ";flags QR AA rcode NXDOMAIN\n"
206 ";authority section\n"
207 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
208 	},
209 
210 	{ "example.com", "deep.ent.example.com. A", "",
211 ";flags QR AA rcode NOERROR\n"
212 ";answer section\n"
213 "deep.ent.example.com.	3600	IN	A	10.0.0.9\n"
214 	},
215 
216 	{ "example.com", "ent.example.com. A", "",
217 ";flags QR AA rcode NOERROR\n"
218 ";authority section\n"
219 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
220 	},
221 
222 	{ "example.com", "below.deep.ent.example.com. A", "",
223 ";flags QR AA rcode NXDOMAIN\n"
224 ";authority section\n"
225 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
226 	},
227 
228 	{ "example.com", "mail.example.com. A", "",
229 ";flags QR AA rcode NOERROR\n"
230 ";answer section\n"
231 "mail.example.com.	3600	IN	A	10.0.0.4\n"
232 	},
233 
234 	{ "example.com", "ns.example.com. A", "",
235 ";flags QR AA rcode NOERROR\n"
236 ";answer section\n"
237 "ns.example.com.	3600	IN	A	10.0.0.5\n"
238 	},
239 
240 	{ "example.com", "out.example.com. A", "",
241 ";flags QR AA rcode NOERROR\n"
242 ";answer section\n"
243 "out.example.com.	3600	IN	CNAME	www.example.com.\n"
244 "www.example.com.	3600	IN	A	10.0.0.2\n"
245 "www.example.com.	3600	IN	A	10.0.0.3\n"
246 	},
247 
248 	{ "example.com", "out.example.com. CNAME", "",
249 ";flags QR AA rcode NOERROR\n"
250 ";answer section\n"
251 "out.example.com.	3600	IN	CNAME	www.example.com.\n"
252 	},
253 
254 	{ "example.com", "plan.example.com. A", "",
255 ";flags QR AA rcode NOERROR\n"
256 ";answer section\n"
257 "plan.example.com.	3600	IN	CNAME	nonexist.example.com.\n"
258 	},
259 
260 	{ "example.com", "plan.example.com. CNAME", "",
261 ";flags QR AA rcode NOERROR\n"
262 ";answer section\n"
263 "plan.example.com.	3600	IN	CNAME	nonexist.example.com.\n"
264 	},
265 
266 	{ "example.com", "redir.example.com. A", "",
267 ";flags QR AA rcode NOERROR\n"
268 ";authority section\n"
269 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
270 	},
271 
272 	{ "example.com", "redir.example.com. DNAME", "",
273 ";flags QR AA rcode NOERROR\n"
274 ";answer section\n"
275 "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
276 	},
277 
278 	{ "example.com", "abc.redir.example.com. A", "",
279 ";flags QR AA rcode NOERROR\n"
280 ";answer section\n"
281 "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
282 "abc.redir.example.com.	3600	IN	CNAME	abc.redir.example.org.\n"
283 	},
284 
285 	{ "example.com", "foo.abc.redir.example.com. A", "",
286 ";flags QR AA rcode NOERROR\n"
287 ";answer section\n"
288 "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
289 "foo.abc.redir.example.com.	3600	IN	CNAME	foo.abc.redir.example.org.\n"
290 	},
291 
292 	{ "example.com", "redir2.example.com. DNAME", "",
293 ";flags QR AA rcode NOERROR\n"
294 ";answer section\n"
295 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
296 	},
297 
298 	{ "example.com", "abc.redir2.example.com. A", "",
299 ";flags QR AA rcode NOERROR\n"
300 ";answer section\n"
301 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
302 "abc.redir2.example.com.	3600	IN	CNAME	abc.redir2.example.org.\n"
303 	},
304 
305 	{ "example.com", "obscured.redir2.example.com. A", "",
306 ";flags QR AA rcode NOERROR\n"
307 ";answer section\n"
308 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
309 "obscured.redir2.example.com.	3600	IN	CNAME	obscured.redir2.example.org.\n"
310 	},
311 
312 	{ "example.com", "under2.redir2.example.com. A", "",
313 ";flags QR AA rcode NOERROR\n"
314 ";answer section\n"
315 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
316 "under2.redir2.example.com.	3600	IN	CNAME	under2.redir2.example.org.\n"
317 	},
318 
319 	{ "example.com", "doubleobscured.under2.redir2.example.com. A", "",
320 ";flags QR AA rcode NOERROR\n"
321 ";answer section\n"
322 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
323 "doubleobscured.under2.redir2.example.com.	3600	IN	CNAME	doubleobscured.under2.redir2.example.org.\n"
324 	},
325 
326 	{ "example.com", "foo.doubleobscured.under2.redir2.example.com. A", "",
327 ";flags QR AA rcode NOERROR\n"
328 ";answer section\n"
329 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
330 "foo.doubleobscured.under2.redir2.example.com.	3600	IN	CNAME	foo.doubleobscured.under2.redir2.example.org.\n"
331 	},
332 
333 	{ "example.com", "foo.under2.redir2.example.com. A", "",
334 ";flags QR AA rcode NOERROR\n"
335 ";answer section\n"
336 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
337 "foo.under2.redir2.example.com.	3600	IN	CNAME	foo.under2.redir2.example.org.\n"
338 	},
339 
340 	{ "example.com", "sub.example.com. NS", "",
341 ";flags QR rcode NOERROR\n"
342 ";authority section\n"
343 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
344 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
345 ";additional section\n"
346 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
347 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
348 	},
349 
350 	{ "example.com", "sub.example.com. DS", "",
351 ";flags QR AA rcode NOERROR\n"
352 ";authority section\n"
353 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
354 	},
355 
356 	{ "example.com", "www.sub.example.com. NS", "",
357 ";flags QR rcode NOERROR\n"
358 ";authority section\n"
359 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
360 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
361 ";additional section\n"
362 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
363 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
364 	},
365 
366 	{ "example.com", "foo.abc.sub.example.com. NS", "",
367 ";flags QR rcode NOERROR\n"
368 ";authority section\n"
369 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
370 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
371 ";additional section\n"
372 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
373 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
374 	},
375 
376 	{ "example.com", "ns1.sub.example.com. A", "",
377 ";flags QR rcode NOERROR\n"
378 ";authority section\n"
379 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
380 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
381 ";additional section\n"
382 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
383 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
384 	},
385 
386 	{ "example.com", "ns1.sub.example.com. AAAA", "",
387 ";flags QR rcode NOERROR\n"
388 ";authority section\n"
389 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
390 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
391 ";additional section\n"
392 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
393 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
394 	},
395 
396 	{ "example.com", "ns2.sub.example.com. A", "",
397 ";flags QR rcode NOERROR\n"
398 ";authority section\n"
399 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
400 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
401 ";additional section\n"
402 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
403 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
404 	},
405 
406 	{ "example.com", "ns2.sub.example.com. AAAA", "",
407 ";flags QR rcode NOERROR\n"
408 ";authority section\n"
409 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
410 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
411 ";additional section\n"
412 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
413 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
414 	},
415 
416 	{ "example.com", "sub2.example.com. A", "",
417 ";flags QR rcode NOERROR\n"
418 ";authority section\n"
419 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
420 ";additional section\n"
421 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
422 	},
423 
424 	{ "example.com", "sub2.example.com. NS", "",
425 ";flags QR rcode NOERROR\n"
426 ";authority section\n"
427 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
428 ";additional section\n"
429 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
430 	},
431 
432 	{ "example.com", "obscured.sub2.example.com. A", "",
433 ";flags QR rcode NOERROR\n"
434 ";authority section\n"
435 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
436 ";additional section\n"
437 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
438 	},
439 
440 	{ "example.com", "abc.obscured.sub2.example.com. A", "",
441 ";flags QR rcode NOERROR\n"
442 ";authority section\n"
443 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
444 ";additional section\n"
445 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
446 	},
447 
448 	{ "example.com", "under.sub2.example.com. A", "",
449 ";flags QR rcode NOERROR\n"
450 ";authority section\n"
451 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
452 ";additional section\n"
453 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
454 	},
455 
456 	{ "example.com", "under.sub2.example.com. NS", "",
457 ";flags QR rcode NOERROR\n"
458 ";authority section\n"
459 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
460 ";additional section\n"
461 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
462 	},
463 
464 	{ "example.com", "abc.under.sub2.example.com. A", "",
465 ";flags QR rcode NOERROR\n"
466 ";authority section\n"
467 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
468 ";additional section\n"
469 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
470 	},
471 
472 	{ "example.com", "doubleobscured.under.sub2.example.com. A", "",
473 ";flags QR rcode NOERROR\n"
474 ";authority section\n"
475 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
476 ";additional section\n"
477 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
478 	},
479 
480 	{ "example.com", "abc.doubleobscured.under.sub2.example.com. A", "",
481 ";flags QR rcode NOERROR\n"
482 ";authority section\n"
483 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
484 ";additional section\n"
485 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
486 	},
487 
488 	{ "example.com", "wild.example.com. A", "",
489 ";flags QR AA rcode NOERROR\n"
490 ";authority section\n"
491 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
492 	},
493 
494 	{ "example.com", "*.wild.example.com. A", "",
495 ";flags QR AA rcode NOERROR\n"
496 ";answer section\n"
497 "*.wild.example.com.	3600	IN	A	10.0.0.8\n"
498 	},
499 
500 	{ "example.com", "*.wild.example.com. AAAA", "",
501 ";flags QR AA rcode NOERROR\n"
502 ";authority section\n"
503 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
504 	},
505 
506 	{ "example.com", "abc.wild.example.com. A", "",
507 ";flags QR AA rcode NOERROR\n"
508 ";answer section\n"
509 "abc.wild.example.com.	3600	IN	A	10.0.0.8\n"
510 	},
511 
512 	{ "example.com", "abc.wild.example.com. AAAA", "",
513 ";flags QR AA rcode NOERROR\n"
514 ";authority section\n"
515 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
516 	},
517 
518 	{ "example.com", "foo.abc.wild.example.com. A", "",
519 ";flags QR AA rcode NOERROR\n"
520 ";answer section\n"
521 "foo.abc.wild.example.com.	3600	IN	A	10.0.0.8\n"
522 	},
523 
524 	{ "example.com", "foo.abc.wild.example.com. AAAA", "",
525 ";flags QR AA rcode NOERROR\n"
526 ";authority section\n"
527 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
528 	},
529 
530 	{ "example.com", "wild2.example.com. A", "",
531 ";flags QR AA rcode NOERROR\n"
532 ";authority section\n"
533 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
534 	},
535 
536 	{ "example.com", "*.wild2.example.com. A", "",
537 ";flags QR AA rcode NOERROR\n"
538 ";answer section\n"
539 "*.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
540 "www.example.com.	3600	IN	A	10.0.0.2\n"
541 "www.example.com.	3600	IN	A	10.0.0.3\n"
542 	},
543 
544 	{ "example.com", "abc.wild2.example.com. A", "",
545 ";flags QR AA rcode NOERROR\n"
546 ";answer section\n"
547 "abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
548 "www.example.com.	3600	IN	A	10.0.0.2\n"
549 "www.example.com.	3600	IN	A	10.0.0.3\n"
550 	},
551 
552 	{ "example.com", "foo.abc.wild2.example.com. A", "",
553 ";flags QR AA rcode NOERROR\n"
554 ";answer section\n"
555 "foo.abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
556 "www.example.com.	3600	IN	A	10.0.0.2\n"
557 "www.example.com.	3600	IN	A	10.0.0.3\n"
558 	},
559 
560 	{ "example.com", "abc.wild2.example.com. CNAME", "",
561 ";flags QR AA rcode NOERROR\n"
562 ";answer section\n"
563 "abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
564 	},
565 
566 	{ "example.com", "abc.wild3.example.com. IN ANY", "",
567 ";flags QR AA rcode NOERROR\n"
568 ";answer section\n"
569 "abc.wild3.example.com.	3600	IN	MX	50 mail.example.com.\n"
570 "abc.wild3.example.com.	3600	IN	A	10.0.0.8\n"
571 	},
572 
573 	{ "example.com", "yy.example.com. TXT", "",
574 ";flags QR AA rcode NOERROR\n"
575 ";answer section\n"
576 "yy.example.com.	3600	IN	TXT	\"a\"\n"
577 "yy.example.com.	3600	IN	TXT	\"b\"\n"
578 "yy.example.com.	3600	IN	TXT	\"c\"\n"
579 "yy.example.com.	3600	IN	TXT	\"d\"\n"
580 "yy.example.com.	3600	IN	TXT	\"e\"\n"
581 "yy.example.com.	3600	IN	TXT	\"f\"\n"
582 	},
583 
584 	{NULL, NULL, NULL, NULL}
585 };
586 
587 /** number of tmpfiles */
588 static int tempno = 0;
589 /** number of deleted files */
590 static int delno = 0;
591 
592 /** cleanup tmp files at exit */
593 static void
tmpfilecleanup(void)594 tmpfilecleanup(void)
595 {
596 	int i;
597 	char buf[256];
598 	for(i=0; i<tempno; i++) {
599 #ifdef USE_WINSOCK
600 		snprintf(buf, sizeof(buf), "unbound.unittest.%u.%d",
601 			(unsigned)getpid(), i);
602 #else
603 		snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d",
604 			(unsigned)getpid(), i);
605 #endif
606 		if(vbmp) printf("cleanup: unlink %s\n", buf);
607 		unlink(buf);
608 	}
609 }
610 
611 /** create temp file, return (malloced) name string, write contents to it */
612 static char*
create_tmp_file(const char * s)613 create_tmp_file(const char* s)
614 {
615 	char buf[256];
616 	char *fname;
617 	FILE *out;
618 	size_t r;
619 #ifdef USE_WINSOCK
620 	snprintf(buf, sizeof(buf), "unbound.unittest.%u.%d",
621 		(unsigned)getpid(), tempno++);
622 #else
623 	snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d",
624 		(unsigned)getpid(), tempno++);
625 #endif
626 	fname = strdup(buf);
627 	if(!fname) fatal_exit("out of memory");
628 	/* if no string, just make the name */
629 	if(!s) return fname;
630 	/* if string, write to file */
631 	out = fopen(fname, "w");
632 	if(!out) fatal_exit("cannot open %s: %s", fname, strerror(errno));
633 	r = fwrite(s, 1, strlen(s), out);
634 	if(r == 0) {
635 		fatal_exit("write failed: %s", strerror(errno));
636 	} else if(r < strlen(s)) {
637 		fatal_exit("write failed: too short (disk full?)");
638 	}
639 	fclose(out);
640 	return fname;
641 }
642 
643 /** delete temp file and free name string */
644 static void
del_tmp_file(char * fname)645 del_tmp_file(char* fname)
646 {
647 	unlink(fname);
648 	free(fname);
649 	delno++;
650 	if(delno == tempno) {
651 		/* deleted all outstanding files, back to start condition */
652 		tempno = 0;
653 		delno = 0;
654 	}
655 }
656 
657 /** Add zone from file for testing */
658 struct auth_zone*
authtest_addzone(struct auth_zones * az,const char * name,char * fname)659 authtest_addzone(struct auth_zones* az, const char* name, char* fname)
660 {
661 	struct auth_zone* z;
662 	size_t nmlen;
663 	uint8_t* nm = sldns_str2wire_dname(name, &nmlen);
664 	struct config_file* cfg;
665 	if(!nm) fatal_exit("out of memory");
666 	lock_rw_wrlock(&az->lock);
667 	z = auth_zone_create(az, nm, nmlen, LDNS_RR_CLASS_IN);
668 	lock_rw_unlock(&az->lock);
669 	if(!z) fatal_exit("cannot find zone");
670 	auth_zone_set_zonefile(z, fname);
671 	z->for_upstream = 1;
672 	cfg = config_create();
673 	free(cfg->chrootdir);
674 	cfg->chrootdir = NULL;
675 
676 	if(!auth_zone_read_zonefile(z, cfg)) {
677 		fatal_exit("parse failure for auth zone %s", name);
678 	}
679 	lock_rw_unlock(&z->lock);
680 	free(nm);
681 	config_delete(cfg);
682 	return z;
683 }
684 
685 /** check that file is the same as other file */
686 static void
checkfile(char * f1,char * f2)687 checkfile(char* f1, char *f2)
688 {
689 	char buf1[10240], buf2[10240];
690 	int line = 0;
691 	FILE* i1, *i2;
692 	i1 = fopen(f1, "r");
693 	if(!i1) fatal_exit("cannot open %s: %s", f1, strerror(errno));
694 	i2 = fopen(f2, "r");
695 	if(!i2) fatal_exit("cannot open %s: %s", f2, strerror(errno));
696 
697 	while(!feof(i1) && !feof(i2)) {
698 		char* cp1, *cp2;
699 		line++;
700 		cp1 = fgets(buf1, (int)sizeof(buf1), i1);
701 		cp2 = fgets(buf2, (int)sizeof(buf2), i2);
702 		if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2)))
703 			fatal_exit("fgets failed: %s", strerror(errno));
704 		if(strncmp(buf1, "end_of_check", 12) == 0) {
705 			fclose(i1);
706 			fclose(i2);
707 			return;
708 		}
709 		if(strcmp(buf1, buf2) != 0) {
710 			log_info("in files %s and %s:%d", f1, f2, line);
711 			log_info("'%s'", buf1);
712 			log_info("'%s'", buf2);
713 			fatal_exit("files are not equal");
714 		}
715 	}
716 	unit_assert(feof(i1) && feof(i2));
717 
718 	fclose(i1);
719 	fclose(i2);
720 }
721 
722 /** check that a zone (in string) can be read and reproduced */
723 static void
check_read_exact(const char * name,const char * zone)724 check_read_exact(const char* name, const char* zone)
725 {
726 	struct auth_zones* az;
727 	struct auth_zone* z;
728 	char* fname, *outf;
729 	if(vbmp) printf("check read zone %s\n", name);
730 	fname = create_tmp_file(zone);
731 
732 	az = auth_zones_create();
733 	unit_assert(az);
734 	z = authtest_addzone(az, name, fname);
735 	unit_assert(z);
736 	outf = create_tmp_file(NULL);
737 	if(!auth_zone_write_file(z, outf)) {
738 		fatal_exit("write file failed for %s", fname);
739 	}
740 	checkfile(fname, outf);
741 
742 	del_tmp_file(fname);
743 	del_tmp_file(outf);
744 	auth_zones_delete(az);
745 }
746 
747 /** parse q_ans structure for making query */
748 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)749 q_ans_parse(struct q_ans* q, struct regional* region,
750 	struct query_info** qinfo, int* fallback, uint8_t** dp_nm,
751 	size_t* dp_nmlen)
752 {
753 	int ret;
754 	uint8_t buf[65535];
755 	size_t len, dname_len;
756 
757 	/* parse flags */
758 	*fallback = 0; /* default fallback value */
759 	if(strstr(q->flags, "fallback"))
760 		*fallback = 1;
761 
762 	/* parse zone */
763 	*dp_nmlen = sizeof(buf);
764 	if((ret=sldns_str2wire_dname_buf(q->zone, buf, dp_nmlen))!=0)
765 		fatal_exit("cannot parse query dp zone %s : %s", q->zone,
766 			sldns_get_errorstr_parse(ret));
767 	*dp_nm = regional_alloc_init(region, buf, *dp_nmlen);
768 	if(!dp_nm) fatal_exit("out of memory");
769 
770 	/* parse query */
771 	len = sizeof(buf);
772 	dname_len = 0;
773 	if((ret=sldns_str2wire_rr_question_buf(q->query, buf, &len, &dname_len,
774 		*dp_nm, *dp_nmlen, NULL, 0))!=0)
775 		fatal_exit("cannot parse query %s : %s", q->query,
776 			sldns_get_errorstr_parse(ret));
777 	*qinfo = (struct query_info*)regional_alloc_zero(region,
778 		sizeof(**qinfo));
779 	if(!*qinfo) fatal_exit("out of memory");
780 	(*qinfo)->qname = regional_alloc_init(region, buf, dname_len);
781 	if(!(*qinfo)->qname) fatal_exit("out of memory");
782 	(*qinfo)->qname_len = dname_len;
783 	(*qinfo)->qtype = sldns_wirerr_get_type(buf, len, dname_len);
784 	(*qinfo)->qclass = sldns_wirerr_get_class(buf, len, dname_len);
785 }
786 
787 /** print flags to string */
788 static void
pr_flags(sldns_buffer * buf,uint16_t flags)789 pr_flags(sldns_buffer* buf, uint16_t flags)
790 {
791 	char rcode[32];
792 	sldns_buffer_printf(buf, ";flags");
793 	if((flags&BIT_QR)!=0) sldns_buffer_printf(buf, " QR");
794 	if((flags&BIT_AA)!=0) sldns_buffer_printf(buf, " AA");
795 	if((flags&BIT_TC)!=0) sldns_buffer_printf(buf, " TC");
796 	if((flags&BIT_RD)!=0) sldns_buffer_printf(buf, " RD");
797 	if((flags&BIT_CD)!=0) sldns_buffer_printf(buf, " CD");
798 	if((flags&BIT_RA)!=0) sldns_buffer_printf(buf, " RA");
799 	if((flags&BIT_AD)!=0) sldns_buffer_printf(buf, " AD");
800 	if((flags&BIT_Z)!=0) sldns_buffer_printf(buf, " Z");
801 	sldns_wire2str_rcode_buf((int)(FLAGS_GET_RCODE(flags)),
802 		rcode, sizeof(rcode));
803 	sldns_buffer_printf(buf, " rcode %s", rcode);
804 	sldns_buffer_printf(buf, "\n");
805 }
806 
807 /** print RRs to string */
808 static void
pr_rrs(sldns_buffer * buf,struct reply_info * rep)809 pr_rrs(sldns_buffer* buf, struct reply_info* rep)
810 {
811 	char s[65536];
812 	size_t i, j;
813 	struct packed_rrset_data* d;
814 	log_assert(rep->rrset_count == rep->an_numrrsets + rep->ns_numrrsets
815 		+ rep->ar_numrrsets);
816 	for(i=0; i<rep->rrset_count; i++) {
817 		/* section heading */
818 		if(i == 0 && rep->an_numrrsets != 0)
819 			sldns_buffer_printf(buf, ";answer section\n");
820 		else if(i == rep->an_numrrsets && rep->ns_numrrsets != 0)
821 			sldns_buffer_printf(buf, ";authority section\n");
822 		else if(i == rep->an_numrrsets+rep->ns_numrrsets &&
823 			rep->ar_numrrsets != 0)
824 			sldns_buffer_printf(buf, ";additional section\n");
825 		/* spool RRset */
826 		d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
827 		for(j=0; j<d->count+d->rrsig_count; j++) {
828 			if(!packed_rr_to_string(rep->rrsets[i], j, 0,
829 				s, sizeof(s))) {
830 				fatal_exit("could not rr_to_string %d",
831 					(int)i);
832 			}
833 			sldns_buffer_printf(buf, "%s", s);
834 		}
835 	}
836 }
837 
838 /** create string for message */
839 static char*
msgtostr(struct dns_msg * msg)840 msgtostr(struct dns_msg* msg)
841 {
842 	char* str;
843 	sldns_buffer* buf = sldns_buffer_new(65535);
844 	if(!buf) fatal_exit("out of memory");
845 	if(!msg) {
846 		sldns_buffer_printf(buf, "null packet\n");
847 	} else {
848 		pr_flags(buf, msg->rep->flags);
849 		pr_rrs(buf, msg->rep);
850 	}
851 
852 	str = strdup((char*)sldns_buffer_begin(buf));
853 	if(!str) fatal_exit("out of memory");
854 	sldns_buffer_free(buf);
855 	return str;
856 }
857 
858 /** find line diff between strings */
859 static void
line_diff(const char * p,const char * q,const char * pdesc,const char * qdesc)860 line_diff(const char* p, const char* q, const char* pdesc, const char* qdesc)
861 {
862 	char* pdup, *qdup, *pl, *ql;
863 	int line = 1;
864 	pdup = strdup(p);
865 	qdup = strdup(q);
866 	if(!pdup || !qdup) fatal_exit("out of memory");
867 	pl=pdup;
868 	ql=qdup;
869 	printf("linediff (<%s, >%s)\n", pdesc, qdesc);
870 	while(pl && ql && *pl && *ql) {
871 		char* ep = strchr(pl, '\n');
872 		char* eq = strchr(ql, '\n');
873 		/* terminate lines */
874 		if(ep) *ep = 0;
875 		if(eq) *eq = 0;
876 		/* printout */
877 		if(strcmp(pl, ql) == 0) {
878 			printf("%3d   %s\n", line, pl);
879 		} else {
880 			printf("%3d < %s\n", line, pl);
881 			printf("%3d > %s\n", line, ql);
882 		}
883 		if(ep) *ep = '\n';
884 		if(eq) *eq = '\n';
885 		if(ep) pl = ep+1;
886 		else pl = NULL;
887 		if(eq) ql = eq+1;
888 		else ql = NULL;
889 		line++;
890 	}
891 	if(pl && *pl) {
892 		printf("%3d < %s\n", line, pl);
893 	}
894 	if(ql && *ql) {
895 		printf("%3d > %s\n", line, ql);
896 	}
897 	free(pdup);
898 	free(qdup);
899 }
900 
901 /** make q_ans query */
902 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)903 q_ans_query(struct q_ans* q, struct auth_zones* az, struct query_info* qinfo,
904 	struct regional* region, int expected_fallback, uint8_t* dp_nm,
905 	size_t dp_nmlen)
906 {
907 	int ret, fallback = 0;
908 	struct dns_msg* msg = NULL;
909 	char* ans_str;
910 	int oldv = verbosity;
911 	/* increase verbosity to printout logic in authzone */
912 	if(vbmp) verbosity = 4;
913 	ret = auth_zones_lookup(az, qinfo, region, &msg, &fallback, dp_nm,
914 		dp_nmlen);
915 	if(vbmp) verbosity = oldv;
916 
917 	/* check the answer */
918 	ans_str = msgtostr(msg);
919 	/* printout if vbmp */
920 	if(vbmp) printf("got (ret=%s%s):\n%s",
921 		(ret?"ok":"fail"), (fallback?" fallback":""), ans_str);
922 	/* check expected value for ret */
923 	if(expected_fallback && ret != 0) {
924 		/* ret is zero on fallback */
925 		if(vbmp) printf("fallback expected, but "
926 			"return value is not false\n");
927 		unit_assert(expected_fallback && ret == 0);
928 	}
929 	if(ret == 0) {
930 		if(!expected_fallback) {
931 			if(vbmp) printf("return value is false, "
932 				"(unexpected)\n");
933 		}
934 		unit_assert(expected_fallback);
935 	}
936 	/* check expected value for fallback */
937 	if(expected_fallback && !fallback) {
938 		if(vbmp) printf("expected fallback, but fallback is no\n");
939 	} else if(!expected_fallback && fallback) {
940 		if(vbmp) printf("expected no fallback, but fallback is yes\n");
941 	}
942 	unit_assert( (expected_fallback&&fallback) ||
943 		(!expected_fallback&&!fallback));
944 	/* check answer string */
945 	if(strcmp(q->answer, ans_str) != 0) {
946 		if(vbmp) printf("wanted:\n%s", q->answer);
947 		line_diff(q->answer, ans_str, "wanted", "got");
948 	}
949 	unit_assert(strcmp(q->answer, ans_str) == 0);
950 	if(vbmp) printf("query ok\n\n");
951 	free(ans_str);
952 }
953 
954 /** check queries on a loaded zone */
955 static void
check_az_q_ans(struct auth_zones * az,struct q_ans * queries)956 check_az_q_ans(struct auth_zones* az, struct q_ans* queries)
957 {
958 	struct q_ans* q;
959 	struct regional* region = regional_create();
960 	struct query_info* qinfo;
961 	int fallback;
962 	uint8_t* dp_nm;
963 	size_t dp_nmlen;
964 	for(q=queries; q->zone; q++) {
965 		if(vbmp) printf("query %s: %s %s\n", q->zone, q->query,
966 			q->flags);
967 		q_ans_parse(q, region, &qinfo, &fallback, &dp_nm, &dp_nmlen);
968 		q_ans_query(q, az, qinfo, region, fallback, dp_nm, dp_nmlen);
969 		regional_free_all(region);
970 	}
971 	regional_destroy(region);
972 }
973 
974 /** check queries for a zone are returned as specified */
975 static void
check_queries(const char * name,const char * zone,struct q_ans * queries)976 check_queries(const char* name, const char* zone, struct q_ans* queries)
977 {
978 	struct auth_zones* az;
979 	struct auth_zone* z;
980 	char* fname;
981 	if(vbmp) printf("check queries %s\n", name);
982 	fname = create_tmp_file(zone);
983 	az = auth_zones_create();
984 	if(!az) fatal_exit("out of memory");
985 	z = authtest_addzone(az, name, fname);
986 	if(!z) fatal_exit("could not read zone for queries test");
987 	del_tmp_file(fname);
988 
989 	/* run queries and test them */
990 	check_az_q_ans(az, queries);
991 
992 	auth_zones_delete(az);
993 }
994 
995 /** Test authzone compare_serial */
996 static void
authzone_compare_serial(void)997 authzone_compare_serial(void)
998 {
999 	if(vbmp) printf("Testing compare_serial\n");
1000 	unit_assert(compare_serial(0, 1) < 0);
1001 	unit_assert(compare_serial(1, 0) > 0);
1002 	unit_assert(compare_serial(0, 0) == 0);
1003 	unit_assert(compare_serial(1, 1) == 0);
1004 	unit_assert(compare_serial(0xf0000000, 0xf0000000) == 0);
1005 	unit_assert(compare_serial(0, 0xf0000000) > 0);
1006 	unit_assert(compare_serial(0xf0000000, 0) < 0);
1007 	unit_assert(compare_serial(0xf0000000, 0xf0000001) < 0);
1008 	unit_assert(compare_serial(0xf0000002, 0xf0000001) > 0);
1009 	unit_assert(compare_serial(0x70000000, 0x80000000) < 0);
1010 	unit_assert(compare_serial(0x90000000, 0x70000000) > 0);
1011 }
1012 
1013 /** Test authzone read from file */
1014 static void
authzone_read_test(void)1015 authzone_read_test(void)
1016 {
1017 	if(vbmp) printf("Testing read auth zone\n");
1018 	check_read_exact("example.com", zone_example_com);
1019 }
1020 
1021 /** Test authzone query from zone */
1022 static void
authzone_query_test(void)1023 authzone_query_test(void)
1024 {
1025 	if(vbmp) printf("Testing query auth zone\n");
1026 	check_queries("example.com", zone_example_com, example_com_queries);
1027 }
1028 
1029 /** test authzone code */
1030 void
authzone_test(void)1031 authzone_test(void)
1032 {
1033 	unit_show_feature("authzone");
1034 	atexit(tmpfilecleanup);
1035 	authzone_compare_serial();
1036 	authzone_read_test();
1037 	authzone_query_test();
1038 }
1039