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