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/data/msgreply.h" 46 #include "services/cache/dns.h" 47 #include "sldns/str2wire.h" 48 #include "sldns/wire2str.h" 49 #include "sldns/sbuffer.h" 50 51 /** verbosity for this test */ 52 static int vbmp = 0; 53 54 /** struct for query and answer checks */ 55 struct q_ans { 56 /** zone to query (delegpt) */ 57 const char* zone; 58 /** query name, class, type */ 59 const char* query; 60 /** additional flags or "" */ 61 const char* flags; 62 /** expected answer to check against, multi-line string */ 63 const char* answer; 64 }; 65 66 /** auth zone for test */ 67 static const char* zone_example_com = 68 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 69 "example.com. 3600 IN A 10.0.0.1\n" 70 "example.com. 3600 IN NS ns.example.com.\n" 71 "example.com. 3600 IN MX 50 mail.example.com.\n" 72 "deep.ent.example.com. 3600 IN A 10.0.0.9\n" 73 "mail.example.com. 3600 IN A 10.0.0.4\n" 74 "ns.example.com. 3600 IN A 10.0.0.5\n" 75 "out.example.com. 3600 IN CNAME www.example.com.\n" 76 "plan.example.com. 3600 IN CNAME nonexist.example.com.\n" 77 "redir.example.com. 3600 IN DNAME redir.example.org.\n" 78 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n" 79 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n" 80 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n" 81 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n" 82 "*.wild.example.com. 3600 IN A 10.0.0.8\n" 83 "*.wild2.example.com. 3600 IN CNAME www.example.com.\n" 84 "*.wild3.example.com. 3600 IN A 10.0.0.8\n" 85 "*.wild3.example.com. 3600 IN MX 50 mail.example.com.\n" 86 "www.example.com. 3600 IN A 10.0.0.2\n" 87 "www.example.com. 3600 IN A 10.0.0.3\n" 88 "yy.example.com. 3600 IN TXT \"a\"\n" 89 "yy.example.com. 3600 IN TXT \"b\"\n" 90 "yy.example.com. 3600 IN TXT \"c\"\n" 91 "yy.example.com. 3600 IN TXT \"d\"\n" 92 "yy.example.com. 3600 IN TXT \"e\"\n" 93 "yy.example.com. 3600 IN TXT \"f\"\n" 94 95 /* and some tests for RRSIGs (rrsig is www.nlnetlabs.nl copy) */ 96 /* normal: domain and 1 rrsig */ 97 "z1.example.com. 3600 IN A 10.0.0.10\n" 98 "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" 99 /* normal: domain and 2 rrsigs */ 100 "z2.example.com. 3600 IN A 10.0.0.10\n" 101 "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" 102 "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" 103 /* normal: domain and 3 rrsigs */ 104 "z3.example.com. 3600 IN A 10.0.0.10\n" 105 "z3.example.com. 3600 IN A 10.0.0.11\n" 106 "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" 107 "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" 108 "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" 109 /* just an RRSIG rrset with nothing else */ 110 "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" 111 /* just an RRSIG rrset with nothing else, 2 rrsigs */ 112 "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" 113 "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" 114 #if 0 /* comparison of file does not work on this part because duplicates */ 115 /* are removed and the rrsets are reordered */ 116 /* first rrsig, then A record */ 117 "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" 118 "z6.example.com. 3600 IN A 10.0.0.10\n" 119 /* first two rrsigs, then A record */ 120 "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" 121 "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" 122 "z7.example.com. 3600 IN A 10.0.0.10\n" 123 /* first two rrsigs, then two A records */ 124 "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" 125 "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" 126 "z8.example.com. 3600 IN A 10.0.0.10\n" 127 "z8.example.com. 3600 IN A 10.0.0.11\n" 128 /* duplicate RR, duplicate RRsig */ 129 "z9.example.com. 3600 IN A 10.0.0.10\n" 130 "z9.example.com. 3600 IN A 10.0.0.11\n" 131 "z9.example.com. 3600 IN A 10.0.0.10\n" 132 "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" 133 "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" 134 #endif /* if0 for duplicates and reordering */ 135 ; 136 137 /** queries for example.com: zone, query, flags, answer. end with NULL */ 138 static struct q_ans example_com_queries[] = { 139 { "example.com", "www.example.com. A", "", 140 ";flags QR AA rcode NOERROR\n" 141 ";answer section\n" 142 "www.example.com. 3600 IN A 10.0.0.2\n" 143 "www.example.com. 3600 IN A 10.0.0.3\n" 144 }, 145 146 { "example.com", "example.com. SOA", "", 147 ";flags QR AA rcode NOERROR\n" 148 ";answer section\n" 149 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 150 }, 151 152 { "example.com", "example.com. A", "", 153 ";flags QR AA rcode NOERROR\n" 154 ";answer section\n" 155 "example.com. 3600 IN A 10.0.0.1\n" 156 }, 157 158 { "example.com", "example.com. AAAA", "", 159 ";flags QR AA rcode NOERROR\n" 160 ";authority section\n" 161 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 162 }, 163 164 { "example.com", "example.com. NS", "", 165 ";flags QR AA rcode NOERROR\n" 166 ";answer section\n" 167 "example.com. 3600 IN NS ns.example.com.\n" 168 ";additional section\n" 169 "ns.example.com. 3600 IN A 10.0.0.5\n" 170 }, 171 172 { "example.com", "example.com. MX", "", 173 ";flags QR AA rcode NOERROR\n" 174 ";answer section\n" 175 "example.com. 3600 IN MX 50 mail.example.com.\n" 176 ";additional section\n" 177 "mail.example.com. 3600 IN A 10.0.0.4\n" 178 }, 179 180 { "example.com", "example.com. IN ANY", "", 181 ";flags QR AA rcode NOERROR\n" 182 ";answer section\n" 183 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 184 "example.com. 3600 IN MX 50 mail.example.com.\n" 185 "example.com. 3600 IN A 10.0.0.1\n" 186 }, 187 188 { "example.com", "nonexist.example.com. A", "", 189 ";flags QR AA rcode NXDOMAIN\n" 190 ";authority section\n" 191 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 192 }, 193 194 { "example.com", "deep.ent.example.com. A", "", 195 ";flags QR AA rcode NOERROR\n" 196 ";answer section\n" 197 "deep.ent.example.com. 3600 IN A 10.0.0.9\n" 198 }, 199 200 { "example.com", "ent.example.com. A", "", 201 ";flags QR AA rcode NOERROR\n" 202 ";authority section\n" 203 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 204 }, 205 206 { "example.com", "below.deep.ent.example.com. A", "", 207 ";flags QR AA rcode NXDOMAIN\n" 208 ";authority section\n" 209 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 210 }, 211 212 { "example.com", "mail.example.com. A", "", 213 ";flags QR AA rcode NOERROR\n" 214 ";answer section\n" 215 "mail.example.com. 3600 IN A 10.0.0.4\n" 216 }, 217 218 { "example.com", "ns.example.com. A", "", 219 ";flags QR AA rcode NOERROR\n" 220 ";answer section\n" 221 "ns.example.com. 3600 IN A 10.0.0.5\n" 222 }, 223 224 { "example.com", "out.example.com. A", "", 225 ";flags QR AA rcode NOERROR\n" 226 ";answer section\n" 227 "out.example.com. 3600 IN CNAME www.example.com.\n" 228 "www.example.com. 3600 IN A 10.0.0.2\n" 229 "www.example.com. 3600 IN A 10.0.0.3\n" 230 }, 231 232 { "example.com", "out.example.com. CNAME", "", 233 ";flags QR AA rcode NOERROR\n" 234 ";answer section\n" 235 "out.example.com. 3600 IN CNAME www.example.com.\n" 236 }, 237 238 { "example.com", "plan.example.com. A", "", 239 ";flags QR AA rcode NOERROR\n" 240 ";answer section\n" 241 "plan.example.com. 3600 IN CNAME nonexist.example.com.\n" 242 }, 243 244 { "example.com", "plan.example.com. CNAME", "", 245 ";flags QR AA rcode NOERROR\n" 246 ";answer section\n" 247 "plan.example.com. 3600 IN CNAME nonexist.example.com.\n" 248 }, 249 250 { "example.com", "redir.example.com. A", "", 251 ";flags QR AA rcode NOERROR\n" 252 ";authority section\n" 253 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 254 }, 255 256 { "example.com", "redir.example.com. DNAME", "", 257 ";flags QR AA rcode NOERROR\n" 258 ";answer section\n" 259 "redir.example.com. 3600 IN DNAME redir.example.org.\n" 260 }, 261 262 { "example.com", "abc.redir.example.com. A", "", 263 ";flags QR AA rcode NOERROR\n" 264 ";answer section\n" 265 "redir.example.com. 3600 IN DNAME redir.example.org.\n" 266 "abc.redir.example.com. 0 IN CNAME abc.redir.example.org.\n" 267 }, 268 269 { "example.com", "foo.abc.redir.example.com. A", "", 270 ";flags QR AA rcode NOERROR\n" 271 ";answer section\n" 272 "redir.example.com. 3600 IN DNAME redir.example.org.\n" 273 "foo.abc.redir.example.com. 0 IN CNAME foo.abc.redir.example.org.\n" 274 }, 275 276 { "example.com", "sub.example.com. NS", "", 277 ";flags QR rcode NOERROR\n" 278 ";authority section\n" 279 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n" 280 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n" 281 ";additional section\n" 282 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n" 283 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n" 284 }, 285 286 { "example.com", "sub.example.com. DS", "", 287 ";flags QR AA rcode NOERROR\n" 288 ";authority section\n" 289 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 290 }, 291 292 { "example.com", "www.sub.example.com. NS", "", 293 ";flags QR rcode NOERROR\n" 294 ";authority section\n" 295 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n" 296 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n" 297 ";additional section\n" 298 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n" 299 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n" 300 }, 301 302 { "example.com", "foo.abc.sub.example.com. NS", "", 303 ";flags QR rcode NOERROR\n" 304 ";authority section\n" 305 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n" 306 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n" 307 ";additional section\n" 308 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n" 309 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n" 310 }, 311 312 { "example.com", "ns1.sub.example.com. A", "", 313 ";flags QR rcode NOERROR\n" 314 ";authority section\n" 315 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n" 316 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n" 317 ";additional section\n" 318 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n" 319 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n" 320 }, 321 322 { "example.com", "ns1.sub.example.com. AAAA", "", 323 ";flags QR rcode NOERROR\n" 324 ";authority section\n" 325 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n" 326 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n" 327 ";additional section\n" 328 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n" 329 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n" 330 }, 331 332 { "example.com", "ns2.sub.example.com. A", "", 333 ";flags QR rcode NOERROR\n" 334 ";authority section\n" 335 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n" 336 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n" 337 ";additional section\n" 338 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n" 339 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n" 340 }, 341 342 { "example.com", "ns2.sub.example.com. AAAA", "", 343 ";flags QR rcode NOERROR\n" 344 ";authority section\n" 345 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n" 346 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n" 347 ";additional section\n" 348 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n" 349 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n" 350 }, 351 352 { "example.com", "wild.example.com. A", "", 353 ";flags QR AA rcode NOERROR\n" 354 ";authority section\n" 355 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 356 }, 357 358 { "example.com", "*.wild.example.com. A", "", 359 ";flags QR AA rcode NOERROR\n" 360 ";answer section\n" 361 "*.wild.example.com. 3600 IN A 10.0.0.8\n" 362 }, 363 364 { "example.com", "*.wild.example.com. AAAA", "", 365 ";flags QR AA rcode NOERROR\n" 366 ";authority section\n" 367 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 368 }, 369 370 { "example.com", "abc.wild.example.com. A", "", 371 ";flags QR AA rcode NOERROR\n" 372 ";answer section\n" 373 "abc.wild.example.com. 3600 IN A 10.0.0.8\n" 374 }, 375 376 { "example.com", "abc.wild.example.com. AAAA", "", 377 ";flags QR AA rcode NOERROR\n" 378 ";authority section\n" 379 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 380 }, 381 382 { "example.com", "foo.abc.wild.example.com. A", "", 383 ";flags QR AA rcode NOERROR\n" 384 ";answer section\n" 385 "foo.abc.wild.example.com. 3600 IN A 10.0.0.8\n" 386 }, 387 388 { "example.com", "foo.abc.wild.example.com. AAAA", "", 389 ";flags QR AA rcode NOERROR\n" 390 ";authority section\n" 391 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 392 }, 393 394 { "example.com", "wild2.example.com. A", "", 395 ";flags QR AA rcode NOERROR\n" 396 ";authority section\n" 397 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n" 398 }, 399 400 { "example.com", "*.wild2.example.com. A", "", 401 ";flags QR AA rcode NOERROR\n" 402 ";answer section\n" 403 "*.wild2.example.com. 3600 IN CNAME www.example.com.\n" 404 "www.example.com. 3600 IN A 10.0.0.2\n" 405 "www.example.com. 3600 IN A 10.0.0.3\n" 406 }, 407 408 { "example.com", "abc.wild2.example.com. A", "", 409 ";flags QR AA rcode NOERROR\n" 410 ";answer section\n" 411 "abc.wild2.example.com. 3600 IN CNAME www.example.com.\n" 412 "www.example.com. 3600 IN A 10.0.0.2\n" 413 "www.example.com. 3600 IN A 10.0.0.3\n" 414 }, 415 416 { "example.com", "foo.abc.wild2.example.com. A", "", 417 ";flags QR AA rcode NOERROR\n" 418 ";answer section\n" 419 "foo.abc.wild2.example.com. 3600 IN CNAME www.example.com.\n" 420 "www.example.com. 3600 IN A 10.0.0.2\n" 421 "www.example.com. 3600 IN A 10.0.0.3\n" 422 }, 423 424 { "example.com", "abc.wild2.example.com. CNAME", "", 425 ";flags QR AA rcode NOERROR\n" 426 ";answer section\n" 427 "abc.wild2.example.com. 3600 IN CNAME www.example.com.\n" 428 }, 429 430 { "example.com", "abc.wild3.example.com. IN ANY", "", 431 ";flags QR AA rcode NOERROR\n" 432 ";answer section\n" 433 "abc.wild3.example.com. 3600 IN MX 50 mail.example.com.\n" 434 "abc.wild3.example.com. 3600 IN A 10.0.0.8\n" 435 }, 436 437 { "example.com", "yy.example.com. TXT", "", 438 ";flags QR AA rcode NOERROR\n" 439 ";answer section\n" 440 "yy.example.com. 3600 IN TXT \"a\"\n" 441 "yy.example.com. 3600 IN TXT \"b\"\n" 442 "yy.example.com. 3600 IN TXT \"c\"\n" 443 "yy.example.com. 3600 IN TXT \"d\"\n" 444 "yy.example.com. 3600 IN TXT \"e\"\n" 445 "yy.example.com. 3600 IN TXT \"f\"\n" 446 }, 447 448 {NULL, NULL, NULL, NULL} 449 }; 450 451 /** number of tmpfiles */ 452 static int tempno = 0; 453 /** number of deleted files */ 454 static int delno = 0; 455 456 /** cleanup tmp files at exit */ 457 static void 458 tmpfilecleanup(void) 459 { 460 int i; 461 char buf[256]; 462 for(i=0; i<tempno; i++) { 463 snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d", 464 (unsigned)getpid(), i); 465 if(vbmp) printf("cleanup: unlink %s\n", buf); 466 unlink(buf); 467 } 468 } 469 470 /** create temp file, return (malloced) name string, write contents to it */ 471 static char* 472 create_tmp_file(const char* s) 473 { 474 char buf[256]; 475 char *fname; 476 FILE *out; 477 size_t r; 478 snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d", 479 (unsigned)getpid(), tempno++); 480 fname = strdup(buf); 481 if(!fname) fatal_exit("out of memory"); 482 /* if no string, just make the name */ 483 if(!s) return fname; 484 /* if string, write to file */ 485 out = fopen(fname, "w"); 486 if(!out) fatal_exit("cannot open %s: %s", fname, strerror(errno)); 487 r = fwrite(s, 1, strlen(s), out); 488 if(r == 0) { 489 fatal_exit("write failed: %s", strerror(errno)); 490 } else if(r < strlen(s)) { 491 fatal_exit("write failed: too short (disk full?)"); 492 } 493 fclose(out); 494 return fname; 495 } 496 497 /** delete temp file and free name string */ 498 static void 499 del_tmp_file(char* fname) 500 { 501 unlink(fname); 502 free(fname); 503 delno++; 504 if(delno == tempno) { 505 /* deleted all outstanding files, back to start condition */ 506 tempno = 0; 507 delno = 0; 508 } 509 } 510 511 /** Add zone from file for testing */ 512 static struct auth_zone* 513 addzone(struct auth_zones* az, const char* name, char* fname) 514 { 515 struct auth_zone* z; 516 size_t nmlen; 517 uint8_t* nm = sldns_str2wire_dname(name, &nmlen); 518 if(!nm) fatal_exit("out of memory"); 519 lock_rw_wrlock(&az->lock); 520 z = auth_zone_create(az, nm, nmlen, LDNS_RR_CLASS_IN); 521 lock_rw_unlock(&az->lock); 522 if(!z) fatal_exit("cannot find zone"); 523 auth_zone_set_zonefile(z, fname); 524 525 if(!auth_zone_read_zonefile(z)) { 526 fatal_exit("parse failure for auth zone %s", name); 527 } 528 lock_rw_unlock(&z->lock); 529 free(nm); 530 return z; 531 } 532 533 /** check that file is the same as other file */ 534 static void 535 checkfile(char* f1, char *f2) 536 { 537 char buf1[10240], buf2[10240]; 538 int line = 0; 539 FILE* i1, *i2; 540 i1 = fopen(f1, "r"); 541 if(!i1) fatal_exit("cannot open %s: %s", f1, strerror(errno)); 542 i2 = fopen(f2, "r"); 543 if(!i2) fatal_exit("cannot open %s: %s", f2, strerror(errno)); 544 545 while(!feof(i1) && !feof(i2)) { 546 char* cp1, *cp2; 547 line++; 548 cp1 = fgets(buf1, (int)sizeof(buf1), i1); 549 cp2 = fgets(buf2, (int)sizeof(buf2), i2); 550 if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2))) 551 fatal_exit("fgets failed: %s", strerror(errno)); 552 if(strcmp(buf1, buf2) != 0) { 553 log_info("in files %s and %s:%d", f1, f2, line); 554 log_info("'%s'", buf1); 555 log_info("'%s'", buf2); 556 fatal_exit("files are not eqaul"); 557 } 558 } 559 unit_assert(feof(i1) && feof(i2)); 560 561 fclose(i1); 562 fclose(i2); 563 } 564 565 /** check that a zone (in string) can be read and reproduced */ 566 static void 567 check_read_exact(const char* name, const char* zone) 568 { 569 struct auth_zones* az; 570 struct auth_zone* z; 571 char* fname, *outf; 572 if(vbmp) printf("check read zone %s\n", name); 573 fname = create_tmp_file(zone); 574 575 az = auth_zones_create(); 576 unit_assert(az); 577 z = addzone(az, name, fname); 578 unit_assert(z); 579 outf = create_tmp_file(NULL); 580 if(!auth_zone_write_file(z, outf)) { 581 fatal_exit("write file failed for %s", fname); 582 } 583 checkfile(fname, outf); 584 585 del_tmp_file(fname); 586 del_tmp_file(outf); 587 auth_zones_delete(az); 588 } 589 590 /** parse q_ans structure for making query */ 591 static void 592 q_ans_parse(struct q_ans* q, struct regional* region, 593 struct query_info** qinfo, int* fallback, uint8_t** dp_nm, 594 size_t* dp_nmlen) 595 { 596 int ret; 597 uint8_t buf[65535]; 598 size_t len, dname_len; 599 600 /* parse flags */ 601 *fallback = 0; /* default fallback value */ 602 if(strstr(q->flags, "fallback")) 603 *fallback = 1; 604 605 /* parse zone */ 606 *dp_nmlen = sizeof(buf); 607 if((ret=sldns_str2wire_dname_buf(q->zone, buf, dp_nmlen))!=0) 608 fatal_exit("cannot parse query dp zone %s : %s", q->zone, 609 sldns_get_errorstr_parse(ret)); 610 *dp_nm = regional_alloc_init(region, buf, *dp_nmlen); 611 if(!dp_nm) fatal_exit("out of memory"); 612 613 /* parse query */ 614 len = sizeof(buf); 615 dname_len = 0; 616 if((ret=sldns_str2wire_rr_question_buf(q->query, buf, &len, &dname_len, 617 *dp_nm, *dp_nmlen, NULL, 0))!=0) 618 fatal_exit("cannot parse query %s : %s", q->query, 619 sldns_get_errorstr_parse(ret)); 620 *qinfo = (struct query_info*)regional_alloc_zero(region, 621 sizeof(**qinfo)); 622 if(!*qinfo) fatal_exit("out of memory"); 623 (*qinfo)->qname = regional_alloc_init(region, buf, dname_len); 624 if(!(*qinfo)->qname) fatal_exit("out of memory"); 625 (*qinfo)->qname_len = dname_len; 626 (*qinfo)->qtype = sldns_wirerr_get_type(buf, len, dname_len); 627 (*qinfo)->qclass = sldns_wirerr_get_class(buf, len, dname_len); 628 } 629 630 /** print flags to string */ 631 static void 632 pr_flags(sldns_buffer* buf, uint16_t flags) 633 { 634 char rcode[32]; 635 sldns_buffer_printf(buf, ";flags"); 636 if((flags&BIT_QR)!=0) sldns_buffer_printf(buf, " QR"); 637 if((flags&BIT_AA)!=0) sldns_buffer_printf(buf, " AA"); 638 if((flags&BIT_TC)!=0) sldns_buffer_printf(buf, " TC"); 639 if((flags&BIT_RD)!=0) sldns_buffer_printf(buf, " RD"); 640 if((flags&BIT_CD)!=0) sldns_buffer_printf(buf, " CD"); 641 if((flags&BIT_RA)!=0) sldns_buffer_printf(buf, " RA"); 642 if((flags&BIT_AD)!=0) sldns_buffer_printf(buf, " AD"); 643 if((flags&BIT_Z)!=0) sldns_buffer_printf(buf, " Z"); 644 sldns_wire2str_rcode_buf((int)(FLAGS_GET_RCODE(flags)), 645 rcode, sizeof(rcode)); 646 sldns_buffer_printf(buf, " rcode %s", rcode); 647 sldns_buffer_printf(buf, "\n"); 648 } 649 650 /** print RRs to string */ 651 static void 652 pr_rrs(sldns_buffer* buf, struct reply_info* rep) 653 { 654 char s[65536]; 655 size_t i, j; 656 struct packed_rrset_data* d; 657 log_assert(rep->rrset_count == rep->an_numrrsets + rep->ns_numrrsets 658 + rep->ar_numrrsets); 659 for(i=0; i<rep->rrset_count; i++) { 660 /* section heading */ 661 if(i == 0 && rep->an_numrrsets != 0) 662 sldns_buffer_printf(buf, ";answer section\n"); 663 else if(i == rep->an_numrrsets && rep->ns_numrrsets != 0) 664 sldns_buffer_printf(buf, ";authority section\n"); 665 else if(i == rep->an_numrrsets+rep->ns_numrrsets && 666 rep->ar_numrrsets != 0) 667 sldns_buffer_printf(buf, ";additional section\n"); 668 /* spool RRset */ 669 d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data; 670 for(j=0; j<d->count+d->rrsig_count; j++) { 671 if(!packed_rr_to_string(rep->rrsets[i], j, 0, 672 s, sizeof(s))) { 673 fatal_exit("could not rr_to_string %d", 674 (int)i); 675 } 676 sldns_buffer_printf(buf, "%s", s); 677 } 678 } 679 } 680 681 /** create string for message */ 682 static char* 683 msgtostr(struct dns_msg* msg) 684 { 685 char* str; 686 sldns_buffer* buf = sldns_buffer_new(65535); 687 if(!buf) fatal_exit("out of memory"); 688 pr_flags(buf, msg->rep->flags); 689 pr_rrs(buf, msg->rep); 690 691 str = strdup((char*)sldns_buffer_begin(buf)); 692 if(!str) fatal_exit("out of memory"); 693 sldns_buffer_free(buf); 694 return str; 695 } 696 697 /** find line diff between strings */ 698 static void 699 line_diff(const char* p, const char* q, const char* pdesc, const char* qdesc) 700 { 701 char* pdup, *qdup, *pl, *ql; 702 int line = 1; 703 pdup = strdup(p); 704 qdup = strdup(q); 705 if(!pdup || !qdup) fatal_exit("out of memory"); 706 pl=pdup; 707 ql=qdup; 708 printf("linediff (<%s, >%s)\n", pdesc, qdesc); 709 while(pl && ql && *pl && *ql) { 710 char* ep = strchr(pl, '\n'); 711 char* eq = strchr(ql, '\n'); 712 /* terminate lines */ 713 if(ep) *ep = 0; 714 if(eq) *eq = 0; 715 /* printout */ 716 if(strcmp(pl, ql) == 0) { 717 printf("%3d %s\n", line, pl); 718 } else { 719 printf("%3d < %s\n", line, pl); 720 printf("%3d > %s\n", line, ql); 721 } 722 if(ep) *ep = '\n'; 723 if(eq) *eq = '\n'; 724 if(ep) pl = ep+1; 725 else pl = NULL; 726 if(eq) ql = eq+1; 727 else ql = NULL; 728 line++; 729 } 730 if(pl && *pl) { 731 printf("%3d < %s\n", line, pl); 732 } 733 if(ql && *ql) { 734 printf("%3d > %s\n", line, ql); 735 } 736 free(pdup); 737 free(qdup); 738 } 739 740 /** make q_ans query */ 741 static void 742 q_ans_query(struct q_ans* q, struct auth_zones* az, struct query_info* qinfo, 743 struct regional* region, int expected_fallback, uint8_t* dp_nm, 744 size_t dp_nmlen) 745 { 746 int ret, fallback = 0; 747 struct dns_msg* msg = NULL; 748 char* ans_str; 749 int oldv = verbosity; 750 /* increase verbosity to printout logic in authzone */ 751 if(vbmp) verbosity = 4; 752 ret = auth_zones_lookup(az, qinfo, region, &msg, &fallback, dp_nm, 753 dp_nmlen); 754 if(vbmp) verbosity = oldv; 755 756 /* check the answer */ 757 ans_str = msgtostr(msg); 758 /* printout if vbmp */ 759 if(vbmp) printf("got (ret=%s%s):\n%s", 760 (ret?"ok":"fail"), (fallback?" fallback":""), ans_str); 761 /* check expected value for ret */ 762 if(expected_fallback && ret != 0) { 763 /* ret is zero on fallback */ 764 if(vbmp) printf("fallback expected, but " 765 "return value is not false\n"); 766 unit_assert(expected_fallback && ret == 0); 767 } 768 if(ret == 0) { 769 if(!expected_fallback) { 770 if(vbmp) printf("return value is false, " 771 "(unexpected)\n"); 772 } 773 unit_assert(expected_fallback); 774 } 775 /* check expected value for fallback */ 776 if(expected_fallback && !fallback) { 777 if(vbmp) printf("expected fallback, but fallback is no\n"); 778 } else if(!expected_fallback && fallback) { 779 if(vbmp) printf("expected no fallback, but fallback is yes\n"); 780 } 781 unit_assert( (expected_fallback&&fallback) || 782 (!expected_fallback&&!fallback)); 783 /* check answer string */ 784 if(strcmp(q->answer, ans_str) != 0) { 785 if(vbmp) printf("wanted:\n%s", q->answer); 786 line_diff(q->answer, ans_str, "wanted", "got"); 787 } 788 unit_assert(strcmp(q->answer, ans_str) == 0); 789 if(vbmp) printf("query ok\n\n"); 790 free(ans_str); 791 } 792 793 /** check queries on a loaded zone */ 794 static void 795 check_az_q_ans(struct auth_zones* az, struct q_ans* queries) 796 { 797 struct q_ans* q; 798 struct regional* region = regional_create(); 799 struct query_info* qinfo; 800 int fallback; 801 uint8_t* dp_nm; 802 size_t dp_nmlen; 803 for(q=queries; q->zone; q++) { 804 if(vbmp) printf("query %s: %s %s\n", q->zone, q->query, 805 q->flags); 806 q_ans_parse(q, region, &qinfo, &fallback, &dp_nm, &dp_nmlen); 807 q_ans_query(q, az, qinfo, region, fallback, dp_nm, dp_nmlen); 808 regional_free_all(region); 809 } 810 regional_destroy(region); 811 } 812 813 /** check queries for a zone are returned as specified */ 814 static void 815 check_queries(const char* name, const char* zone, struct q_ans* queries) 816 { 817 struct auth_zones* az; 818 struct auth_zone* z; 819 char* fname; 820 if(vbmp) printf("check queries %s\n", name); 821 fname = create_tmp_file(zone); 822 az = auth_zones_create(); 823 if(!az) fatal_exit("out of memory"); 824 z = addzone(az, name, fname); 825 if(!z) fatal_exit("could not read zone for queries test"); 826 del_tmp_file(fname); 827 828 /* run queries and test them */ 829 check_az_q_ans(az, queries); 830 831 auth_zones_delete(az); 832 } 833 834 /** Test authzone read from file */ 835 static void 836 authzone_read_test(void) 837 { 838 if(vbmp) printf("Testing read auth zone\n"); 839 check_read_exact("example.com", zone_example_com); 840 } 841 842 /** Test authzone query from zone */ 843 static void 844 authzone_query_test(void) 845 { 846 if(vbmp) printf("Testing query auth zone\n"); 847 check_queries("example.com", zone_example_com, example_com_queries); 848 } 849 850 /** test authzone code */ 851 void 852 authzone_test(void) 853 { 854 unit_show_feature("authzone"); 855 atexit(tmpfilecleanup); 856 authzone_read_test(); 857 authzone_query_test(); 858 } 859