1 1.1 christos /* 2 1.1 christos * services/authzone.c - authoritative zone that is locally hosted. 3 1.1 christos * 4 1.1 christos * Copyright (c) 2017, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * This software is open source. 7 1.1 christos * 8 1.1 christos * Redistribution and use in source and binary forms, with or without 9 1.1 christos * modification, are permitted provided that the following conditions 10 1.1 christos * are met: 11 1.1 christos * 12 1.1 christos * Redistributions of source code must retain the above copyright notice, 13 1.1 christos * this list of conditions and the following disclaimer. 14 1.1 christos * 15 1.1 christos * Redistributions in binary form must reproduce the above copyright notice, 16 1.1 christos * this list of conditions and the following disclaimer in the documentation 17 1.1 christos * and/or other materials provided with the distribution. 18 1.1 christos * 19 1.1 christos * Neither the name of the NLNET LABS nor the names of its contributors may 20 1.1 christos * be used to endorse or promote products derived from this software without 21 1.1 christos * specific prior written permission. 22 1.1 christos * 23 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 1.1 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 1.1 christos * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 1.1 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 1.1 christos * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 1.1 christos * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 1.1 christos * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 1.1 christos * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 1.1 christos * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 1.1 christos */ 35 1.1 christos 36 1.1 christos /** 37 1.1 christos * \file 38 1.1 christos * 39 1.1 christos * This file contains the functions for an authority zone. This zone 40 1.1 christos * is queried by the iterator, just like a stub or forward zone, but then 41 1.1 christos * the data is locally held. 42 1.1 christos */ 43 1.1 christos 44 1.1 christos #include "config.h" 45 1.1 christos #include "services/authzone.h" 46 1.1 christos #include "util/data/dname.h" 47 1.2 christos #include "util/data/msgparse.h" 48 1.1 christos #include "util/data/msgreply.h" 49 1.2 christos #include "util/data/msgencode.h" 50 1.1 christos #include "util/data/packed_rrset.h" 51 1.1 christos #include "util/regional.h" 52 1.1 christos #include "util/net_help.h" 53 1.2 christos #include "util/netevent.h" 54 1.1 christos #include "util/config_file.h" 55 1.1 christos #include "util/log.h" 56 1.2 christos #include "util/module.h" 57 1.2 christos #include "util/random.h" 58 1.1 christos #include "services/cache/dns.h" 59 1.2 christos #include "services/outside_network.h" 60 1.2 christos #include "services/listen_dnsport.h" 61 1.2 christos #include "services/mesh.h" 62 1.1 christos #include "sldns/rrdef.h" 63 1.1 christos #include "sldns/pkthdr.h" 64 1.1 christos #include "sldns/sbuffer.h" 65 1.1 christos #include "sldns/str2wire.h" 66 1.1 christos #include "sldns/wire2str.h" 67 1.1 christos #include "sldns/parseutil.h" 68 1.2 christos #include "sldns/keyraw.h" 69 1.1 christos #include "validator/val_nsec3.h" 70 1.2 christos #include "validator/val_nsec.h" 71 1.1 christos #include "validator/val_secalgo.h" 72 1.2 christos #include "validator/val_sigcrypt.h" 73 1.2 christos #include "validator/val_anchor.h" 74 1.2 christos #include "validator/val_utils.h" 75 1.2 christos #include <ctype.h> 76 1.1 christos 77 1.1 christos /** bytes to use for NSEC3 hash buffer. 20 for sha1 */ 78 1.1 christos #define N3HASHBUFLEN 32 79 1.1 christos /** max number of CNAMEs we are willing to follow (in one answer) */ 80 1.1 christos #define MAX_CNAME_CHAIN 8 81 1.2 christos /** timeout for probe packets for SOA */ 82 1.2 christos #define AUTH_PROBE_TIMEOUT 100 /* msec */ 83 1.2 christos /** when to stop with SOA probes (when exponential timeouts exceed this) */ 84 1.2 christos #define AUTH_PROBE_TIMEOUT_STOP 1000 /* msec */ 85 1.2 christos /* auth transfer timeout for TCP connections, in msec */ 86 1.2 christos #define AUTH_TRANSFER_TIMEOUT 10000 /* msec */ 87 1.2 christos /* auth transfer max backoff for failed transfers and probes */ 88 1.2 christos #define AUTH_TRANSFER_MAX_BACKOFF 86400 /* sec */ 89 1.2 christos /* auth http port number */ 90 1.2 christos #define AUTH_HTTP_PORT 80 91 1.2 christos /* auth https port number */ 92 1.2 christos #define AUTH_HTTPS_PORT 443 93 1.2 christos /* max depth for nested $INCLUDEs */ 94 1.2 christos #define MAX_INCLUDE_DEPTH 10 95 1.2 christos /** number of timeouts before we fallback from IXFR to AXFR, 96 1.2 christos * because some versions of servers (eg. dnsmasq) drop IXFR packets. */ 97 1.2 christos #define NUM_TIMEOUTS_FALLBACK_IXFR 3 98 1.2 christos 99 1.2 christos /** pick up nextprobe task to start waiting to perform transfer actions */ 100 1.2 christos static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, 101 1.2 christos int failure, int lookup_only); 102 1.2 christos /** move to sending the probe packets, next if fails. task_probe */ 103 1.2 christos static void xfr_probe_send_or_end(struct auth_xfer* xfr, 104 1.2 christos struct module_env* env); 105 1.2 christos /** pick up probe task with specified(or NULL) destination first, 106 1.2 christos * or transfer task if nothing to probe, or false if already in progress */ 107 1.2 christos static int xfr_start_probe(struct auth_xfer* xfr, struct module_env* env, 108 1.2 christos struct auth_master* spec); 109 1.2 christos /** delete xfer structure (not its tree entry) */ 110 1.2 christos void auth_xfer_delete(struct auth_xfer* xfr); 111 1.1 christos 112 1.1 christos /** create new dns_msg */ 113 1.1 christos static struct dns_msg* 114 1.1 christos msg_create(struct regional* region, struct query_info* qinfo) 115 1.1 christos { 116 1.1 christos struct dns_msg* msg = (struct dns_msg*)regional_alloc(region, 117 1.1 christos sizeof(struct dns_msg)); 118 1.1 christos if(!msg) 119 1.1 christos return NULL; 120 1.1 christos msg->qinfo.qname = regional_alloc_init(region, qinfo->qname, 121 1.1 christos qinfo->qname_len); 122 1.1 christos if(!msg->qinfo.qname) 123 1.1 christos return NULL; 124 1.1 christos msg->qinfo.qname_len = qinfo->qname_len; 125 1.1 christos msg->qinfo.qtype = qinfo->qtype; 126 1.1 christos msg->qinfo.qclass = qinfo->qclass; 127 1.1 christos msg->qinfo.local_alias = NULL; 128 1.1 christos /* non-packed reply_info, because it needs to grow the array */ 129 1.1 christos msg->rep = (struct reply_info*)regional_alloc_zero(region, 130 1.1 christos sizeof(struct reply_info)-sizeof(struct rrset_ref)); 131 1.1 christos if(!msg->rep) 132 1.1 christos return NULL; 133 1.1 christos msg->rep->flags = (uint16_t)(BIT_QR | BIT_AA); 134 1.1 christos msg->rep->authoritative = 1; 135 1.2 christos msg->rep->reason_bogus = LDNS_EDE_NONE; 136 1.1 christos msg->rep->qdcount = 1; 137 1.1 christos /* rrsets is NULL, no rrsets yet */ 138 1.1 christos return msg; 139 1.1 christos } 140 1.1 christos 141 1.1 christos /** grow rrset array by one in msg */ 142 1.1 christos static int 143 1.1 christos msg_grow_array(struct regional* region, struct dns_msg* msg) 144 1.1 christos { 145 1.1 christos if(msg->rep->rrsets == NULL) { 146 1.1 christos msg->rep->rrsets = regional_alloc_zero(region, 147 1.1 christos sizeof(struct ub_packed_rrset_key*)*(msg->rep->rrset_count+1)); 148 1.1 christos if(!msg->rep->rrsets) 149 1.1 christos return 0; 150 1.1 christos } else { 151 1.1 christos struct ub_packed_rrset_key** rrsets_old = msg->rep->rrsets; 152 1.1 christos msg->rep->rrsets = regional_alloc_zero(region, 153 1.1 christos sizeof(struct ub_packed_rrset_key*)*(msg->rep->rrset_count+1)); 154 1.1 christos if(!msg->rep->rrsets) 155 1.1 christos return 0; 156 1.1 christos memmove(msg->rep->rrsets, rrsets_old, 157 1.1 christos sizeof(struct ub_packed_rrset_key*)*msg->rep->rrset_count); 158 1.1 christos } 159 1.1 christos return 1; 160 1.1 christos } 161 1.1 christos 162 1.1 christos /** get ttl of rrset */ 163 1.1 christos static time_t 164 1.1 christos get_rrset_ttl(struct ub_packed_rrset_key* k) 165 1.1 christos { 166 1.1 christos struct packed_rrset_data* d = (struct packed_rrset_data*) 167 1.1 christos k->entry.data; 168 1.1 christos return d->ttl; 169 1.1 christos } 170 1.1 christos 171 1.1 christos /** Copy rrset into region from domain-datanode and packet rrset */ 172 1.1 christos static struct ub_packed_rrset_key* 173 1.1 christos auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node, 174 1.1 christos struct auth_rrset* rrset, struct regional* region, time_t adjust) 175 1.1 christos { 176 1.1 christos struct ub_packed_rrset_key key; 177 1.1 christos memset(&key, 0, sizeof(key)); 178 1.1 christos key.entry.key = &key; 179 1.1 christos key.entry.data = rrset->data; 180 1.1 christos key.rk.dname = node->name; 181 1.1 christos key.rk.dname_len = node->namelen; 182 1.1 christos key.rk.type = htons(rrset->type); 183 1.1 christos key.rk.rrset_class = htons(z->dclass); 184 1.1 christos key.entry.hash = rrset_key_hash(&key.rk); 185 1.1 christos return packed_rrset_copy_region(&key, region, adjust); 186 1.1 christos } 187 1.1 christos 188 1.1 christos /** fix up msg->rep TTL and prefetch ttl */ 189 1.1 christos static void 190 1.1 christos msg_ttl(struct dns_msg* msg) 191 1.1 christos { 192 1.1 christos if(msg->rep->rrset_count == 0) return; 193 1.1 christos if(msg->rep->rrset_count == 1) { 194 1.1 christos msg->rep->ttl = get_rrset_ttl(msg->rep->rrsets[0]); 195 1.1 christos msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); 196 1.2 christos msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; 197 1.1 christos } else if(get_rrset_ttl(msg->rep->rrsets[msg->rep->rrset_count-1]) < 198 1.1 christos msg->rep->ttl) { 199 1.1 christos msg->rep->ttl = get_rrset_ttl(msg->rep->rrsets[ 200 1.1 christos msg->rep->rrset_count-1]); 201 1.1 christos msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); 202 1.2 christos msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; 203 1.1 christos } 204 1.1 christos } 205 1.1 christos 206 1.1 christos /** see if rrset is a duplicate in the answer message */ 207 1.1 christos static int 208 1.1 christos msg_rrset_duplicate(struct dns_msg* msg, uint8_t* nm, size_t nmlen, 209 1.1 christos uint16_t type, uint16_t dclass) 210 1.1 christos { 211 1.1 christos size_t i; 212 1.1 christos for(i=0; i<msg->rep->rrset_count; i++) { 213 1.1 christos struct ub_packed_rrset_key* k = msg->rep->rrsets[i]; 214 1.1 christos if(ntohs(k->rk.type) == type && k->rk.dname_len == nmlen && 215 1.1 christos ntohs(k->rk.rrset_class) == dclass && 216 1.1 christos query_dname_compare(k->rk.dname, nm) == 0) 217 1.1 christos return 1; 218 1.1 christos } 219 1.1 christos return 0; 220 1.1 christos } 221 1.1 christos 222 1.1 christos /** add rrset to answer section (no auth, add rrsets yet) */ 223 1.1 christos static int 224 1.1 christos msg_add_rrset_an(struct auth_zone* z, struct regional* region, 225 1.1 christos struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset) 226 1.1 christos { 227 1.1 christos log_assert(msg->rep->ns_numrrsets == 0); 228 1.1 christos log_assert(msg->rep->ar_numrrsets == 0); 229 1.2 christos if(!rrset || !node) 230 1.1 christos return 1; 231 1.1 christos if(msg_rrset_duplicate(msg, node->name, node->namelen, rrset->type, 232 1.1 christos z->dclass)) 233 1.1 christos return 1; 234 1.1 christos /* grow array */ 235 1.1 christos if(!msg_grow_array(region, msg)) 236 1.1 christos return 0; 237 1.1 christos /* copy it */ 238 1.1 christos if(!(msg->rep->rrsets[msg->rep->rrset_count] = 239 1.1 christos auth_packed_rrset_copy_region(z, node, rrset, region, 0))) 240 1.1 christos return 0; 241 1.1 christos msg->rep->rrset_count++; 242 1.1 christos msg->rep->an_numrrsets++; 243 1.1 christos msg_ttl(msg); 244 1.1 christos return 1; 245 1.1 christos } 246 1.1 christos 247 1.2 christos /** add rrset to authority section (no additional section rrsets yet) */ 248 1.1 christos static int 249 1.1 christos msg_add_rrset_ns(struct auth_zone* z, struct regional* region, 250 1.1 christos struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset) 251 1.1 christos { 252 1.1 christos log_assert(msg->rep->ar_numrrsets == 0); 253 1.2 christos if(!rrset || !node) 254 1.1 christos return 1; 255 1.1 christos if(msg_rrset_duplicate(msg, node->name, node->namelen, rrset->type, 256 1.1 christos z->dclass)) 257 1.1 christos return 1; 258 1.1 christos /* grow array */ 259 1.1 christos if(!msg_grow_array(region, msg)) 260 1.1 christos return 0; 261 1.1 christos /* copy it */ 262 1.1 christos if(!(msg->rep->rrsets[msg->rep->rrset_count] = 263 1.1 christos auth_packed_rrset_copy_region(z, node, rrset, region, 0))) 264 1.1 christos return 0; 265 1.1 christos msg->rep->rrset_count++; 266 1.1 christos msg->rep->ns_numrrsets++; 267 1.1 christos msg_ttl(msg); 268 1.1 christos return 1; 269 1.1 christos } 270 1.1 christos 271 1.1 christos /** add rrset to additional section */ 272 1.1 christos static int 273 1.1 christos msg_add_rrset_ar(struct auth_zone* z, struct regional* region, 274 1.1 christos struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset) 275 1.1 christos { 276 1.2 christos if(!rrset || !node) 277 1.1 christos return 1; 278 1.1 christos if(msg_rrset_duplicate(msg, node->name, node->namelen, rrset->type, 279 1.1 christos z->dclass)) 280 1.1 christos return 1; 281 1.1 christos /* grow array */ 282 1.1 christos if(!msg_grow_array(region, msg)) 283 1.1 christos return 0; 284 1.1 christos /* copy it */ 285 1.1 christos if(!(msg->rep->rrsets[msg->rep->rrset_count] = 286 1.1 christos auth_packed_rrset_copy_region(z, node, rrset, region, 0))) 287 1.1 christos return 0; 288 1.1 christos msg->rep->rrset_count++; 289 1.1 christos msg->rep->ar_numrrsets++; 290 1.1 christos msg_ttl(msg); 291 1.1 christos return 1; 292 1.1 christos } 293 1.1 christos 294 1.1 christos struct auth_zones* auth_zones_create(void) 295 1.1 christos { 296 1.1 christos struct auth_zones* az = (struct auth_zones*)calloc(1, sizeof(*az)); 297 1.1 christos if(!az) { 298 1.1 christos log_err("out of memory"); 299 1.1 christos return NULL; 300 1.1 christos } 301 1.1 christos rbtree_init(&az->ztree, &auth_zone_cmp); 302 1.2 christos rbtree_init(&az->xtree, &auth_xfer_cmp); 303 1.1 christos lock_rw_init(&az->lock); 304 1.1 christos lock_protect(&az->lock, &az->ztree, sizeof(az->ztree)); 305 1.2 christos lock_protect(&az->lock, &az->xtree, sizeof(az->xtree)); 306 1.2 christos /* also lock protects the rbnode's in struct auth_zone, auth_xfer */ 307 1.2 christos lock_rw_init(&az->rpz_lock); 308 1.2 christos lock_protect(&az->rpz_lock, &az->rpz_first, sizeof(az->rpz_first)); 309 1.1 christos return az; 310 1.1 christos } 311 1.1 christos 312 1.1 christos int auth_zone_cmp(const void* z1, const void* z2) 313 1.1 christos { 314 1.1 christos /* first sort on class, so that hierarchy can be maintained within 315 1.1 christos * a class */ 316 1.1 christos struct auth_zone* a = (struct auth_zone*)z1; 317 1.1 christos struct auth_zone* b = (struct auth_zone*)z2; 318 1.1 christos int m; 319 1.1 christos if(a->dclass != b->dclass) { 320 1.1 christos if(a->dclass < b->dclass) 321 1.1 christos return -1; 322 1.1 christos return 1; 323 1.1 christos } 324 1.1 christos /* sorted such that higher zones sort before lower zones (their 325 1.1 christos * contents) */ 326 1.1 christos return dname_lab_cmp(a->name, a->namelabs, b->name, b->namelabs, &m); 327 1.1 christos } 328 1.1 christos 329 1.1 christos int auth_data_cmp(const void* z1, const void* z2) 330 1.1 christos { 331 1.1 christos struct auth_data* a = (struct auth_data*)z1; 332 1.1 christos struct auth_data* b = (struct auth_data*)z2; 333 1.1 christos int m; 334 1.1 christos /* canonical sort, because DNSSEC needs that */ 335 1.1 christos return dname_canon_lab_cmp(a->name, a->namelabs, b->name, 336 1.1 christos b->namelabs, &m); 337 1.1 christos } 338 1.1 christos 339 1.2 christos int auth_xfer_cmp(const void* z1, const void* z2) 340 1.2 christos { 341 1.2 christos /* first sort on class, so that hierarchy can be maintained within 342 1.2 christos * a class */ 343 1.2 christos struct auth_xfer* a = (struct auth_xfer*)z1; 344 1.2 christos struct auth_xfer* b = (struct auth_xfer*)z2; 345 1.2 christos int m; 346 1.2 christos if(a->dclass != b->dclass) { 347 1.2 christos if(a->dclass < b->dclass) 348 1.2 christos return -1; 349 1.2 christos return 1; 350 1.2 christos } 351 1.2 christos /* sorted such that higher zones sort before lower zones (their 352 1.2 christos * contents) */ 353 1.2 christos return dname_lab_cmp(a->name, a->namelabs, b->name, b->namelabs, &m); 354 1.2 christos } 355 1.2 christos 356 1.1 christos /** delete auth rrset node */ 357 1.1 christos static void 358 1.1 christos auth_rrset_delete(struct auth_rrset* rrset) 359 1.1 christos { 360 1.1 christos if(!rrset) return; 361 1.1 christos free(rrset->data); 362 1.1 christos free(rrset); 363 1.1 christos } 364 1.1 christos 365 1.1 christos /** delete auth data domain node */ 366 1.1 christos static void 367 1.1 christos auth_data_delete(struct auth_data* n) 368 1.1 christos { 369 1.1 christos struct auth_rrset* p, *np; 370 1.1 christos if(!n) return; 371 1.1 christos p = n->rrsets; 372 1.1 christos while(p) { 373 1.1 christos np = p->next; 374 1.1 christos auth_rrset_delete(p); 375 1.1 christos p = np; 376 1.1 christos } 377 1.1 christos free(n->name); 378 1.1 christos free(n); 379 1.1 christos } 380 1.1 christos 381 1.1 christos /** helper traverse to delete zones */ 382 1.1 christos static void 383 1.1 christos auth_data_del(rbnode_type* n, void* ATTR_UNUSED(arg)) 384 1.1 christos { 385 1.1 christos struct auth_data* z = (struct auth_data*)n->key; 386 1.1 christos auth_data_delete(z); 387 1.1 christos } 388 1.1 christos 389 1.1 christos /** delete an auth zone structure (tree remove must be done elsewhere) */ 390 1.1 christos static void 391 1.2 christos auth_zone_delete(struct auth_zone* z, struct auth_zones* az) 392 1.1 christos { 393 1.1 christos if(!z) return; 394 1.1 christos lock_rw_destroy(&z->lock); 395 1.1 christos traverse_postorder(&z->data, auth_data_del, NULL); 396 1.2 christos 397 1.2 christos if(az && z->rpz) { 398 1.2 christos /* keep RPZ linked list intact */ 399 1.2 christos lock_rw_wrlock(&az->rpz_lock); 400 1.2 christos if(z->rpz_az_prev) 401 1.2 christos z->rpz_az_prev->rpz_az_next = z->rpz_az_next; 402 1.2 christos else 403 1.2 christos az->rpz_first = z->rpz_az_next; 404 1.2 christos if(z->rpz_az_next) 405 1.2 christos z->rpz_az_next->rpz_az_prev = z->rpz_az_prev; 406 1.2 christos lock_rw_unlock(&az->rpz_lock); 407 1.2 christos } 408 1.2 christos if(z->rpz) 409 1.2 christos rpz_delete(z->rpz); 410 1.1 christos free(z->name); 411 1.1 christos free(z->zonefile); 412 1.1 christos free(z); 413 1.1 christos } 414 1.1 christos 415 1.1 christos struct auth_zone* 416 1.1 christos auth_zone_create(struct auth_zones* az, uint8_t* nm, size_t nmlen, 417 1.1 christos uint16_t dclass) 418 1.1 christos { 419 1.1 christos struct auth_zone* z = (struct auth_zone*)calloc(1, sizeof(*z)); 420 1.1 christos if(!z) { 421 1.1 christos return NULL; 422 1.1 christos } 423 1.1 christos z->node.key = z; 424 1.1 christos z->dclass = dclass; 425 1.1 christos z->namelen = nmlen; 426 1.1 christos z->namelabs = dname_count_labels(nm); 427 1.1 christos z->name = memdup(nm, nmlen); 428 1.1 christos if(!z->name) { 429 1.1 christos free(z); 430 1.1 christos return NULL; 431 1.1 christos } 432 1.1 christos rbtree_init(&z->data, &auth_data_cmp); 433 1.1 christos lock_rw_init(&z->lock); 434 1.2 christos lock_protect(&z->lock, &z->name, sizeof(*z)-sizeof(rbnode_type)- 435 1.2 christos sizeof(&z->rpz_az_next)-sizeof(&z->rpz_az_prev)); 436 1.1 christos lock_rw_wrlock(&z->lock); 437 1.2 christos /* z lock protects all, except rbtree itself and the rpz linked list 438 1.2 christos * pointers, which are protected using az->lock */ 439 1.1 christos if(!rbtree_insert(&az->ztree, &z->node)) { 440 1.1 christos lock_rw_unlock(&z->lock); 441 1.2 christos auth_zone_delete(z, NULL); 442 1.1 christos log_warn("duplicate auth zone"); 443 1.1 christos return NULL; 444 1.1 christos } 445 1.1 christos return z; 446 1.1 christos } 447 1.1 christos 448 1.1 christos struct auth_zone* 449 1.1 christos auth_zone_find(struct auth_zones* az, uint8_t* nm, size_t nmlen, 450 1.1 christos uint16_t dclass) 451 1.1 christos { 452 1.1 christos struct auth_zone key; 453 1.1 christos key.node.key = &key; 454 1.1 christos key.dclass = dclass; 455 1.1 christos key.name = nm; 456 1.1 christos key.namelen = nmlen; 457 1.1 christos key.namelabs = dname_count_labels(nm); 458 1.1 christos return (struct auth_zone*)rbtree_search(&az->ztree, &key); 459 1.1 christos } 460 1.1 christos 461 1.2 christos struct auth_xfer* 462 1.2 christos auth_xfer_find(struct auth_zones* az, uint8_t* nm, size_t nmlen, 463 1.2 christos uint16_t dclass) 464 1.2 christos { 465 1.2 christos struct auth_xfer key; 466 1.2 christos key.node.key = &key; 467 1.2 christos key.dclass = dclass; 468 1.2 christos key.name = nm; 469 1.2 christos key.namelen = nmlen; 470 1.2 christos key.namelabs = dname_count_labels(nm); 471 1.2 christos return (struct auth_xfer*)rbtree_search(&az->xtree, &key); 472 1.2 christos } 473 1.2 christos 474 1.1 christos /** find an auth zone or sorted less-or-equal, return true if exact */ 475 1.1 christos static int 476 1.1 christos auth_zone_find_less_equal(struct auth_zones* az, uint8_t* nm, size_t nmlen, 477 1.1 christos uint16_t dclass, struct auth_zone** z) 478 1.1 christos { 479 1.1 christos struct auth_zone key; 480 1.1 christos key.node.key = &key; 481 1.1 christos key.dclass = dclass; 482 1.1 christos key.name = nm; 483 1.1 christos key.namelen = nmlen; 484 1.1 christos key.namelabs = dname_count_labels(nm); 485 1.1 christos return rbtree_find_less_equal(&az->ztree, &key, (rbnode_type**)z); 486 1.1 christos } 487 1.1 christos 488 1.2 christos 489 1.2 christos /** find the auth zone that is above the given name */ 490 1.1 christos struct auth_zone* 491 1.2 christos auth_zones_find_zone(struct auth_zones* az, uint8_t* name, size_t name_len, 492 1.2 christos uint16_t dclass) 493 1.1 christos { 494 1.2 christos uint8_t* nm = name; 495 1.2 christos size_t nmlen = name_len; 496 1.1 christos struct auth_zone* z; 497 1.2 christos if(auth_zone_find_less_equal(az, nm, nmlen, dclass, &z)) { 498 1.1 christos /* exact match */ 499 1.1 christos return z; 500 1.1 christos } else { 501 1.1 christos /* less-or-nothing */ 502 1.1 christos if(!z) return NULL; /* nothing smaller, nothing above it */ 503 1.2 christos /* we found smaller name; smaller may be above the name, 504 1.1 christos * but not below it. */ 505 1.2 christos nm = dname_get_shared_topdomain(z->name, name); 506 1.1 christos dname_count_size_labels(nm, &nmlen); 507 1.2 christos z = NULL; 508 1.1 christos } 509 1.2 christos 510 1.1 christos /* search up */ 511 1.2 christos while(!z) { 512 1.2 christos z = auth_zone_find(az, nm, nmlen, dclass); 513 1.2 christos if(z) return z; 514 1.2 christos if(dname_is_root(nm)) break; 515 1.1 christos dname_remove_label(&nm, &nmlen); 516 1.1 christos } 517 1.2 christos return NULL; 518 1.1 christos } 519 1.1 christos 520 1.1 christos /** find or create zone with name str. caller must have lock on az. 521 1.1 christos * returns a wrlocked zone */ 522 1.1 christos static struct auth_zone* 523 1.1 christos auth_zones_find_or_add_zone(struct auth_zones* az, char* name) 524 1.1 christos { 525 1.1 christos uint8_t nm[LDNS_MAX_DOMAINLEN+1]; 526 1.1 christos size_t nmlen = sizeof(nm); 527 1.1 christos struct auth_zone* z; 528 1.1 christos 529 1.1 christos if(sldns_str2wire_dname_buf(name, nm, &nmlen) != 0) { 530 1.1 christos log_err("cannot parse auth zone name: %s", name); 531 1.1 christos return 0; 532 1.1 christos } 533 1.1 christos z = auth_zone_find(az, nm, nmlen, LDNS_RR_CLASS_IN); 534 1.1 christos if(!z) { 535 1.1 christos /* not found, create the zone */ 536 1.1 christos z = auth_zone_create(az, nm, nmlen, LDNS_RR_CLASS_IN); 537 1.1 christos } else { 538 1.1 christos lock_rw_wrlock(&z->lock); 539 1.1 christos } 540 1.1 christos return z; 541 1.1 christos } 542 1.1 christos 543 1.2 christos /** find or create xfer zone with name str. caller must have lock on az. 544 1.2 christos * returns a locked xfer */ 545 1.2 christos static struct auth_xfer* 546 1.2 christos auth_zones_find_or_add_xfer(struct auth_zones* az, struct auth_zone* z) 547 1.2 christos { 548 1.2 christos struct auth_xfer* x; 549 1.2 christos x = auth_xfer_find(az, z->name, z->namelen, z->dclass); 550 1.2 christos if(!x) { 551 1.2 christos /* not found, create the zone */ 552 1.2 christos x = auth_xfer_create(az, z); 553 1.2 christos } else { 554 1.2 christos lock_basic_lock(&x->lock); 555 1.2 christos } 556 1.2 christos return x; 557 1.2 christos } 558 1.2 christos 559 1.1 christos int 560 1.1 christos auth_zone_set_zonefile(struct auth_zone* z, char* zonefile) 561 1.1 christos { 562 1.1 christos if(z->zonefile) free(z->zonefile); 563 1.1 christos if(zonefile == NULL) { 564 1.1 christos z->zonefile = NULL; 565 1.1 christos } else { 566 1.1 christos z->zonefile = strdup(zonefile); 567 1.1 christos if(!z->zonefile) { 568 1.1 christos log_err("malloc failure"); 569 1.1 christos return 0; 570 1.1 christos } 571 1.1 christos } 572 1.1 christos return 1; 573 1.1 christos } 574 1.1 christos 575 1.1 christos /** set auth zone fallback. caller must have lock on zone */ 576 1.1 christos int 577 1.1 christos auth_zone_set_fallback(struct auth_zone* z, char* fallbackstr) 578 1.1 christos { 579 1.1 christos if(strcmp(fallbackstr, "yes") != 0 && strcmp(fallbackstr, "no") != 0){ 580 1.1 christos log_err("auth zone fallback, expected yes or no, got %s", 581 1.1 christos fallbackstr); 582 1.1 christos return 0; 583 1.1 christos } 584 1.1 christos z->fallback_enabled = (strcmp(fallbackstr, "yes")==0); 585 1.1 christos return 1; 586 1.1 christos } 587 1.1 christos 588 1.1 christos /** create domain with the given name */ 589 1.1 christos static struct auth_data* 590 1.1 christos az_domain_create(struct auth_zone* z, uint8_t* nm, size_t nmlen) 591 1.1 christos { 592 1.1 christos struct auth_data* n = (struct auth_data*)malloc(sizeof(*n)); 593 1.1 christos if(!n) return NULL; 594 1.1 christos memset(n, 0, sizeof(*n)); 595 1.1 christos n->node.key = n; 596 1.1 christos n->name = memdup(nm, nmlen); 597 1.1 christos if(!n->name) { 598 1.1 christos free(n); 599 1.1 christos return NULL; 600 1.1 christos } 601 1.1 christos n->namelen = nmlen; 602 1.1 christos n->namelabs = dname_count_labels(nm); 603 1.1 christos if(!rbtree_insert(&z->data, &n->node)) { 604 1.1 christos log_warn("duplicate auth domain name"); 605 1.1 christos free(n->name); 606 1.1 christos free(n); 607 1.1 christos return NULL; 608 1.1 christos } 609 1.1 christos return n; 610 1.1 christos } 611 1.1 christos 612 1.1 christos /** find domain with exactly the given name */ 613 1.1 christos static struct auth_data* 614 1.1 christos az_find_name(struct auth_zone* z, uint8_t* nm, size_t nmlen) 615 1.1 christos { 616 1.1 christos struct auth_zone key; 617 1.1 christos key.node.key = &key; 618 1.1 christos key.name = nm; 619 1.1 christos key.namelen = nmlen; 620 1.1 christos key.namelabs = dname_count_labels(nm); 621 1.1 christos return (struct auth_data*)rbtree_search(&z->data, &key); 622 1.1 christos } 623 1.1 christos 624 1.1 christos /** Find domain name (or closest match) */ 625 1.1 christos static void 626 1.1 christos az_find_domain(struct auth_zone* z, struct query_info* qinfo, int* node_exact, 627 1.1 christos struct auth_data** node) 628 1.1 christos { 629 1.1 christos struct auth_zone key; 630 1.1 christos key.node.key = &key; 631 1.1 christos key.name = qinfo->qname; 632 1.1 christos key.namelen = qinfo->qname_len; 633 1.1 christos key.namelabs = dname_count_labels(key.name); 634 1.1 christos *node_exact = rbtree_find_less_equal(&z->data, &key, 635 1.1 christos (rbnode_type**)node); 636 1.1 christos } 637 1.1 christos 638 1.1 christos /** find or create domain with name in zone */ 639 1.1 christos static struct auth_data* 640 1.1 christos az_domain_find_or_create(struct auth_zone* z, uint8_t* dname, 641 1.1 christos size_t dname_len) 642 1.1 christos { 643 1.1 christos struct auth_data* n = az_find_name(z, dname, dname_len); 644 1.1 christos if(!n) { 645 1.1 christos n = az_domain_create(z, dname, dname_len); 646 1.1 christos } 647 1.1 christos return n; 648 1.1 christos } 649 1.1 christos 650 1.1 christos /** find rrset of given type in the domain */ 651 1.1 christos static struct auth_rrset* 652 1.1 christos az_domain_rrset(struct auth_data* n, uint16_t t) 653 1.1 christos { 654 1.1 christos struct auth_rrset* rrset; 655 1.1 christos if(!n) return NULL; 656 1.1 christos rrset = n->rrsets; 657 1.1 christos while(rrset) { 658 1.1 christos if(rrset->type == t) 659 1.1 christos return rrset; 660 1.1 christos rrset = rrset->next; 661 1.1 christos } 662 1.1 christos return NULL; 663 1.1 christos } 664 1.1 christos 665 1.1 christos /** remove rrset of this type from domain */ 666 1.1 christos static void 667 1.1 christos domain_remove_rrset(struct auth_data* node, uint16_t rr_type) 668 1.1 christos { 669 1.1 christos struct auth_rrset* rrset, *prev; 670 1.1 christos if(!node) return; 671 1.1 christos prev = NULL; 672 1.1 christos rrset = node->rrsets; 673 1.1 christos while(rrset) { 674 1.1 christos if(rrset->type == rr_type) { 675 1.1 christos /* found it, now delete it */ 676 1.1 christos if(prev) prev->next = rrset->next; 677 1.1 christos else node->rrsets = rrset->next; 678 1.1 christos auth_rrset_delete(rrset); 679 1.1 christos return; 680 1.1 christos } 681 1.1 christos prev = rrset; 682 1.1 christos rrset = rrset->next; 683 1.1 christos } 684 1.1 christos } 685 1.1 christos 686 1.2 christos /** find an rrsig index in the rrset. returns true if found */ 687 1.2 christos static int 688 1.2 christos az_rrset_find_rrsig(struct packed_rrset_data* d, uint8_t* rdata, size_t len, 689 1.2 christos size_t* index) 690 1.2 christos { 691 1.2 christos size_t i; 692 1.2 christos for(i=d->count; i<d->count + d->rrsig_count; i++) { 693 1.2 christos if(d->rr_len[i] != len) 694 1.2 christos continue; 695 1.2 christos if(memcmp(d->rr_data[i], rdata, len) == 0) { 696 1.2 christos *index = i; 697 1.2 christos return 1; 698 1.2 christos } 699 1.2 christos } 700 1.2 christos return 0; 701 1.2 christos } 702 1.2 christos 703 1.1 christos /** see if rdata is duplicate */ 704 1.1 christos static int 705 1.1 christos rdata_duplicate(struct packed_rrset_data* d, uint8_t* rdata, size_t len) 706 1.1 christos { 707 1.1 christos size_t i; 708 1.1 christos for(i=0; i<d->count + d->rrsig_count; i++) { 709 1.1 christos if(d->rr_len[i] != len) 710 1.1 christos continue; 711 1.1 christos if(memcmp(d->rr_data[i], rdata, len) == 0) 712 1.1 christos return 1; 713 1.1 christos } 714 1.1 christos return 0; 715 1.1 christos } 716 1.1 christos 717 1.1 christos /** get rrsig type covered from rdata. 718 1.1 christos * @param rdata: rdata in wireformat, starting with 16bit rdlength. 719 1.1 christos * @param rdatalen: length of rdata buffer. 720 1.1 christos * @return type covered (or 0). 721 1.1 christos */ 722 1.1 christos static uint16_t 723 1.1 christos rrsig_rdata_get_type_covered(uint8_t* rdata, size_t rdatalen) 724 1.1 christos { 725 1.1 christos if(rdatalen < 4) 726 1.1 christos return 0; 727 1.1 christos return sldns_read_uint16(rdata+2); 728 1.1 christos } 729 1.1 christos 730 1.2 christos /** remove RR from existing RRset. Also sig, if it is a signature. 731 1.2 christos * reallocates the packed rrset for a new one, false on alloc failure */ 732 1.2 christos static int 733 1.2 christos rrset_remove_rr(struct auth_rrset* rrset, size_t index) 734 1.2 christos { 735 1.2 christos struct packed_rrset_data* d, *old = rrset->data; 736 1.2 christos size_t i; 737 1.2 christos if(index >= old->count + old->rrsig_count) 738 1.2 christos return 0; /* index out of bounds */ 739 1.2 christos d = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(old) - ( 740 1.2 christos sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t) + 741 1.2 christos old->rr_len[index])); 742 1.2 christos if(!d) { 743 1.2 christos log_err("malloc failure"); 744 1.2 christos return 0; 745 1.2 christos } 746 1.2 christos d->ttl = old->ttl; 747 1.2 christos d->count = old->count; 748 1.2 christos d->rrsig_count = old->rrsig_count; 749 1.2 christos if(index < d->count) d->count--; 750 1.2 christos else d->rrsig_count--; 751 1.2 christos d->trust = old->trust; 752 1.2 christos d->security = old->security; 753 1.2 christos 754 1.2 christos /* set rr_len, needed for ptr_fixup */ 755 1.2 christos d->rr_len = (size_t*)((uint8_t*)d + 756 1.2 christos sizeof(struct packed_rrset_data)); 757 1.2 christos if(index > 0) 758 1.2 christos memmove(d->rr_len, old->rr_len, (index)*sizeof(size_t)); 759 1.2 christos if(index+1 < old->count+old->rrsig_count) 760 1.2 christos memmove(&d->rr_len[index], &old->rr_len[index+1], 761 1.2 christos (old->count+old->rrsig_count - (index+1))*sizeof(size_t)); 762 1.2 christos packed_rrset_ptr_fixup(d); 763 1.2 christos 764 1.2 christos /* move over ttls */ 765 1.2 christos if(index > 0) 766 1.2 christos memmove(d->rr_ttl, old->rr_ttl, (index)*sizeof(time_t)); 767 1.2 christos if(index+1 < old->count+old->rrsig_count) 768 1.2 christos memmove(&d->rr_ttl[index], &old->rr_ttl[index+1], 769 1.2 christos (old->count+old->rrsig_count - (index+1))*sizeof(time_t)); 770 1.2 christos 771 1.2 christos /* move over rr_data */ 772 1.2 christos for(i=0; i<d->count+d->rrsig_count; i++) { 773 1.2 christos size_t oldi; 774 1.2 christos if(i < index) oldi = i; 775 1.2 christos else oldi = i+1; 776 1.2 christos memmove(d->rr_data[i], old->rr_data[oldi], d->rr_len[i]); 777 1.2 christos } 778 1.2 christos 779 1.2 christos /* recalc ttl (lowest of remaining RR ttls) */ 780 1.2 christos if(d->count + d->rrsig_count > 0) 781 1.2 christos d->ttl = d->rr_ttl[0]; 782 1.2 christos for(i=0; i<d->count+d->rrsig_count; i++) { 783 1.2 christos if(d->rr_ttl[i] < d->ttl) 784 1.2 christos d->ttl = d->rr_ttl[i]; 785 1.2 christos } 786 1.2 christos 787 1.2 christos free(rrset->data); 788 1.2 christos rrset->data = d; 789 1.2 christos return 1; 790 1.2 christos } 791 1.2 christos 792 1.1 christos /** add RR to existing RRset. If insert_sig is true, add to rrsigs. 793 1.1 christos * This reallocates the packed rrset for a new one */ 794 1.1 christos static int 795 1.1 christos rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata, 796 1.1 christos size_t rdatalen, int insert_sig) 797 1.1 christos { 798 1.1 christos struct packed_rrset_data* d, *old = rrset->data; 799 1.1 christos size_t total, old_total; 800 1.1 christos 801 1.1 christos d = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(old) 802 1.1 christos + sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t) 803 1.1 christos + rdatalen); 804 1.1 christos if(!d) { 805 1.1 christos log_err("out of memory"); 806 1.1 christos return 0; 807 1.1 christos } 808 1.1 christos /* copy base values */ 809 1.1 christos memcpy(d, old, sizeof(struct packed_rrset_data)); 810 1.1 christos if(!insert_sig) { 811 1.1 christos d->count++; 812 1.1 christos } else { 813 1.1 christos d->rrsig_count++; 814 1.1 christos } 815 1.1 christos old_total = old->count + old->rrsig_count; 816 1.1 christos total = d->count + d->rrsig_count; 817 1.1 christos /* set rr_len, needed for ptr_fixup */ 818 1.1 christos d->rr_len = (size_t*)((uint8_t*)d + 819 1.1 christos sizeof(struct packed_rrset_data)); 820 1.1 christos if(old->count != 0) 821 1.1 christos memmove(d->rr_len, old->rr_len, old->count*sizeof(size_t)); 822 1.1 christos if(old->rrsig_count != 0) 823 1.1 christos memmove(d->rr_len+d->count, old->rr_len+old->count, 824 1.1 christos old->rrsig_count*sizeof(size_t)); 825 1.1 christos if(!insert_sig) 826 1.1 christos d->rr_len[d->count-1] = rdatalen; 827 1.1 christos else d->rr_len[total-1] = rdatalen; 828 1.1 christos packed_rrset_ptr_fixup(d); 829 1.1 christos if((time_t)rr_ttl < d->ttl) 830 1.1 christos d->ttl = rr_ttl; 831 1.1 christos 832 1.1 christos /* copy old values into new array */ 833 1.1 christos if(old->count != 0) { 834 1.1 christos memmove(d->rr_ttl, old->rr_ttl, old->count*sizeof(time_t)); 835 1.1 christos /* all the old rr pieces are allocated sequential, so we 836 1.1 christos * can copy them in one go */ 837 1.1 christos memmove(d->rr_data[0], old->rr_data[0], 838 1.1 christos (old->rr_data[old->count-1] - old->rr_data[0]) + 839 1.1 christos old->rr_len[old->count-1]); 840 1.1 christos } 841 1.1 christos if(old->rrsig_count != 0) { 842 1.1 christos memmove(d->rr_ttl+d->count, old->rr_ttl+old->count, 843 1.1 christos old->rrsig_count*sizeof(time_t)); 844 1.1 christos memmove(d->rr_data[d->count], old->rr_data[old->count], 845 1.1 christos (old->rr_data[old_total-1] - old->rr_data[old->count]) + 846 1.1 christos old->rr_len[old_total-1]); 847 1.1 christos } 848 1.1 christos 849 1.1 christos /* insert new value */ 850 1.1 christos if(!insert_sig) { 851 1.1 christos d->rr_ttl[d->count-1] = rr_ttl; 852 1.1 christos memmove(d->rr_data[d->count-1], rdata, rdatalen); 853 1.1 christos } else { 854 1.1 christos d->rr_ttl[total-1] = rr_ttl; 855 1.1 christos memmove(d->rr_data[total-1], rdata, rdatalen); 856 1.1 christos } 857 1.1 christos 858 1.1 christos rrset->data = d; 859 1.1 christos free(old); 860 1.1 christos return 1; 861 1.1 christos } 862 1.1 christos 863 1.1 christos /** Create new rrset for node with packed rrset with one RR element */ 864 1.1 christos static struct auth_rrset* 865 1.1 christos rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl, 866 1.1 christos uint8_t* rdata, size_t rdatalen) 867 1.1 christos { 868 1.1 christos struct auth_rrset* rrset = (struct auth_rrset*)calloc(1, 869 1.1 christos sizeof(*rrset)); 870 1.1 christos struct auth_rrset* p, *prev; 871 1.1 christos struct packed_rrset_data* d; 872 1.1 christos if(!rrset) { 873 1.1 christos log_err("out of memory"); 874 1.1 christos return NULL; 875 1.1 christos } 876 1.1 christos rrset->type = rr_type; 877 1.1 christos 878 1.1 christos /* the rrset data structure, with one RR */ 879 1.1 christos d = (struct packed_rrset_data*)calloc(1, 880 1.1 christos sizeof(struct packed_rrset_data) + sizeof(size_t) + 881 1.1 christos sizeof(uint8_t*) + sizeof(time_t) + rdatalen); 882 1.1 christos if(!d) { 883 1.1 christos free(rrset); 884 1.1 christos log_err("out of memory"); 885 1.1 christos return NULL; 886 1.1 christos } 887 1.1 christos rrset->data = d; 888 1.1 christos d->ttl = rr_ttl; 889 1.1 christos d->trust = rrset_trust_prim_noglue; 890 1.1 christos d->rr_len = (size_t*)((uint8_t*)d + sizeof(struct packed_rrset_data)); 891 1.1 christos d->rr_data = (uint8_t**)&(d->rr_len[1]); 892 1.1 christos d->rr_ttl = (time_t*)&(d->rr_data[1]); 893 1.1 christos d->rr_data[0] = (uint8_t*)&(d->rr_ttl[1]); 894 1.1 christos 895 1.1 christos /* insert the RR */ 896 1.1 christos d->rr_len[0] = rdatalen; 897 1.1 christos d->rr_ttl[0] = rr_ttl; 898 1.1 christos memmove(d->rr_data[0], rdata, rdatalen); 899 1.1 christos d->count++; 900 1.1 christos 901 1.1 christos /* insert rrset into linked list for domain */ 902 1.1 christos /* find sorted place to link the rrset into the list */ 903 1.1 christos prev = NULL; 904 1.1 christos p = node->rrsets; 905 1.1 christos while(p && p->type<=rr_type) { 906 1.1 christos prev = p; 907 1.1 christos p = p->next; 908 1.1 christos } 909 1.1 christos /* so, prev is smaller, and p is larger than rr_type */ 910 1.1 christos rrset->next = p; 911 1.1 christos if(prev) prev->next = rrset; 912 1.1 christos else node->rrsets = rrset; 913 1.1 christos return rrset; 914 1.1 christos } 915 1.1 christos 916 1.1 christos /** count number (and size) of rrsigs that cover a type */ 917 1.1 christos static size_t 918 1.1 christos rrsig_num_that_cover(struct auth_rrset* rrsig, uint16_t rr_type, size_t* sigsz) 919 1.1 christos { 920 1.1 christos struct packed_rrset_data* d = rrsig->data; 921 1.1 christos size_t i, num = 0; 922 1.1 christos *sigsz = 0; 923 1.1 christos log_assert(d && rrsig->type == LDNS_RR_TYPE_RRSIG); 924 1.1 christos for(i=0; i<d->count+d->rrsig_count; i++) { 925 1.1 christos if(rrsig_rdata_get_type_covered(d->rr_data[i], 926 1.1 christos d->rr_len[i]) == rr_type) { 927 1.1 christos num++; 928 1.1 christos (*sigsz) += d->rr_len[i]; 929 1.1 christos } 930 1.1 christos } 931 1.1 christos return num; 932 1.1 christos } 933 1.1 christos 934 1.1 christos /** See if rrsig set has covered sigs for rrset and move them over */ 935 1.1 christos static int 936 1.1 christos rrset_moveover_rrsigs(struct auth_data* node, uint16_t rr_type, 937 1.1 christos struct auth_rrset* rrset, struct auth_rrset* rrsig) 938 1.1 christos { 939 1.1 christos size_t sigs, sigsz, i, j, total; 940 1.1 christos struct packed_rrset_data* sigold = rrsig->data; 941 1.1 christos struct packed_rrset_data* old = rrset->data; 942 1.1 christos struct packed_rrset_data* d, *sigd; 943 1.1 christos 944 1.1 christos log_assert(rrset->type == rr_type); 945 1.1 christos log_assert(rrsig->type == LDNS_RR_TYPE_RRSIG); 946 1.1 christos sigs = rrsig_num_that_cover(rrsig, rr_type, &sigsz); 947 1.1 christos if(sigs == 0) { 948 1.1 christos /* 0 rrsigs to move over, done */ 949 1.1 christos return 1; 950 1.1 christos } 951 1.1 christos 952 1.1 christos /* allocate rrset sigsz larger for extra sigs elements, and 953 1.1 christos * allocate rrsig sigsz smaller for less sigs elements. */ 954 1.1 christos d = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(old) 955 1.1 christos + sigs*(sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t)) 956 1.1 christos + sigsz); 957 1.1 christos if(!d) { 958 1.1 christos log_err("out of memory"); 959 1.1 christos return 0; 960 1.1 christos } 961 1.1 christos /* copy base values */ 962 1.1 christos total = old->count + old->rrsig_count; 963 1.1 christos memcpy(d, old, sizeof(struct packed_rrset_data)); 964 1.1 christos d->rrsig_count += sigs; 965 1.1 christos /* setup rr_len */ 966 1.1 christos d->rr_len = (size_t*)((uint8_t*)d + 967 1.1 christos sizeof(struct packed_rrset_data)); 968 1.1 christos if(total != 0) 969 1.1 christos memmove(d->rr_len, old->rr_len, total*sizeof(size_t)); 970 1.1 christos j = d->count+d->rrsig_count-sigs; 971 1.1 christos for(i=0; i<sigold->count+sigold->rrsig_count; i++) { 972 1.1 christos if(rrsig_rdata_get_type_covered(sigold->rr_data[i], 973 1.1 christos sigold->rr_len[i]) == rr_type) { 974 1.1 christos d->rr_len[j] = sigold->rr_len[i]; 975 1.1 christos j++; 976 1.1 christos } 977 1.1 christos } 978 1.1 christos packed_rrset_ptr_fixup(d); 979 1.1 christos 980 1.1 christos /* copy old values into new array */ 981 1.1 christos if(total != 0) { 982 1.1 christos memmove(d->rr_ttl, old->rr_ttl, total*sizeof(time_t)); 983 1.1 christos /* all the old rr pieces are allocated sequential, so we 984 1.1 christos * can copy them in one go */ 985 1.1 christos memmove(d->rr_data[0], old->rr_data[0], 986 1.1 christos (old->rr_data[total-1] - old->rr_data[0]) + 987 1.1 christos old->rr_len[total-1]); 988 1.1 christos } 989 1.1 christos 990 1.1 christos /* move over the rrsigs to the larger rrset*/ 991 1.1 christos j = d->count+d->rrsig_count-sigs; 992 1.1 christos for(i=0; i<sigold->count+sigold->rrsig_count; i++) { 993 1.1 christos if(rrsig_rdata_get_type_covered(sigold->rr_data[i], 994 1.1 christos sigold->rr_len[i]) == rr_type) { 995 1.1 christos /* move this one over to location j */ 996 1.1 christos d->rr_ttl[j] = sigold->rr_ttl[i]; 997 1.1 christos memmove(d->rr_data[j], sigold->rr_data[i], 998 1.1 christos sigold->rr_len[i]); 999 1.1 christos if(d->rr_ttl[j] < d->ttl) 1000 1.1 christos d->ttl = d->rr_ttl[j]; 1001 1.1 christos j++; 1002 1.1 christos } 1003 1.1 christos } 1004 1.1 christos 1005 1.1 christos /* put it in and deallocate the old rrset */ 1006 1.1 christos rrset->data = d; 1007 1.1 christos free(old); 1008 1.1 christos 1009 1.1 christos /* now make rrsig set smaller */ 1010 1.1 christos if(sigold->count+sigold->rrsig_count == sigs) { 1011 1.1 christos /* remove all sigs from rrsig, remove it entirely */ 1012 1.1 christos domain_remove_rrset(node, LDNS_RR_TYPE_RRSIG); 1013 1.1 christos return 1; 1014 1.1 christos } 1015 1.1 christos log_assert(packed_rrset_sizeof(sigold) > sigs*(sizeof(size_t) + 1016 1.1 christos sizeof(uint8_t*) + sizeof(time_t)) + sigsz); 1017 1.1 christos sigd = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(sigold) 1018 1.1 christos - sigs*(sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t)) 1019 1.1 christos - sigsz); 1020 1.1 christos if(!sigd) { 1021 1.1 christos /* no need to free up d, it has already been placed in the 1022 1.1 christos * node->rrset structure */ 1023 1.1 christos log_err("out of memory"); 1024 1.1 christos return 0; 1025 1.1 christos } 1026 1.1 christos /* copy base values */ 1027 1.1 christos memcpy(sigd, sigold, sizeof(struct packed_rrset_data)); 1028 1.2 christos /* in sigd the RRSIGs are stored in the base of the RR, in count */ 1029 1.2 christos sigd->count -= sigs; 1030 1.1 christos /* setup rr_len */ 1031 1.1 christos sigd->rr_len = (size_t*)((uint8_t*)sigd + 1032 1.1 christos sizeof(struct packed_rrset_data)); 1033 1.1 christos j = 0; 1034 1.1 christos for(i=0; i<sigold->count+sigold->rrsig_count; i++) { 1035 1.1 christos if(rrsig_rdata_get_type_covered(sigold->rr_data[i], 1036 1.1 christos sigold->rr_len[i]) != rr_type) { 1037 1.1 christos sigd->rr_len[j] = sigold->rr_len[i]; 1038 1.1 christos j++; 1039 1.1 christos } 1040 1.1 christos } 1041 1.1 christos packed_rrset_ptr_fixup(sigd); 1042 1.1 christos 1043 1.1 christos /* copy old values into new rrsig array */ 1044 1.1 christos j = 0; 1045 1.1 christos for(i=0; i<sigold->count+sigold->rrsig_count; i++) { 1046 1.1 christos if(rrsig_rdata_get_type_covered(sigold->rr_data[i], 1047 1.1 christos sigold->rr_len[i]) != rr_type) { 1048 1.1 christos /* move this one over to location j */ 1049 1.1 christos sigd->rr_ttl[j] = sigold->rr_ttl[i]; 1050 1.1 christos memmove(sigd->rr_data[j], sigold->rr_data[i], 1051 1.1 christos sigold->rr_len[i]); 1052 1.1 christos if(j==0) sigd->ttl = sigd->rr_ttl[j]; 1053 1.1 christos else { 1054 1.1 christos if(sigd->rr_ttl[j] < sigd->ttl) 1055 1.1 christos sigd->ttl = sigd->rr_ttl[j]; 1056 1.1 christos } 1057 1.1 christos j++; 1058 1.1 christos } 1059 1.1 christos } 1060 1.1 christos 1061 1.1 christos /* put it in and deallocate the old rrset */ 1062 1.1 christos rrsig->data = sigd; 1063 1.1 christos free(sigold); 1064 1.1 christos 1065 1.1 christos return 1; 1066 1.1 christos } 1067 1.1 christos 1068 1.2 christos /** copy the rrsigs from the rrset to the rrsig rrset, because the rrset 1069 1.2 christos * is going to be deleted. reallocates the RRSIG rrset data. */ 1070 1.2 christos static int 1071 1.2 christos rrsigs_copy_from_rrset_to_rrsigset(struct auth_rrset* rrset, 1072 1.2 christos struct auth_rrset* rrsigset) 1073 1.2 christos { 1074 1.2 christos size_t i; 1075 1.2 christos if(rrset->data->rrsig_count == 0) 1076 1.2 christos return 1; 1077 1.2 christos 1078 1.2 christos /* move them over one by one, because there might be duplicates, 1079 1.2 christos * duplicates are ignored */ 1080 1.2 christos for(i=rrset->data->count; 1081 1.2 christos i<rrset->data->count+rrset->data->rrsig_count; i++) { 1082 1.2 christos uint8_t* rdata = rrset->data->rr_data[i]; 1083 1.2 christos size_t rdatalen = rrset->data->rr_len[i]; 1084 1.2 christos time_t rr_ttl = rrset->data->rr_ttl[i]; 1085 1.2 christos 1086 1.2 christos if(rdata_duplicate(rrsigset->data, rdata, rdatalen)) { 1087 1.2 christos continue; 1088 1.2 christos } 1089 1.2 christos if(!rrset_add_rr(rrsigset, rr_ttl, rdata, rdatalen, 0)) 1090 1.2 christos return 0; 1091 1.2 christos } 1092 1.2 christos return 1; 1093 1.2 christos } 1094 1.2 christos 1095 1.1 christos /** Add rr to node, ignores duplicate RRs, 1096 1.1 christos * rdata points to buffer with rdatalen octets, starts with 2bytelength. */ 1097 1.1 christos static int 1098 1.1 christos az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl, 1099 1.2 christos uint8_t* rdata, size_t rdatalen, int* duplicate) 1100 1.1 christos { 1101 1.1 christos struct auth_rrset* rrset; 1102 1.1 christos /* packed rrsets have their rrsigs along with them, sort them out */ 1103 1.1 christos if(rr_type == LDNS_RR_TYPE_RRSIG) { 1104 1.1 christos uint16_t ctype = rrsig_rdata_get_type_covered(rdata, rdatalen); 1105 1.1 christos if((rrset=az_domain_rrset(node, ctype))!= NULL) { 1106 1.1 christos /* a node of the correct type exists, add the RRSIG 1107 1.1 christos * to the rrset of the covered data type */ 1108 1.2 christos if(rdata_duplicate(rrset->data, rdata, rdatalen)) { 1109 1.2 christos if(duplicate) *duplicate = 1; 1110 1.1 christos return 1; 1111 1.2 christos } 1112 1.1 christos if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 1)) 1113 1.1 christos return 0; 1114 1.1 christos } else if((rrset=az_domain_rrset(node, rr_type))!= NULL) { 1115 1.1 christos /* add RRSIG to rrset of type RRSIG */ 1116 1.2 christos if(rdata_duplicate(rrset->data, rdata, rdatalen)) { 1117 1.2 christos if(duplicate) *duplicate = 1; 1118 1.1 christos return 1; 1119 1.2 christos } 1120 1.1 christos if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0)) 1121 1.1 christos return 0; 1122 1.1 christos } else { 1123 1.1 christos /* create rrset of type RRSIG */ 1124 1.1 christos if(!rrset_create(node, rr_type, rr_ttl, rdata, 1125 1.1 christos rdatalen)) 1126 1.1 christos return 0; 1127 1.1 christos } 1128 1.1 christos } else { 1129 1.1 christos /* normal RR type */ 1130 1.1 christos if((rrset=az_domain_rrset(node, rr_type))!= NULL) { 1131 1.1 christos /* add data to existing node with data type */ 1132 1.2 christos if(rdata_duplicate(rrset->data, rdata, rdatalen)) { 1133 1.2 christos if(duplicate) *duplicate = 1; 1134 1.1 christos return 1; 1135 1.2 christos } 1136 1.1 christos if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0)) 1137 1.1 christos return 0; 1138 1.1 christos } else { 1139 1.1 christos struct auth_rrset* rrsig; 1140 1.1 christos /* create new node with data type */ 1141 1.1 christos if(!(rrset=rrset_create(node, rr_type, rr_ttl, rdata, 1142 1.1 christos rdatalen))) 1143 1.1 christos return 0; 1144 1.1 christos 1145 1.1 christos /* see if node of type RRSIG has signatures that 1146 1.1 christos * cover the data type, and move them over */ 1147 1.1 christos /* and then make the RRSIG type smaller */ 1148 1.1 christos if((rrsig=az_domain_rrset(node, LDNS_RR_TYPE_RRSIG)) 1149 1.1 christos != NULL) { 1150 1.1 christos if(!rrset_moveover_rrsigs(node, rr_type, 1151 1.1 christos rrset, rrsig)) 1152 1.1 christos return 0; 1153 1.1 christos } 1154 1.1 christos } 1155 1.1 christos } 1156 1.1 christos return 1; 1157 1.1 christos } 1158 1.1 christos 1159 1.1 christos /** insert RR into zone, ignore duplicates */ 1160 1.1 christos static int 1161 1.1 christos az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len, 1162 1.2 christos size_t dname_len, int* duplicate) 1163 1.1 christos { 1164 1.1 christos struct auth_data* node; 1165 1.1 christos uint8_t* dname = rr; 1166 1.1 christos uint16_t rr_type = sldns_wirerr_get_type(rr, rr_len, dname_len); 1167 1.1 christos uint16_t rr_class = sldns_wirerr_get_class(rr, rr_len, dname_len); 1168 1.1 christos uint32_t rr_ttl = sldns_wirerr_get_ttl(rr, rr_len, dname_len); 1169 1.1 christos size_t rdatalen = ((size_t)sldns_wirerr_get_rdatalen(rr, rr_len, 1170 1.1 christos dname_len))+2; 1171 1.1 christos /* rdata points to rdata prefixed with uint16 rdatalength */ 1172 1.1 christos uint8_t* rdata = sldns_wirerr_get_rdatawl(rr, rr_len, dname_len); 1173 1.1 christos 1174 1.1 christos if(rr_class != z->dclass) { 1175 1.1 christos log_err("wrong class for RR"); 1176 1.1 christos return 0; 1177 1.1 christos } 1178 1.1 christos if(!(node=az_domain_find_or_create(z, dname, dname_len))) { 1179 1.1 christos log_err("cannot create domain"); 1180 1.1 christos return 0; 1181 1.1 christos } 1182 1.2 christos if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata, rdatalen, 1183 1.2 christos duplicate)) { 1184 1.1 christos log_err("cannot add RR to domain"); 1185 1.1 christos return 0; 1186 1.1 christos } 1187 1.2 christos if(z->rpz) { 1188 1.2 christos if(!(rpz_insert_rr(z->rpz, z->name, z->namelen, dname, 1189 1.2 christos dname_len, rr_type, rr_class, rr_ttl, rdata, rdatalen, 1190 1.2 christos rr, rr_len))) 1191 1.2 christos return 0; 1192 1.2 christos } 1193 1.2 christos return 1; 1194 1.2 christos } 1195 1.2 christos 1196 1.2 christos /** Remove rr from node, ignores nonexisting RRs, 1197 1.2 christos * rdata points to buffer with rdatalen octets, starts with 2bytelength. */ 1198 1.2 christos static int 1199 1.2 christos az_domain_remove_rr(struct auth_data* node, uint16_t rr_type, 1200 1.2 christos uint8_t* rdata, size_t rdatalen, int* nonexist) 1201 1.2 christos { 1202 1.2 christos struct auth_rrset* rrset; 1203 1.2 christos size_t index = 0; 1204 1.2 christos 1205 1.2 christos /* find the plain RR of the given type */ 1206 1.2 christos if((rrset=az_domain_rrset(node, rr_type))!= NULL) { 1207 1.2 christos if(packed_rrset_find_rr(rrset->data, rdata, rdatalen, &index)) { 1208 1.2 christos if(rrset->data->count == 1 && 1209 1.2 christos rrset->data->rrsig_count == 0) { 1210 1.2 christos /* last RR, delete the rrset */ 1211 1.2 christos domain_remove_rrset(node, rr_type); 1212 1.2 christos } else if(rrset->data->count == 1 && 1213 1.2 christos rrset->data->rrsig_count != 0) { 1214 1.2 christos /* move RRSIGs to the RRSIG rrset, or 1215 1.2 christos * this one becomes that RRset */ 1216 1.2 christos struct auth_rrset* rrsigset = az_domain_rrset( 1217 1.2 christos node, LDNS_RR_TYPE_RRSIG); 1218 1.2 christos if(rrsigset) { 1219 1.2 christos /* move left over rrsigs to the 1220 1.2 christos * existing rrset of type RRSIG */ 1221 1.2 christos rrsigs_copy_from_rrset_to_rrsigset( 1222 1.2 christos rrset, rrsigset); 1223 1.2 christos /* and then delete the rrset */ 1224 1.2 christos domain_remove_rrset(node, rr_type); 1225 1.2 christos } else { 1226 1.2 christos /* no rrset of type RRSIG, this 1227 1.2 christos * set is now of that type, 1228 1.2 christos * just remove the rr */ 1229 1.2 christos if(!rrset_remove_rr(rrset, index)) 1230 1.2 christos return 0; 1231 1.2 christos rrset->type = LDNS_RR_TYPE_RRSIG; 1232 1.2 christos rrset->data->count = rrset->data->rrsig_count; 1233 1.2 christos rrset->data->rrsig_count = 0; 1234 1.2 christos } 1235 1.2 christos } else { 1236 1.2 christos /* remove the RR from the rrset */ 1237 1.2 christos if(!rrset_remove_rr(rrset, index)) 1238 1.2 christos return 0; 1239 1.2 christos } 1240 1.2 christos return 1; 1241 1.2 christos } 1242 1.2 christos /* rr not found in rrset */ 1243 1.2 christos } 1244 1.2 christos 1245 1.2 christos /* is it a type RRSIG, look under the covered type */ 1246 1.2 christos if(rr_type == LDNS_RR_TYPE_RRSIG) { 1247 1.2 christos uint16_t ctype = rrsig_rdata_get_type_covered(rdata, rdatalen); 1248 1.2 christos if((rrset=az_domain_rrset(node, ctype))!= NULL) { 1249 1.2 christos if(az_rrset_find_rrsig(rrset->data, rdata, rdatalen, 1250 1.2 christos &index)) { 1251 1.2 christos /* rrsig should have d->count > 0, be 1252 1.2 christos * over some rr of that type */ 1253 1.2 christos /* remove the rrsig from the rrsigs list of the 1254 1.2 christos * rrset */ 1255 1.2 christos if(!rrset_remove_rr(rrset, index)) 1256 1.2 christos return 0; 1257 1.2 christos return 1; 1258 1.2 christos } 1259 1.2 christos } 1260 1.2 christos /* also RRSIG not found */ 1261 1.2 christos } 1262 1.2 christos 1263 1.2 christos /* nothing found to delete */ 1264 1.2 christos if(nonexist) *nonexist = 1; 1265 1.2 christos return 1; 1266 1.2 christos } 1267 1.2 christos 1268 1.2 christos /** remove RR from zone, ignore if it does not exist, false on alloc failure*/ 1269 1.2 christos static int 1270 1.2 christos az_remove_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len, 1271 1.2 christos size_t dname_len, int* nonexist) 1272 1.2 christos { 1273 1.2 christos struct auth_data* node; 1274 1.2 christos uint8_t* dname = rr; 1275 1.2 christos uint16_t rr_type = sldns_wirerr_get_type(rr, rr_len, dname_len); 1276 1.2 christos uint16_t rr_class = sldns_wirerr_get_class(rr, rr_len, dname_len); 1277 1.2 christos size_t rdatalen = ((size_t)sldns_wirerr_get_rdatalen(rr, rr_len, 1278 1.2 christos dname_len))+2; 1279 1.2 christos /* rdata points to rdata prefixed with uint16 rdatalength */ 1280 1.2 christos uint8_t* rdata = sldns_wirerr_get_rdatawl(rr, rr_len, dname_len); 1281 1.2 christos 1282 1.2 christos if(rr_class != z->dclass) { 1283 1.2 christos log_err("wrong class for RR"); 1284 1.2 christos /* really also a nonexisting entry, because no records 1285 1.2 christos * of that class in the zone, but return an error because 1286 1.2 christos * getting records of the wrong class is a failure of the 1287 1.2 christos * zone transfer */ 1288 1.2 christos return 0; 1289 1.2 christos } 1290 1.2 christos node = az_find_name(z, dname, dname_len); 1291 1.2 christos if(!node) { 1292 1.2 christos /* node with that name does not exist */ 1293 1.2 christos /* nonexisting entry, because no such name */ 1294 1.2 christos *nonexist = 1; 1295 1.2 christos return 1; 1296 1.2 christos } 1297 1.2 christos if(!az_domain_remove_rr(node, rr_type, rdata, rdatalen, nonexist)) { 1298 1.2 christos /* alloc failure or so */ 1299 1.2 christos return 0; 1300 1.2 christos } 1301 1.2 christos /* remove the node, if necessary */ 1302 1.2 christos /* an rrsets==NULL entry is not kept around for empty nonterminals, 1303 1.2 christos * and also parent nodes are not kept around, so we just delete it */ 1304 1.2 christos if(node->rrsets == NULL) { 1305 1.2 christos (void)rbtree_delete(&z->data, node); 1306 1.2 christos auth_data_delete(node); 1307 1.2 christos } 1308 1.2 christos if(z->rpz) { 1309 1.3 christos rpz_remove_rr(z->rpz, z->name, z->namelen, dname, dname_len, 1310 1.3 christos rr_type, rr_class, rdata, rdatalen); 1311 1.2 christos } 1312 1.2 christos return 1; 1313 1.2 christos } 1314 1.2 christos 1315 1.2 christos /** decompress an RR into the buffer where it'll be an uncompressed RR 1316 1.2 christos * with uncompressed dname and uncompressed rdata (dnames) */ 1317 1.2 christos static int 1318 1.2 christos decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt, 1319 1.2 christos size_t pktlen, uint8_t* dname, uint16_t rr_type, uint16_t rr_class, 1320 1.2 christos uint32_t rr_ttl, uint8_t* rr_data, uint16_t rr_rdlen) 1321 1.2 christos { 1322 1.2 christos sldns_buffer pktbuf; 1323 1.2 christos size_t dname_len = 0; 1324 1.2 christos size_t rdlenpos; 1325 1.2 christos size_t rdlen; 1326 1.2 christos uint8_t* rd; 1327 1.2 christos const sldns_rr_descriptor* desc; 1328 1.2 christos sldns_buffer_init_frm_data(&pktbuf, pkt, pktlen); 1329 1.2 christos sldns_buffer_clear(buf); 1330 1.2 christos 1331 1.2 christos /* decompress dname */ 1332 1.2 christos sldns_buffer_set_position(&pktbuf, 1333 1.2 christos (size_t)(dname - sldns_buffer_current(&pktbuf))); 1334 1.2 christos dname_len = pkt_dname_len(&pktbuf); 1335 1.2 christos if(dname_len == 0) return 0; /* parse fail on dname */ 1336 1.2 christos if(!sldns_buffer_available(buf, dname_len)) return 0; 1337 1.2 christos dname_pkt_copy(&pktbuf, sldns_buffer_current(buf), dname); 1338 1.2 christos sldns_buffer_skip(buf, (ssize_t)dname_len); 1339 1.2 christos 1340 1.2 christos /* type, class, ttl and rdatalength fields */ 1341 1.2 christos if(!sldns_buffer_available(buf, 10)) return 0; 1342 1.2 christos sldns_buffer_write_u16(buf, rr_type); 1343 1.2 christos sldns_buffer_write_u16(buf, rr_class); 1344 1.2 christos sldns_buffer_write_u32(buf, rr_ttl); 1345 1.2 christos rdlenpos = sldns_buffer_position(buf); 1346 1.2 christos sldns_buffer_write_u16(buf, 0); /* rd length position */ 1347 1.2 christos 1348 1.2 christos /* decompress rdata */ 1349 1.2 christos desc = sldns_rr_descript(rr_type); 1350 1.2 christos rd = rr_data; 1351 1.2 christos rdlen = rr_rdlen; 1352 1.2 christos if(rdlen > 0 && desc && desc->_dname_count > 0) { 1353 1.2 christos int count = (int)desc->_dname_count; 1354 1.2 christos int rdf = 0; 1355 1.2 christos size_t len; /* how much rdata to plain copy */ 1356 1.2 christos size_t uncompressed_len, compressed_len; 1357 1.2 christos size_t oldpos; 1358 1.2 christos /* decompress dnames. */ 1359 1.2 christos while(rdlen > 0 && count) { 1360 1.2 christos switch(desc->_wireformat[rdf]) { 1361 1.2 christos case LDNS_RDF_TYPE_DNAME: 1362 1.2 christos sldns_buffer_set_position(&pktbuf, 1363 1.2 christos (size_t)(rd - 1364 1.2 christos sldns_buffer_begin(&pktbuf))); 1365 1.2 christos oldpos = sldns_buffer_position(&pktbuf); 1366 1.2 christos /* moves pktbuf to right after the 1367 1.2 christos * compressed dname, and returns uncompressed 1368 1.2 christos * dname length */ 1369 1.2 christos uncompressed_len = pkt_dname_len(&pktbuf); 1370 1.2 christos if(!uncompressed_len) 1371 1.2 christos return 0; /* parse error in dname */ 1372 1.2 christos if(!sldns_buffer_available(buf, 1373 1.2 christos uncompressed_len)) 1374 1.2 christos /* dname too long for buffer */ 1375 1.2 christos return 0; 1376 1.2 christos dname_pkt_copy(&pktbuf, 1377 1.2 christos sldns_buffer_current(buf), rd); 1378 1.2 christos sldns_buffer_skip(buf, (ssize_t)uncompressed_len); 1379 1.2 christos compressed_len = sldns_buffer_position( 1380 1.2 christos &pktbuf) - oldpos; 1381 1.2 christos rd += compressed_len; 1382 1.2 christos rdlen -= compressed_len; 1383 1.2 christos count--; 1384 1.2 christos len = 0; 1385 1.2 christos break; 1386 1.2 christos case LDNS_RDF_TYPE_STR: 1387 1.2 christos len = rd[0] + 1; 1388 1.2 christos break; 1389 1.2 christos default: 1390 1.2 christos len = get_rdf_size(desc->_wireformat[rdf]); 1391 1.2 christos break; 1392 1.2 christos } 1393 1.2 christos if(len) { 1394 1.2 christos if(!sldns_buffer_available(buf, len)) 1395 1.2 christos return 0; /* too long for buffer */ 1396 1.2 christos sldns_buffer_write(buf, rd, len); 1397 1.2 christos rd += len; 1398 1.2 christos rdlen -= len; 1399 1.2 christos } 1400 1.2 christos rdf++; 1401 1.2 christos } 1402 1.2 christos } 1403 1.2 christos /* copy remaining data */ 1404 1.2 christos if(rdlen > 0) { 1405 1.2 christos if(!sldns_buffer_available(buf, rdlen)) return 0; 1406 1.2 christos sldns_buffer_write(buf, rd, rdlen); 1407 1.2 christos } 1408 1.2 christos /* fixup rdlength */ 1409 1.2 christos sldns_buffer_write_u16_at(buf, rdlenpos, 1410 1.2 christos sldns_buffer_position(buf)-rdlenpos-2); 1411 1.2 christos sldns_buffer_flip(buf); 1412 1.1 christos return 1; 1413 1.1 christos } 1414 1.1 christos 1415 1.2 christos /** insert RR into zone, from packet, decompress RR, 1416 1.2 christos * if duplicate is nonNULL set the flag but otherwise ignore duplicates */ 1417 1.2 christos static int 1418 1.2 christos az_insert_rr_decompress(struct auth_zone* z, uint8_t* pkt, size_t pktlen, 1419 1.2 christos struct sldns_buffer* scratch_buffer, uint8_t* dname, uint16_t rr_type, 1420 1.2 christos uint16_t rr_class, uint32_t rr_ttl, uint8_t* rr_data, 1421 1.2 christos uint16_t rr_rdlen, int* duplicate) 1422 1.2 christos { 1423 1.2 christos uint8_t* rr; 1424 1.2 christos size_t rr_len; 1425 1.2 christos size_t dname_len; 1426 1.2 christos if(!decompress_rr_into_buffer(scratch_buffer, pkt, pktlen, dname, 1427 1.2 christos rr_type, rr_class, rr_ttl, rr_data, rr_rdlen)) { 1428 1.2 christos log_err("could not decompress RR"); 1429 1.2 christos return 0; 1430 1.2 christos } 1431 1.2 christos rr = sldns_buffer_begin(scratch_buffer); 1432 1.2 christos rr_len = sldns_buffer_limit(scratch_buffer); 1433 1.2 christos dname_len = dname_valid(rr, rr_len); 1434 1.2 christos return az_insert_rr(z, rr, rr_len, dname_len, duplicate); 1435 1.2 christos } 1436 1.2 christos 1437 1.2 christos /** remove RR from zone, from packet, decompress RR, 1438 1.2 christos * if nonexist is nonNULL set the flag but otherwise ignore nonexisting entries*/ 1439 1.2 christos static int 1440 1.2 christos az_remove_rr_decompress(struct auth_zone* z, uint8_t* pkt, size_t pktlen, 1441 1.2 christos struct sldns_buffer* scratch_buffer, uint8_t* dname, uint16_t rr_type, 1442 1.2 christos uint16_t rr_class, uint32_t rr_ttl, uint8_t* rr_data, 1443 1.2 christos uint16_t rr_rdlen, int* nonexist) 1444 1.2 christos { 1445 1.2 christos uint8_t* rr; 1446 1.2 christos size_t rr_len; 1447 1.2 christos size_t dname_len; 1448 1.2 christos if(!decompress_rr_into_buffer(scratch_buffer, pkt, pktlen, dname, 1449 1.2 christos rr_type, rr_class, rr_ttl, rr_data, rr_rdlen)) { 1450 1.2 christos log_err("could not decompress RR"); 1451 1.2 christos return 0; 1452 1.2 christos } 1453 1.2 christos rr = sldns_buffer_begin(scratch_buffer); 1454 1.2 christos rr_len = sldns_buffer_limit(scratch_buffer); 1455 1.2 christos dname_len = dname_valid(rr, rr_len); 1456 1.2 christos return az_remove_rr(z, rr, rr_len, dname_len, nonexist); 1457 1.2 christos } 1458 1.2 christos 1459 1.1 christos /** 1460 1.1 christos * Parse zonefile 1461 1.1 christos * @param z: zone to read in. 1462 1.1 christos * @param in: file to read from (just opened). 1463 1.1 christos * @param rr: buffer to use for RRs, 64k. 1464 1.1 christos * passed so that recursive includes can use the same buffer and do 1465 1.1 christos * not grow the stack too much. 1466 1.1 christos * @param rrbuflen: sizeof rr buffer. 1467 1.1 christos * @param state: parse state with $ORIGIN, $TTL and 'prev-dname' and so on, 1468 1.1 christos * that is kept between includes. 1469 1.1 christos * The lineno is set at 1 and then increased by the function. 1470 1.2 christos * @param fname: file name. 1471 1.2 christos * @param depth: recursion depth for includes 1472 1.2 christos * @param cfg: config for chroot. 1473 1.1 christos * returns false on failure, has printed an error message 1474 1.1 christos */ 1475 1.1 christos static int 1476 1.1 christos az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen, 1477 1.2 christos struct sldns_file_parse_state* state, char* fname, int depth, 1478 1.2 christos struct config_file* cfg) 1479 1.1 christos { 1480 1.1 christos size_t rr_len, dname_len; 1481 1.1 christos int status; 1482 1.1 christos state->lineno = 1; 1483 1.1 christos 1484 1.1 christos while(!feof(in)) { 1485 1.1 christos rr_len = rrbuflen; 1486 1.1 christos dname_len = 0; 1487 1.1 christos status = sldns_fp2wire_rr_buf(in, rr, &rr_len, &dname_len, 1488 1.1 christos state); 1489 1.1 christos if(status == LDNS_WIREPARSE_ERR_INCLUDE && rr_len == 0) { 1490 1.1 christos /* we have $INCLUDE or $something */ 1491 1.1 christos if(strncmp((char*)rr, "$INCLUDE ", 9) == 0 || 1492 1.1 christos strncmp((char*)rr, "$INCLUDE\t", 9) == 0) { 1493 1.1 christos FILE* inc; 1494 1.1 christos int lineno_orig = state->lineno; 1495 1.1 christos char* incfile = (char*)rr + 8; 1496 1.2 christos if(depth > MAX_INCLUDE_DEPTH) { 1497 1.2 christos log_err("%s:%d max include depth" 1498 1.2 christos "exceeded", fname, state->lineno); 1499 1.2 christos return 0; 1500 1.2 christos } 1501 1.1 christos /* skip spaces */ 1502 1.1 christos while(*incfile == ' ' || *incfile == '\t') 1503 1.1 christos incfile++; 1504 1.2 christos /* adjust for chroot on include file */ 1505 1.2 christos if(cfg->chrootdir && cfg->chrootdir[0] && 1506 1.2 christos strncmp(incfile, cfg->chrootdir, 1507 1.2 christos strlen(cfg->chrootdir)) == 0) 1508 1.2 christos incfile += strlen(cfg->chrootdir); 1509 1.2 christos incfile = strdup(incfile); 1510 1.2 christos if(!incfile) { 1511 1.2 christos log_err("malloc failure"); 1512 1.2 christos return 0; 1513 1.2 christos } 1514 1.1 christos verbose(VERB_ALGO, "opening $INCLUDE %s", 1515 1.1 christos incfile); 1516 1.1 christos inc = fopen(incfile, "r"); 1517 1.1 christos if(!inc) { 1518 1.1 christos log_err("%s:%d cannot open include " 1519 1.2 christos "file %s: %s", fname, 1520 1.1 christos lineno_orig, incfile, 1521 1.1 christos strerror(errno)); 1522 1.2 christos free(incfile); 1523 1.1 christos return 0; 1524 1.1 christos } 1525 1.1 christos /* recurse read that file now */ 1526 1.1 christos if(!az_parse_file(z, inc, rr, rrbuflen, 1527 1.2 christos state, incfile, depth+1, cfg)) { 1528 1.1 christos log_err("%s:%d cannot parse include " 1529 1.2 christos "file %s", fname, 1530 1.1 christos lineno_orig, incfile); 1531 1.1 christos fclose(inc); 1532 1.2 christos free(incfile); 1533 1.1 christos return 0; 1534 1.1 christos } 1535 1.1 christos fclose(inc); 1536 1.1 christos verbose(VERB_ALGO, "done with $INCLUDE %s", 1537 1.1 christos incfile); 1538 1.2 christos free(incfile); 1539 1.1 christos state->lineno = lineno_orig; 1540 1.1 christos } 1541 1.1 christos continue; 1542 1.1 christos } 1543 1.1 christos if(status != 0) { 1544 1.2 christos log_err("parse error %s %d:%d: %s", fname, 1545 1.1 christos state->lineno, LDNS_WIREPARSE_OFFSET(status), 1546 1.1 christos sldns_get_errorstr_parse(status)); 1547 1.1 christos return 0; 1548 1.1 christos } 1549 1.1 christos if(rr_len == 0) { 1550 1.1 christos /* EMPTY line, TTL or ORIGIN */ 1551 1.1 christos continue; 1552 1.1 christos } 1553 1.1 christos /* insert wirerr in rrbuf */ 1554 1.2 christos if(!az_insert_rr(z, rr, rr_len, dname_len, NULL)) { 1555 1.1 christos char buf[17]; 1556 1.1 christos sldns_wire2str_type_buf(sldns_wirerr_get_type(rr, 1557 1.1 christos rr_len, dname_len), buf, sizeof(buf)); 1558 1.1 christos log_err("%s:%d cannot insert RR of type %s", 1559 1.2 christos fname, state->lineno, buf); 1560 1.1 christos return 0; 1561 1.1 christos } 1562 1.1 christos } 1563 1.1 christos return 1; 1564 1.1 christos } 1565 1.1 christos 1566 1.1 christos int 1567 1.2 christos auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg) 1568 1.1 christos { 1569 1.1 christos uint8_t rr[LDNS_RR_BUF_SIZE]; 1570 1.1 christos struct sldns_file_parse_state state; 1571 1.2 christos char* zfilename; 1572 1.1 christos FILE* in; 1573 1.1 christos if(!z || !z->zonefile || z->zonefile[0]==0) 1574 1.1 christos return 1; /* no file, or "", nothing to read */ 1575 1.2 christos 1576 1.2 christos zfilename = z->zonefile; 1577 1.2 christos if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(zfilename, 1578 1.2 christos cfg->chrootdir, strlen(cfg->chrootdir)) == 0) 1579 1.2 christos zfilename += strlen(cfg->chrootdir); 1580 1.2 christos if(verbosity >= VERB_ALGO) { 1581 1.4 christos char nm[LDNS_MAX_DOMAINLEN]; 1582 1.2 christos dname_str(z->name, nm); 1583 1.2 christos verbose(VERB_ALGO, "read zonefile %s for %s", zfilename, nm); 1584 1.2 christos } 1585 1.2 christos in = fopen(zfilename, "r"); 1586 1.1 christos if(!in) { 1587 1.1 christos char* n = sldns_wire2str_dname(z->name, z->namelen); 1588 1.2 christos if(z->zone_is_slave && errno == ENOENT) { 1589 1.2 christos /* we fetch the zone contents later, no file yet */ 1590 1.2 christos verbose(VERB_ALGO, "no zonefile %s for %s", 1591 1.2 christos zfilename, n?n:"error"); 1592 1.2 christos free(n); 1593 1.2 christos return 1; 1594 1.2 christos } 1595 1.1 christos log_err("cannot open zonefile %s for %s: %s", 1596 1.2 christos zfilename, n?n:"error", strerror(errno)); 1597 1.1 christos free(n); 1598 1.1 christos return 0; 1599 1.1 christos } 1600 1.2 christos 1601 1.2 christos /* clear the data tree */ 1602 1.2 christos traverse_postorder(&z->data, auth_data_del, NULL); 1603 1.2 christos rbtree_init(&z->data, &auth_data_cmp); 1604 1.2 christos /* clear the RPZ policies */ 1605 1.2 christos if(z->rpz) 1606 1.2 christos rpz_clear(z->rpz); 1607 1.2 christos 1608 1.1 christos memset(&state, 0, sizeof(state)); 1609 1.1 christos /* default TTL to 3600 */ 1610 1.1 christos state.default_ttl = 3600; 1611 1.1 christos /* set $ORIGIN to the zone name */ 1612 1.1 christos if(z->namelen <= sizeof(state.origin)) { 1613 1.1 christos memcpy(state.origin, z->name, z->namelen); 1614 1.1 christos state.origin_len = z->namelen; 1615 1.1 christos } 1616 1.1 christos /* parse the (toplevel) file */ 1617 1.2 christos if(!az_parse_file(z, in, rr, sizeof(rr), &state, zfilename, 0, cfg)) { 1618 1.1 christos char* n = sldns_wire2str_dname(z->name, z->namelen); 1619 1.1 christos log_err("error parsing zonefile %s for %s", 1620 1.2 christos zfilename, n?n:"error"); 1621 1.1 christos free(n); 1622 1.1 christos fclose(in); 1623 1.1 christos return 0; 1624 1.1 christos } 1625 1.1 christos fclose(in); 1626 1.2 christos 1627 1.2 christos if(z->rpz) 1628 1.2 christos rpz_finish_config(z->rpz); 1629 1.1 christos return 1; 1630 1.1 christos } 1631 1.1 christos 1632 1.1 christos /** write buffer to file and check return codes */ 1633 1.1 christos static int 1634 1.2 christos write_out(FILE* out, const char* str, size_t len) 1635 1.1 christos { 1636 1.2 christos size_t r; 1637 1.1 christos if(len == 0) 1638 1.1 christos return 1; 1639 1.1 christos r = fwrite(str, 1, len, out); 1640 1.1 christos if(r == 0) { 1641 1.1 christos log_err("write failed: %s", strerror(errno)); 1642 1.1 christos return 0; 1643 1.1 christos } else if(r < len) { 1644 1.1 christos log_err("write failed: too short (disk full?)"); 1645 1.1 christos return 0; 1646 1.1 christos } 1647 1.1 christos return 1; 1648 1.1 christos } 1649 1.1 christos 1650 1.2 christos /** convert auth rr to string */ 1651 1.2 christos static int 1652 1.2 christos auth_rr_to_string(uint8_t* nm, size_t nmlen, uint16_t tp, uint16_t cl, 1653 1.2 christos struct packed_rrset_data* data, size_t i, char* s, size_t buflen) 1654 1.2 christos { 1655 1.2 christos int w = 0; 1656 1.2 christos size_t slen = buflen, datlen; 1657 1.2 christos uint8_t* dat; 1658 1.2 christos if(i >= data->count) tp = LDNS_RR_TYPE_RRSIG; 1659 1.2 christos dat = nm; 1660 1.2 christos datlen = nmlen; 1661 1.2 christos w += sldns_wire2str_dname_scan(&dat, &datlen, &s, &slen, NULL, 0, NULL); 1662 1.2 christos w += sldns_str_print(&s, &slen, "\t"); 1663 1.2 christos w += sldns_str_print(&s, &slen, "%lu\t", (unsigned long)data->rr_ttl[i]); 1664 1.2 christos w += sldns_wire2str_class_print(&s, &slen, cl); 1665 1.2 christos w += sldns_str_print(&s, &slen, "\t"); 1666 1.2 christos w += sldns_wire2str_type_print(&s, &slen, tp); 1667 1.2 christos w += sldns_str_print(&s, &slen, "\t"); 1668 1.2 christos datlen = data->rr_len[i]-2; 1669 1.2 christos dat = data->rr_data[i]+2; 1670 1.2 christos w += sldns_wire2str_rdata_scan(&dat, &datlen, &s, &slen, tp, NULL, 0, NULL); 1671 1.2 christos 1672 1.2 christos if(tp == LDNS_RR_TYPE_DNSKEY) { 1673 1.2 christos w += sldns_str_print(&s, &slen, " ;{id = %u}", 1674 1.2 christos sldns_calc_keytag_raw(data->rr_data[i]+2, 1675 1.2 christos data->rr_len[i]-2)); 1676 1.2 christos } 1677 1.2 christos w += sldns_str_print(&s, &slen, "\n"); 1678 1.2 christos 1679 1.2 christos if(w >= (int)buflen) { 1680 1.2 christos log_nametypeclass(NO_VERBOSE, "RR too long to print", nm, tp, cl); 1681 1.2 christos return 0; 1682 1.2 christos } 1683 1.2 christos return 1; 1684 1.2 christos } 1685 1.2 christos 1686 1.1 christos /** write rrset to file */ 1687 1.1 christos static int 1688 1.1 christos auth_zone_write_rrset(struct auth_zone* z, struct auth_data* node, 1689 1.1 christos struct auth_rrset* r, FILE* out) 1690 1.1 christos { 1691 1.1 christos size_t i, count = r->data->count + r->data->rrsig_count; 1692 1.1 christos char buf[LDNS_RR_BUF_SIZE]; 1693 1.1 christos for(i=0; i<count; i++) { 1694 1.2 christos if(!auth_rr_to_string(node->name, node->namelen, r->type, 1695 1.2 christos z->dclass, r->data, i, buf, sizeof(buf))) { 1696 1.1 christos verbose(VERB_ALGO, "failed to rr2str rr %d", (int)i); 1697 1.1 christos continue; 1698 1.1 christos } 1699 1.2 christos if(!write_out(out, buf, strlen(buf))) 1700 1.1 christos return 0; 1701 1.1 christos } 1702 1.1 christos return 1; 1703 1.1 christos } 1704 1.1 christos 1705 1.1 christos /** write domain to file */ 1706 1.1 christos static int 1707 1.1 christos auth_zone_write_domain(struct auth_zone* z, struct auth_data* n, FILE* out) 1708 1.1 christos { 1709 1.1 christos struct auth_rrset* r; 1710 1.1 christos /* if this is zone apex, write SOA first */ 1711 1.1 christos if(z->namelen == n->namelen) { 1712 1.1 christos struct auth_rrset* soa = az_domain_rrset(n, LDNS_RR_TYPE_SOA); 1713 1.1 christos if(soa) { 1714 1.1 christos if(!auth_zone_write_rrset(z, n, soa, out)) 1715 1.1 christos return 0; 1716 1.1 christos } 1717 1.1 christos } 1718 1.1 christos /* write all the RRsets for this domain */ 1719 1.1 christos for(r = n->rrsets; r; r = r->next) { 1720 1.1 christos if(z->namelen == n->namelen && 1721 1.1 christos r->type == LDNS_RR_TYPE_SOA) 1722 1.1 christos continue; /* skip SOA here */ 1723 1.1 christos if(!auth_zone_write_rrset(z, n, r, out)) 1724 1.1 christos return 0; 1725 1.1 christos } 1726 1.1 christos return 1; 1727 1.1 christos } 1728 1.1 christos 1729 1.1 christos int auth_zone_write_file(struct auth_zone* z, const char* fname) 1730 1.1 christos { 1731 1.1 christos FILE* out; 1732 1.1 christos struct auth_data* n; 1733 1.1 christos out = fopen(fname, "w"); 1734 1.1 christos if(!out) { 1735 1.1 christos log_err("could not open %s: %s", fname, strerror(errno)); 1736 1.1 christos return 0; 1737 1.1 christos } 1738 1.1 christos RBTREE_FOR(n, struct auth_data*, &z->data) { 1739 1.1 christos if(!auth_zone_write_domain(z, n, out)) { 1740 1.1 christos log_err("could not write domain to %s", fname); 1741 1.1 christos fclose(out); 1742 1.1 christos return 0; 1743 1.1 christos } 1744 1.1 christos } 1745 1.1 christos fclose(out); 1746 1.1 christos return 1; 1747 1.1 christos } 1748 1.1 christos 1749 1.2 christos /** offline verify for zonemd, while reading a zone file to immediately 1750 1.2 christos * spot bad hashes in zonefile as they are read. 1751 1.2 christos * Creates temp buffers, but uses anchors and validation environment 1752 1.2 christos * from the module_env. */ 1753 1.2 christos static void 1754 1.2 christos zonemd_offline_verify(struct auth_zone* z, struct module_env* env_for_val, 1755 1.2 christos struct module_stack* mods) 1756 1.2 christos { 1757 1.2 christos struct module_env env; 1758 1.2 christos time_t now = 0; 1759 1.2 christos if(!z->zonemd_check) 1760 1.2 christos return; 1761 1.2 christos env = *env_for_val; 1762 1.2 christos env.scratch_buffer = sldns_buffer_new(env.cfg->msg_buffer_size); 1763 1.2 christos if(!env.scratch_buffer) { 1764 1.2 christos log_err("out of memory"); 1765 1.2 christos goto clean_exit; 1766 1.2 christos } 1767 1.2 christos env.scratch = regional_create(); 1768 1.2 christos if(!env.now) { 1769 1.2 christos env.now = &now; 1770 1.2 christos now = time(NULL); 1771 1.2 christos } 1772 1.2 christos if(!env.scratch) { 1773 1.2 christos log_err("out of memory"); 1774 1.2 christos goto clean_exit; 1775 1.2 christos } 1776 1.2 christos auth_zone_verify_zonemd(z, &env, mods, NULL, 1, 0); 1777 1.2 christos 1778 1.2 christos clean_exit: 1779 1.2 christos /* clean up and exit */ 1780 1.2 christos sldns_buffer_free(env.scratch_buffer); 1781 1.2 christos regional_destroy(env.scratch); 1782 1.2 christos } 1783 1.2 christos 1784 1.1 christos /** read all auth zones from file (if they have) */ 1785 1.1 christos static int 1786 1.2 christos auth_zones_read_zones(struct auth_zones* az, struct config_file* cfg, 1787 1.2 christos struct module_env* env, struct module_stack* mods) 1788 1.1 christos { 1789 1.1 christos struct auth_zone* z; 1790 1.1 christos lock_rw_wrlock(&az->lock); 1791 1.1 christos RBTREE_FOR(z, struct auth_zone*, &az->ztree) { 1792 1.1 christos lock_rw_wrlock(&z->lock); 1793 1.2 christos if(!auth_zone_read_zonefile(z, cfg)) { 1794 1.1 christos lock_rw_unlock(&z->lock); 1795 1.1 christos lock_rw_unlock(&az->lock); 1796 1.1 christos return 0; 1797 1.1 christos } 1798 1.2 christos if(z->zonefile && z->zonefile[0]!=0 && env) 1799 1.2 christos zonemd_offline_verify(z, env, mods); 1800 1.1 christos lock_rw_unlock(&z->lock); 1801 1.1 christos } 1802 1.1 christos lock_rw_unlock(&az->lock); 1803 1.1 christos return 1; 1804 1.1 christos } 1805 1.1 christos 1806 1.2 christos /** fetch the content of a ZONEMD RR from the rdata */ 1807 1.2 christos static int zonemd_fetch_parameters(struct auth_rrset* zonemd_rrset, size_t i, 1808 1.2 christos uint32_t* serial, int* scheme, int* hashalgo, uint8_t** hash, 1809 1.2 christos size_t* hashlen) 1810 1.2 christos { 1811 1.2 christos size_t rr_len; 1812 1.2 christos uint8_t* rdata; 1813 1.2 christos if(i >= zonemd_rrset->data->count) 1814 1.2 christos return 0; 1815 1.2 christos rr_len = zonemd_rrset->data->rr_len[i]; 1816 1.2 christos if(rr_len < 2+4+1+1) 1817 1.2 christos return 0; /* too short, for rdlen+serial+scheme+algo */ 1818 1.2 christos rdata = zonemd_rrset->data->rr_data[i]; 1819 1.2 christos *serial = sldns_read_uint32(rdata+2); 1820 1.2 christos *scheme = rdata[6]; 1821 1.2 christos *hashalgo = rdata[7]; 1822 1.2 christos *hashlen = rr_len - 8; 1823 1.2 christos if(*hashlen == 0) 1824 1.2 christos *hash = NULL; 1825 1.2 christos else *hash = rdata+8; 1826 1.1 christos return 1; 1827 1.1 christos } 1828 1.1 christos 1829 1.2 christos /** 1830 1.2 christos * See if the ZONEMD scheme, hash occurs more than once. 1831 1.2 christos * @param zonemd_rrset: the zonemd rrset to check with the RRs in it. 1832 1.2 christos * @param index: index of the original, this is allowed to have that 1833 1.2 christos * scheme and hashalgo, but other RRs should not have it. 1834 1.2 christos * @param scheme: the scheme to check for. 1835 1.2 christos * @param hashalgo: the hash algorithm to check for. 1836 1.2 christos * @return true if it occurs more than once. 1837 1.2 christos */ 1838 1.2 christos static int zonemd_is_duplicate_scheme_hash(struct auth_rrset* zonemd_rrset, 1839 1.2 christos size_t index, int scheme, int hashalgo) 1840 1.1 christos { 1841 1.2 christos size_t j; 1842 1.2 christos for(j=0; j<zonemd_rrset->data->count; j++) { 1843 1.2 christos uint32_t serial2 = 0; 1844 1.2 christos int scheme2 = 0, hashalgo2 = 0; 1845 1.2 christos uint8_t* hash2 = NULL; 1846 1.2 christos size_t hashlen2 = 0; 1847 1.2 christos if(index == j) { 1848 1.2 christos /* this is the original */ 1849 1.2 christos continue; 1850 1.2 christos } 1851 1.2 christos if(!zonemd_fetch_parameters(zonemd_rrset, j, &serial2, 1852 1.2 christos &scheme2, &hashalgo2, &hash2, &hashlen2)) { 1853 1.2 christos /* malformed, skip it */ 1854 1.2 christos continue; 1855 1.1 christos } 1856 1.2 christos if(scheme == scheme2 && hashalgo == hashalgo2) { 1857 1.2 christos /* duplicate scheme, hash */ 1858 1.2 christos verbose(VERB_ALGO, "zonemd duplicate for scheme %d " 1859 1.2 christos "and hash %d", scheme, hashalgo); 1860 1.2 christos return 1; 1861 1.1 christos } 1862 1.1 christos } 1863 1.2 christos return 0; 1864 1.1 christos } 1865 1.1 christos 1866 1.2 christos /** 1867 1.2 christos * Check ZONEMDs if present for the auth zone. Depending on config 1868 1.2 christos * it can warn or fail on that. Checks the hash of the ZONEMD. 1869 1.2 christos * @param z: auth zone to check for. 1870 1.2 christos * caller must hold lock on zone. 1871 1.2 christos * @param env: module env for temp buffers. 1872 1.2 christos * @param reason: returned on failure. 1873 1.2 christos * @return false on failure, true if hash checks out. 1874 1.2 christos */ 1875 1.2 christos static int auth_zone_zonemd_check_hash(struct auth_zone* z, 1876 1.2 christos struct module_env* env, char** reason) 1877 1.1 christos { 1878 1.2 christos /* loop over ZONEMDs and see which one is valid. if not print 1879 1.2 christos * failure (depending on config) */ 1880 1.2 christos struct auth_data* apex; 1881 1.2 christos struct auth_rrset* zonemd_rrset; 1882 1.2 christos size_t i; 1883 1.2 christos struct regional* region = NULL; 1884 1.2 christos struct sldns_buffer* buf = NULL; 1885 1.2 christos uint32_t soa_serial = 0; 1886 1.2 christos char* unsupported_reason = NULL; 1887 1.2 christos int only_unsupported = 1; 1888 1.2 christos region = env->scratch; 1889 1.2 christos regional_free_all(region); 1890 1.2 christos buf = env->scratch_buffer; 1891 1.2 christos if(!auth_zone_get_serial(z, &soa_serial)) { 1892 1.2 christos *reason = "zone has no SOA serial"; 1893 1.1 christos return 0; 1894 1.2 christos } 1895 1.2 christos 1896 1.2 christos apex = az_find_name(z, z->name, z->namelen); 1897 1.2 christos if(!apex) { 1898 1.2 christos *reason = "zone has no apex"; 1899 1.1 christos return 0; 1900 1.2 christos } 1901 1.2 christos zonemd_rrset = az_domain_rrset(apex, LDNS_RR_TYPE_ZONEMD); 1902 1.2 christos if(!zonemd_rrset || zonemd_rrset->data->count==0) { 1903 1.2 christos *reason = "zone has no ZONEMD"; 1904 1.2 christos return 0; /* no RRset or no RRs in rrset */ 1905 1.2 christos } 1906 1.2 christos 1907 1.2 christos /* we have a ZONEMD, check if it is correct */ 1908 1.2 christos for(i=0; i<zonemd_rrset->data->count; i++) { 1909 1.2 christos uint32_t serial = 0; 1910 1.2 christos int scheme = 0, hashalgo = 0; 1911 1.2 christos uint8_t* hash = NULL; 1912 1.2 christos size_t hashlen = 0; 1913 1.2 christos if(!zonemd_fetch_parameters(zonemd_rrset, i, &serial, &scheme, 1914 1.2 christos &hashalgo, &hash, &hashlen)) { 1915 1.2 christos /* malformed RR */ 1916 1.2 christos *reason = "ZONEMD rdata malformed"; 1917 1.2 christos only_unsupported = 0; 1918 1.2 christos continue; 1919 1.2 christos } 1920 1.2 christos /* check for duplicates */ 1921 1.2 christos if(zonemd_is_duplicate_scheme_hash(zonemd_rrset, i, scheme, 1922 1.2 christos hashalgo)) { 1923 1.2 christos /* duplicate hash of the same scheme,hash 1924 1.2 christos * is not allowed. */ 1925 1.2 christos *reason = "ZONEMD RRSet contains more than one RR " 1926 1.2 christos "with the same scheme and hash algorithm"; 1927 1.2 christos only_unsupported = 0; 1928 1.2 christos continue; 1929 1.2 christos } 1930 1.2 christos regional_free_all(region); 1931 1.2 christos if(serial != soa_serial) { 1932 1.2 christos *reason = "ZONEMD serial is wrong"; 1933 1.2 christos only_unsupported = 0; 1934 1.2 christos continue; 1935 1.2 christos } 1936 1.2 christos *reason = NULL; 1937 1.2 christos if(auth_zone_generate_zonemd_check(z, scheme, hashalgo, 1938 1.2 christos hash, hashlen, region, buf, reason)) { 1939 1.2 christos /* success */ 1940 1.2 christos if(*reason) { 1941 1.2 christos if(!unsupported_reason) 1942 1.2 christos unsupported_reason = *reason; 1943 1.2 christos /* continue to check for valid ZONEMD */ 1944 1.2 christos if(verbosity >= VERB_ALGO) { 1945 1.4 christos char zstr[LDNS_MAX_DOMAINLEN]; 1946 1.2 christos dname_str(z->name, zstr); 1947 1.2 christos verbose(VERB_ALGO, "auth-zone %s ZONEMD %d %d is unsupported: %s", zstr, (int)scheme, (int)hashalgo, *reason); 1948 1.2 christos } 1949 1.2 christos *reason = NULL; 1950 1.2 christos continue; 1951 1.2 christos } 1952 1.2 christos if(verbosity >= VERB_ALGO) { 1953 1.4 christos char zstr[LDNS_MAX_DOMAINLEN]; 1954 1.2 christos dname_str(z->name, zstr); 1955 1.2 christos if(!*reason) 1956 1.2 christos verbose(VERB_ALGO, "auth-zone %s ZONEMD hash is correct", zstr); 1957 1.2 christos } 1958 1.2 christos return 1; 1959 1.2 christos } 1960 1.2 christos only_unsupported = 0; 1961 1.2 christos /* try next one */ 1962 1.2 christos } 1963 1.2 christos /* have we seen no failures but only unsupported algo, 1964 1.2 christos * and one unsupported algorithm, or more. */ 1965 1.2 christos if(only_unsupported && unsupported_reason) { 1966 1.2 christos /* only unsupported algorithms, with valid serial, not 1967 1.2 christos * malformed. Did not see supported algorithms, failed or 1968 1.2 christos * successful ones. */ 1969 1.2 christos *reason = unsupported_reason; 1970 1.2 christos return 1; 1971 1.2 christos } 1972 1.2 christos /* fail, we may have reason */ 1973 1.2 christos if(!*reason) 1974 1.2 christos *reason = "no ZONEMD records found"; 1975 1.2 christos if(verbosity >= VERB_ALGO) { 1976 1.4 christos char zstr[LDNS_MAX_DOMAINLEN]; 1977 1.2 christos dname_str(z->name, zstr); 1978 1.2 christos verbose(VERB_ALGO, "auth-zone %s ZONEMD failed: %s", zstr, *reason); 1979 1.2 christos } 1980 1.2 christos return 0; 1981 1.1 christos } 1982 1.1 christos 1983 1.2 christos /** find the apex SOA RRset, if it exists */ 1984 1.2 christos struct auth_rrset* auth_zone_get_soa_rrset(struct auth_zone* z) 1985 1.1 christos { 1986 1.2 christos struct auth_data* apex; 1987 1.2 christos struct auth_rrset* soa; 1988 1.2 christos apex = az_find_name(z, z->name, z->namelen); 1989 1.2 christos if(!apex) return NULL; 1990 1.2 christos soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA); 1991 1.2 christos return soa; 1992 1.2 christos } 1993 1.2 christos 1994 1.2 christos /** find serial number of zone or false if none */ 1995 1.2 christos int 1996 1.2 christos auth_zone_get_serial(struct auth_zone* z, uint32_t* serial) 1997 1.2 christos { 1998 1.2 christos struct auth_data* apex; 1999 1.2 christos struct auth_rrset* soa; 2000 1.2 christos struct packed_rrset_data* d; 2001 1.2 christos apex = az_find_name(z, z->name, z->namelen); 2002 1.2 christos if(!apex) return 0; 2003 1.2 christos soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA); 2004 1.2 christos if(!soa || soa->data->count==0) 2005 1.2 christos return 0; /* no RRset or no RRs in rrset */ 2006 1.2 christos if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */ 2007 1.2 christos d = soa->data; 2008 1.2 christos *serial = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-20)); 2009 1.2 christos return 1; 2010 1.2 christos } 2011 1.2 christos 2012 1.2 christos /** Find auth_zone SOA and populate the values in xfr(soa values). */ 2013 1.2 christos int 2014 1.2 christos xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr) 2015 1.2 christos { 2016 1.2 christos struct auth_data* apex; 2017 1.2 christos struct auth_rrset* soa; 2018 1.2 christos struct packed_rrset_data* d; 2019 1.2 christos apex = az_find_name(z, z->name, z->namelen); 2020 1.2 christos if(!apex) return 0; 2021 1.2 christos soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA); 2022 1.2 christos if(!soa || soa->data->count==0) 2023 1.2 christos return 0; /* no RRset or no RRs in rrset */ 2024 1.2 christos if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */ 2025 1.2 christos /* SOA record ends with serial, refresh, retry, expiry, minimum, 2026 1.2 christos * as 4 byte fields */ 2027 1.2 christos d = soa->data; 2028 1.2 christos xfr->have_zone = 1; 2029 1.2 christos xfr->serial = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-20)); 2030 1.2 christos xfr->refresh = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-16)); 2031 1.2 christos xfr->retry = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-12)); 2032 1.2 christos xfr->expiry = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-8)); 2033 1.2 christos /* soa minimum at d->rr_len[0]-4 */ 2034 1.2 christos return 1; 2035 1.2 christos } 2036 1.2 christos 2037 1.2 christos /** 2038 1.2 christos * Setup auth_xfer zone 2039 1.2 christos * This populates the have_zone, soa values, and so on times. 2040 1.2 christos * Doesn't do network traffic yet, can set option flags. 2041 1.2 christos * @param z: locked by caller, and modified for setup 2042 1.2 christos * @param x: locked by caller, and modified. 2043 1.2 christos * @return false on failure. 2044 1.2 christos */ 2045 1.2 christos static int 2046 1.2 christos auth_xfer_setup(struct auth_zone* z, struct auth_xfer* x) 2047 1.2 christos { 2048 1.2 christos /* for a zone without zone transfers, x==NULL, so skip them, 2049 1.2 christos * i.e. the zone config is fixed with no masters or urls */ 2050 1.2 christos if(!z || !x) return 1; 2051 1.2 christos if(!xfr_find_soa(z, x)) { 2052 1.2 christos return 1; 2053 1.2 christos } 2054 1.2 christos /* nothing for probe, nextprobe and transfer tasks */ 2055 1.2 christos return 1; 2056 1.2 christos } 2057 1.2 christos 2058 1.2 christos /** 2059 1.2 christos * Setup all zones 2060 1.2 christos * @param az: auth zones structure 2061 1.2 christos * @return false on failure. 2062 1.2 christos */ 2063 1.2 christos static int 2064 1.2 christos auth_zones_setup_zones(struct auth_zones* az) 2065 1.2 christos { 2066 1.2 christos struct auth_zone* z; 2067 1.2 christos struct auth_xfer* x; 2068 1.2 christos lock_rw_wrlock(&az->lock); 2069 1.2 christos RBTREE_FOR(z, struct auth_zone*, &az->ztree) { 2070 1.2 christos lock_rw_wrlock(&z->lock); 2071 1.2 christos x = auth_xfer_find(az, z->name, z->namelen, z->dclass); 2072 1.2 christos if(x) { 2073 1.2 christos lock_basic_lock(&x->lock); 2074 1.2 christos } 2075 1.2 christos if(!auth_xfer_setup(z, x)) { 2076 1.2 christos if(x) { 2077 1.2 christos lock_basic_unlock(&x->lock); 2078 1.2 christos } 2079 1.2 christos lock_rw_unlock(&z->lock); 2080 1.2 christos lock_rw_unlock(&az->lock); 2081 1.2 christos return 0; 2082 1.2 christos } 2083 1.2 christos if(x) { 2084 1.2 christos lock_basic_unlock(&x->lock); 2085 1.2 christos } 2086 1.2 christos lock_rw_unlock(&z->lock); 2087 1.2 christos } 2088 1.2 christos lock_rw_unlock(&az->lock); 2089 1.2 christos return 1; 2090 1.2 christos } 2091 1.2 christos 2092 1.2 christos /** set config items and create zones */ 2093 1.2 christos static int 2094 1.2 christos auth_zones_cfg(struct auth_zones* az, struct config_auth* c) 2095 1.2 christos { 2096 1.2 christos struct auth_zone* z; 2097 1.2 christos struct auth_xfer* x = NULL; 2098 1.2 christos 2099 1.2 christos /* create zone */ 2100 1.2 christos if(c->isrpz) { 2101 1.2 christos /* if the rpz lock is needed, grab it before the other 2102 1.2 christos * locks to avoid a lock dependency cycle */ 2103 1.2 christos lock_rw_wrlock(&az->rpz_lock); 2104 1.2 christos } 2105 1.2 christos lock_rw_wrlock(&az->lock); 2106 1.2 christos if(!(z=auth_zones_find_or_add_zone(az, c->name))) { 2107 1.2 christos lock_rw_unlock(&az->lock); 2108 1.2 christos if(c->isrpz) { 2109 1.2 christos lock_rw_unlock(&az->rpz_lock); 2110 1.2 christos } 2111 1.2 christos return 0; 2112 1.2 christos } 2113 1.2 christos if(c->masters || c->urls) { 2114 1.2 christos if(!(x=auth_zones_find_or_add_xfer(az, z))) { 2115 1.2 christos lock_rw_unlock(&az->lock); 2116 1.2 christos lock_rw_unlock(&z->lock); 2117 1.2 christos if(c->isrpz) { 2118 1.2 christos lock_rw_unlock(&az->rpz_lock); 2119 1.2 christos } 2120 1.2 christos return 0; 2121 1.2 christos } 2122 1.2 christos } 2123 1.2 christos if(c->for_downstream) 2124 1.2 christos az->have_downstream = 1; 2125 1.2 christos lock_rw_unlock(&az->lock); 2126 1.2 christos 2127 1.2 christos /* set options */ 2128 1.2 christos z->zone_deleted = 0; 2129 1.2 christos if(!auth_zone_set_zonefile(z, c->zonefile)) { 2130 1.2 christos if(x) { 2131 1.2 christos lock_basic_unlock(&x->lock); 2132 1.2 christos } 2133 1.2 christos lock_rw_unlock(&z->lock); 2134 1.2 christos if(c->isrpz) { 2135 1.2 christos lock_rw_unlock(&az->rpz_lock); 2136 1.2 christos } 2137 1.2 christos return 0; 2138 1.2 christos } 2139 1.2 christos z->for_downstream = c->for_downstream; 2140 1.2 christos z->for_upstream = c->for_upstream; 2141 1.2 christos z->fallback_enabled = c->fallback_enabled; 2142 1.2 christos z->zonemd_check = c->zonemd_check; 2143 1.2 christos z->zonemd_reject_absence = c->zonemd_reject_absence; 2144 1.2 christos if(c->isrpz && !z->rpz){ 2145 1.2 christos if(!(z->rpz = rpz_create(c))){ 2146 1.2 christos fatal_exit("Could not setup RPZ zones"); 2147 1.2 christos return 0; 2148 1.2 christos } 2149 1.2 christos lock_protect(&z->lock, &z->rpz->local_zones, sizeof(*z->rpz)); 2150 1.2 christos /* the az->rpz_lock is locked above */ 2151 1.2 christos z->rpz_az_next = az->rpz_first; 2152 1.2 christos if(az->rpz_first) 2153 1.2 christos az->rpz_first->rpz_az_prev = z; 2154 1.2 christos az->rpz_first = z; 2155 1.4 christos } else if(c->isrpz && z->rpz) { 2156 1.4 christos if(!rpz_config(z->rpz, c)) { 2157 1.4 christos log_err("Could not change rpz config"); 2158 1.4 christos if(x) { 2159 1.4 christos lock_basic_unlock(&x->lock); 2160 1.4 christos } 2161 1.4 christos lock_rw_unlock(&z->lock); 2162 1.4 christos lock_rw_unlock(&az->rpz_lock); 2163 1.4 christos return 0; 2164 1.4 christos } 2165 1.2 christos } 2166 1.2 christos if(c->isrpz) { 2167 1.2 christos lock_rw_unlock(&az->rpz_lock); 2168 1.2 christos } 2169 1.2 christos 2170 1.2 christos /* xfer zone */ 2171 1.2 christos if(x) { 2172 1.2 christos z->zone_is_slave = 1; 2173 1.2 christos /* set options on xfer zone */ 2174 1.2 christos if(!xfer_set_masters(&x->task_probe->masters, c, 0)) { 2175 1.2 christos lock_basic_unlock(&x->lock); 2176 1.2 christos lock_rw_unlock(&z->lock); 2177 1.2 christos return 0; 2178 1.2 christos } 2179 1.2 christos if(!xfer_set_masters(&x->task_transfer->masters, c, 1)) { 2180 1.2 christos lock_basic_unlock(&x->lock); 2181 1.2 christos lock_rw_unlock(&z->lock); 2182 1.2 christos return 0; 2183 1.2 christos } 2184 1.2 christos lock_basic_unlock(&x->lock); 2185 1.2 christos } 2186 1.2 christos 2187 1.2 christos lock_rw_unlock(&z->lock); 2188 1.2 christos return 1; 2189 1.2 christos } 2190 1.2 christos 2191 1.2 christos /** set all auth zones deleted, then in auth_zones_cfg, it marks them 2192 1.2 christos * as nondeleted (if they are still in the config), and then later 2193 1.2 christos * we can find deleted zones */ 2194 1.2 christos static void 2195 1.2 christos az_setall_deleted(struct auth_zones* az) 2196 1.2 christos { 2197 1.2 christos struct auth_zone* z; 2198 1.2 christos lock_rw_wrlock(&az->lock); 2199 1.2 christos RBTREE_FOR(z, struct auth_zone*, &az->ztree) { 2200 1.2 christos lock_rw_wrlock(&z->lock); 2201 1.2 christos z->zone_deleted = 1; 2202 1.2 christos lock_rw_unlock(&z->lock); 2203 1.2 christos } 2204 1.2 christos lock_rw_unlock(&az->lock); 2205 1.2 christos } 2206 1.2 christos 2207 1.2 christos /** find zones that are marked deleted and delete them. 2208 1.2 christos * This is called from apply_cfg, and there are no threads and no 2209 1.2 christos * workers, so the xfr can just be deleted. */ 2210 1.2 christos static void 2211 1.2 christos az_delete_deleted_zones(struct auth_zones* az) 2212 1.2 christos { 2213 1.2 christos struct auth_zone* z; 2214 1.2 christos struct auth_zone* delete_list = NULL, *next; 2215 1.2 christos struct auth_xfer* xfr; 2216 1.2 christos lock_rw_wrlock(&az->lock); 2217 1.2 christos RBTREE_FOR(z, struct auth_zone*, &az->ztree) { 2218 1.2 christos lock_rw_wrlock(&z->lock); 2219 1.2 christos if(z->zone_deleted) { 2220 1.2 christos /* we cannot alter the rbtree right now, but 2221 1.2 christos * we can put it on a linked list and then 2222 1.2 christos * delete it */ 2223 1.2 christos z->delete_next = delete_list; 2224 1.2 christos delete_list = z; 2225 1.2 christos } 2226 1.2 christos lock_rw_unlock(&z->lock); 2227 1.2 christos } 2228 1.2 christos /* now we are out of the tree loop and we can loop and delete 2229 1.2 christos * the zones */ 2230 1.2 christos z = delete_list; 2231 1.2 christos while(z) { 2232 1.2 christos next = z->delete_next; 2233 1.2 christos xfr = auth_xfer_find(az, z->name, z->namelen, z->dclass); 2234 1.2 christos if(xfr) { 2235 1.2 christos (void)rbtree_delete(&az->xtree, &xfr->node); 2236 1.2 christos auth_xfer_delete(xfr); 2237 1.2 christos } 2238 1.2 christos (void)rbtree_delete(&az->ztree, &z->node); 2239 1.2 christos auth_zone_delete(z, az); 2240 1.2 christos z = next; 2241 1.2 christos } 2242 1.2 christos lock_rw_unlock(&az->lock); 2243 1.2 christos } 2244 1.2 christos 2245 1.2 christos int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg, 2246 1.2 christos int setup, int* is_rpz, struct module_env* env, 2247 1.2 christos struct module_stack* mods) 2248 1.2 christos { 2249 1.2 christos struct config_auth* p; 2250 1.2 christos az_setall_deleted(az); 2251 1.2 christos for(p = cfg->auths; p; p = p->next) { 2252 1.2 christos if(!p->name || p->name[0] == 0) { 2253 1.2 christos log_warn("auth-zone without a name, skipped"); 2254 1.2 christos continue; 2255 1.2 christos } 2256 1.2 christos *is_rpz = (*is_rpz || p->isrpz); 2257 1.2 christos if(!auth_zones_cfg(az, p)) { 2258 1.2 christos log_err("cannot config auth zone %s", p->name); 2259 1.2 christos return 0; 2260 1.2 christos } 2261 1.2 christos } 2262 1.2 christos az_delete_deleted_zones(az); 2263 1.2 christos if(!auth_zones_read_zones(az, cfg, env, mods)) 2264 1.2 christos return 0; 2265 1.2 christos if(setup) { 2266 1.2 christos if(!auth_zones_setup_zones(az)) 2267 1.2 christos return 0; 2268 1.2 christos } 2269 1.2 christos return 1; 2270 1.2 christos } 2271 1.2 christos 2272 1.2 christos /** delete chunks 2273 1.2 christos * @param at: transfer structure with chunks list. The chunks and their 2274 1.2 christos * data are freed. 2275 1.2 christos */ 2276 1.2 christos static void 2277 1.2 christos auth_chunks_delete(struct auth_transfer* at) 2278 1.2 christos { 2279 1.2 christos if(at->chunks_first) { 2280 1.2 christos struct auth_chunk* c, *cn; 2281 1.2 christos c = at->chunks_first; 2282 1.2 christos while(c) { 2283 1.2 christos cn = c->next; 2284 1.2 christos free(c->data); 2285 1.2 christos free(c); 2286 1.2 christos c = cn; 2287 1.2 christos } 2288 1.2 christos } 2289 1.2 christos at->chunks_first = NULL; 2290 1.2 christos at->chunks_last = NULL; 2291 1.2 christos } 2292 1.2 christos 2293 1.2 christos /** free master addr list */ 2294 1.2 christos static void 2295 1.2 christos auth_free_master_addrs(struct auth_addr* list) 2296 1.2 christos { 2297 1.2 christos struct auth_addr *n; 2298 1.2 christos while(list) { 2299 1.2 christos n = list->next; 2300 1.2 christos free(list); 2301 1.2 christos list = n; 2302 1.2 christos } 2303 1.2 christos } 2304 1.2 christos 2305 1.2 christos /** free the masters list */ 2306 1.2 christos static void 2307 1.2 christos auth_free_masters(struct auth_master* list) 2308 1.2 christos { 2309 1.2 christos struct auth_master* n; 2310 1.2 christos while(list) { 2311 1.2 christos n = list->next; 2312 1.2 christos auth_free_master_addrs(list->list); 2313 1.2 christos free(list->host); 2314 1.2 christos free(list->file); 2315 1.2 christos free(list); 2316 1.2 christos list = n; 2317 1.2 christos } 2318 1.2 christos } 2319 1.2 christos 2320 1.2 christos void 2321 1.2 christos auth_xfer_delete(struct auth_xfer* xfr) 2322 1.2 christos { 2323 1.2 christos if(!xfr) return; 2324 1.2 christos lock_basic_destroy(&xfr->lock); 2325 1.2 christos free(xfr->name); 2326 1.2 christos if(xfr->task_nextprobe) { 2327 1.2 christos comm_timer_delete(xfr->task_nextprobe->timer); 2328 1.2 christos free(xfr->task_nextprobe); 2329 1.2 christos } 2330 1.2 christos if(xfr->task_probe) { 2331 1.2 christos auth_free_masters(xfr->task_probe->masters); 2332 1.2 christos comm_point_delete(xfr->task_probe->cp); 2333 1.2 christos comm_timer_delete(xfr->task_probe->timer); 2334 1.2 christos free(xfr->task_probe); 2335 1.2 christos } 2336 1.2 christos if(xfr->task_transfer) { 2337 1.2 christos auth_free_masters(xfr->task_transfer->masters); 2338 1.2 christos comm_point_delete(xfr->task_transfer->cp); 2339 1.2 christos comm_timer_delete(xfr->task_transfer->timer); 2340 1.2 christos if(xfr->task_transfer->chunks_first) { 2341 1.2 christos auth_chunks_delete(xfr->task_transfer); 2342 1.2 christos } 2343 1.2 christos free(xfr->task_transfer); 2344 1.2 christos } 2345 1.2 christos auth_free_masters(xfr->allow_notify_list); 2346 1.2 christos free(xfr); 2347 1.2 christos } 2348 1.2 christos 2349 1.2 christos /** helper traverse to delete zones */ 2350 1.2 christos static void 2351 1.2 christos auth_zone_del(rbnode_type* n, void* ATTR_UNUSED(arg)) 2352 1.2 christos { 2353 1.2 christos struct auth_zone* z = (struct auth_zone*)n->key; 2354 1.2 christos auth_zone_delete(z, NULL); 2355 1.2 christos } 2356 1.2 christos 2357 1.2 christos /** helper traverse to delete xfer zones */ 2358 1.2 christos static void 2359 1.2 christos auth_xfer_del(rbnode_type* n, void* ATTR_UNUSED(arg)) 2360 1.2 christos { 2361 1.2 christos struct auth_xfer* z = (struct auth_xfer*)n->key; 2362 1.2 christos auth_xfer_delete(z); 2363 1.1 christos } 2364 1.1 christos 2365 1.1 christos void auth_zones_delete(struct auth_zones* az) 2366 1.1 christos { 2367 1.1 christos if(!az) return; 2368 1.1 christos lock_rw_destroy(&az->lock); 2369 1.2 christos lock_rw_destroy(&az->rpz_lock); 2370 1.1 christos traverse_postorder(&az->ztree, auth_zone_del, NULL); 2371 1.2 christos traverse_postorder(&az->xtree, auth_xfer_del, NULL); 2372 1.1 christos free(az); 2373 1.1 christos } 2374 1.1 christos 2375 1.1 christos /** true if domain has only nsec3 */ 2376 1.1 christos static int 2377 1.1 christos domain_has_only_nsec3(struct auth_data* n) 2378 1.1 christos { 2379 1.1 christos struct auth_rrset* rrset = n->rrsets; 2380 1.1 christos int nsec3_seen = 0; 2381 1.1 christos while(rrset) { 2382 1.1 christos if(rrset->type == LDNS_RR_TYPE_NSEC3) { 2383 1.1 christos nsec3_seen = 1; 2384 1.1 christos } else if(rrset->type != LDNS_RR_TYPE_RRSIG) { 2385 1.1 christos return 0; 2386 1.1 christos } 2387 1.1 christos rrset = rrset->next; 2388 1.1 christos } 2389 1.1 christos return nsec3_seen; 2390 1.1 christos } 2391 1.1 christos 2392 1.1 christos /** see if the domain has a wildcard child '*.domain' */ 2393 1.1 christos static struct auth_data* 2394 1.1 christos az_find_wildcard_domain(struct auth_zone* z, uint8_t* nm, size_t nmlen) 2395 1.1 christos { 2396 1.1 christos uint8_t wc[LDNS_MAX_DOMAINLEN]; 2397 1.1 christos if(nmlen+2 > sizeof(wc)) 2398 1.1 christos return NULL; /* result would be too long */ 2399 1.1 christos wc[0] = 1; /* length of wildcard label */ 2400 1.1 christos wc[1] = (uint8_t)'*'; /* wildcard label */ 2401 1.1 christos memmove(wc+2, nm, nmlen); 2402 1.1 christos return az_find_name(z, wc, nmlen+2); 2403 1.1 christos } 2404 1.1 christos 2405 1.1 christos /** find wildcard between qname and cename */ 2406 1.1 christos static struct auth_data* 2407 1.1 christos az_find_wildcard(struct auth_zone* z, struct query_info* qinfo, 2408 1.1 christos struct auth_data* ce) 2409 1.1 christos { 2410 1.1 christos uint8_t* nm = qinfo->qname; 2411 1.1 christos size_t nmlen = qinfo->qname_len; 2412 1.1 christos struct auth_data* node; 2413 1.1 christos if(!dname_subdomain_c(nm, z->name)) 2414 1.1 christos return NULL; /* out of zone */ 2415 1.1 christos while((node=az_find_wildcard_domain(z, nm, nmlen))==NULL) { 2416 1.1 christos if(nmlen == z->namelen) 2417 1.1 christos return NULL; /* top of zone reached */ 2418 1.1 christos if(ce && nmlen == ce->namelen) 2419 1.1 christos return NULL; /* ce reached */ 2420 1.5 christos if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) 2421 1.5 christos return NULL; /* can't go up */ 2422 1.1 christos } 2423 1.1 christos return node; 2424 1.1 christos } 2425 1.1 christos 2426 1.1 christos /** domain is not exact, find first candidate ce (name that matches 2427 1.1 christos * a part of qname) in tree */ 2428 1.1 christos static struct auth_data* 2429 1.1 christos az_find_candidate_ce(struct auth_zone* z, struct query_info* qinfo, 2430 1.1 christos struct auth_data* n) 2431 1.1 christos { 2432 1.1 christos uint8_t* nm; 2433 1.1 christos size_t nmlen; 2434 1.1 christos if(n) { 2435 1.1 christos nm = dname_get_shared_topdomain(qinfo->qname, n->name); 2436 1.1 christos } else { 2437 1.1 christos nm = qinfo->qname; 2438 1.1 christos } 2439 1.1 christos dname_count_size_labels(nm, &nmlen); 2440 1.1 christos n = az_find_name(z, nm, nmlen); 2441 1.1 christos /* delete labels and go up on name */ 2442 1.1 christos while(!n) { 2443 1.5 christos if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) 2444 1.5 christos return NULL; /* can't go up */ 2445 1.1 christos n = az_find_name(z, nm, nmlen); 2446 1.1 christos } 2447 1.1 christos return n; 2448 1.1 christos } 2449 1.1 christos 2450 1.1 christos /** go up the auth tree to next existing name. */ 2451 1.1 christos static struct auth_data* 2452 1.1 christos az_domain_go_up(struct auth_zone* z, struct auth_data* n) 2453 1.1 christos { 2454 1.1 christos uint8_t* nm = n->name; 2455 1.1 christos size_t nmlen = n->namelen; 2456 1.5 christos while(dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) { 2457 1.1 christos if((n=az_find_name(z, nm, nmlen)) != NULL) 2458 1.1 christos return n; 2459 1.1 christos } 2460 1.1 christos return NULL; 2461 1.1 christos } 2462 1.1 christos 2463 1.1 christos /** Find the closest encloser, an name that exists and is above the 2464 1.1 christos * qname. 2465 1.1 christos * return true if the node (param node) is existing, nonobscured and 2466 1.1 christos * can be used to generate answers from. It is then also node_exact. 2467 1.1 christos * returns false if the node is not good enough (or it wasn't node_exact) 2468 1.2 christos * in this case the ce can be filled. 2469 1.2 christos * if ce is NULL, no ce exists, and likely the zone is completely empty, 2470 1.2 christos * not even with a zone apex. 2471 1.1 christos * if ce is nonNULL it is the closest enclosing upper name (that exists 2472 1.1 christos * itself for answer purposes). That name may have DNAME, NS or wildcard 2473 1.1 christos * rrset is the closest DNAME or NS rrset that was found. 2474 1.1 christos */ 2475 1.1 christos static int 2476 1.1 christos az_find_ce(struct auth_zone* z, struct query_info* qinfo, 2477 1.1 christos struct auth_data* node, int node_exact, struct auth_data** ce, 2478 1.1 christos struct auth_rrset** rrset) 2479 1.1 christos { 2480 1.1 christos struct auth_data* n = node; 2481 1.3 christos struct auth_rrset* lookrrset; 2482 1.1 christos *ce = NULL; 2483 1.1 christos *rrset = NULL; 2484 1.1 christos if(!node_exact) { 2485 1.1 christos /* if not exact, lookup closest exact match */ 2486 1.1 christos n = az_find_candidate_ce(z, qinfo, n); 2487 1.1 christos } else { 2488 1.1 christos /* if exact, the node itself is the first candidate ce */ 2489 1.1 christos *ce = n; 2490 1.1 christos } 2491 1.1 christos 2492 1.1 christos /* no direct answer from nsec3-only domains */ 2493 1.1 christos if(n && domain_has_only_nsec3(n)) { 2494 1.1 christos node_exact = 0; 2495 1.1 christos *ce = NULL; 2496 1.1 christos } 2497 1.1 christos 2498 1.1 christos /* with exact matches, walk up the labels until we find the 2499 1.1 christos * delegation, or DNAME or zone end */ 2500 1.1 christos while(n) { 2501 1.1 christos /* see if the current candidate has issues */ 2502 1.1 christos /* not zone apex and has type NS */ 2503 1.1 christos if(n->namelen != z->namelen && 2504 1.3 christos (lookrrset=az_domain_rrset(n, LDNS_RR_TYPE_NS)) && 2505 1.1 christos /* delegate here, but DS at exact the dp has notype */ 2506 1.1 christos (qinfo->qtype != LDNS_RR_TYPE_DS || 2507 1.1 christos n->namelen != qinfo->qname_len)) { 2508 1.1 christos /* referral */ 2509 1.1 christos /* this is ce and the lowernode is nonexisting */ 2510 1.1 christos *ce = n; 2511 1.3 christos *rrset = lookrrset; 2512 1.3 christos node_exact = 0; 2513 1.1 christos } 2514 1.1 christos /* not equal to qname and has type DNAME */ 2515 1.1 christos if(n->namelen != qinfo->qname_len && 2516 1.3 christos (lookrrset=az_domain_rrset(n, LDNS_RR_TYPE_DNAME))) { 2517 1.1 christos /* this is ce and the lowernode is nonexisting */ 2518 1.1 christos *ce = n; 2519 1.3 christos *rrset = lookrrset; 2520 1.3 christos node_exact = 0; 2521 1.1 christos } 2522 1.1 christos 2523 1.1 christos if(*ce == NULL && !domain_has_only_nsec3(n)) { 2524 1.1 christos /* if not found yet, this exact name must be 2525 1.1 christos * our lowest match (but not nsec3onlydomain) */ 2526 1.1 christos *ce = n; 2527 1.1 christos } 2528 1.1 christos 2529 1.1 christos /* walk up the tree by removing labels from name and lookup */ 2530 1.1 christos n = az_domain_go_up(z, n); 2531 1.1 christos } 2532 1.1 christos /* found no problems, if it was an exact node, it is fine to use */ 2533 1.1 christos return node_exact; 2534 1.1 christos } 2535 1.1 christos 2536 1.1 christos /** add additional A/AAAA from domain names in rrset rdata (+offset) 2537 1.1 christos * offset is number of bytes in rdata where the dname is located. */ 2538 1.1 christos static int 2539 1.1 christos az_add_additionals_from(struct auth_zone* z, struct regional* region, 2540 1.1 christos struct dns_msg* msg, struct auth_rrset* rrset, size_t offset) 2541 1.1 christos { 2542 1.1 christos struct packed_rrset_data* d = rrset->data; 2543 1.1 christos size_t i; 2544 1.1 christos if(!d) return 0; 2545 1.1 christos for(i=0; i<d->count; i++) { 2546 1.1 christos size_t dlen; 2547 1.1 christos struct auth_data* domain; 2548 1.1 christos struct auth_rrset* ref; 2549 1.1 christos if(d->rr_len[i] < 2+offset) 2550 1.1 christos continue; /* too short */ 2551 1.1 christos if(!(dlen = dname_valid(d->rr_data[i]+2+offset, 2552 1.1 christos d->rr_len[i]-2-offset))) 2553 1.1 christos continue; /* malformed */ 2554 1.1 christos domain = az_find_name(z, d->rr_data[i]+2+offset, dlen); 2555 1.1 christos if(!domain) 2556 1.1 christos continue; 2557 1.1 christos if((ref=az_domain_rrset(domain, LDNS_RR_TYPE_A)) != NULL) { 2558 1.1 christos if(!msg_add_rrset_ar(z, region, msg, domain, ref)) 2559 1.1 christos return 0; 2560 1.1 christos } 2561 1.1 christos if((ref=az_domain_rrset(domain, LDNS_RR_TYPE_AAAA)) != NULL) { 2562 1.1 christos if(!msg_add_rrset_ar(z, region, msg, domain, ref)) 2563 1.1 christos return 0; 2564 1.1 christos } 2565 1.1 christos } 2566 1.1 christos return 1; 2567 1.1 christos } 2568 1.1 christos 2569 1.1 christos /** add negative SOA record (with negative TTL) */ 2570 1.1 christos static int 2571 1.1 christos az_add_negative_soa(struct auth_zone* z, struct regional* region, 2572 1.1 christos struct dns_msg* msg) 2573 1.1 christos { 2574 1.2 christos time_t minimum; 2575 1.2 christos size_t i; 2576 1.1 christos struct packed_rrset_data* d; 2577 1.1 christos struct auth_rrset* soa; 2578 1.1 christos struct auth_data* apex = az_find_name(z, z->name, z->namelen); 2579 1.1 christos if(!apex) return 0; 2580 1.1 christos soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA); 2581 1.1 christos if(!soa) return 0; 2582 1.1 christos /* must be first to put in message; we want to fix the TTL with 2583 1.1 christos * one RRset here, otherwise we'd need to loop over the RRs to get 2584 1.1 christos * the resulting lower TTL */ 2585 1.1 christos log_assert(msg->rep->rrset_count == 0); 2586 1.1 christos if(!msg_add_rrset_ns(z, region, msg, apex, soa)) return 0; 2587 1.1 christos /* fixup TTL */ 2588 1.1 christos d = (struct packed_rrset_data*)msg->rep->rrsets[msg->rep->rrset_count-1]->entry.data; 2589 1.1 christos /* last 4 bytes are minimum ttl in network format */ 2590 1.1 christos if(d->count == 0) return 0; 2591 1.1 christos if(d->rr_len[0] < 2+4) return 0; 2592 1.2 christos minimum = (time_t)sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-4)); 2593 1.2 christos minimum = d->ttl<minimum?d->ttl:minimum; 2594 1.2 christos d->ttl = minimum; 2595 1.2 christos for(i=0; i < d->count + d->rrsig_count; i++) 2596 1.2 christos d->rr_ttl[i] = minimum; 2597 1.1 christos msg->rep->ttl = get_rrset_ttl(msg->rep->rrsets[0]); 2598 1.1 christos msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); 2599 1.2 christos msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; 2600 1.1 christos return 1; 2601 1.1 christos } 2602 1.1 christos 2603 1.1 christos /** See if the query goes to empty nonterminal (that has no auth_data, 2604 1.1 christos * but there are nodes underneath. We already checked that there are 2605 1.1 christos * not NS, or DNAME above, so that we only need to check if some node 2606 1.1 christos * exists below (with nonempty rr list), return true if emptynonterminal */ 2607 1.1 christos static int 2608 1.1 christos az_empty_nonterminal(struct auth_zone* z, struct query_info* qinfo, 2609 1.1 christos struct auth_data* node) 2610 1.1 christos { 2611 1.1 christos struct auth_data* next; 2612 1.1 christos if(!node) { 2613 1.1 christos /* no smaller was found, use first (smallest) node as the 2614 1.1 christos * next one */ 2615 1.1 christos next = (struct auth_data*)rbtree_first(&z->data); 2616 1.1 christos } else { 2617 1.1 christos next = (struct auth_data*)rbtree_next(&node->node); 2618 1.1 christos } 2619 1.1 christos while(next && (rbnode_type*)next != RBTREE_NULL && next->rrsets == NULL) { 2620 1.1 christos /* the next name has empty rrsets, is an empty nonterminal 2621 1.1 christos * itself, see if there exists something below it */ 2622 1.1 christos next = (struct auth_data*)rbtree_next(&node->node); 2623 1.1 christos } 2624 1.1 christos if((rbnode_type*)next == RBTREE_NULL || !next) { 2625 1.1 christos /* there is no next node, so something below it cannot 2626 1.1 christos * exist */ 2627 1.1 christos return 0; 2628 1.1 christos } 2629 1.1 christos /* a next node exists, if there was something below the query, 2630 1.1 christos * this node has to be it. See if it is below the query name */ 2631 1.1 christos if(dname_strict_subdomain_c(next->name, qinfo->qname)) 2632 1.1 christos return 1; 2633 1.1 christos return 0; 2634 1.1 christos } 2635 1.1 christos 2636 1.1 christos /** create synth cname target name in buffer, or fail if too long */ 2637 1.1 christos static size_t 2638 1.1 christos synth_cname_buf(uint8_t* qname, size_t qname_len, size_t dname_len, 2639 1.1 christos uint8_t* dtarg, size_t dtarglen, uint8_t* buf, size_t buflen) 2640 1.1 christos { 2641 1.1 christos size_t newlen = qname_len + dtarglen - dname_len; 2642 1.1 christos if(newlen > buflen) { 2643 1.1 christos /* YXDOMAIN error */ 2644 1.1 christos return 0; 2645 1.1 christos } 2646 1.1 christos /* new name is concatenation of qname front (without DNAME owner) 2647 1.1 christos * and DNAME target name */ 2648 1.1 christos memcpy(buf, qname, qname_len-dname_len); 2649 1.1 christos memmove(buf+(qname_len-dname_len), dtarg, dtarglen); 2650 1.1 christos return newlen; 2651 1.1 christos } 2652 1.1 christos 2653 1.1 christos /** create synthetic CNAME rrset for in a DNAME answer in region, 2654 1.1 christos * false on alloc failure, cname==NULL when name too long. */ 2655 1.1 christos static int 2656 1.1 christos create_synth_cname(uint8_t* qname, size_t qname_len, struct regional* region, 2657 1.1 christos struct auth_data* node, struct auth_rrset* dname, uint16_t dclass, 2658 1.1 christos struct ub_packed_rrset_key** cname) 2659 1.1 christos { 2660 1.1 christos uint8_t buf[LDNS_MAX_DOMAINLEN]; 2661 1.1 christos uint8_t* dtarg; 2662 1.1 christos size_t dtarglen, newlen; 2663 1.1 christos struct packed_rrset_data* d; 2664 1.1 christos 2665 1.1 christos /* get DNAME target name */ 2666 1.1 christos if(dname->data->count < 1) return 0; 2667 1.1 christos if(dname->data->rr_len[0] < 3) return 0; /* at least rdatalen +1 */ 2668 1.1 christos dtarg = dname->data->rr_data[0]+2; 2669 1.1 christos dtarglen = dname->data->rr_len[0]-2; 2670 1.1 christos if(sldns_read_uint16(dname->data->rr_data[0]) != dtarglen) 2671 1.1 christos return 0; /* rdatalen in DNAME rdata is malformed */ 2672 1.1 christos if(dname_valid(dtarg, dtarglen) != dtarglen) 2673 1.1 christos return 0; /* DNAME RR has malformed rdata */ 2674 1.2 christos if(qname_len == 0) 2675 1.2 christos return 0; /* too short */ 2676 1.2 christos if(qname_len <= node->namelen) 2677 1.2 christos return 0; /* qname too short for dname removal */ 2678 1.1 christos 2679 1.1 christos /* synthesize a CNAME */ 2680 1.1 christos newlen = synth_cname_buf(qname, qname_len, node->namelen, 2681 1.1 christos dtarg, dtarglen, buf, sizeof(buf)); 2682 1.1 christos if(newlen == 0) { 2683 1.1 christos /* YXDOMAIN error */ 2684 1.1 christos *cname = NULL; 2685 1.1 christos return 1; 2686 1.1 christos } 2687 1.1 christos *cname = (struct ub_packed_rrset_key*)regional_alloc(region, 2688 1.1 christos sizeof(struct ub_packed_rrset_key)); 2689 1.1 christos if(!*cname) 2690 1.1 christos return 0; /* out of memory */ 2691 1.1 christos memset(&(*cname)->entry, 0, sizeof((*cname)->entry)); 2692 1.1 christos (*cname)->entry.key = (*cname); 2693 1.1 christos (*cname)->rk.type = htons(LDNS_RR_TYPE_CNAME); 2694 1.1 christos (*cname)->rk.rrset_class = htons(dclass); 2695 1.1 christos (*cname)->rk.flags = 0; 2696 1.1 christos (*cname)->rk.dname = regional_alloc_init(region, qname, qname_len); 2697 1.1 christos if(!(*cname)->rk.dname) 2698 1.1 christos return 0; /* out of memory */ 2699 1.1 christos (*cname)->rk.dname_len = qname_len; 2700 1.1 christos (*cname)->entry.hash = rrset_key_hash(&(*cname)->rk); 2701 1.1 christos d = (struct packed_rrset_data*)regional_alloc_zero(region, 2702 1.1 christos sizeof(struct packed_rrset_data) + sizeof(size_t) + 2703 1.1 christos sizeof(uint8_t*) + sizeof(time_t) + sizeof(uint16_t) 2704 1.1 christos + newlen); 2705 1.1 christos if(!d) 2706 1.1 christos return 0; /* out of memory */ 2707 1.1 christos (*cname)->entry.data = d; 2708 1.4 christos d->ttl = dname->data->ttl; /* RFC6672: synth CNAME TTL == DNAME TTL */ 2709 1.1 christos d->count = 1; 2710 1.1 christos d->rrsig_count = 0; 2711 1.1 christos d->trust = rrset_trust_ans_noAA; 2712 1.1 christos d->rr_len = (size_t*)((uint8_t*)d + 2713 1.1 christos sizeof(struct packed_rrset_data)); 2714 1.1 christos d->rr_len[0] = newlen + sizeof(uint16_t); 2715 1.1 christos packed_rrset_ptr_fixup(d); 2716 1.1 christos d->rr_ttl[0] = d->ttl; 2717 1.1 christos sldns_write_uint16(d->rr_data[0], newlen); 2718 1.1 christos memmove(d->rr_data[0] + sizeof(uint16_t), buf, newlen); 2719 1.1 christos return 1; 2720 1.1 christos } 2721 1.1 christos 2722 1.1 christos /** add a synthesized CNAME to the answer section */ 2723 1.1 christos static int 2724 1.1 christos add_synth_cname(struct auth_zone* z, uint8_t* qname, size_t qname_len, 2725 1.1 christos struct regional* region, struct dns_msg* msg, struct auth_data* dname, 2726 1.1 christos struct auth_rrset* rrset) 2727 1.1 christos { 2728 1.1 christos struct ub_packed_rrset_key* cname; 2729 1.1 christos /* synthesize a CNAME */ 2730 1.1 christos if(!create_synth_cname(qname, qname_len, region, dname, rrset, 2731 1.1 christos z->dclass, &cname)) { 2732 1.1 christos /* out of memory */ 2733 1.1 christos return 0; 2734 1.1 christos } 2735 1.1 christos if(!cname) { 2736 1.1 christos /* cname cannot be create because of YXDOMAIN */ 2737 1.1 christos msg->rep->flags |= LDNS_RCODE_YXDOMAIN; 2738 1.1 christos return 1; 2739 1.1 christos } 2740 1.1 christos /* add cname to message */ 2741 1.1 christos if(!msg_grow_array(region, msg)) 2742 1.1 christos return 0; 2743 1.1 christos msg->rep->rrsets[msg->rep->rrset_count] = cname; 2744 1.1 christos msg->rep->rrset_count++; 2745 1.1 christos msg->rep->an_numrrsets++; 2746 1.1 christos msg_ttl(msg); 2747 1.1 christos return 1; 2748 1.1 christos } 2749 1.1 christos 2750 1.1 christos /** Change a dname to a different one, for wildcard namechange */ 2751 1.1 christos static void 2752 1.1 christos az_change_dnames(struct dns_msg* msg, uint8_t* oldname, uint8_t* newname, 2753 1.1 christos size_t newlen, int an_only) 2754 1.1 christos { 2755 1.1 christos size_t i; 2756 1.1 christos size_t start = 0, end = msg->rep->rrset_count; 2757 1.1 christos if(!an_only) start = msg->rep->an_numrrsets; 2758 1.1 christos if(an_only) end = msg->rep->an_numrrsets; 2759 1.1 christos for(i=start; i<end; i++) { 2760 1.1 christos /* allocated in region so we can change the ptrs */ 2761 1.1 christos if(query_dname_compare(msg->rep->rrsets[i]->rk.dname, oldname) 2762 1.1 christos == 0) { 2763 1.1 christos msg->rep->rrsets[i]->rk.dname = newname; 2764 1.1 christos msg->rep->rrsets[i]->rk.dname_len = newlen; 2765 1.3 christos msg->rep->rrsets[i]->entry.hash = rrset_key_hash(&msg->rep->rrsets[i]->rk); 2766 1.1 christos } 2767 1.1 christos } 2768 1.1 christos } 2769 1.1 christos 2770 1.5 christos /** find NSEC record covering the query, with the given node in the zone */ 2771 1.1 christos static struct auth_rrset* 2772 1.1 christos az_find_nsec_cover(struct auth_zone* z, struct auth_data** node) 2773 1.1 christos { 2774 1.5 christos uint8_t* nm; 2775 1.5 christos size_t nmlen; 2776 1.1 christos struct auth_rrset* rrset; 2777 1.5 christos log_assert(*node); /* we already have a node when calling this */ 2778 1.5 christos nm = (*node)->name; 2779 1.5 christos nmlen = (*node)->namelen; 2780 1.1 christos /* find the NSEC for the smallest-or-equal node */ 2781 1.5 christos /* But there could be glue, and then it has no NSEC. 2782 1.1 christos * Go up to find nonglue (previous) NSEC-holding nodes */ 2783 1.1 christos while((rrset=az_domain_rrset(*node, LDNS_RR_TYPE_NSEC)) == NULL) { 2784 1.1 christos if(nmlen == z->namelen) return NULL; 2785 1.5 christos if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) 2786 1.5 christos return NULL; /* can't go up */ 2787 1.1 christos /* adjust *node for the nsec rrset to find in */ 2788 1.1 christos *node = az_find_name(z, nm, nmlen); 2789 1.1 christos } 2790 1.1 christos return rrset; 2791 1.1 christos } 2792 1.1 christos 2793 1.1 christos /** Find NSEC and add for wildcard denial */ 2794 1.1 christos static int 2795 1.1 christos az_nsec_wildcard_denial(struct auth_zone* z, struct regional* region, 2796 1.1 christos struct dns_msg* msg, uint8_t* cenm, size_t cenmlen) 2797 1.1 christos { 2798 1.1 christos struct query_info qinfo; 2799 1.1 christos int node_exact; 2800 1.1 christos struct auth_data* node; 2801 1.1 christos struct auth_rrset* nsec; 2802 1.1 christos uint8_t wc[LDNS_MAX_DOMAINLEN]; 2803 1.1 christos if(cenmlen+2 > sizeof(wc)) 2804 1.1 christos return 0; /* result would be too long */ 2805 1.1 christos wc[0] = 1; /* length of wildcard label */ 2806 1.1 christos wc[1] = (uint8_t)'*'; /* wildcard label */ 2807 1.1 christos memmove(wc+2, cenm, cenmlen); 2808 1.1 christos 2809 1.1 christos /* we have '*.ce' in wc wildcard name buffer */ 2810 1.1 christos /* get nsec cover for that */ 2811 1.1 christos qinfo.qname = wc; 2812 1.1 christos qinfo.qname_len = cenmlen+2; 2813 1.1 christos qinfo.qtype = 0; 2814 1.1 christos qinfo.qclass = 0; 2815 1.1 christos az_find_domain(z, &qinfo, &node_exact, &node); 2816 1.1 christos if((nsec=az_find_nsec_cover(z, &node)) != NULL) { 2817 1.1 christos if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0; 2818 1.1 christos } 2819 1.1 christos return 1; 2820 1.1 christos } 2821 1.1 christos 2822 1.1 christos /** Find the NSEC3PARAM rrset (if any) and if true you have the parameters */ 2823 1.1 christos static int 2824 1.1 christos az_nsec3_param(struct auth_zone* z, int* algo, size_t* iter, uint8_t** salt, 2825 1.1 christos size_t* saltlen) 2826 1.1 christos { 2827 1.1 christos struct auth_data* apex; 2828 1.1 christos struct auth_rrset* param; 2829 1.1 christos size_t i; 2830 1.1 christos apex = az_find_name(z, z->name, z->namelen); 2831 1.1 christos if(!apex) return 0; 2832 1.1 christos param = az_domain_rrset(apex, LDNS_RR_TYPE_NSEC3PARAM); 2833 1.1 christos if(!param || param->data->count==0) 2834 1.1 christos return 0; /* no RRset or no RRs in rrset */ 2835 1.1 christos /* find out which NSEC3PARAM RR has supported parameters */ 2836 1.1 christos /* skip unknown flags (dynamic signer is recalculating nsec3 chain) */ 2837 1.1 christos for(i=0; i<param->data->count; i++) { 2838 1.1 christos uint8_t* rdata = param->data->rr_data[i]+2; 2839 1.1 christos size_t rdatalen = param->data->rr_len[i]; 2840 1.1 christos if(rdatalen < 2+5) 2841 1.1 christos continue; /* too short */ 2842 1.1 christos if(!nsec3_hash_algo_size_supported((int)(rdata[0]))) 2843 1.1 christos continue; /* unsupported algo */ 2844 1.1 christos if(rdatalen < (size_t)(2+5+(size_t)rdata[4])) 2845 1.1 christos continue; /* salt missing */ 2846 1.1 christos if((rdata[1]&NSEC3_UNKNOWN_FLAGS)!=0) 2847 1.1 christos continue; /* unknown flags */ 2848 1.1 christos *algo = (int)(rdata[0]); 2849 1.1 christos *iter = sldns_read_uint16(rdata+2); 2850 1.1 christos *saltlen = rdata[4]; 2851 1.1 christos if(*saltlen == 0) 2852 1.1 christos *salt = NULL; 2853 1.1 christos else *salt = rdata+5; 2854 1.1 christos return 1; 2855 1.1 christos } 2856 1.1 christos /* no supported params */ 2857 1.1 christos return 0; 2858 1.1 christos } 2859 1.1 christos 2860 1.1 christos /** Hash a name with nsec3param into buffer, it has zone name appended. 2861 1.1 christos * return length of hash */ 2862 1.1 christos static size_t 2863 1.1 christos az_nsec3_hash(uint8_t* buf, size_t buflen, uint8_t* nm, size_t nmlen, 2864 1.1 christos int algo, size_t iter, uint8_t* salt, size_t saltlen) 2865 1.1 christos { 2866 1.1 christos size_t hlen = nsec3_hash_algo_size_supported(algo); 2867 1.1 christos /* buffer has domain name, nsec3hash, and 256 is for max saltlen 2868 1.1 christos * (salt has 0-255 length) */ 2869 1.1 christos unsigned char p[LDNS_MAX_DOMAINLEN+1+N3HASHBUFLEN+256]; 2870 1.1 christos size_t i; 2871 1.1 christos if(nmlen+saltlen > sizeof(p) || hlen+saltlen > sizeof(p)) 2872 1.1 christos return 0; 2873 1.1 christos if(hlen > buflen) 2874 1.1 christos return 0; /* somehow too large for destination buffer */ 2875 1.1 christos /* hashfunc(name, salt) */ 2876 1.1 christos memmove(p, nm, nmlen); 2877 1.1 christos query_dname_tolower(p); 2878 1.2 christos if(salt && saltlen > 0) 2879 1.2 christos memmove(p+nmlen, salt, saltlen); 2880 1.1 christos (void)secalgo_nsec3_hash(algo, p, nmlen+saltlen, (unsigned char*)buf); 2881 1.1 christos for(i=0; i<iter; i++) { 2882 1.1 christos /* hashfunc(hash, salt) */ 2883 1.1 christos memmove(p, buf, hlen); 2884 1.2 christos if(salt && saltlen > 0) 2885 1.2 christos memmove(p+hlen, salt, saltlen); 2886 1.1 christos (void)secalgo_nsec3_hash(algo, p, hlen+saltlen, 2887 1.1 christos (unsigned char*)buf); 2888 1.1 christos } 2889 1.1 christos return hlen; 2890 1.1 christos } 2891 1.1 christos 2892 1.1 christos /** Hash name and return b32encoded hashname for lookup, zone name appended */ 2893 1.1 christos static int 2894 1.1 christos az_nsec3_hashname(struct auth_zone* z, uint8_t* hashname, size_t* hashnmlen, 2895 1.1 christos uint8_t* nm, size_t nmlen, int algo, size_t iter, uint8_t* salt, 2896 1.1 christos size_t saltlen) 2897 1.1 christos { 2898 1.1 christos uint8_t hash[N3HASHBUFLEN]; 2899 1.1 christos size_t hlen; 2900 1.1 christos int ret; 2901 1.1 christos hlen = az_nsec3_hash(hash, sizeof(hash), nm, nmlen, algo, iter, 2902 1.1 christos salt, saltlen); 2903 1.1 christos if(!hlen) return 0; 2904 1.1 christos /* b32 encode */ 2905 1.1 christos if(*hashnmlen < hlen*2+1+z->namelen) /* approx b32 as hexb16 */ 2906 1.1 christos return 0; 2907 1.1 christos ret = sldns_b32_ntop_extended_hex(hash, hlen, (char*)(hashname+1), 2908 1.1 christos (*hashnmlen)-1); 2909 1.1 christos if(ret<1) 2910 1.1 christos return 0; 2911 1.1 christos hashname[0] = (uint8_t)ret; 2912 1.1 christos ret++; 2913 1.1 christos if((*hashnmlen) - ret < z->namelen) 2914 1.1 christos return 0; 2915 1.1 christos memmove(hashname+ret, z->name, z->namelen); 2916 1.1 christos *hashnmlen = z->namelen+(size_t)ret; 2917 1.1 christos return 1; 2918 1.1 christos } 2919 1.1 christos 2920 1.1 christos /** Find the datanode that covers the nsec3hash-name */ 2921 1.2 christos static struct auth_data* 2922 1.1 christos az_nsec3_findnode(struct auth_zone* z, uint8_t* hashnm, size_t hashnmlen) 2923 1.1 christos { 2924 1.1 christos struct query_info qinfo; 2925 1.1 christos struct auth_data* node; 2926 1.1 christos int node_exact; 2927 1.1 christos qinfo.qclass = 0; 2928 1.1 christos qinfo.qtype = 0; 2929 1.1 christos qinfo.qname = hashnm; 2930 1.1 christos qinfo.qname_len = hashnmlen; 2931 1.1 christos /* because canonical ordering and b32 nsec3 ordering are the same. 2932 1.1 christos * this is a good lookup to find the nsec3 name. */ 2933 1.1 christos az_find_domain(z, &qinfo, &node_exact, &node); 2934 1.1 christos /* but we may have to skip non-nsec3 nodes */ 2935 1.1 christos /* this may be a lot, the way to speed that up is to have a 2936 1.1 christos * separate nsec3 tree with nsec3 nodes */ 2937 1.1 christos while(node && (rbnode_type*)node != RBTREE_NULL && 2938 1.1 christos !az_domain_rrset(node, LDNS_RR_TYPE_NSEC3)) { 2939 1.1 christos node = (struct auth_data*)rbtree_previous(&node->node); 2940 1.1 christos } 2941 1.1 christos if((rbnode_type*)node == RBTREE_NULL) 2942 1.1 christos node = NULL; 2943 1.1 christos return node; 2944 1.1 christos } 2945 1.1 christos 2946 1.1 christos /** Find cover for hashed(nm, nmlen) (or NULL) */ 2947 1.1 christos static struct auth_data* 2948 1.1 christos az_nsec3_find_cover(struct auth_zone* z, uint8_t* nm, size_t nmlen, 2949 1.1 christos int algo, size_t iter, uint8_t* salt, size_t saltlen) 2950 1.1 christos { 2951 1.1 christos struct auth_data* node; 2952 1.1 christos uint8_t hname[LDNS_MAX_DOMAINLEN]; 2953 1.1 christos size_t hlen = sizeof(hname); 2954 1.1 christos if(!az_nsec3_hashname(z, hname, &hlen, nm, nmlen, algo, iter, 2955 1.1 christos salt, saltlen)) 2956 1.1 christos return NULL; 2957 1.1 christos node = az_nsec3_findnode(z, hname, hlen); 2958 1.1 christos if(node) 2959 1.1 christos return node; 2960 1.1 christos /* we did not find any, perhaps because the NSEC3 hash is before 2961 1.1 christos * the first hash, we have to find the 'last hash' in the zone */ 2962 1.1 christos node = (struct auth_data*)rbtree_last(&z->data); 2963 1.1 christos while(node && (rbnode_type*)node != RBTREE_NULL && 2964 1.1 christos !az_domain_rrset(node, LDNS_RR_TYPE_NSEC3)) { 2965 1.1 christos node = (struct auth_data*)rbtree_previous(&node->node); 2966 1.1 christos } 2967 1.2 christos if((rbnode_type*)node == RBTREE_NULL) 2968 1.1 christos node = NULL; 2969 1.1 christos return node; 2970 1.1 christos } 2971 1.1 christos 2972 1.1 christos /** Find exact match for hashed(nm, nmlen) NSEC3 record or NULL */ 2973 1.1 christos static struct auth_data* 2974 1.1 christos az_nsec3_find_exact(struct auth_zone* z, uint8_t* nm, size_t nmlen, 2975 1.1 christos int algo, size_t iter, uint8_t* salt, size_t saltlen) 2976 1.1 christos { 2977 1.1 christos struct auth_data* node; 2978 1.1 christos uint8_t hname[LDNS_MAX_DOMAINLEN]; 2979 1.1 christos size_t hlen = sizeof(hname); 2980 1.1 christos if(!az_nsec3_hashname(z, hname, &hlen, nm, nmlen, algo, iter, 2981 1.1 christos salt, saltlen)) 2982 1.1 christos return NULL; 2983 1.1 christos node = az_find_name(z, hname, hlen); 2984 1.1 christos if(az_domain_rrset(node, LDNS_RR_TYPE_NSEC3)) 2985 1.1 christos return node; 2986 1.1 christos return NULL; 2987 1.1 christos } 2988 1.1 christos 2989 1.1 christos /** Return nextcloser name (as a ref into the qname). This is one label 2990 1.1 christos * more than the cenm (cename must be a suffix of qname) */ 2991 1.1 christos static void 2992 1.1 christos az_nsec3_get_nextcloser(uint8_t* cenm, uint8_t* qname, size_t qname_len, 2993 1.1 christos uint8_t** nx, size_t* nxlen) 2994 1.1 christos { 2995 1.1 christos int celabs = dname_count_labels(cenm); 2996 1.1 christos int qlabs = dname_count_labels(qname); 2997 1.1 christos int strip = qlabs - celabs -1; 2998 1.1 christos log_assert(dname_strict_subdomain(qname, qlabs, cenm, celabs)); 2999 1.1 christos *nx = qname; 3000 1.1 christos *nxlen = qname_len; 3001 1.1 christos if(strip>0) 3002 1.1 christos dname_remove_labels(nx, nxlen, strip); 3003 1.1 christos } 3004 1.1 christos 3005 1.1 christos /** Find the closest encloser that has exact NSEC3. 3006 1.1 christos * updated cenm to the new name. If it went up no-exact-ce is true. */ 3007 1.1 christos static struct auth_data* 3008 1.1 christos az_nsec3_find_ce(struct auth_zone* z, uint8_t** cenm, size_t* cenmlen, 3009 1.1 christos int* no_exact_ce, int algo, size_t iter, uint8_t* salt, size_t saltlen) 3010 1.1 christos { 3011 1.1 christos struct auth_data* node; 3012 1.1 christos while((node = az_nsec3_find_exact(z, *cenm, *cenmlen, 3013 1.1 christos algo, iter, salt, saltlen)) == NULL) { 3014 1.5 christos if(!dname_remove_label_limit_len(cenm, cenmlen, z->namelen)) 3015 1.5 christos return NULL; /* can't go up */ 3016 1.1 christos *no_exact_ce = 1; 3017 1.1 christos } 3018 1.1 christos return node; 3019 1.1 christos } 3020 1.1 christos 3021 1.1 christos /* Insert NSEC3 record in authority section, if NULL does nothing */ 3022 1.1 christos static int 3023 1.1 christos az_nsec3_insert(struct auth_zone* z, struct regional* region, 3024 1.1 christos struct dns_msg* msg, struct auth_data* node) 3025 1.1 christos { 3026 1.1 christos struct auth_rrset* nsec3; 3027 1.1 christos if(!node) return 1; /* no node, skip this */ 3028 1.1 christos nsec3 = az_domain_rrset(node, LDNS_RR_TYPE_NSEC3); 3029 1.1 christos if(!nsec3) return 1; /* if no nsec3 RR, skip it */ 3030 1.1 christos if(!msg_add_rrset_ns(z, region, msg, node, nsec3)) return 0; 3031 1.1 christos return 1; 3032 1.1 christos } 3033 1.1 christos 3034 1.1 christos /** add NSEC3 records to the zone for the nsec3 proof. 3035 1.1 christos * Specify with the flags with parts of the proof are required. 3036 1.1 christos * the ce is the exact matching name (for notype) but also delegation points. 3037 1.1 christos * qname is the one where the nextcloser name can be derived from. 3038 1.1 christos * If NSEC3 is not properly there (in the zone) nothing is added. 3039 1.1 christos * always enabled: include nsec3 proving about the Closest Encloser. 3040 1.1 christos * that is an exact match that should exist for it. 3041 1.1 christos * If that does not exist, a higher exact match + nxproof is enabled 3042 1.1 christos * (for some sort of opt-out empty nonterminal cases). 3043 1.2 christos * nodataproof: search for exact match and include that instead. 3044 1.2 christos * ceproof: include ce proof NSEC3 (omitted for wildcard replies). 3045 1.1 christos * nxproof: include denial of the qname. 3046 1.1 christos * wcproof: include denial of wildcard (wildcard.ce). 3047 1.1 christos */ 3048 1.1 christos static int 3049 1.1 christos az_add_nsec3_proof(struct auth_zone* z, struct regional* region, 3050 1.1 christos struct dns_msg* msg, uint8_t* cenm, size_t cenmlen, uint8_t* qname, 3051 1.2 christos size_t qname_len, int nodataproof, int ceproof, int nxproof, 3052 1.2 christos int wcproof) 3053 1.1 christos { 3054 1.1 christos int algo; 3055 1.1 christos size_t iter, saltlen; 3056 1.1 christos uint8_t* salt; 3057 1.1 christos int no_exact_ce = 0; 3058 1.1 christos struct auth_data* node; 3059 1.1 christos 3060 1.1 christos /* find parameters of nsec3 proof */ 3061 1.1 christos if(!az_nsec3_param(z, &algo, &iter, &salt, &saltlen)) 3062 1.1 christos return 1; /* no nsec3 */ 3063 1.2 christos if(nodataproof) { 3064 1.2 christos /* see if the node has a hash of itself for the nodata 3065 1.2 christos * proof nsec3, this has to be an exact match nsec3. */ 3066 1.2 christos struct auth_data* match; 3067 1.2 christos match = az_nsec3_find_exact(z, qname, qname_len, algo, 3068 1.2 christos iter, salt, saltlen); 3069 1.2 christos if(match) { 3070 1.2 christos if(!az_nsec3_insert(z, region, msg, match)) 3071 1.2 christos return 0; 3072 1.2 christos /* only nodata NSEC3 needed, no CE or others. */ 3073 1.2 christos return 1; 3074 1.2 christos } 3075 1.2 christos } 3076 1.1 christos /* find ce that has an NSEC3 */ 3077 1.2 christos if(ceproof) { 3078 1.2 christos node = az_nsec3_find_ce(z, &cenm, &cenmlen, &no_exact_ce, 3079 1.2 christos algo, iter, salt, saltlen); 3080 1.2 christos if(no_exact_ce) nxproof = 1; 3081 1.2 christos if(!az_nsec3_insert(z, region, msg, node)) 3082 1.2 christos return 0; 3083 1.2 christos } 3084 1.1 christos 3085 1.1 christos if(nxproof) { 3086 1.1 christos uint8_t* nx; 3087 1.1 christos size_t nxlen; 3088 1.1 christos /* create nextcloser domain name */ 3089 1.1 christos az_nsec3_get_nextcloser(cenm, qname, qname_len, &nx, &nxlen); 3090 1.1 christos /* find nsec3 that matches or covers it */ 3091 1.1 christos node = az_nsec3_find_cover(z, nx, nxlen, algo, iter, salt, 3092 1.1 christos saltlen); 3093 1.1 christos if(!az_nsec3_insert(z, region, msg, node)) 3094 1.1 christos return 0; 3095 1.1 christos } 3096 1.1 christos if(wcproof) { 3097 1.1 christos /* create wildcard name *.ce */ 3098 1.1 christos uint8_t wc[LDNS_MAX_DOMAINLEN]; 3099 1.1 christos size_t wclen; 3100 1.1 christos if(cenmlen+2 > sizeof(wc)) 3101 1.1 christos return 0; /* result would be too long */ 3102 1.1 christos wc[0] = 1; /* length of wildcard label */ 3103 1.1 christos wc[1] = (uint8_t)'*'; /* wildcard label */ 3104 1.1 christos memmove(wc+2, cenm, cenmlen); 3105 1.1 christos wclen = cenmlen+2; 3106 1.1 christos /* find nsec3 that matches or covers it */ 3107 1.1 christos node = az_nsec3_find_cover(z, wc, wclen, algo, iter, salt, 3108 1.1 christos saltlen); 3109 1.1 christos if(!az_nsec3_insert(z, region, msg, node)) 3110 1.1 christos return 0; 3111 1.1 christos } 3112 1.1 christos return 1; 3113 1.1 christos } 3114 1.1 christos 3115 1.1 christos /** generate answer for positive answer */ 3116 1.1 christos static int 3117 1.1 christos az_generate_positive_answer(struct auth_zone* z, struct regional* region, 3118 1.1 christos struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset) 3119 1.1 christos { 3120 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0; 3121 1.1 christos /* see if we want additional rrs */ 3122 1.1 christos if(rrset->type == LDNS_RR_TYPE_MX) { 3123 1.1 christos if(!az_add_additionals_from(z, region, msg, rrset, 2)) 3124 1.1 christos return 0; 3125 1.1 christos } else if(rrset->type == LDNS_RR_TYPE_SRV) { 3126 1.1 christos if(!az_add_additionals_from(z, region, msg, rrset, 6)) 3127 1.1 christos return 0; 3128 1.1 christos } else if(rrset->type == LDNS_RR_TYPE_NS) { 3129 1.1 christos if(!az_add_additionals_from(z, region, msg, rrset, 0)) 3130 1.1 christos return 0; 3131 1.1 christos } 3132 1.1 christos return 1; 3133 1.1 christos } 3134 1.1 christos 3135 1.1 christos /** generate answer for type ANY answer */ 3136 1.1 christos static int 3137 1.1 christos az_generate_any_answer(struct auth_zone* z, struct regional* region, 3138 1.1 christos struct dns_msg* msg, struct auth_data* node) 3139 1.1 christos { 3140 1.1 christos struct auth_rrset* rrset; 3141 1.1 christos int added = 0; 3142 1.1 christos /* add a couple (at least one) RRs */ 3143 1.1 christos if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_SOA)) != NULL) { 3144 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0; 3145 1.1 christos added++; 3146 1.1 christos } 3147 1.1 christos if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_MX)) != NULL) { 3148 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0; 3149 1.1 christos added++; 3150 1.1 christos } 3151 1.1 christos if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_A)) != NULL) { 3152 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0; 3153 1.1 christos added++; 3154 1.1 christos } 3155 1.1 christos if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_AAAA)) != NULL) { 3156 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0; 3157 1.1 christos added++; 3158 1.1 christos } 3159 1.2 christos if(added == 0 && node && node->rrsets) { 3160 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, 3161 1.1 christos node->rrsets)) return 0; 3162 1.1 christos } 3163 1.1 christos return 1; 3164 1.1 christos } 3165 1.1 christos 3166 1.1 christos /** follow cname chain and add more data to the answer section */ 3167 1.1 christos static int 3168 1.1 christos follow_cname_chain(struct auth_zone* z, uint16_t qtype, 3169 1.1 christos struct regional* region, struct dns_msg* msg, 3170 1.1 christos struct packed_rrset_data* d) 3171 1.1 christos { 3172 1.1 christos int maxchain = 0; 3173 1.1 christos /* see if we can add the target of the CNAME into the answer */ 3174 1.1 christos while(maxchain++ < MAX_CNAME_CHAIN) { 3175 1.1 christos struct auth_data* node; 3176 1.1 christos struct auth_rrset* rrset; 3177 1.1 christos size_t clen; 3178 1.1 christos /* d has cname rdata */ 3179 1.1 christos if(d->count == 0) break; /* no CNAME */ 3180 1.1 christos if(d->rr_len[0] < 2+1) break; /* too small */ 3181 1.1 christos if((clen=dname_valid(d->rr_data[0]+2, d->rr_len[0]-2))==0) 3182 1.1 christos break; /* malformed */ 3183 1.1 christos if(!dname_subdomain_c(d->rr_data[0]+2, z->name)) 3184 1.1 christos break; /* target out of zone */ 3185 1.1 christos if((node = az_find_name(z, d->rr_data[0]+2, clen))==NULL) 3186 1.1 christos break; /* no such target name */ 3187 1.1 christos if((rrset=az_domain_rrset(node, qtype))!=NULL) { 3188 1.1 christos /* done we found the target */ 3189 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, rrset)) 3190 1.1 christos return 0; 3191 1.1 christos break; 3192 1.1 christos } 3193 1.1 christos if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_CNAME))==NULL) 3194 1.1 christos break; /* no further CNAME chain, notype */ 3195 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0; 3196 1.1 christos d = rrset->data; 3197 1.1 christos } 3198 1.1 christos return 1; 3199 1.1 christos } 3200 1.1 christos 3201 1.1 christos /** generate answer for cname answer */ 3202 1.1 christos static int 3203 1.1 christos az_generate_cname_answer(struct auth_zone* z, struct query_info* qinfo, 3204 1.1 christos struct regional* region, struct dns_msg* msg, 3205 1.1 christos struct auth_data* node, struct auth_rrset* rrset) 3206 1.1 christos { 3207 1.1 christos if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0; 3208 1.1 christos if(!rrset) return 1; 3209 1.1 christos if(!follow_cname_chain(z, qinfo->qtype, region, msg, rrset->data)) 3210 1.1 christos return 0; 3211 1.1 christos return 1; 3212 1.1 christos } 3213 1.1 christos 3214 1.1 christos /** generate answer for notype answer */ 3215 1.1 christos static int 3216 1.1 christos az_generate_notype_answer(struct auth_zone* z, struct regional* region, 3217 1.1 christos struct dns_msg* msg, struct auth_data* node) 3218 1.1 christos { 3219 1.1 christos struct auth_rrset* rrset; 3220 1.1 christos if(!az_add_negative_soa(z, region, msg)) return 0; 3221 1.1 christos /* DNSSEC denial NSEC */ 3222 1.1 christos if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_NSEC))!=NULL) { 3223 1.1 christos if(!msg_add_rrset_ns(z, region, msg, node, rrset)) return 0; 3224 1.1 christos } else if(node) { 3225 1.1 christos /* DNSSEC denial NSEC3 */ 3226 1.1 christos if(!az_add_nsec3_proof(z, region, msg, node->name, 3227 1.1 christos node->namelen, msg->qinfo.qname, 3228 1.2 christos msg->qinfo.qname_len, 1, 1, 0, 0)) 3229 1.1 christos return 0; 3230 1.1 christos } 3231 1.1 christos return 1; 3232 1.1 christos } 3233 1.1 christos 3234 1.1 christos /** generate answer for referral answer */ 3235 1.1 christos static int 3236 1.1 christos az_generate_referral_answer(struct auth_zone* z, struct regional* region, 3237 1.1 christos struct dns_msg* msg, struct auth_data* ce, struct auth_rrset* rrset) 3238 1.1 christos { 3239 1.1 christos struct auth_rrset* ds, *nsec; 3240 1.1 christos /* turn off AA flag, referral is nonAA because it leaves the zone */ 3241 1.1 christos log_assert(ce); 3242 1.1 christos msg->rep->flags &= ~BIT_AA; 3243 1.1 christos if(!msg_add_rrset_ns(z, region, msg, ce, rrset)) return 0; 3244 1.1 christos /* add DS or deny it */ 3245 1.1 christos if((ds=az_domain_rrset(ce, LDNS_RR_TYPE_DS))!=NULL) { 3246 1.1 christos if(!msg_add_rrset_ns(z, region, msg, ce, ds)) return 0; 3247 1.1 christos } else { 3248 1.1 christos /* deny the DS */ 3249 1.1 christos if((nsec=az_domain_rrset(ce, LDNS_RR_TYPE_NSEC))!=NULL) { 3250 1.1 christos if(!msg_add_rrset_ns(z, region, msg, ce, nsec)) 3251 1.1 christos return 0; 3252 1.1 christos } else { 3253 1.1 christos if(!az_add_nsec3_proof(z, region, msg, ce->name, 3254 1.1 christos ce->namelen, msg->qinfo.qname, 3255 1.2 christos msg->qinfo.qname_len, 1, 1, 0, 0)) 3256 1.1 christos return 0; 3257 1.1 christos } 3258 1.1 christos } 3259 1.1 christos /* add additional rrs for type NS */ 3260 1.1 christos if(!az_add_additionals_from(z, region, msg, rrset, 0)) return 0; 3261 1.1 christos return 1; 3262 1.1 christos } 3263 1.1 christos 3264 1.1 christos /** generate answer for DNAME answer */ 3265 1.1 christos static int 3266 1.1 christos az_generate_dname_answer(struct auth_zone* z, struct query_info* qinfo, 3267 1.1 christos struct regional* region, struct dns_msg* msg, struct auth_data* ce, 3268 1.1 christos struct auth_rrset* rrset) 3269 1.1 christos { 3270 1.1 christos log_assert(ce); 3271 1.1 christos /* add the DNAME and then a CNAME */ 3272 1.1 christos if(!msg_add_rrset_an(z, region, msg, ce, rrset)) return 0; 3273 1.1 christos if(!add_synth_cname(z, qinfo->qname, qinfo->qname_len, region, 3274 1.1 christos msg, ce, rrset)) return 0; 3275 1.1 christos if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_YXDOMAIN) 3276 1.1 christos return 1; 3277 1.1 christos if(msg->rep->rrset_count == 0 || 3278 1.1 christos !msg->rep->rrsets[msg->rep->rrset_count-1]) 3279 1.1 christos return 0; 3280 1.1 christos if(!follow_cname_chain(z, qinfo->qtype, region, msg, 3281 1.1 christos (struct packed_rrset_data*)msg->rep->rrsets[ 3282 1.1 christos msg->rep->rrset_count-1]->entry.data)) 3283 1.1 christos return 0; 3284 1.1 christos return 1; 3285 1.1 christos } 3286 1.1 christos 3287 1.1 christos /** generate answer for wildcard answer */ 3288 1.1 christos static int 3289 1.1 christos az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo, 3290 1.1 christos struct regional* region, struct dns_msg* msg, struct auth_data* ce, 3291 1.1 christos struct auth_data* wildcard, struct auth_data* node) 3292 1.1 christos { 3293 1.1 christos struct auth_rrset* rrset, *nsec; 3294 1.2 christos int insert_ce = 0; 3295 1.1 christos if((rrset=az_domain_rrset(wildcard, qinfo->qtype)) != NULL) { 3296 1.1 christos /* wildcard has type, add it */ 3297 1.1 christos if(!msg_add_rrset_an(z, region, msg, wildcard, rrset)) 3298 1.1 christos return 0; 3299 1.1 christos az_change_dnames(msg, wildcard->name, msg->qinfo.qname, 3300 1.1 christos msg->qinfo.qname_len, 1); 3301 1.1 christos } else if((rrset=az_domain_rrset(wildcard, LDNS_RR_TYPE_CNAME))!=NULL) { 3302 1.1 christos /* wildcard has cname instead, do that */ 3303 1.1 christos if(!msg_add_rrset_an(z, region, msg, wildcard, rrset)) 3304 1.1 christos return 0; 3305 1.1 christos az_change_dnames(msg, wildcard->name, msg->qinfo.qname, 3306 1.1 christos msg->qinfo.qname_len, 1); 3307 1.1 christos if(!follow_cname_chain(z, qinfo->qtype, region, msg, 3308 1.1 christos rrset->data)) 3309 1.1 christos return 0; 3310 1.1 christos } else if(qinfo->qtype == LDNS_RR_TYPE_ANY && wildcard->rrsets) { 3311 1.1 christos /* add ANY rrsets from wildcard node */ 3312 1.1 christos if(!az_generate_any_answer(z, region, msg, wildcard)) 3313 1.1 christos return 0; 3314 1.1 christos az_change_dnames(msg, wildcard->name, msg->qinfo.qname, 3315 1.1 christos msg->qinfo.qname_len, 1); 3316 1.1 christos } else { 3317 1.1 christos /* wildcard has nodata, notype answer */ 3318 1.1 christos /* call other notype routine for dnssec notype denials */ 3319 1.1 christos if(!az_generate_notype_answer(z, region, msg, wildcard)) 3320 1.1 christos return 0; 3321 1.2 christos /* because the notype, there is no positive data with an 3322 1.2 christos * RRSIG that indicates the wildcard position. Thus the 3323 1.2 christos * wildcard qname denial needs to have a CE nsec3. */ 3324 1.2 christos insert_ce = 1; 3325 1.1 christos } 3326 1.1 christos 3327 1.1 christos /* ce and node for dnssec denial of wildcard original name */ 3328 1.1 christos if((nsec=az_find_nsec_cover(z, &node)) != NULL) { 3329 1.1 christos if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0; 3330 1.1 christos } else if(ce) { 3331 1.2 christos uint8_t* wildup = wildcard->name; 3332 1.2 christos size_t wilduplen= wildcard->namelen; 3333 1.5 christos if(!dname_remove_label_limit_len(&wildup, &wilduplen, z->namelen)) 3334 1.5 christos return 0; /* can't go up */ 3335 1.2 christos if(!az_add_nsec3_proof(z, region, msg, wildup, 3336 1.2 christos wilduplen, msg->qinfo.qname, 3337 1.2 christos msg->qinfo.qname_len, 0, insert_ce, 1, 0)) 3338 1.1 christos return 0; 3339 1.1 christos } 3340 1.1 christos 3341 1.1 christos /* fixup name of wildcard from *.zone to qname, use already allocated 3342 1.1 christos * pointer to msg qname */ 3343 1.1 christos az_change_dnames(msg, wildcard->name, msg->qinfo.qname, 3344 1.1 christos msg->qinfo.qname_len, 0); 3345 1.1 christos return 1; 3346 1.1 christos } 3347 1.1 christos 3348 1.1 christos /** generate answer for nxdomain answer */ 3349 1.1 christos static int 3350 1.1 christos az_generate_nxdomain_answer(struct auth_zone* z, struct regional* region, 3351 1.1 christos struct dns_msg* msg, struct auth_data* ce, struct auth_data* node) 3352 1.1 christos { 3353 1.1 christos struct auth_rrset* nsec; 3354 1.1 christos msg->rep->flags |= LDNS_RCODE_NXDOMAIN; 3355 1.1 christos if(!az_add_negative_soa(z, region, msg)) return 0; 3356 1.1 christos if((nsec=az_find_nsec_cover(z, &node)) != NULL) { 3357 1.1 christos if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0; 3358 1.1 christos if(ce && !az_nsec_wildcard_denial(z, region, msg, ce->name, 3359 1.1 christos ce->namelen)) return 0; 3360 1.1 christos } else if(ce) { 3361 1.1 christos if(!az_add_nsec3_proof(z, region, msg, ce->name, 3362 1.1 christos ce->namelen, msg->qinfo.qname, 3363 1.2 christos msg->qinfo.qname_len, 0, 1, 1, 1)) 3364 1.1 christos return 0; 3365 1.1 christos } 3366 1.1 christos return 1; 3367 1.1 christos } 3368 1.1 christos 3369 1.1 christos /** Create answers when an exact match exists for the domain name */ 3370 1.1 christos static int 3371 1.1 christos az_generate_answer_with_node(struct auth_zone* z, struct query_info* qinfo, 3372 1.1 christos struct regional* region, struct dns_msg* msg, struct auth_data* node) 3373 1.1 christos { 3374 1.1 christos struct auth_rrset* rrset; 3375 1.1 christos /* positive answer, rrset we are looking for exists */ 3376 1.1 christos if((rrset=az_domain_rrset(node, qinfo->qtype)) != NULL) { 3377 1.1 christos return az_generate_positive_answer(z, region, msg, node, rrset); 3378 1.1 christos } 3379 1.1 christos /* CNAME? */ 3380 1.1 christos if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_CNAME)) != NULL) { 3381 1.1 christos return az_generate_cname_answer(z, qinfo, region, msg, 3382 1.1 christos node, rrset); 3383 1.1 christos } 3384 1.1 christos /* type ANY ? */ 3385 1.1 christos if(qinfo->qtype == LDNS_RR_TYPE_ANY) { 3386 1.1 christos return az_generate_any_answer(z, region, msg, node); 3387 1.1 christos } 3388 1.1 christos /* NOERROR/NODATA (no such type at domain name) */ 3389 1.1 christos return az_generate_notype_answer(z, region, msg, node); 3390 1.1 christos } 3391 1.1 christos 3392 1.1 christos /** Generate answer without an existing-node that we can use. 3393 1.5 christos * So it'll be a referral, DNAME, notype, wildcard or nxdomain */ 3394 1.1 christos static int 3395 1.1 christos az_generate_answer_nonexistnode(struct auth_zone* z, struct query_info* qinfo, 3396 1.1 christos struct regional* region, struct dns_msg* msg, struct auth_data* ce, 3397 1.1 christos struct auth_rrset* rrset, struct auth_data* node) 3398 1.1 christos { 3399 1.1 christos struct auth_data* wildcard; 3400 1.1 christos 3401 1.1 christos /* we do not have an exact matching name (that exists) */ 3402 1.1 christos /* see if we have a NS or DNAME in the ce */ 3403 1.1 christos if(ce && rrset && rrset->type == LDNS_RR_TYPE_NS) { 3404 1.1 christos return az_generate_referral_answer(z, region, msg, ce, rrset); 3405 1.1 christos } 3406 1.1 christos if(ce && rrset && rrset->type == LDNS_RR_TYPE_DNAME) { 3407 1.1 christos return az_generate_dname_answer(z, qinfo, region, msg, ce, 3408 1.1 christos rrset); 3409 1.1 christos } 3410 1.1 christos /* if there is an empty nonterminal, wildcard and nxdomain don't 3411 1.1 christos * happen, it is a notype answer */ 3412 1.1 christos if(az_empty_nonterminal(z, qinfo, node)) { 3413 1.1 christos return az_generate_notype_answer(z, region, msg, node); 3414 1.1 christos } 3415 1.1 christos /* see if we have a wildcard under the ce */ 3416 1.1 christos if((wildcard=az_find_wildcard(z, qinfo, ce)) != NULL) { 3417 1.1 christos return az_generate_wildcard_answer(z, qinfo, region, msg, 3418 1.1 christos ce, wildcard, node); 3419 1.1 christos } 3420 1.1 christos /* generate nxdomain answer */ 3421 1.1 christos return az_generate_nxdomain_answer(z, region, msg, ce, node); 3422 1.1 christos } 3423 1.1 christos 3424 1.1 christos /** Lookup answer in a zone. */ 3425 1.1 christos static int 3426 1.1 christos auth_zone_generate_answer(struct auth_zone* z, struct query_info* qinfo, 3427 1.1 christos struct regional* region, struct dns_msg** msg, int* fallback) 3428 1.1 christos { 3429 1.1 christos struct auth_data* node, *ce; 3430 1.1 christos struct auth_rrset* rrset; 3431 1.1 christos int node_exact, node_exists; 3432 1.1 christos /* does the zone want fallback in case of failure? */ 3433 1.1 christos *fallback = z->fallback_enabled; 3434 1.1 christos if(!(*msg=msg_create(region, qinfo))) return 0; 3435 1.1 christos 3436 1.1 christos /* lookup if there is a matching domain name for the query */ 3437 1.1 christos az_find_domain(z, qinfo, &node_exact, &node); 3438 1.1 christos 3439 1.1 christos /* see if node exists for generating answers from (i.e. not glue and 3440 1.1 christos * obscured by NS or DNAME or NSEC3-only), and also return the 3441 1.1 christos * closest-encloser from that, closest node that should be used 3442 1.1 christos * to generate answers from that is above the query */ 3443 1.1 christos node_exists = az_find_ce(z, qinfo, node, node_exact, &ce, &rrset); 3444 1.1 christos 3445 1.1 christos if(verbosity >= VERB_ALGO) { 3446 1.1 christos char zname[256], qname[256], nname[256], cename[256], 3447 1.1 christos tpstr[32], rrstr[32]; 3448 1.1 christos sldns_wire2str_dname_buf(qinfo->qname, qinfo->qname_len, qname, 3449 1.1 christos sizeof(qname)); 3450 1.1 christos sldns_wire2str_type_buf(qinfo->qtype, tpstr, sizeof(tpstr)); 3451 1.1 christos sldns_wire2str_dname_buf(z->name, z->namelen, zname, 3452 1.1 christos sizeof(zname)); 3453 1.1 christos if(node) 3454 1.1 christos sldns_wire2str_dname_buf(node->name, node->namelen, 3455 1.1 christos nname, sizeof(nname)); 3456 1.1 christos else snprintf(nname, sizeof(nname), "NULL"); 3457 1.1 christos if(ce) 3458 1.1 christos sldns_wire2str_dname_buf(ce->name, ce->namelen, 3459 1.1 christos cename, sizeof(cename)); 3460 1.1 christos else snprintf(cename, sizeof(cename), "NULL"); 3461 1.1 christos if(rrset) sldns_wire2str_type_buf(rrset->type, rrstr, 3462 1.1 christos sizeof(rrstr)); 3463 1.1 christos else snprintf(rrstr, sizeof(rrstr), "NULL"); 3464 1.1 christos log_info("auth_zone %s query %s %s, domain %s %s %s, " 3465 1.1 christos "ce %s, rrset %s", zname, qname, tpstr, nname, 3466 1.1 christos (node_exact?"exact":"notexact"), 3467 1.1 christos (node_exists?"exist":"notexist"), cename, rrstr); 3468 1.1 christos } 3469 1.1 christos 3470 1.1 christos if(node_exists) { 3471 1.1 christos /* the node is fine, generate answer from node */ 3472 1.1 christos return az_generate_answer_with_node(z, qinfo, region, *msg, 3473 1.1 christos node); 3474 1.1 christos } 3475 1.1 christos return az_generate_answer_nonexistnode(z, qinfo, region, *msg, 3476 1.1 christos ce, rrset, node); 3477 1.1 christos } 3478 1.1 christos 3479 1.1 christos int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo, 3480 1.1 christos struct regional* region, struct dns_msg** msg, int* fallback, 3481 1.1 christos uint8_t* dp_nm, size_t dp_nmlen) 3482 1.1 christos { 3483 1.1 christos int r; 3484 1.1 christos struct auth_zone* z; 3485 1.1 christos /* find the zone that should contain the answer. */ 3486 1.1 christos lock_rw_rdlock(&az->lock); 3487 1.1 christos z = auth_zone_find(az, dp_nm, dp_nmlen, qinfo->qclass); 3488 1.1 christos if(!z) { 3489 1.1 christos lock_rw_unlock(&az->lock); 3490 1.1 christos /* no auth zone, fallback to internet */ 3491 1.1 christos *fallback = 1; 3492 1.1 christos return 0; 3493 1.1 christos } 3494 1.1 christos lock_rw_rdlock(&z->lock); 3495 1.1 christos lock_rw_unlock(&az->lock); 3496 1.1 christos 3497 1.2 christos /* if not for upstream queries, fallback */ 3498 1.2 christos if(!z->for_upstream) { 3499 1.2 christos lock_rw_unlock(&z->lock); 3500 1.2 christos *fallback = 1; 3501 1.2 christos return 0; 3502 1.2 christos } 3503 1.2 christos if(z->zone_expired) { 3504 1.2 christos *fallback = z->fallback_enabled; 3505 1.2 christos lock_rw_unlock(&z->lock); 3506 1.2 christos return 0; 3507 1.2 christos } 3508 1.1 christos /* see what answer that zone would generate */ 3509 1.1 christos r = auth_zone_generate_answer(z, qinfo, region, msg, fallback); 3510 1.1 christos lock_rw_unlock(&z->lock); 3511 1.1 christos return r; 3512 1.1 christos } 3513 1.2 christos 3514 1.2 christos /** encode auth answer */ 3515 1.2 christos static void 3516 1.2 christos auth_answer_encode(struct query_info* qinfo, struct module_env* env, 3517 1.2 christos struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 3518 1.2 christos struct regional* temp, struct dns_msg* msg) 3519 1.2 christos { 3520 1.2 christos uint16_t udpsize; 3521 1.2 christos udpsize = edns->udp_size; 3522 1.2 christos edns->edns_version = EDNS_ADVERTISED_VERSION; 3523 1.2 christos edns->udp_size = EDNS_ADVERTISED_SIZE; 3524 1.2 christos edns->ext_rcode = 0; 3525 1.2 christos edns->bits &= EDNS_DO; 3526 1.2 christos 3527 1.2 christos if(!inplace_cb_reply_local_call(env, qinfo, NULL, msg->rep, 3528 1.2 christos (int)FLAGS_GET_RCODE(msg->rep->flags), edns, repinfo, temp, env->now_tv) 3529 1.2 christos || !reply_info_answer_encode(qinfo, msg->rep, 3530 1.2 christos *(uint16_t*)sldns_buffer_begin(buf), 3531 1.2 christos sldns_buffer_read_u16_at(buf, 2), 3532 1.2 christos buf, 0, 0, temp, udpsize, edns, 3533 1.2 christos (int)(edns->bits&EDNS_DO), 0)) { 3534 1.2 christos error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, 3535 1.2 christos *(uint16_t*)sldns_buffer_begin(buf), 3536 1.2 christos sldns_buffer_read_u16_at(buf, 2), edns); 3537 1.2 christos } 3538 1.2 christos } 3539 1.2 christos 3540 1.2 christos /** encode auth error answer */ 3541 1.2 christos static void 3542 1.2 christos auth_error_encode(struct query_info* qinfo, struct module_env* env, 3543 1.2 christos struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 3544 1.2 christos struct regional* temp, int rcode) 3545 1.2 christos { 3546 1.2 christos edns->edns_version = EDNS_ADVERTISED_VERSION; 3547 1.2 christos edns->udp_size = EDNS_ADVERTISED_SIZE; 3548 1.2 christos edns->ext_rcode = 0; 3549 1.2 christos edns->bits &= EDNS_DO; 3550 1.2 christos 3551 1.2 christos if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL, 3552 1.2 christos rcode, edns, repinfo, temp, env->now_tv)) 3553 1.2 christos edns->opt_list_inplace_cb_out = NULL; 3554 1.2 christos error_encode(buf, rcode|BIT_AA, qinfo, 3555 1.2 christos *(uint16_t*)sldns_buffer_begin(buf), 3556 1.2 christos sldns_buffer_read_u16_at(buf, 2), edns); 3557 1.2 christos } 3558 1.2 christos 3559 1.5 christos int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env, 3560 1.2 christos struct query_info* qinfo, struct edns_data* edns, 3561 1.5 christos struct comm_reply* repinfo, struct sldns_buffer* buf, 3562 1.5 christos struct regional* temp) 3563 1.2 christos { 3564 1.2 christos struct dns_msg* msg = NULL; 3565 1.2 christos struct auth_zone* z; 3566 1.2 christos int r; 3567 1.2 christos int fallback = 0; 3568 1.5 christos /* Copy the qinfo in case of cname aliasing from local-zone */ 3569 1.5 christos struct query_info zqinfo = *qinfo; 3570 1.2 christos 3571 1.2 christos lock_rw_rdlock(&az->lock); 3572 1.2 christos if(!az->have_downstream) { 3573 1.2 christos /* no downstream auth zones */ 3574 1.2 christos lock_rw_unlock(&az->lock); 3575 1.2 christos return 0; 3576 1.2 christos } 3577 1.5 christos 3578 1.2 christos if(qinfo->qtype == LDNS_RR_TYPE_DS) { 3579 1.2 christos uint8_t* delname = qinfo->qname; 3580 1.2 christos size_t delnamelen = qinfo->qname_len; 3581 1.2 christos dname_remove_label(&delname, &delnamelen); 3582 1.2 christos z = auth_zones_find_zone(az, delname, delnamelen, 3583 1.2 christos qinfo->qclass); 3584 1.2 christos } else { 3585 1.5 christos if(zqinfo.local_alias && !local_alias_shallow_copy_qname( 3586 1.5 christos zqinfo.local_alias, &zqinfo.qname, 3587 1.5 christos &zqinfo.qname_len)) { 3588 1.5 christos lock_rw_unlock(&az->lock); 3589 1.5 christos return 0; 3590 1.5 christos } 3591 1.5 christos z = auth_zones_find_zone(az, zqinfo.qname, zqinfo.qname_len, 3592 1.5 christos zqinfo.qclass); 3593 1.2 christos } 3594 1.2 christos if(!z) { 3595 1.2 christos /* no zone above it */ 3596 1.2 christos lock_rw_unlock(&az->lock); 3597 1.2 christos return 0; 3598 1.2 christos } 3599 1.2 christos lock_rw_rdlock(&z->lock); 3600 1.2 christos lock_rw_unlock(&az->lock); 3601 1.2 christos if(!z->for_downstream) { 3602 1.2 christos lock_rw_unlock(&z->lock); 3603 1.2 christos return 0; 3604 1.2 christos } 3605 1.2 christos if(z->zone_expired) { 3606 1.2 christos if(z->fallback_enabled) { 3607 1.2 christos lock_rw_unlock(&z->lock); 3608 1.2 christos return 0; 3609 1.2 christos } 3610 1.2 christos lock_rw_unlock(&z->lock); 3611 1.4 christos env->mesh->num_query_authzone_down++; 3612 1.2 christos auth_error_encode(qinfo, env, edns, repinfo, buf, temp, 3613 1.2 christos LDNS_RCODE_SERVFAIL); 3614 1.2 christos return 1; 3615 1.2 christos } 3616 1.2 christos 3617 1.2 christos /* answer it from zone z */ 3618 1.5 christos r = auth_zone_generate_answer(z, &zqinfo, temp, &msg, &fallback); 3619 1.2 christos lock_rw_unlock(&z->lock); 3620 1.2 christos if(!r && fallback) { 3621 1.2 christos /* fallback to regular answering (recursive) */ 3622 1.2 christos return 0; 3623 1.2 christos } 3624 1.4 christos env->mesh->num_query_authzone_down++; 3625 1.2 christos 3626 1.2 christos /* encode answer */ 3627 1.2 christos if(!r) 3628 1.2 christos auth_error_encode(qinfo, env, edns, repinfo, buf, temp, 3629 1.2 christos LDNS_RCODE_SERVFAIL); 3630 1.2 christos else auth_answer_encode(qinfo, env, edns, repinfo, buf, temp, msg); 3631 1.2 christos 3632 1.2 christos return 1; 3633 1.2 christos } 3634 1.2 christos 3635 1.2 christos int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen, 3636 1.2 christos uint16_t dclass) 3637 1.2 christos { 3638 1.2 christos int r; 3639 1.2 christos struct auth_zone* z; 3640 1.2 christos lock_rw_rdlock(&az->lock); 3641 1.2 christos z = auth_zone_find(az, nm, nmlen, dclass); 3642 1.2 christos if(!z) { 3643 1.2 christos lock_rw_unlock(&az->lock); 3644 1.2 christos /* no such auth zone, fallback */ 3645 1.2 christos return 1; 3646 1.2 christos } 3647 1.2 christos lock_rw_rdlock(&z->lock); 3648 1.2 christos lock_rw_unlock(&az->lock); 3649 1.2 christos r = z->fallback_enabled || (!z->for_upstream); 3650 1.2 christos lock_rw_unlock(&z->lock); 3651 1.2 christos return r; 3652 1.2 christos } 3653 1.2 christos 3654 1.2 christos int 3655 1.2 christos auth_zone_parse_notify_serial(sldns_buffer* pkt, uint32_t *serial) 3656 1.2 christos { 3657 1.2 christos struct query_info q; 3658 1.2 christos uint16_t rdlen; 3659 1.2 christos memset(&q, 0, sizeof(q)); 3660 1.2 christos sldns_buffer_set_position(pkt, 0); 3661 1.2 christos if(!query_info_parse(&q, pkt)) return 0; 3662 1.2 christos if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0) return 0; 3663 1.2 christos /* skip name of RR in answer section */ 3664 1.2 christos if(sldns_buffer_remaining(pkt) < 1) return 0; 3665 1.2 christos if(pkt_dname_len(pkt) == 0) return 0; 3666 1.2 christos /* check type */ 3667 1.2 christos if(sldns_buffer_remaining(pkt) < 10 /* type,class,ttl,rdatalen*/) 3668 1.2 christos return 0; 3669 1.2 christos if(sldns_buffer_read_u16(pkt) != LDNS_RR_TYPE_SOA) return 0; 3670 1.2 christos sldns_buffer_skip(pkt, 2); /* class */ 3671 1.2 christos sldns_buffer_skip(pkt, 4); /* ttl */ 3672 1.2 christos rdlen = sldns_buffer_read_u16(pkt); /* rdatalen */ 3673 1.2 christos if(sldns_buffer_remaining(pkt) < rdlen) return 0; 3674 1.2 christos if(rdlen < 22) return 0; /* bad soa length */ 3675 1.2 christos sldns_buffer_skip(pkt, (ssize_t)(rdlen-20)); 3676 1.2 christos *serial = sldns_buffer_read_u32(pkt); 3677 1.2 christos /* return true when has serial in answer section */ 3678 1.2 christos return 1; 3679 1.2 christos } 3680 1.2 christos 3681 1.4 christos /** print addr to str, and if not 53, append "@port_number", for logs. */ 3682 1.4 christos static void addr_port_to_str(struct sockaddr_storage* addr, socklen_t addrlen, 3683 1.4 christos char* buf, size_t len) 3684 1.4 christos { 3685 1.4 christos uint16_t port = 0; 3686 1.4 christos if(addr_is_ip6(addr, addrlen)) { 3687 1.4 christos struct sockaddr_in6* sa = (struct sockaddr_in6*)addr; 3688 1.4 christos port = ntohs((uint16_t)sa->sin6_port); 3689 1.4 christos } else { 3690 1.4 christos struct sockaddr_in* sa = (struct sockaddr_in*)addr; 3691 1.4 christos port = ntohs((uint16_t)sa->sin_port); 3692 1.4 christos } 3693 1.4 christos if(port == UNBOUND_DNS_PORT) { 3694 1.4 christos /* If it is port 53, print it plainly. */ 3695 1.4 christos addr_to_str(addr, addrlen, buf, len); 3696 1.4 christos } else { 3697 1.4 christos char a[256]; 3698 1.4 christos a[0]=0; 3699 1.4 christos addr_to_str(addr, addrlen, a, sizeof(a)); 3700 1.4 christos snprintf(buf, len, "%s@%d", a, (int)port); 3701 1.4 christos } 3702 1.4 christos } 3703 1.4 christos 3704 1.2 christos /** see if addr appears in the list */ 3705 1.2 christos static int 3706 1.2 christos addr_in_list(struct auth_addr* list, struct sockaddr_storage* addr, 3707 1.2 christos socklen_t addrlen) 3708 1.2 christos { 3709 1.2 christos struct auth_addr* p; 3710 1.2 christos for(p=list; p; p=p->next) { 3711 1.2 christos if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0) 3712 1.2 christos return 1; 3713 1.2 christos } 3714 1.2 christos return 0; 3715 1.2 christos } 3716 1.2 christos 3717 1.2 christos /** check if an address matches a master specification (or one of its 3718 1.2 christos * addresses in the addr list) */ 3719 1.2 christos static int 3720 1.2 christos addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr, 3721 1.2 christos socklen_t addrlen, struct auth_master** fromhost) 3722 1.2 christos { 3723 1.2 christos struct sockaddr_storage a; 3724 1.2 christos socklen_t alen = 0; 3725 1.2 christos int net = 0; 3726 1.2 christos if(addr_in_list(master->list, addr, addrlen)) { 3727 1.2 christos *fromhost = master; 3728 1.2 christos return 1; 3729 1.2 christos } 3730 1.2 christos /* compare address (but not port number, that is the destination 3731 1.2 christos * port of the master, the port number of the received notify is 3732 1.2 christos * allowed to by any port on that master) */ 3733 1.3 christos if(extstrtoaddr(master->host, &a, &alen, UNBOUND_DNS_PORT) && 3734 1.2 christos sockaddr_cmp_addr(addr, addrlen, &a, alen)==0) { 3735 1.2 christos *fromhost = master; 3736 1.2 christos return 1; 3737 1.2 christos } 3738 1.2 christos /* prefixes, addr/len, like 10.0.0.0/8 */ 3739 1.2 christos /* not http and has a / and there is one / */ 3740 1.2 christos if(master->allow_notify && !master->http && 3741 1.2 christos strchr(master->host, '/') != NULL && 3742 1.2 christos strchr(master->host, '/') == strrchr(master->host, '/') && 3743 1.2 christos netblockstrtoaddr(master->host, UNBOUND_DNS_PORT, &a, &alen, 3744 1.2 christos &net) && alen == addrlen) { 3745 1.2 christos if(addr_in_common(addr, (addr_is_ip6(addr, addrlen)?128:32), 3746 1.2 christos &a, net, alen) >= net) { 3747 1.2 christos *fromhost = NULL; /* prefix does not have destination 3748 1.2 christos to send the probe or transfer with */ 3749 1.2 christos return 1; /* matches the netblock */ 3750 1.2 christos } 3751 1.2 christos } 3752 1.2 christos return 0; 3753 1.2 christos } 3754 1.2 christos 3755 1.2 christos /** check access list for notifies */ 3756 1.2 christos static int 3757 1.2 christos az_xfr_allowed_notify(struct auth_xfer* xfr, struct sockaddr_storage* addr, 3758 1.2 christos socklen_t addrlen, struct auth_master** fromhost) 3759 1.2 christos { 3760 1.2 christos struct auth_master* p; 3761 1.2 christos for(p=xfr->allow_notify_list; p; p=p->next) { 3762 1.2 christos if(addr_matches_master(p, addr, addrlen, fromhost)) { 3763 1.2 christos return 1; 3764 1.2 christos } 3765 1.2 christos } 3766 1.2 christos return 0; 3767 1.2 christos } 3768 1.2 christos 3769 1.2 christos /** see if the serial means the zone has to be updated, i.e. the serial 3770 1.2 christos * is newer than the zone serial, or we have no zone */ 3771 1.2 christos static int 3772 1.2 christos xfr_serial_means_update(struct auth_xfer* xfr, uint32_t serial) 3773 1.2 christos { 3774 1.2 christos if(!xfr->have_zone) 3775 1.2 christos return 1; /* no zone, anything is better */ 3776 1.2 christos if(xfr->zone_expired) 3777 1.2 christos return 1; /* expired, the sent serial is better than expired 3778 1.2 christos data */ 3779 1.2 christos if(compare_serial(xfr->serial, serial) < 0) 3780 1.2 christos return 1; /* our serial is smaller than the sent serial, 3781 1.2 christos the data is newer, fetch it */ 3782 1.2 christos return 0; 3783 1.2 christos } 3784 1.2 christos 3785 1.2 christos /** note notify serial, updates the notify information in the xfr struct */ 3786 1.2 christos static void 3787 1.2 christos xfr_note_notify_serial(struct auth_xfer* xfr, int has_serial, uint32_t serial) 3788 1.2 christos { 3789 1.2 christos if(xfr->notify_received && xfr->notify_has_serial && has_serial) { 3790 1.2 christos /* see if this serial is newer */ 3791 1.2 christos if(compare_serial(xfr->notify_serial, serial) < 0) 3792 1.2 christos xfr->notify_serial = serial; 3793 1.2 christos } else if(xfr->notify_received && xfr->notify_has_serial && 3794 1.2 christos !has_serial) { 3795 1.2 christos /* remove serial, we have notify without serial */ 3796 1.2 christos xfr->notify_has_serial = 0; 3797 1.2 christos xfr->notify_serial = 0; 3798 1.2 christos } else if(xfr->notify_received && !xfr->notify_has_serial) { 3799 1.2 christos /* we already have notify without serial, keep it 3800 1.2 christos * that way; no serial check when current operation 3801 1.2 christos * is done */ 3802 1.2 christos } else { 3803 1.2 christos xfr->notify_received = 1; 3804 1.2 christos xfr->notify_has_serial = has_serial; 3805 1.2 christos xfr->notify_serial = serial; 3806 1.2 christos } 3807 1.2 christos } 3808 1.2 christos 3809 1.2 christos /** process a notify serial, start new probe or note serial. xfr is locked */ 3810 1.2 christos static void 3811 1.2 christos xfr_process_notify(struct auth_xfer* xfr, struct module_env* env, 3812 1.2 christos int has_serial, uint32_t serial, struct auth_master* fromhost) 3813 1.2 christos { 3814 1.2 christos /* if the serial of notify is older than we have, don't fetch 3815 1.2 christos * a zone, we already have it */ 3816 1.2 christos if(has_serial && !xfr_serial_means_update(xfr, serial)) { 3817 1.2 christos lock_basic_unlock(&xfr->lock); 3818 1.2 christos return; 3819 1.2 christos } 3820 1.2 christos /* start new probe with this addr src, or note serial */ 3821 1.2 christos if(!xfr_start_probe(xfr, env, fromhost)) { 3822 1.2 christos /* not started because already in progress, note the serial */ 3823 1.2 christos xfr_note_notify_serial(xfr, has_serial, serial); 3824 1.2 christos lock_basic_unlock(&xfr->lock); 3825 1.2 christos } 3826 1.2 christos /* successful end of start_probe unlocked xfr->lock */ 3827 1.2 christos } 3828 1.2 christos 3829 1.2 christos int auth_zones_notify(struct auth_zones* az, struct module_env* env, 3830 1.2 christos uint8_t* nm, size_t nmlen, uint16_t dclass, 3831 1.2 christos struct sockaddr_storage* addr, socklen_t addrlen, int has_serial, 3832 1.2 christos uint32_t serial, int* refused) 3833 1.2 christos { 3834 1.2 christos struct auth_xfer* xfr; 3835 1.2 christos struct auth_master* fromhost = NULL; 3836 1.2 christos /* see which zone this is */ 3837 1.2 christos lock_rw_rdlock(&az->lock); 3838 1.2 christos xfr = auth_xfer_find(az, nm, nmlen, dclass); 3839 1.2 christos if(!xfr) { 3840 1.2 christos lock_rw_unlock(&az->lock); 3841 1.2 christos /* no such zone, refuse the notify */ 3842 1.2 christos *refused = 1; 3843 1.2 christos return 0; 3844 1.2 christos } 3845 1.2 christos lock_basic_lock(&xfr->lock); 3846 1.2 christos lock_rw_unlock(&az->lock); 3847 1.2 christos 3848 1.2 christos /* check access list for notifies */ 3849 1.2 christos if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost)) { 3850 1.2 christos lock_basic_unlock(&xfr->lock); 3851 1.2 christos /* notify not allowed, refuse the notify */ 3852 1.2 christos *refused = 1; 3853 1.2 christos return 0; 3854 1.2 christos } 3855 1.2 christos 3856 1.2 christos /* process the notify */ 3857 1.2 christos xfr_process_notify(xfr, env, has_serial, serial, fromhost); 3858 1.2 christos return 1; 3859 1.2 christos } 3860 1.2 christos 3861 1.2 christos int auth_zones_startprobesequence(struct auth_zones* az, 3862 1.2 christos struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t dclass) 3863 1.2 christos { 3864 1.2 christos struct auth_xfer* xfr; 3865 1.2 christos lock_rw_rdlock(&az->lock); 3866 1.2 christos xfr = auth_xfer_find(az, nm, nmlen, dclass); 3867 1.2 christos if(!xfr) { 3868 1.2 christos lock_rw_unlock(&az->lock); 3869 1.2 christos return 0; 3870 1.2 christos } 3871 1.2 christos lock_basic_lock(&xfr->lock); 3872 1.2 christos lock_rw_unlock(&az->lock); 3873 1.2 christos 3874 1.2 christos xfr_process_notify(xfr, env, 0, 0, NULL); 3875 1.2 christos return 1; 3876 1.2 christos } 3877 1.2 christos 3878 1.2 christos /** set a zone expired */ 3879 1.2 christos static void 3880 1.2 christos auth_xfer_set_expired(struct auth_xfer* xfr, struct module_env* env, 3881 1.2 christos int expired) 3882 1.2 christos { 3883 1.2 christos struct auth_zone* z; 3884 1.2 christos 3885 1.2 christos /* expire xfr */ 3886 1.2 christos lock_basic_lock(&xfr->lock); 3887 1.2 christos xfr->zone_expired = expired; 3888 1.2 christos lock_basic_unlock(&xfr->lock); 3889 1.2 christos 3890 1.2 christos /* find auth_zone */ 3891 1.2 christos lock_rw_rdlock(&env->auth_zones->lock); 3892 1.2 christos z = auth_zone_find(env->auth_zones, xfr->name, xfr->namelen, 3893 1.2 christos xfr->dclass); 3894 1.2 christos if(!z) { 3895 1.2 christos lock_rw_unlock(&env->auth_zones->lock); 3896 1.2 christos return; 3897 1.2 christos } 3898 1.2 christos lock_rw_wrlock(&z->lock); 3899 1.2 christos lock_rw_unlock(&env->auth_zones->lock); 3900 1.2 christos 3901 1.2 christos /* expire auth_zone */ 3902 1.2 christos z->zone_expired = expired; 3903 1.2 christos lock_rw_unlock(&z->lock); 3904 1.2 christos } 3905 1.2 christos 3906 1.2 christos /** find master (from notify or probe) in list of masters */ 3907 1.2 christos static struct auth_master* 3908 1.2 christos find_master_by_host(struct auth_master* list, char* host) 3909 1.2 christos { 3910 1.2 christos struct auth_master* p; 3911 1.2 christos for(p=list; p; p=p->next) { 3912 1.2 christos if(strcmp(p->host, host) == 0) 3913 1.2 christos return p; 3914 1.2 christos } 3915 1.2 christos return NULL; 3916 1.2 christos } 3917 1.2 christos 3918 1.2 christos /** delete the looked up auth_addrs for all the masters in the list */ 3919 1.2 christos static void 3920 1.2 christos xfr_masterlist_free_addrs(struct auth_master* list) 3921 1.2 christos { 3922 1.2 christos struct auth_master* m; 3923 1.2 christos for(m=list; m; m=m->next) { 3924 1.2 christos if(m->list) { 3925 1.2 christos auth_free_master_addrs(m->list); 3926 1.2 christos m->list = NULL; 3927 1.2 christos } 3928 1.2 christos } 3929 1.2 christos } 3930 1.2 christos 3931 1.2 christos /** copy a list of auth_addrs */ 3932 1.2 christos static struct auth_addr* 3933 1.2 christos auth_addr_list_copy(struct auth_addr* source) 3934 1.2 christos { 3935 1.2 christos struct auth_addr* list = NULL, *last = NULL; 3936 1.2 christos struct auth_addr* p; 3937 1.2 christos for(p=source; p; p=p->next) { 3938 1.2 christos struct auth_addr* a = (struct auth_addr*)memdup(p, sizeof(*p)); 3939 1.2 christos if(!a) { 3940 1.2 christos log_err("malloc failure"); 3941 1.2 christos auth_free_master_addrs(list); 3942 1.2 christos return NULL; 3943 1.2 christos } 3944 1.2 christos a->next = NULL; 3945 1.2 christos if(last) last->next = a; 3946 1.2 christos if(!list) list = a; 3947 1.2 christos last = a; 3948 1.2 christos } 3949 1.2 christos return list; 3950 1.2 christos } 3951 1.2 christos 3952 1.2 christos /** copy a master to a new structure, NULL on alloc failure */ 3953 1.2 christos static struct auth_master* 3954 1.2 christos auth_master_copy(struct auth_master* o) 3955 1.2 christos { 3956 1.2 christos struct auth_master* m; 3957 1.2 christos if(!o) return NULL; 3958 1.2 christos m = (struct auth_master*)memdup(o, sizeof(*o)); 3959 1.2 christos if(!m) { 3960 1.2 christos log_err("malloc failure"); 3961 1.2 christos return NULL; 3962 1.2 christos } 3963 1.2 christos m->next = NULL; 3964 1.2 christos if(m->host) { 3965 1.2 christos m->host = strdup(m->host); 3966 1.2 christos if(!m->host) { 3967 1.2 christos free(m); 3968 1.2 christos log_err("malloc failure"); 3969 1.2 christos return NULL; 3970 1.2 christos } 3971 1.2 christos } 3972 1.2 christos if(m->file) { 3973 1.2 christos m->file = strdup(m->file); 3974 1.2 christos if(!m->file) { 3975 1.2 christos free(m->host); 3976 1.2 christos free(m); 3977 1.2 christos log_err("malloc failure"); 3978 1.2 christos return NULL; 3979 1.2 christos } 3980 1.2 christos } 3981 1.2 christos if(m->list) { 3982 1.2 christos m->list = auth_addr_list_copy(m->list); 3983 1.2 christos if(!m->list) { 3984 1.2 christos free(m->file); 3985 1.2 christos free(m->host); 3986 1.2 christos free(m); 3987 1.2 christos return NULL; 3988 1.2 christos } 3989 1.2 christos } 3990 1.2 christos return m; 3991 1.2 christos } 3992 1.2 christos 3993 1.2 christos /** copy the master addresses from the task_probe lookups to the allow_notify 3994 1.2 christos * list of masters */ 3995 1.2 christos static void 3996 1.2 christos probe_copy_masters_for_allow_notify(struct auth_xfer* xfr) 3997 1.2 christos { 3998 1.2 christos struct auth_master* list = NULL, *last = NULL; 3999 1.2 christos struct auth_master* p; 4000 1.2 christos /* build up new list with copies */ 4001 1.2 christos for(p = xfr->task_transfer->masters; p; p=p->next) { 4002 1.2 christos struct auth_master* m = auth_master_copy(p); 4003 1.2 christos if(!m) { 4004 1.2 christos auth_free_masters(list); 4005 1.2 christos /* failed because of malloc failure, use old list */ 4006 1.2 christos return; 4007 1.2 christos } 4008 1.2 christos m->next = NULL; 4009 1.2 christos if(last) last->next = m; 4010 1.2 christos if(!list) list = m; 4011 1.2 christos last = m; 4012 1.2 christos } 4013 1.2 christos /* success, replace list */ 4014 1.2 christos auth_free_masters(xfr->allow_notify_list); 4015 1.2 christos xfr->allow_notify_list = list; 4016 1.2 christos } 4017 1.2 christos 4018 1.2 christos /** start the lookups for task_transfer */ 4019 1.2 christos static void 4020 1.2 christos xfr_transfer_start_lookups(struct auth_xfer* xfr) 4021 1.2 christos { 4022 1.2 christos /* delete all the looked up addresses in the list */ 4023 1.2 christos xfr->task_transfer->scan_addr = NULL; 4024 1.2 christos xfr_masterlist_free_addrs(xfr->task_transfer->masters); 4025 1.2 christos 4026 1.2 christos /* start lookup at the first master */ 4027 1.2 christos xfr->task_transfer->lookup_target = xfr->task_transfer->masters; 4028 1.2 christos xfr->task_transfer->lookup_aaaa = 0; 4029 1.2 christos } 4030 1.2 christos 4031 1.2 christos /** move to the next lookup of hostname for task_transfer */ 4032 1.2 christos static void 4033 1.2 christos xfr_transfer_move_to_next_lookup(struct auth_xfer* xfr, struct module_env* env) 4034 1.2 christos { 4035 1.2 christos if(!xfr->task_transfer->lookup_target) 4036 1.2 christos return; /* already at end of list */ 4037 1.2 christos if(!xfr->task_transfer->lookup_aaaa && env->cfg->do_ip6) { 4038 1.2 christos /* move to lookup AAAA */ 4039 1.2 christos xfr->task_transfer->lookup_aaaa = 1; 4040 1.2 christos return; 4041 1.2 christos } 4042 1.2 christos xfr->task_transfer->lookup_target = 4043 1.2 christos xfr->task_transfer->lookup_target->next; 4044 1.2 christos xfr->task_transfer->lookup_aaaa = 0; 4045 1.2 christos if(!env->cfg->do_ip4 && xfr->task_transfer->lookup_target!=NULL) 4046 1.2 christos xfr->task_transfer->lookup_aaaa = 1; 4047 1.2 christos } 4048 1.2 christos 4049 1.2 christos /** start the lookups for task_probe */ 4050 1.2 christos static void 4051 1.2 christos xfr_probe_start_lookups(struct auth_xfer* xfr) 4052 1.2 christos { 4053 1.2 christos /* delete all the looked up addresses in the list */ 4054 1.2 christos xfr->task_probe->scan_addr = NULL; 4055 1.2 christos xfr_masterlist_free_addrs(xfr->task_probe->masters); 4056 1.2 christos 4057 1.2 christos /* start lookup at the first master */ 4058 1.2 christos xfr->task_probe->lookup_target = xfr->task_probe->masters; 4059 1.2 christos xfr->task_probe->lookup_aaaa = 0; 4060 1.2 christos } 4061 1.2 christos 4062 1.2 christos /** move to the next lookup of hostname for task_probe */ 4063 1.2 christos static void 4064 1.2 christos xfr_probe_move_to_next_lookup(struct auth_xfer* xfr, struct module_env* env) 4065 1.2 christos { 4066 1.2 christos if(!xfr->task_probe->lookup_target) 4067 1.2 christos return; /* already at end of list */ 4068 1.2 christos if(!xfr->task_probe->lookup_aaaa && env->cfg->do_ip6) { 4069 1.2 christos /* move to lookup AAAA */ 4070 1.2 christos xfr->task_probe->lookup_aaaa = 1; 4071 1.2 christos return; 4072 1.2 christos } 4073 1.2 christos xfr->task_probe->lookup_target = xfr->task_probe->lookup_target->next; 4074 1.2 christos xfr->task_probe->lookup_aaaa = 0; 4075 1.2 christos if(!env->cfg->do_ip4 && xfr->task_probe->lookup_target!=NULL) 4076 1.2 christos xfr->task_probe->lookup_aaaa = 1; 4077 1.2 christos } 4078 1.2 christos 4079 1.2 christos /** start the iteration of the task_transfer list of masters */ 4080 1.2 christos static void 4081 1.2 christos xfr_transfer_start_list(struct auth_xfer* xfr, struct auth_master* spec) 4082 1.2 christos { 4083 1.2 christos if(spec) { 4084 1.2 christos xfr->task_transfer->scan_specific = find_master_by_host( 4085 1.2 christos xfr->task_transfer->masters, spec->host); 4086 1.2 christos if(xfr->task_transfer->scan_specific) { 4087 1.2 christos xfr->task_transfer->scan_target = NULL; 4088 1.2 christos xfr->task_transfer->scan_addr = NULL; 4089 1.2 christos if(xfr->task_transfer->scan_specific->list) 4090 1.2 christos xfr->task_transfer->scan_addr = 4091 1.2 christos xfr->task_transfer->scan_specific->list; 4092 1.2 christos return; 4093 1.2 christos } 4094 1.2 christos } 4095 1.2 christos /* no specific (notified) host to scan */ 4096 1.2 christos xfr->task_transfer->scan_specific = NULL; 4097 1.2 christos xfr->task_transfer->scan_addr = NULL; 4098 1.2 christos /* pick up first scan target */ 4099 1.2 christos xfr->task_transfer->scan_target = xfr->task_transfer->masters; 4100 1.2 christos if(xfr->task_transfer->scan_target && xfr->task_transfer-> 4101 1.2 christos scan_target->list) 4102 1.2 christos xfr->task_transfer->scan_addr = 4103 1.2 christos xfr->task_transfer->scan_target->list; 4104 1.2 christos } 4105 1.2 christos 4106 1.2 christos /** start the iteration of the task_probe list of masters */ 4107 1.2 christos static void 4108 1.2 christos xfr_probe_start_list(struct auth_xfer* xfr, struct auth_master* spec) 4109 1.2 christos { 4110 1.2 christos if(spec) { 4111 1.2 christos xfr->task_probe->scan_specific = find_master_by_host( 4112 1.2 christos xfr->task_probe->masters, spec->host); 4113 1.2 christos if(xfr->task_probe->scan_specific) { 4114 1.2 christos xfr->task_probe->scan_target = NULL; 4115 1.2 christos xfr->task_probe->scan_addr = NULL; 4116 1.2 christos if(xfr->task_probe->scan_specific->list) 4117 1.2 christos xfr->task_probe->scan_addr = 4118 1.2 christos xfr->task_probe->scan_specific->list; 4119 1.2 christos return; 4120 1.2 christos } 4121 1.2 christos } 4122 1.2 christos /* no specific (notified) host to scan */ 4123 1.2 christos xfr->task_probe->scan_specific = NULL; 4124 1.2 christos xfr->task_probe->scan_addr = NULL; 4125 1.2 christos /* pick up first scan target */ 4126 1.2 christos xfr->task_probe->scan_target = xfr->task_probe->masters; 4127 1.2 christos if(xfr->task_probe->scan_target && xfr->task_probe->scan_target->list) 4128 1.2 christos xfr->task_probe->scan_addr = 4129 1.2 christos xfr->task_probe->scan_target->list; 4130 1.2 christos } 4131 1.2 christos 4132 1.2 christos /** pick up the master that is being scanned right now, task_transfer */ 4133 1.2 christos static struct auth_master* 4134 1.2 christos xfr_transfer_current_master(struct auth_xfer* xfr) 4135 1.2 christos { 4136 1.2 christos if(xfr->task_transfer->scan_specific) 4137 1.2 christos return xfr->task_transfer->scan_specific; 4138 1.2 christos return xfr->task_transfer->scan_target; 4139 1.2 christos } 4140 1.2 christos 4141 1.2 christos /** pick up the master that is being scanned right now, task_probe */ 4142 1.2 christos static struct auth_master* 4143 1.2 christos xfr_probe_current_master(struct auth_xfer* xfr) 4144 1.2 christos { 4145 1.2 christos if(xfr->task_probe->scan_specific) 4146 1.2 christos return xfr->task_probe->scan_specific; 4147 1.2 christos return xfr->task_probe->scan_target; 4148 1.2 christos } 4149 1.2 christos 4150 1.2 christos /** true if at end of list, task_transfer */ 4151 1.2 christos static int 4152 1.2 christos xfr_transfer_end_of_list(struct auth_xfer* xfr) 4153 1.2 christos { 4154 1.2 christos return !xfr->task_transfer->scan_specific && 4155 1.2 christos !xfr->task_transfer->scan_target; 4156 1.2 christos } 4157 1.2 christos 4158 1.2 christos /** true if at end of list, task_probe */ 4159 1.2 christos static int 4160 1.2 christos xfr_probe_end_of_list(struct auth_xfer* xfr) 4161 1.2 christos { 4162 1.2 christos return !xfr->task_probe->scan_specific && !xfr->task_probe->scan_target; 4163 1.2 christos } 4164 1.2 christos 4165 1.2 christos /** move to next master in list, task_transfer */ 4166 1.2 christos static void 4167 1.2 christos xfr_transfer_nextmaster(struct auth_xfer* xfr) 4168 1.2 christos { 4169 1.2 christos if(!xfr->task_transfer->scan_specific && 4170 1.2 christos !xfr->task_transfer->scan_target) 4171 1.2 christos return; 4172 1.2 christos if(xfr->task_transfer->scan_addr) { 4173 1.2 christos xfr->task_transfer->scan_addr = 4174 1.2 christos xfr->task_transfer->scan_addr->next; 4175 1.2 christos if(xfr->task_transfer->scan_addr) 4176 1.2 christos return; 4177 1.2 christos } 4178 1.2 christos if(xfr->task_transfer->scan_specific) { 4179 1.2 christos xfr->task_transfer->scan_specific = NULL; 4180 1.2 christos xfr->task_transfer->scan_target = xfr->task_transfer->masters; 4181 1.2 christos if(xfr->task_transfer->scan_target && xfr->task_transfer-> 4182 1.2 christos scan_target->list) 4183 1.2 christos xfr->task_transfer->scan_addr = 4184 1.2 christos xfr->task_transfer->scan_target->list; 4185 1.2 christos return; 4186 1.2 christos } 4187 1.2 christos if(!xfr->task_transfer->scan_target) 4188 1.2 christos return; 4189 1.2 christos xfr->task_transfer->scan_target = xfr->task_transfer->scan_target->next; 4190 1.2 christos if(xfr->task_transfer->scan_target && xfr->task_transfer-> 4191 1.2 christos scan_target->list) 4192 1.2 christos xfr->task_transfer->scan_addr = 4193 1.2 christos xfr->task_transfer->scan_target->list; 4194 1.2 christos return; 4195 1.2 christos } 4196 1.2 christos 4197 1.2 christos /** move to next master in list, task_probe */ 4198 1.2 christos static void 4199 1.2 christos xfr_probe_nextmaster(struct auth_xfer* xfr) 4200 1.2 christos { 4201 1.2 christos if(!xfr->task_probe->scan_specific && !xfr->task_probe->scan_target) 4202 1.2 christos return; 4203 1.2 christos if(xfr->task_probe->scan_addr) { 4204 1.2 christos xfr->task_probe->scan_addr = xfr->task_probe->scan_addr->next; 4205 1.2 christos if(xfr->task_probe->scan_addr) 4206 1.2 christos return; 4207 1.2 christos } 4208 1.2 christos if(xfr->task_probe->scan_specific) { 4209 1.2 christos xfr->task_probe->scan_specific = NULL; 4210 1.2 christos xfr->task_probe->scan_target = xfr->task_probe->masters; 4211 1.2 christos if(xfr->task_probe->scan_target && xfr->task_probe-> 4212 1.2 christos scan_target->list) 4213 1.2 christos xfr->task_probe->scan_addr = 4214 1.2 christos xfr->task_probe->scan_target->list; 4215 1.2 christos return; 4216 1.2 christos } 4217 1.2 christos if(!xfr->task_probe->scan_target) 4218 1.2 christos return; 4219 1.2 christos xfr->task_probe->scan_target = xfr->task_probe->scan_target->next; 4220 1.2 christos if(xfr->task_probe->scan_target && xfr->task_probe-> 4221 1.2 christos scan_target->list) 4222 1.2 christos xfr->task_probe->scan_addr = 4223 1.2 christos xfr->task_probe->scan_target->list; 4224 1.2 christos return; 4225 1.2 christos } 4226 1.2 christos 4227 1.2 christos /** create SOA probe packet for xfr */ 4228 1.2 christos static void 4229 1.2 christos xfr_create_soa_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf, 4230 1.2 christos uint16_t id) 4231 1.2 christos { 4232 1.2 christos struct query_info qinfo; 4233 1.2 christos 4234 1.2 christos memset(&qinfo, 0, sizeof(qinfo)); 4235 1.2 christos qinfo.qname = xfr->name; 4236 1.2 christos qinfo.qname_len = xfr->namelen; 4237 1.2 christos qinfo.qtype = LDNS_RR_TYPE_SOA; 4238 1.2 christos qinfo.qclass = xfr->dclass; 4239 1.2 christos qinfo_query_encode(buf, &qinfo); 4240 1.2 christos sldns_buffer_write_u16_at(buf, 0, id); 4241 1.2 christos } 4242 1.2 christos 4243 1.2 christos /** create IXFR/AXFR packet for xfr */ 4244 1.2 christos static void 4245 1.2 christos xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id, 4246 1.2 christos struct auth_master* master) 4247 1.2 christos { 4248 1.2 christos struct query_info qinfo; 4249 1.2 christos uint32_t serial; 4250 1.2 christos int have_zone; 4251 1.2 christos have_zone = xfr->have_zone; 4252 1.2 christos serial = xfr->serial; 4253 1.2 christos 4254 1.2 christos memset(&qinfo, 0, sizeof(qinfo)); 4255 1.2 christos qinfo.qname = xfr->name; 4256 1.2 christos qinfo.qname_len = xfr->namelen; 4257 1.2 christos xfr->task_transfer->got_xfr_serial = 0; 4258 1.2 christos xfr->task_transfer->rr_scan_num = 0; 4259 1.2 christos xfr->task_transfer->incoming_xfr_serial = 0; 4260 1.2 christos xfr->task_transfer->on_ixfr_is_axfr = 0; 4261 1.2 christos xfr->task_transfer->on_ixfr = 1; 4262 1.2 christos qinfo.qtype = LDNS_RR_TYPE_IXFR; 4263 1.2 christos if(!have_zone || xfr->task_transfer->ixfr_fail || !master->ixfr) { 4264 1.2 christos qinfo.qtype = LDNS_RR_TYPE_AXFR; 4265 1.2 christos xfr->task_transfer->ixfr_fail = 0; 4266 1.2 christos xfr->task_transfer->on_ixfr = 0; 4267 1.2 christos } 4268 1.2 christos 4269 1.2 christos qinfo.qclass = xfr->dclass; 4270 1.2 christos qinfo_query_encode(buf, &qinfo); 4271 1.2 christos sldns_buffer_write_u16_at(buf, 0, id); 4272 1.2 christos 4273 1.2 christos /* append serial for IXFR */ 4274 1.2 christos if(qinfo.qtype == LDNS_RR_TYPE_IXFR) { 4275 1.2 christos size_t end = sldns_buffer_limit(buf); 4276 1.2 christos sldns_buffer_clear(buf); 4277 1.2 christos sldns_buffer_set_position(buf, end); 4278 1.2 christos /* auth section count 1 */ 4279 1.2 christos sldns_buffer_write_u16_at(buf, LDNS_NSCOUNT_OFF, 1); 4280 1.2 christos /* write SOA */ 4281 1.2 christos sldns_buffer_write_u8(buf, 0xC0); /* compressed ptr to qname */ 4282 1.2 christos sldns_buffer_write_u8(buf, 0x0C); 4283 1.2 christos sldns_buffer_write_u16(buf, LDNS_RR_TYPE_SOA); 4284 1.2 christos sldns_buffer_write_u16(buf, qinfo.qclass); 4285 1.2 christos sldns_buffer_write_u32(buf, 0); /* ttl */ 4286 1.2 christos sldns_buffer_write_u16(buf, 22); /* rdata length */ 4287 1.2 christos sldns_buffer_write_u8(buf, 0); /* . */ 4288 1.2 christos sldns_buffer_write_u8(buf, 0); /* . */ 4289 1.2 christos sldns_buffer_write_u32(buf, serial); /* serial */ 4290 1.2 christos sldns_buffer_write_u32(buf, 0); /* refresh */ 4291 1.2 christos sldns_buffer_write_u32(buf, 0); /* retry */ 4292 1.2 christos sldns_buffer_write_u32(buf, 0); /* expire */ 4293 1.2 christos sldns_buffer_write_u32(buf, 0); /* minimum */ 4294 1.2 christos sldns_buffer_flip(buf); 4295 1.2 christos } 4296 1.2 christos } 4297 1.2 christos 4298 1.2 christos /** check if returned packet is OK */ 4299 1.2 christos static int 4300 1.2 christos check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr, 4301 1.2 christos uint32_t* serial) 4302 1.2 christos { 4303 1.2 christos /* parse to see if packet worked, valid reply */ 4304 1.2 christos 4305 1.2 christos /* check serial number of SOA */ 4306 1.2 christos if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) 4307 1.2 christos return 0; 4308 1.2 christos 4309 1.2 christos /* check ID */ 4310 1.2 christos if(LDNS_ID_WIRE(sldns_buffer_begin(pkt)) != xfr->task_probe->id) 4311 1.2 christos return 0; 4312 1.2 christos 4313 1.2 christos /* check flag bits and rcode */ 4314 1.2 christos if(!LDNS_QR_WIRE(sldns_buffer_begin(pkt))) 4315 1.2 christos return 0; 4316 1.2 christos if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) 4317 1.2 christos return 0; 4318 1.2 christos if(LDNS_RCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_RCODE_NOERROR) 4319 1.2 christos return 0; 4320 1.2 christos 4321 1.2 christos /* check qname */ 4322 1.2 christos if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) 4323 1.2 christos return 0; 4324 1.2 christos sldns_buffer_skip(pkt, LDNS_HEADER_SIZE); 4325 1.2 christos if(sldns_buffer_remaining(pkt) < xfr->namelen) 4326 1.2 christos return 0; 4327 1.2 christos if(query_dname_compare(sldns_buffer_current(pkt), xfr->name) != 0) 4328 1.2 christos return 0; 4329 1.2 christos sldns_buffer_skip(pkt, (ssize_t)xfr->namelen); 4330 1.2 christos 4331 1.2 christos /* check qtype, qclass */ 4332 1.2 christos if(sldns_buffer_remaining(pkt) < 4) 4333 1.2 christos return 0; 4334 1.2 christos if(sldns_buffer_read_u16(pkt) != qtype) 4335 1.2 christos return 0; 4336 1.2 christos if(sldns_buffer_read_u16(pkt) != xfr->dclass) 4337 1.2 christos return 0; 4338 1.2 christos 4339 1.2 christos if(serial) { 4340 1.2 christos uint16_t rdlen; 4341 1.2 christos /* read serial number, from answer section SOA */ 4342 1.2 christos if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0) 4343 1.2 christos return 0; 4344 1.2 christos /* read from first record SOA record */ 4345 1.2 christos if(sldns_buffer_remaining(pkt) < 1) 4346 1.2 christos return 0; 4347 1.2 christos if(dname_pkt_compare(pkt, sldns_buffer_current(pkt), 4348 1.2 christos xfr->name) != 0) 4349 1.2 christos return 0; 4350 1.2 christos if(!pkt_dname_len(pkt)) 4351 1.2 christos return 0; 4352 1.2 christos /* type, class, ttl, rdatalen */ 4353 1.2 christos if(sldns_buffer_remaining(pkt) < 4+4+2) 4354 1.2 christos return 0; 4355 1.2 christos if(sldns_buffer_read_u16(pkt) != qtype) 4356 1.2 christos return 0; 4357 1.2 christos if(sldns_buffer_read_u16(pkt) != xfr->dclass) 4358 1.2 christos return 0; 4359 1.2 christos sldns_buffer_skip(pkt, 4); /* ttl */ 4360 1.2 christos rdlen = sldns_buffer_read_u16(pkt); 4361 1.2 christos if(sldns_buffer_remaining(pkt) < rdlen) 4362 1.2 christos return 0; 4363 1.2 christos if(sldns_buffer_remaining(pkt) < 1) 4364 1.2 christos return 0; 4365 1.2 christos if(!pkt_dname_len(pkt)) /* soa name */ 4366 1.2 christos return 0; 4367 1.2 christos if(sldns_buffer_remaining(pkt) < 1) 4368 1.2 christos return 0; 4369 1.2 christos if(!pkt_dname_len(pkt)) /* soa name */ 4370 1.2 christos return 0; 4371 1.2 christos if(sldns_buffer_remaining(pkt) < 20) 4372 1.2 christos return 0; 4373 1.2 christos *serial = sldns_buffer_read_u32(pkt); 4374 1.2 christos } 4375 1.2 christos return 1; 4376 1.2 christos } 4377 1.2 christos 4378 1.2 christos /** read one line from chunks into buffer at current position */ 4379 1.2 christos static int 4380 1.2 christos chunkline_get_line(struct auth_chunk** chunk, size_t* chunk_pos, 4381 1.2 christos sldns_buffer* buf) 4382 1.2 christos { 4383 1.2 christos int readsome = 0; 4384 1.2 christos while(*chunk) { 4385 1.2 christos /* more text in this chunk? */ 4386 1.2 christos if(*chunk_pos < (*chunk)->len) { 4387 1.2 christos readsome = 1; 4388 1.2 christos while(*chunk_pos < (*chunk)->len) { 4389 1.2 christos char c = (char)((*chunk)->data[*chunk_pos]); 4390 1.2 christos (*chunk_pos)++; 4391 1.2 christos if(sldns_buffer_remaining(buf) < 2) { 4392 1.2 christos /* buffer too short */ 4393 1.2 christos verbose(VERB_ALGO, "http chunkline, " 4394 1.2 christos "line too long"); 4395 1.2 christos return 0; 4396 1.2 christos } 4397 1.2 christos sldns_buffer_write_u8(buf, (uint8_t)c); 4398 1.2 christos if(c == '\n') { 4399 1.2 christos /* we are done */ 4400 1.2 christos return 1; 4401 1.2 christos } 4402 1.2 christos } 4403 1.2 christos } 4404 1.2 christos /* move to next chunk */ 4405 1.2 christos *chunk = (*chunk)->next; 4406 1.2 christos *chunk_pos = 0; 4407 1.2 christos } 4408 1.2 christos /* no more text */ 4409 1.2 christos if(readsome) return 1; 4410 1.2 christos return 0; 4411 1.2 christos } 4412 1.2 christos 4413 1.2 christos /** count number of open and closed parenthesis in a chunkline */ 4414 1.2 christos static int 4415 1.2 christos chunkline_count_parens(sldns_buffer* buf, size_t start) 4416 1.2 christos { 4417 1.2 christos size_t end = sldns_buffer_position(buf); 4418 1.2 christos size_t i; 4419 1.2 christos int count = 0; 4420 1.2 christos int squote = 0, dquote = 0; 4421 1.2 christos for(i=start; i<end; i++) { 4422 1.2 christos char c = (char)sldns_buffer_read_u8_at(buf, i); 4423 1.2 christos if(squote && c != '\'') continue; 4424 1.2 christos if(dquote && c != '"') continue; 4425 1.2 christos if(c == '"') 4426 1.2 christos dquote = !dquote; /* skip quoted part */ 4427 1.2 christos else if(c == '\'') 4428 1.2 christos squote = !squote; /* skip quoted part */ 4429 1.2 christos else if(c == '(') 4430 1.2 christos count ++; 4431 1.2 christos else if(c == ')') 4432 1.2 christos count --; 4433 1.2 christos else if(c == ';') { 4434 1.2 christos /* rest is a comment */ 4435 1.2 christos return count; 4436 1.2 christos } 4437 1.2 christos } 4438 1.2 christos return count; 4439 1.2 christos } 4440 1.2 christos 4441 1.2 christos /** remove trailing ;... comment from a line in the chunkline buffer */ 4442 1.2 christos static void 4443 1.2 christos chunkline_remove_trailcomment(sldns_buffer* buf, size_t start) 4444 1.2 christos { 4445 1.2 christos size_t end = sldns_buffer_position(buf); 4446 1.2 christos size_t i; 4447 1.2 christos int squote = 0, dquote = 0; 4448 1.2 christos for(i=start; i<end; i++) { 4449 1.2 christos char c = (char)sldns_buffer_read_u8_at(buf, i); 4450 1.2 christos if(squote && c != '\'') continue; 4451 1.2 christos if(dquote && c != '"') continue; 4452 1.2 christos if(c == '"') 4453 1.2 christos dquote = !dquote; /* skip quoted part */ 4454 1.2 christos else if(c == '\'') 4455 1.2 christos squote = !squote; /* skip quoted part */ 4456 1.2 christos else if(c == ';') { 4457 1.2 christos /* rest is a comment */ 4458 1.2 christos sldns_buffer_set_position(buf, i); 4459 1.2 christos return; 4460 1.2 christos } 4461 1.2 christos } 4462 1.2 christos /* nothing to remove */ 4463 1.2 christos } 4464 1.2 christos 4465 1.2 christos /** see if a chunkline is a comment line (or empty line) */ 4466 1.2 christos static int 4467 1.2 christos chunkline_is_comment_line_or_empty(sldns_buffer* buf) 4468 1.2 christos { 4469 1.2 christos size_t i, end = sldns_buffer_limit(buf); 4470 1.2 christos for(i=0; i<end; i++) { 4471 1.2 christos char c = (char)sldns_buffer_read_u8_at(buf, i); 4472 1.2 christos if(c == ';') 4473 1.2 christos return 1; /* comment */ 4474 1.2 christos else if(c != ' ' && c != '\t' && c != '\r' && c != '\n') 4475 1.2 christos return 0; /* not a comment */ 4476 1.2 christos } 4477 1.2 christos return 1; /* empty */ 4478 1.2 christos } 4479 1.2 christos 4480 1.2 christos /** find a line with ( ) collated */ 4481 1.2 christos static int 4482 1.2 christos chunkline_get_line_collated(struct auth_chunk** chunk, size_t* chunk_pos, 4483 1.2 christos sldns_buffer* buf) 4484 1.2 christos { 4485 1.2 christos size_t pos; 4486 1.2 christos int parens = 0; 4487 1.2 christos sldns_buffer_clear(buf); 4488 1.2 christos pos = sldns_buffer_position(buf); 4489 1.2 christos if(!chunkline_get_line(chunk, chunk_pos, buf)) { 4490 1.2 christos if(sldns_buffer_position(buf) < sldns_buffer_limit(buf)) 4491 1.2 christos sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf), 0); 4492 1.2 christos else sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf)-1, 0); 4493 1.2 christos sldns_buffer_flip(buf); 4494 1.2 christos return 0; 4495 1.2 christos } 4496 1.2 christos parens += chunkline_count_parens(buf, pos); 4497 1.2 christos while(parens > 0) { 4498 1.2 christos chunkline_remove_trailcomment(buf, pos); 4499 1.2 christos pos = sldns_buffer_position(buf); 4500 1.2 christos if(!chunkline_get_line(chunk, chunk_pos, buf)) { 4501 1.2 christos if(sldns_buffer_position(buf) < sldns_buffer_limit(buf)) 4502 1.2 christos sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf), 0); 4503 1.2 christos else sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf)-1, 0); 4504 1.2 christos sldns_buffer_flip(buf); 4505 1.2 christos return 0; 4506 1.2 christos } 4507 1.2 christos parens += chunkline_count_parens(buf, pos); 4508 1.2 christos } 4509 1.2 christos 4510 1.2 christos if(sldns_buffer_remaining(buf) < 1) { 4511 1.2 christos verbose(VERB_ALGO, "http chunkline: " 4512 1.2 christos "line too long"); 4513 1.2 christos return 0; 4514 1.2 christos } 4515 1.2 christos sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf), 0); 4516 1.2 christos sldns_buffer_flip(buf); 4517 1.2 christos return 1; 4518 1.2 christos } 4519 1.2 christos 4520 1.2 christos /** process $ORIGIN for http, 0 nothing, 1 done, 2 error */ 4521 1.2 christos static int 4522 1.2 christos http_parse_origin(sldns_buffer* buf, struct sldns_file_parse_state* pstate) 4523 1.2 christos { 4524 1.2 christos char* line = (char*)sldns_buffer_begin(buf); 4525 1.2 christos if(strncmp(line, "$ORIGIN", 7) == 0 && 4526 1.2 christos isspace((unsigned char)line[7])) { 4527 1.2 christos int s; 4528 1.2 christos pstate->origin_len = sizeof(pstate->origin); 4529 1.2 christos s = sldns_str2wire_dname_buf(sldns_strip_ws(line+8), 4530 1.2 christos pstate->origin, &pstate->origin_len); 4531 1.2 christos if(s) { 4532 1.2 christos pstate->origin_len = 0; 4533 1.2 christos return 2; 4534 1.2 christos } 4535 1.2 christos return 1; 4536 1.2 christos } 4537 1.2 christos return 0; 4538 1.2 christos } 4539 1.2 christos 4540 1.2 christos /** process $TTL for http, 0 nothing, 1 done, 2 error */ 4541 1.2 christos static int 4542 1.2 christos http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate) 4543 1.2 christos { 4544 1.2 christos char* line = (char*)sldns_buffer_begin(buf); 4545 1.2 christos if(strncmp(line, "$TTL", 4) == 0 && 4546 1.2 christos isspace((unsigned char)line[4])) { 4547 1.2 christos const char* end = NULL; 4548 1.2 christos int overflow = 0; 4549 1.2 christos pstate->default_ttl = sldns_str2period( 4550 1.2 christos sldns_strip_ws(line+5), &end, &overflow); 4551 1.2 christos if(overflow) { 4552 1.2 christos return 2; 4553 1.2 christos } 4554 1.2 christos return 1; 4555 1.2 christos } 4556 1.2 christos return 0; 4557 1.2 christos } 4558 1.2 christos 4559 1.2 christos /** find noncomment RR line in chunks, collates lines if ( ) format */ 4560 1.2 christos static int 4561 1.2 christos chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos, 4562 1.2 christos sldns_buffer* buf, struct sldns_file_parse_state* pstate) 4563 1.2 christos { 4564 1.2 christos int ret; 4565 1.2 christos while(chunkline_get_line_collated(chunk, chunk_pos, buf)) { 4566 1.2 christos if(chunkline_is_comment_line_or_empty(buf)) { 4567 1.2 christos /* a comment, go to next line */ 4568 1.2 christos continue; 4569 1.2 christos } 4570 1.2 christos if((ret=http_parse_origin(buf, pstate))!=0) { 4571 1.2 christos if(ret == 2) 4572 1.2 christos return 0; 4573 1.2 christos continue; /* $ORIGIN has been handled */ 4574 1.2 christos } 4575 1.2 christos if((ret=http_parse_ttl(buf, pstate))!=0) { 4576 1.2 christos if(ret == 2) 4577 1.2 christos return 0; 4578 1.2 christos continue; /* $TTL has been handled */ 4579 1.2 christos } 4580 1.2 christos return 1; 4581 1.2 christos } 4582 1.2 christos /* no noncomments, fail */ 4583 1.2 christos return 0; 4584 1.2 christos } 4585 1.2 christos 4586 1.2 christos /** check syntax of chunklist zonefile, parse first RR, return false on 4587 1.2 christos * failure and return a string in the scratch buffer (first RR string) 4588 1.2 christos * on failure. */ 4589 1.2 christos static int 4590 1.2 christos http_zonefile_syntax_check(struct auth_xfer* xfr, sldns_buffer* buf) 4591 1.2 christos { 4592 1.2 christos uint8_t rr[LDNS_RR_BUF_SIZE]; 4593 1.2 christos size_t rr_len, dname_len = 0; 4594 1.2 christos struct sldns_file_parse_state pstate; 4595 1.2 christos struct auth_chunk* chunk; 4596 1.2 christos size_t chunk_pos; 4597 1.2 christos int e; 4598 1.2 christos memset(&pstate, 0, sizeof(pstate)); 4599 1.2 christos pstate.default_ttl = 3600; 4600 1.2 christos if(xfr->namelen < sizeof(pstate.origin)) { 4601 1.2 christos pstate.origin_len = xfr->namelen; 4602 1.2 christos memmove(pstate.origin, xfr->name, xfr->namelen); 4603 1.2 christos } 4604 1.2 christos chunk = xfr->task_transfer->chunks_first; 4605 1.2 christos chunk_pos = 0; 4606 1.2 christos if(!chunkline_non_comment_RR(&chunk, &chunk_pos, buf, &pstate)) { 4607 1.2 christos return 0; 4608 1.2 christos } 4609 1.2 christos rr_len = sizeof(rr); 4610 1.2 christos e=sldns_str2wire_rr_buf((char*)sldns_buffer_begin(buf), rr, &rr_len, 4611 1.2 christos &dname_len, pstate.default_ttl, 4612 1.2 christos pstate.origin_len?pstate.origin:NULL, pstate.origin_len, 4613 1.2 christos pstate.prev_rr_len?pstate.prev_rr:NULL, pstate.prev_rr_len); 4614 1.2 christos if(e != 0) { 4615 1.2 christos log_err("parse failure on first RR[%d]: %s", 4616 1.2 christos LDNS_WIREPARSE_OFFSET(e), 4617 1.2 christos sldns_get_errorstr_parse(LDNS_WIREPARSE_ERROR(e))); 4618 1.2 christos return 0; 4619 1.2 christos } 4620 1.2 christos /* check that class is correct */ 4621 1.2 christos if(sldns_wirerr_get_class(rr, rr_len, dname_len) != xfr->dclass) { 4622 1.2 christos log_err("parse failure: first record in downloaded zonefile " 4623 1.2 christos "from wrong RR class"); 4624 1.2 christos return 0; 4625 1.2 christos } 4626 1.2 christos return 1; 4627 1.2 christos } 4628 1.2 christos 4629 1.2 christos /** sum sizes of chunklist */ 4630 1.2 christos static size_t 4631 1.2 christos chunklist_sum(struct auth_chunk* list) 4632 1.2 christos { 4633 1.2 christos struct auth_chunk* p; 4634 1.2 christos size_t s = 0; 4635 1.2 christos for(p=list; p; p=p->next) { 4636 1.2 christos s += p->len; 4637 1.2 christos } 4638 1.2 christos return s; 4639 1.2 christos } 4640 1.2 christos 4641 1.2 christos /** remove newlines from collated line */ 4642 1.2 christos static void 4643 1.2 christos chunkline_newline_removal(sldns_buffer* buf) 4644 1.2 christos { 4645 1.2 christos size_t i, end=sldns_buffer_limit(buf); 4646 1.2 christos for(i=0; i<end; i++) { 4647 1.2 christos char c = (char)sldns_buffer_read_u8_at(buf, i); 4648 1.2 christos if(c == '\n' && i==end-1) { 4649 1.2 christos sldns_buffer_write_u8_at(buf, i, 0); 4650 1.2 christos sldns_buffer_set_limit(buf, end-1); 4651 1.2 christos return; 4652 1.2 christos } 4653 1.2 christos if(c == '\n') 4654 1.2 christos sldns_buffer_write_u8_at(buf, i, (uint8_t)' '); 4655 1.2 christos } 4656 1.2 christos } 4657 1.2 christos 4658 1.2 christos /** for http download, parse and add RR to zone */ 4659 1.2 christos static int 4660 1.2 christos http_parse_add_rr(struct auth_xfer* xfr, struct auth_zone* z, 4661 1.2 christos sldns_buffer* buf, struct sldns_file_parse_state* pstate) 4662 1.2 christos { 4663 1.2 christos uint8_t rr[LDNS_RR_BUF_SIZE]; 4664 1.2 christos size_t rr_len, dname_len = 0; 4665 1.2 christos int e; 4666 1.2 christos char* line = (char*)sldns_buffer_begin(buf); 4667 1.2 christos rr_len = sizeof(rr); 4668 1.2 christos e = sldns_str2wire_rr_buf(line, rr, &rr_len, &dname_len, 4669 1.2 christos pstate->default_ttl, 4670 1.2 christos pstate->origin_len?pstate->origin:NULL, pstate->origin_len, 4671 1.2 christos pstate->prev_rr_len?pstate->prev_rr:NULL, pstate->prev_rr_len); 4672 1.2 christos if(e != 0) { 4673 1.2 christos log_err("%s/%s parse failure RR[%d]: %s in '%s'", 4674 1.2 christos xfr->task_transfer->master->host, 4675 1.2 christos xfr->task_transfer->master->file, 4676 1.2 christos LDNS_WIREPARSE_OFFSET(e), 4677 1.2 christos sldns_get_errorstr_parse(LDNS_WIREPARSE_ERROR(e)), 4678 1.2 christos line); 4679 1.2 christos return 0; 4680 1.2 christos } 4681 1.2 christos if(rr_len == 0) 4682 1.2 christos return 1; /* empty line or so */ 4683 1.2 christos 4684 1.2 christos /* set prev */ 4685 1.2 christos if(dname_len < sizeof(pstate->prev_rr)) { 4686 1.2 christos memmove(pstate->prev_rr, rr, dname_len); 4687 1.2 christos pstate->prev_rr_len = dname_len; 4688 1.2 christos } 4689 1.2 christos 4690 1.2 christos return az_insert_rr(z, rr, rr_len, dname_len, NULL); 4691 1.2 christos } 4692 1.2 christos 4693 1.2 christos /** RR list iterator, returns RRs from answer section one by one from the 4694 1.2 christos * dns packets in the chunklist */ 4695 1.2 christos static void 4696 1.2 christos chunk_rrlist_start(struct auth_xfer* xfr, struct auth_chunk** rr_chunk, 4697 1.2 christos int* rr_num, size_t* rr_pos) 4698 1.2 christos { 4699 1.2 christos *rr_chunk = xfr->task_transfer->chunks_first; 4700 1.2 christos *rr_num = 0; 4701 1.2 christos *rr_pos = 0; 4702 1.2 christos } 4703 1.2 christos 4704 1.2 christos /** RR list iterator, see if we are at the end of the list */ 4705 1.2 christos static int 4706 1.2 christos chunk_rrlist_end(struct auth_chunk* rr_chunk, int rr_num) 4707 1.2 christos { 4708 1.2 christos while(rr_chunk) { 4709 1.2 christos if(rr_chunk->len < LDNS_HEADER_SIZE) 4710 1.2 christos return 1; 4711 1.2 christos if(rr_num < (int)LDNS_ANCOUNT(rr_chunk->data)) 4712 1.2 christos return 0; 4713 1.2 christos /* no more RRs in this chunk */ 4714 1.2 christos /* continue with next chunk, see if it has RRs */ 4715 1.2 christos rr_chunk = rr_chunk->next; 4716 1.2 christos rr_num = 0; 4717 1.2 christos } 4718 1.2 christos return 1; 4719 1.2 christos } 4720 1.2 christos 4721 1.2 christos /** RR list iterator, move to next RR */ 4722 1.2 christos static void 4723 1.2 christos chunk_rrlist_gonext(struct auth_chunk** rr_chunk, int* rr_num, 4724 1.2 christos size_t* rr_pos, size_t rr_nextpos) 4725 1.2 christos { 4726 1.2 christos /* already at end of chunks? */ 4727 1.2 christos if(!*rr_chunk) 4728 1.2 christos return; 4729 1.2 christos /* move within this chunk */ 4730 1.2 christos if((*rr_chunk)->len >= LDNS_HEADER_SIZE && 4731 1.2 christos (*rr_num)+1 < (int)LDNS_ANCOUNT((*rr_chunk)->data)) { 4732 1.2 christos (*rr_num) += 1; 4733 1.2 christos *rr_pos = rr_nextpos; 4734 1.2 christos return; 4735 1.2 christos } 4736 1.2 christos /* no more RRs in this chunk */ 4737 1.2 christos /* continue with next chunk, see if it has RRs */ 4738 1.2 christos if(*rr_chunk) 4739 1.2 christos *rr_chunk = (*rr_chunk)->next; 4740 1.2 christos while(*rr_chunk) { 4741 1.2 christos *rr_num = 0; 4742 1.2 christos *rr_pos = 0; 4743 1.2 christos if((*rr_chunk)->len >= LDNS_HEADER_SIZE && 4744 1.2 christos LDNS_ANCOUNT((*rr_chunk)->data) > 0) { 4745 1.2 christos return; 4746 1.2 christos } 4747 1.2 christos *rr_chunk = (*rr_chunk)->next; 4748 1.2 christos } 4749 1.2 christos } 4750 1.2 christos 4751 1.2 christos /** RR iterator, get current RR information, false on parse error */ 4752 1.2 christos static int 4753 1.2 christos chunk_rrlist_get_current(struct auth_chunk* rr_chunk, int rr_num, 4754 1.2 christos size_t rr_pos, uint8_t** rr_dname, uint16_t* rr_type, 4755 1.2 christos uint16_t* rr_class, uint32_t* rr_ttl, uint16_t* rr_rdlen, 4756 1.2 christos uint8_t** rr_rdata, size_t* rr_nextpos) 4757 1.2 christos { 4758 1.2 christos sldns_buffer pkt; 4759 1.2 christos /* integrity checks on position */ 4760 1.2 christos if(!rr_chunk) return 0; 4761 1.2 christos if(rr_chunk->len < LDNS_HEADER_SIZE) return 0; 4762 1.2 christos if(rr_num >= (int)LDNS_ANCOUNT(rr_chunk->data)) return 0; 4763 1.2 christos if(rr_pos >= rr_chunk->len) return 0; 4764 1.2 christos 4765 1.2 christos /* fetch rr information */ 4766 1.2 christos sldns_buffer_init_frm_data(&pkt, rr_chunk->data, rr_chunk->len); 4767 1.2 christos if(rr_pos == 0) { 4768 1.2 christos size_t i; 4769 1.2 christos /* skip question section */ 4770 1.2 christos sldns_buffer_set_position(&pkt, LDNS_HEADER_SIZE); 4771 1.2 christos for(i=0; i<LDNS_QDCOUNT(rr_chunk->data); i++) { 4772 1.2 christos if(pkt_dname_len(&pkt) == 0) return 0; 4773 1.2 christos if(sldns_buffer_remaining(&pkt) < 4) return 0; 4774 1.2 christos sldns_buffer_skip(&pkt, 4); /* type and class */ 4775 1.2 christos } 4776 1.2 christos } else { 4777 1.2 christos sldns_buffer_set_position(&pkt, rr_pos); 4778 1.2 christos } 4779 1.2 christos *rr_dname = sldns_buffer_current(&pkt); 4780 1.2 christos if(pkt_dname_len(&pkt) == 0) return 0; 4781 1.2 christos if(sldns_buffer_remaining(&pkt) < 10) return 0; 4782 1.2 christos *rr_type = sldns_buffer_read_u16(&pkt); 4783 1.2 christos *rr_class = sldns_buffer_read_u16(&pkt); 4784 1.2 christos *rr_ttl = sldns_buffer_read_u32(&pkt); 4785 1.2 christos *rr_rdlen = sldns_buffer_read_u16(&pkt); 4786 1.2 christos if(sldns_buffer_remaining(&pkt) < (*rr_rdlen)) return 0; 4787 1.2 christos *rr_rdata = sldns_buffer_current(&pkt); 4788 1.2 christos sldns_buffer_skip(&pkt, (ssize_t)(*rr_rdlen)); 4789 1.2 christos *rr_nextpos = sldns_buffer_position(&pkt); 4790 1.2 christos return 1; 4791 1.2 christos } 4792 1.2 christos 4793 1.2 christos /** print log message where we are in parsing the zone transfer */ 4794 1.2 christos static void 4795 1.2 christos log_rrlist_position(const char* label, struct auth_chunk* rr_chunk, 4796 1.2 christos uint8_t* rr_dname, uint16_t rr_type, size_t rr_counter) 4797 1.2 christos { 4798 1.2 christos sldns_buffer pkt; 4799 1.2 christos size_t dlen; 4800 1.4 christos uint8_t buf[LDNS_MAX_DOMAINLEN]; 4801 1.4 christos char str[LDNS_MAX_DOMAINLEN]; 4802 1.2 christos char typestr[32]; 4803 1.2 christos sldns_buffer_init_frm_data(&pkt, rr_chunk->data, rr_chunk->len); 4804 1.2 christos sldns_buffer_set_position(&pkt, (size_t)(rr_dname - 4805 1.2 christos sldns_buffer_begin(&pkt))); 4806 1.2 christos if((dlen=pkt_dname_len(&pkt)) == 0) return; 4807 1.2 christos if(dlen >= sizeof(buf)) return; 4808 1.2 christos dname_pkt_copy(&pkt, buf, rr_dname); 4809 1.2 christos dname_str(buf, str); 4810 1.2 christos (void)sldns_wire2str_type_buf(rr_type, typestr, sizeof(typestr)); 4811 1.2 christos verbose(VERB_ALGO, "%s at[%d] %s %s", label, (int)rr_counter, 4812 1.2 christos str, typestr); 4813 1.2 christos } 4814 1.2 christos 4815 1.2 christos /** check that start serial is OK for ixfr. we are at rr_counter == 0, 4816 1.2 christos * and we are going to check rr_counter == 1 (has to be type SOA) serial */ 4817 1.2 christos static int 4818 1.2 christos ixfr_start_serial(struct auth_chunk* rr_chunk, int rr_num, size_t rr_pos, 4819 1.2 christos uint8_t* rr_dname, uint16_t rr_type, uint16_t rr_class, 4820 1.2 christos uint32_t rr_ttl, uint16_t rr_rdlen, uint8_t* rr_rdata, 4821 1.2 christos size_t rr_nextpos, uint32_t transfer_serial, uint32_t xfr_serial) 4822 1.2 christos { 4823 1.2 christos uint32_t startserial; 4824 1.2 christos /* move forward on RR */ 4825 1.2 christos chunk_rrlist_gonext(&rr_chunk, &rr_num, &rr_pos, rr_nextpos); 4826 1.2 christos if(chunk_rrlist_end(rr_chunk, rr_num)) { 4827 1.2 christos /* no second SOA */ 4828 1.2 christos verbose(VERB_OPS, "IXFR has no second SOA record"); 4829 1.2 christos return 0; 4830 1.2 christos } 4831 1.2 christos if(!chunk_rrlist_get_current(rr_chunk, rr_num, rr_pos, 4832 1.2 christos &rr_dname, &rr_type, &rr_class, &rr_ttl, &rr_rdlen, 4833 1.2 christos &rr_rdata, &rr_nextpos)) { 4834 1.2 christos verbose(VERB_OPS, "IXFR cannot parse second SOA record"); 4835 1.2 christos /* failed to parse RR */ 4836 1.2 christos return 0; 4837 1.2 christos } 4838 1.2 christos if(rr_type != LDNS_RR_TYPE_SOA) { 4839 1.2 christos verbose(VERB_OPS, "IXFR second record is not type SOA"); 4840 1.2 christos return 0; 4841 1.2 christos } 4842 1.2 christos if(rr_rdlen < 22) { 4843 1.2 christos verbose(VERB_OPS, "IXFR, second SOA has short rdlength"); 4844 1.2 christos return 0; /* bad SOA rdlen */ 4845 1.2 christos } 4846 1.2 christos startserial = sldns_read_uint32(rr_rdata+rr_rdlen-20); 4847 1.2 christos if(startserial == transfer_serial) { 4848 1.2 christos /* empty AXFR, not an IXFR */ 4849 1.2 christos verbose(VERB_OPS, "IXFR second serial same as first"); 4850 1.2 christos return 0; 4851 1.2 christos } 4852 1.2 christos if(startserial != xfr_serial) { 4853 1.2 christos /* wrong start serial, it does not match the serial in 4854 1.2 christos * memory */ 4855 1.2 christos verbose(VERB_OPS, "IXFR is from serial %u to %u but %u " 4856 1.2 christos "in memory, rejecting the zone transfer", 4857 1.2 christos (unsigned)startserial, (unsigned)transfer_serial, 4858 1.2 christos (unsigned)xfr_serial); 4859 1.2 christos return 0; 4860 1.2 christos } 4861 1.2 christos /* everything OK in second SOA serial */ 4862 1.2 christos return 1; 4863 1.2 christos } 4864 1.2 christos 4865 1.2 christos /** apply IXFR to zone in memory. z is locked. false on failure(mallocfail) */ 4866 1.2 christos static int 4867 1.2 christos apply_ixfr(struct auth_xfer* xfr, struct auth_zone* z, 4868 1.2 christos struct sldns_buffer* scratch_buffer) 4869 1.2 christos { 4870 1.2 christos struct auth_chunk* rr_chunk; 4871 1.2 christos int rr_num; 4872 1.2 christos size_t rr_pos; 4873 1.2 christos uint8_t* rr_dname, *rr_rdata; 4874 1.2 christos uint16_t rr_type, rr_class, rr_rdlen; 4875 1.2 christos uint32_t rr_ttl; 4876 1.2 christos size_t rr_nextpos; 4877 1.2 christos int have_transfer_serial = 0; 4878 1.2 christos uint32_t transfer_serial = 0; 4879 1.2 christos size_t rr_counter = 0; 4880 1.2 christos int delmode = 0; 4881 1.2 christos int softfail = 0; 4882 1.2 christos 4883 1.2 christos /* start RR iterator over chunklist of packets */ 4884 1.2 christos chunk_rrlist_start(xfr, &rr_chunk, &rr_num, &rr_pos); 4885 1.2 christos while(!chunk_rrlist_end(rr_chunk, rr_num)) { 4886 1.2 christos if(!chunk_rrlist_get_current(rr_chunk, rr_num, rr_pos, 4887 1.2 christos &rr_dname, &rr_type, &rr_class, &rr_ttl, &rr_rdlen, 4888 1.2 christos &rr_rdata, &rr_nextpos)) { 4889 1.2 christos /* failed to parse RR */ 4890 1.2 christos return 0; 4891 1.2 christos } 4892 1.2 christos if(verbosity>=7) log_rrlist_position("apply ixfr", 4893 1.2 christos rr_chunk, rr_dname, rr_type, rr_counter); 4894 1.2 christos /* twiddle add/del mode and check for start and end */ 4895 1.2 christos if(rr_counter == 0 && rr_type != LDNS_RR_TYPE_SOA) 4896 1.2 christos return 0; 4897 1.2 christos if(rr_counter == 1 && rr_type != LDNS_RR_TYPE_SOA) { 4898 1.2 christos /* this is an AXFR returned from the IXFR master */ 4899 1.2 christos /* but that should already have been detected, by 4900 1.2 christos * on_ixfr_is_axfr */ 4901 1.2 christos return 0; 4902 1.2 christos } 4903 1.2 christos if(rr_type == LDNS_RR_TYPE_SOA) { 4904 1.2 christos uint32_t serial; 4905 1.2 christos if(rr_rdlen < 22) return 0; /* bad SOA rdlen */ 4906 1.2 christos serial = sldns_read_uint32(rr_rdata+rr_rdlen-20); 4907 1.2 christos if(have_transfer_serial == 0) { 4908 1.2 christos have_transfer_serial = 1; 4909 1.2 christos transfer_serial = serial; 4910 1.2 christos delmode = 1; /* gets negated below */ 4911 1.2 christos /* check second RR before going any further */ 4912 1.2 christos if(!ixfr_start_serial(rr_chunk, rr_num, rr_pos, 4913 1.2 christos rr_dname, rr_type, rr_class, rr_ttl, 4914 1.2 christos rr_rdlen, rr_rdata, rr_nextpos, 4915 1.2 christos transfer_serial, xfr->serial)) { 4916 1.2 christos return 0; 4917 1.2 christos } 4918 1.2 christos } else if(transfer_serial == serial) { 4919 1.2 christos have_transfer_serial++; 4920 1.2 christos if(rr_counter == 1) { 4921 1.2 christos /* empty AXFR, with SOA; SOA; */ 4922 1.2 christos /* should have been detected by 4923 1.2 christos * on_ixfr_is_axfr */ 4924 1.2 christos return 0; 4925 1.2 christos } 4926 1.2 christos if(have_transfer_serial == 3) { 4927 1.2 christos /* see serial three times for end */ 4928 1.2 christos /* eg. IXFR: 4929 1.2 christos * SOA 3 start 4930 1.2 christos * SOA 1 second RR, followed by del 4931 1.2 christos * SOA 2 followed by add 4932 1.2 christos * SOA 2 followed by del 4933 1.2 christos * SOA 3 followed by add 4934 1.2 christos * SOA 3 end */ 4935 1.2 christos /* ended by SOA record */ 4936 1.2 christos xfr->serial = transfer_serial; 4937 1.2 christos break; 4938 1.2 christos } 4939 1.2 christos } 4940 1.2 christos /* twiddle add/del mode */ 4941 1.2 christos /* switch from delete part to add part and back again 4942 1.2 christos * just before the soa, it gets deleted and added too 4943 1.2 christos * this means we switch to delete mode for the final 4944 1.2 christos * SOA(so skip that one) */ 4945 1.2 christos delmode = !delmode; 4946 1.2 christos } 4947 1.2 christos /* process this RR */ 4948 1.2 christos /* if the RR is deleted twice or added twice, then we 4949 1.2 christos * softfail, and continue with the rest of the IXFR, so 4950 1.2 christos * that we serve something fairly nice during the refetch */ 4951 1.2 christos if(verbosity>=7) log_rrlist_position((delmode?"del":"add"), 4952 1.2 christos rr_chunk, rr_dname, rr_type, rr_counter); 4953 1.2 christos if(delmode) { 4954 1.2 christos /* delete this RR */ 4955 1.2 christos int nonexist = 0; 4956 1.2 christos if(!az_remove_rr_decompress(z, rr_chunk->data, 4957 1.2 christos rr_chunk->len, scratch_buffer, rr_dname, 4958 1.2 christos rr_type, rr_class, rr_ttl, rr_rdata, rr_rdlen, 4959 1.2 christos &nonexist)) { 4960 1.2 christos /* failed, malloc error or so */ 4961 1.2 christos return 0; 4962 1.2 christos } 4963 1.2 christos if(nonexist) { 4964 1.2 christos /* it was removal of a nonexisting RR */ 4965 1.2 christos if(verbosity>=4) log_rrlist_position( 4966 1.2 christos "IXFR error nonexistent RR", 4967 1.2 christos rr_chunk, rr_dname, rr_type, rr_counter); 4968 1.2 christos softfail = 1; 4969 1.2 christos } 4970 1.2 christos } else if(rr_counter != 0) { 4971 1.2 christos /* skip first SOA RR for addition, it is added in 4972 1.2 christos * the addition part near the end of the ixfr, when 4973 1.2 christos * that serial is seen the second time. */ 4974 1.2 christos int duplicate = 0; 4975 1.2 christos /* add this RR */ 4976 1.2 christos if(!az_insert_rr_decompress(z, rr_chunk->data, 4977 1.2 christos rr_chunk->len, scratch_buffer, rr_dname, 4978 1.2 christos rr_type, rr_class, rr_ttl, rr_rdata, rr_rdlen, 4979 1.2 christos &duplicate)) { 4980 1.2 christos /* failed, malloc error or so */ 4981 1.2 christos return 0; 4982 1.2 christos } 4983 1.2 christos if(duplicate) { 4984 1.2 christos /* it was a duplicate */ 4985 1.2 christos if(verbosity>=4) log_rrlist_position( 4986 1.2 christos "IXFR error duplicate RR", 4987 1.2 christos rr_chunk, rr_dname, rr_type, rr_counter); 4988 1.2 christos softfail = 1; 4989 1.2 christos } 4990 1.2 christos } 4991 1.2 christos 4992 1.2 christos rr_counter++; 4993 1.2 christos chunk_rrlist_gonext(&rr_chunk, &rr_num, &rr_pos, rr_nextpos); 4994 1.2 christos } 4995 1.2 christos if(softfail) { 4996 1.2 christos verbose(VERB_ALGO, "IXFR did not apply cleanly, fetching full zone"); 4997 1.2 christos return 0; 4998 1.2 christos } 4999 1.2 christos return 1; 5000 1.2 christos } 5001 1.2 christos 5002 1.2 christos /** apply AXFR to zone in memory. z is locked. false on failure(mallocfail) */ 5003 1.2 christos static int 5004 1.2 christos apply_axfr(struct auth_xfer* xfr, struct auth_zone* z, 5005 1.2 christos struct sldns_buffer* scratch_buffer) 5006 1.2 christos { 5007 1.2 christos struct auth_chunk* rr_chunk; 5008 1.2 christos int rr_num; 5009 1.2 christos size_t rr_pos; 5010 1.2 christos uint8_t* rr_dname, *rr_rdata; 5011 1.2 christos uint16_t rr_type, rr_class, rr_rdlen; 5012 1.2 christos uint32_t rr_ttl; 5013 1.2 christos uint32_t serial = 0; 5014 1.2 christos size_t rr_nextpos; 5015 1.2 christos size_t rr_counter = 0; 5016 1.2 christos int have_end_soa = 0; 5017 1.2 christos 5018 1.2 christos /* clear the data tree */ 5019 1.2 christos traverse_postorder(&z->data, auth_data_del, NULL); 5020 1.2 christos rbtree_init(&z->data, &auth_data_cmp); 5021 1.2 christos /* clear the RPZ policies */ 5022 1.2 christos if(z->rpz) 5023 1.2 christos rpz_clear(z->rpz); 5024 1.2 christos 5025 1.2 christos xfr->have_zone = 0; 5026 1.2 christos xfr->serial = 0; 5027 1.5 christos xfr->soa_zone_acquired = 0; 5028 1.2 christos 5029 1.2 christos /* insert all RRs in to the zone */ 5030 1.2 christos /* insert the SOA only once, skip the last one */ 5031 1.2 christos /* start RR iterator over chunklist of packets */ 5032 1.2 christos chunk_rrlist_start(xfr, &rr_chunk, &rr_num, &rr_pos); 5033 1.2 christos while(!chunk_rrlist_end(rr_chunk, rr_num)) { 5034 1.2 christos if(!chunk_rrlist_get_current(rr_chunk, rr_num, rr_pos, 5035 1.2 christos &rr_dname, &rr_type, &rr_class, &rr_ttl, &rr_rdlen, 5036 1.2 christos &rr_rdata, &rr_nextpos)) { 5037 1.2 christos /* failed to parse RR */ 5038 1.2 christos return 0; 5039 1.2 christos } 5040 1.2 christos if(verbosity>=7) log_rrlist_position("apply_axfr", 5041 1.2 christos rr_chunk, rr_dname, rr_type, rr_counter); 5042 1.2 christos if(rr_type == LDNS_RR_TYPE_SOA) { 5043 1.2 christos if(rr_counter != 0) { 5044 1.2 christos /* end of the axfr */ 5045 1.2 christos have_end_soa = 1; 5046 1.2 christos break; 5047 1.2 christos } 5048 1.2 christos if(rr_rdlen < 22) return 0; /* bad SOA rdlen */ 5049 1.2 christos serial = sldns_read_uint32(rr_rdata+rr_rdlen-20); 5050 1.2 christos } 5051 1.2 christos 5052 1.2 christos /* add this RR */ 5053 1.2 christos if(!az_insert_rr_decompress(z, rr_chunk->data, rr_chunk->len, 5054 1.2 christos scratch_buffer, rr_dname, rr_type, rr_class, rr_ttl, 5055 1.2 christos rr_rdata, rr_rdlen, NULL)) { 5056 1.2 christos /* failed, malloc error or so */ 5057 1.2 christos return 0; 5058 1.2 christos } 5059 1.2 christos 5060 1.2 christos rr_counter++; 5061 1.2 christos chunk_rrlist_gonext(&rr_chunk, &rr_num, &rr_pos, rr_nextpos); 5062 1.2 christos } 5063 1.2 christos if(!have_end_soa) { 5064 1.2 christos log_err("no end SOA record for AXFR"); 5065 1.2 christos return 0; 5066 1.2 christos } 5067 1.2 christos 5068 1.2 christos xfr->serial = serial; 5069 1.2 christos xfr->have_zone = 1; 5070 1.2 christos return 1; 5071 1.2 christos } 5072 1.2 christos 5073 1.2 christos /** apply HTTP to zone in memory. z is locked. false on failure(mallocfail) */ 5074 1.2 christos static int 5075 1.2 christos apply_http(struct auth_xfer* xfr, struct auth_zone* z, 5076 1.2 christos struct sldns_buffer* scratch_buffer) 5077 1.2 christos { 5078 1.2 christos /* parse data in chunks */ 5079 1.2 christos /* parse RR's and read into memory. ignore $INCLUDE from the 5080 1.2 christos * downloaded file*/ 5081 1.2 christos struct sldns_file_parse_state pstate; 5082 1.2 christos struct auth_chunk* chunk; 5083 1.2 christos size_t chunk_pos; 5084 1.2 christos int ret; 5085 1.2 christos memset(&pstate, 0, sizeof(pstate)); 5086 1.2 christos pstate.default_ttl = 3600; 5087 1.2 christos if(xfr->namelen < sizeof(pstate.origin)) { 5088 1.2 christos pstate.origin_len = xfr->namelen; 5089 1.2 christos memmove(pstate.origin, xfr->name, xfr->namelen); 5090 1.2 christos } 5091 1.2 christos 5092 1.2 christos if(verbosity >= VERB_ALGO) 5093 1.2 christos verbose(VERB_ALGO, "http download %s of size %d", 5094 1.2 christos xfr->task_transfer->master->file, 5095 1.2 christos (int)chunklist_sum(xfr->task_transfer->chunks_first)); 5096 1.2 christos if(xfr->task_transfer->chunks_first && verbosity >= VERB_ALGO) { 5097 1.2 christos char preview[1024]; 5098 1.2 christos if(xfr->task_transfer->chunks_first->len+1 > sizeof(preview)) { 5099 1.2 christos memmove(preview, xfr->task_transfer->chunks_first->data, 5100 1.2 christos sizeof(preview)-1); 5101 1.2 christos preview[sizeof(preview)-1]=0; 5102 1.2 christos } else { 5103 1.2 christos memmove(preview, xfr->task_transfer->chunks_first->data, 5104 1.2 christos xfr->task_transfer->chunks_first->len); 5105 1.2 christos preview[xfr->task_transfer->chunks_first->len]=0; 5106 1.2 christos } 5107 1.2 christos log_info("auth zone http downloaded content preview: %s", 5108 1.2 christos preview); 5109 1.2 christos } 5110 1.2 christos 5111 1.2 christos /* perhaps a little syntax check before we try to apply the data? */ 5112 1.2 christos if(!http_zonefile_syntax_check(xfr, scratch_buffer)) { 5113 1.2 christos log_err("http download %s/%s does not contain a zonefile, " 5114 1.2 christos "but got '%s'", xfr->task_transfer->master->host, 5115 1.2 christos xfr->task_transfer->master->file, 5116 1.2 christos sldns_buffer_begin(scratch_buffer)); 5117 1.2 christos return 0; 5118 1.2 christos } 5119 1.2 christos 5120 1.2 christos /* clear the data tree */ 5121 1.2 christos traverse_postorder(&z->data, auth_data_del, NULL); 5122 1.2 christos rbtree_init(&z->data, &auth_data_cmp); 5123 1.2 christos /* clear the RPZ policies */ 5124 1.2 christos if(z->rpz) 5125 1.2 christos rpz_clear(z->rpz); 5126 1.2 christos 5127 1.2 christos xfr->have_zone = 0; 5128 1.2 christos xfr->serial = 0; 5129 1.5 christos xfr->soa_zone_acquired = 0; 5130 1.2 christos 5131 1.2 christos chunk = xfr->task_transfer->chunks_first; 5132 1.2 christos chunk_pos = 0; 5133 1.2 christos pstate.lineno = 0; 5134 1.2 christos while(chunkline_get_line_collated(&chunk, &chunk_pos, scratch_buffer)) { 5135 1.2 christos /* process this line */ 5136 1.2 christos pstate.lineno++; 5137 1.2 christos chunkline_newline_removal(scratch_buffer); 5138 1.2 christos if(chunkline_is_comment_line_or_empty(scratch_buffer)) { 5139 1.2 christos continue; 5140 1.2 christos } 5141 1.2 christos /* parse line and add RR */ 5142 1.2 christos if((ret=http_parse_origin(scratch_buffer, &pstate))!=0) { 5143 1.2 christos if(ret == 2) { 5144 1.2 christos verbose(VERB_ALGO, "error parsing ORIGIN on line [%s:%d] %s", 5145 1.2 christos xfr->task_transfer->master->file, 5146 1.2 christos pstate.lineno, 5147 1.2 christos sldns_buffer_begin(scratch_buffer)); 5148 1.2 christos return 0; 5149 1.2 christos } 5150 1.2 christos continue; /* $ORIGIN has been handled */ 5151 1.2 christos } 5152 1.2 christos if((ret=http_parse_ttl(scratch_buffer, &pstate))!=0) { 5153 1.2 christos if(ret == 2) { 5154 1.2 christos verbose(VERB_ALGO, "error parsing TTL on line [%s:%d] %s", 5155 1.2 christos xfr->task_transfer->master->file, 5156 1.2 christos pstate.lineno, 5157 1.2 christos sldns_buffer_begin(scratch_buffer)); 5158 1.2 christos return 0; 5159 1.2 christos } 5160 1.2 christos continue; /* $TTL has been handled */ 5161 1.2 christos } 5162 1.2 christos if(!http_parse_add_rr(xfr, z, scratch_buffer, &pstate)) { 5163 1.2 christos verbose(VERB_ALGO, "error parsing line [%s:%d] %s", 5164 1.2 christos xfr->task_transfer->master->file, 5165 1.2 christos pstate.lineno, 5166 1.2 christos sldns_buffer_begin(scratch_buffer)); 5167 1.2 christos return 0; 5168 1.2 christos } 5169 1.2 christos } 5170 1.2 christos return 1; 5171 1.2 christos } 5172 1.2 christos 5173 1.2 christos /** write http chunks to zonefile to create downloaded file */ 5174 1.2 christos static int 5175 1.2 christos auth_zone_write_chunks(struct auth_xfer* xfr, const char* fname) 5176 1.2 christos { 5177 1.2 christos FILE* out; 5178 1.2 christos struct auth_chunk* p; 5179 1.2 christos out = fopen(fname, "w"); 5180 1.2 christos if(!out) { 5181 1.2 christos log_err("could not open %s: %s", fname, strerror(errno)); 5182 1.2 christos return 0; 5183 1.2 christos } 5184 1.2 christos for(p = xfr->task_transfer->chunks_first; p ; p = p->next) { 5185 1.2 christos if(!write_out(out, (char*)p->data, p->len)) { 5186 1.2 christos log_err("could not write http download to %s", fname); 5187 1.2 christos fclose(out); 5188 1.2 christos return 0; 5189 1.2 christos } 5190 1.2 christos } 5191 1.2 christos fclose(out); 5192 1.2 christos return 1; 5193 1.2 christos } 5194 1.2 christos 5195 1.2 christos /** write to zonefile after zone has been updated */ 5196 1.2 christos static void 5197 1.2 christos xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env) 5198 1.2 christos { 5199 1.2 christos struct config_file* cfg = env->cfg; 5200 1.2 christos struct auth_zone* z; 5201 1.2 christos char tmpfile[1024]; 5202 1.2 christos char* zfilename; 5203 1.2 christos lock_basic_unlock(&xfr->lock); 5204 1.2 christos 5205 1.2 christos /* get lock again, so it is a readlock and concurrently queries 5206 1.2 christos * can be answered */ 5207 1.2 christos lock_rw_rdlock(&env->auth_zones->lock); 5208 1.2 christos z = auth_zone_find(env->auth_zones, xfr->name, xfr->namelen, 5209 1.2 christos xfr->dclass); 5210 1.2 christos if(!z) { 5211 1.2 christos lock_rw_unlock(&env->auth_zones->lock); 5212 1.2 christos /* the zone is gone, ignore xfr results */ 5213 1.2 christos lock_basic_lock(&xfr->lock); 5214 1.2 christos return; 5215 1.2 christos } 5216 1.2 christos lock_rw_rdlock(&z->lock); 5217 1.2 christos lock_basic_lock(&xfr->lock); 5218 1.2 christos lock_rw_unlock(&env->auth_zones->lock); 5219 1.2 christos 5220 1.2 christos if(z->zonefile == NULL || z->zonefile[0] == 0) { 5221 1.2 christos lock_rw_unlock(&z->lock); 5222 1.2 christos /* no write needed, no zonefile set */ 5223 1.2 christos return; 5224 1.2 christos } 5225 1.2 christos zfilename = z->zonefile; 5226 1.2 christos if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(zfilename, 5227 1.2 christos cfg->chrootdir, strlen(cfg->chrootdir)) == 0) 5228 1.2 christos zfilename += strlen(cfg->chrootdir); 5229 1.2 christos if(verbosity >= VERB_ALGO) { 5230 1.4 christos char nm[LDNS_MAX_DOMAINLEN]; 5231 1.2 christos dname_str(z->name, nm); 5232 1.2 christos verbose(VERB_ALGO, "write zonefile %s for %s", zfilename, nm); 5233 1.2 christos } 5234 1.2 christos 5235 1.2 christos /* write to tempfile first */ 5236 1.2 christos if((size_t)strlen(zfilename) + 16 > sizeof(tmpfile)) { 5237 1.2 christos verbose(VERB_ALGO, "tmpfilename too long, cannot update " 5238 1.2 christos " zonefile %s", zfilename); 5239 1.2 christos lock_rw_unlock(&z->lock); 5240 1.2 christos return; 5241 1.2 christos } 5242 1.2 christos snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", zfilename, 5243 1.2 christos (unsigned)getpid()); 5244 1.2 christos if(xfr->task_transfer->master->http) { 5245 1.2 christos /* use the stored chunk list to write them */ 5246 1.2 christos if(!auth_zone_write_chunks(xfr, tmpfile)) { 5247 1.2 christos unlink(tmpfile); 5248 1.2 christos lock_rw_unlock(&z->lock); 5249 1.2 christos return; 5250 1.2 christos } 5251 1.2 christos } else if(!auth_zone_write_file(z, tmpfile)) { 5252 1.2 christos unlink(tmpfile); 5253 1.2 christos lock_rw_unlock(&z->lock); 5254 1.2 christos return; 5255 1.2 christos } 5256 1.2 christos #ifdef UB_ON_WINDOWS 5257 1.2 christos (void)unlink(zfilename); /* windows does not replace file with rename() */ 5258 1.2 christos #endif 5259 1.2 christos if(rename(tmpfile, zfilename) < 0) { 5260 1.2 christos log_err("could not rename(%s, %s): %s", tmpfile, zfilename, 5261 1.2 christos strerror(errno)); 5262 1.2 christos unlink(tmpfile); 5263 1.2 christos lock_rw_unlock(&z->lock); 5264 1.2 christos return; 5265 1.2 christos } 5266 1.2 christos lock_rw_unlock(&z->lock); 5267 1.2 christos } 5268 1.2 christos 5269 1.2 christos /** reacquire locks and structures. Starts with no locks, ends 5270 1.2 christos * with xfr and z locks, if fail, no z lock */ 5271 1.2 christos static int xfr_process_reacquire_locks(struct auth_xfer* xfr, 5272 1.2 christos struct module_env* env, struct auth_zone** z) 5273 1.2 christos { 5274 1.2 christos /* release xfr lock, then, while holding az->lock grab both 5275 1.2 christos * z->lock and xfr->lock */ 5276 1.2 christos lock_rw_rdlock(&env->auth_zones->lock); 5277 1.2 christos *z = auth_zone_find(env->auth_zones, xfr->name, xfr->namelen, 5278 1.2 christos xfr->dclass); 5279 1.2 christos if(!*z) { 5280 1.2 christos lock_rw_unlock(&env->auth_zones->lock); 5281 1.2 christos lock_basic_lock(&xfr->lock); 5282 1.2 christos *z = NULL; 5283 1.2 christos return 0; 5284 1.2 christos } 5285 1.2 christos lock_rw_wrlock(&(*z)->lock); 5286 1.2 christos lock_basic_lock(&xfr->lock); 5287 1.2 christos lock_rw_unlock(&env->auth_zones->lock); 5288 1.2 christos return 1; 5289 1.2 christos } 5290 1.2 christos 5291 1.2 christos /** process chunk list and update zone in memory, 5292 1.2 christos * return false if it did not work */ 5293 1.2 christos static int 5294 1.2 christos xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env, 5295 1.2 christos int* ixfr_fail) 5296 1.2 christos { 5297 1.2 christos struct auth_zone* z; 5298 1.2 christos 5299 1.2 christos /* obtain locks and structures */ 5300 1.2 christos lock_basic_unlock(&xfr->lock); 5301 1.2 christos if(!xfr_process_reacquire_locks(xfr, env, &z)) { 5302 1.2 christos /* the zone is gone, ignore xfr results */ 5303 1.2 christos return 0; 5304 1.2 christos } 5305 1.2 christos /* holding xfr and z locks */ 5306 1.2 christos 5307 1.2 christos /* apply data */ 5308 1.2 christos if(xfr->task_transfer->master->http) { 5309 1.2 christos if(!apply_http(xfr, z, env->scratch_buffer)) { 5310 1.2 christos lock_rw_unlock(&z->lock); 5311 1.2 christos verbose(VERB_ALGO, "http from %s: could not store data", 5312 1.2 christos xfr->task_transfer->master->host); 5313 1.2 christos return 0; 5314 1.2 christos } 5315 1.2 christos } else if(xfr->task_transfer->on_ixfr && 5316 1.2 christos !xfr->task_transfer->on_ixfr_is_axfr) { 5317 1.2 christos if(!apply_ixfr(xfr, z, env->scratch_buffer)) { 5318 1.2 christos lock_rw_unlock(&z->lock); 5319 1.2 christos verbose(VERB_ALGO, "xfr from %s: could not store IXFR" 5320 1.2 christos " data", xfr->task_transfer->master->host); 5321 1.2 christos *ixfr_fail = 1; 5322 1.2 christos return 0; 5323 1.2 christos } 5324 1.2 christos } else { 5325 1.2 christos if(!apply_axfr(xfr, z, env->scratch_buffer)) { 5326 1.2 christos lock_rw_unlock(&z->lock); 5327 1.2 christos verbose(VERB_ALGO, "xfr from %s: could not store AXFR" 5328 1.2 christos " data", xfr->task_transfer->master->host); 5329 1.2 christos return 0; 5330 1.2 christos } 5331 1.2 christos } 5332 1.2 christos xfr->zone_expired = 0; 5333 1.2 christos z->zone_expired = 0; 5334 1.2 christos if(!xfr_find_soa(z, xfr)) { 5335 1.2 christos lock_rw_unlock(&z->lock); 5336 1.2 christos verbose(VERB_ALGO, "xfr from %s: no SOA in zone after update" 5337 1.2 christos " (or malformed RR)", xfr->task_transfer->master->host); 5338 1.2 christos return 0; 5339 1.2 christos } 5340 1.5 christos z->soa_zone_acquired = *env->now; 5341 1.5 christos xfr->soa_zone_acquired = *env->now; 5342 1.2 christos 5343 1.2 christos /* release xfr lock while verifying zonemd because it may have 5344 1.2 christos * to spawn lookups in the state machines */ 5345 1.2 christos lock_basic_unlock(&xfr->lock); 5346 1.2 christos /* holding z lock */ 5347 1.2 christos auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 0); 5348 1.2 christos if(z->zone_expired) { 5349 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 5350 1.2 christos /* ZONEMD must have failed */ 5351 1.2 christos /* reacquire locks, so we hold xfr lock on exit of routine, 5352 1.2 christos * and both xfr and z again after releasing xfr for potential 5353 1.2 christos * state machine mesh callbacks */ 5354 1.2 christos lock_rw_unlock(&z->lock); 5355 1.2 christos if(!xfr_process_reacquire_locks(xfr, env, &z)) 5356 1.2 christos return 0; 5357 1.2 christos dname_str(xfr->name, zname); 5358 1.2 christos verbose(VERB_ALGO, "xfr from %s: ZONEMD failed for %s, transfer is failed", xfr->task_transfer->master->host, zname); 5359 1.2 christos xfr->zone_expired = 1; 5360 1.2 christos lock_rw_unlock(&z->lock); 5361 1.2 christos return 0; 5362 1.2 christos } 5363 1.2 christos /* reacquire locks, so we hold xfr lock on exit of routine, 5364 1.2 christos * and both xfr and z again after releasing xfr for potential 5365 1.2 christos * state machine mesh callbacks */ 5366 1.2 christos lock_rw_unlock(&z->lock); 5367 1.2 christos if(!xfr_process_reacquire_locks(xfr, env, &z)) 5368 1.2 christos return 0; 5369 1.2 christos /* holding xfr and z locks */ 5370 1.2 christos 5371 1.2 christos if(xfr->have_zone) 5372 1.2 christos xfr->lease_time = *env->now; 5373 1.2 christos 5374 1.2 christos if(z->rpz) 5375 1.2 christos rpz_finish_config(z->rpz); 5376 1.2 christos 5377 1.2 christos /* unlock */ 5378 1.2 christos lock_rw_unlock(&z->lock); 5379 1.2 christos 5380 1.2 christos if(verbosity >= VERB_QUERY && xfr->have_zone) { 5381 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 5382 1.2 christos dname_str(xfr->name, zname); 5383 1.2 christos verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname, 5384 1.2 christos (unsigned)xfr->serial); 5385 1.2 christos } 5386 1.2 christos /* see if we need to write to a zonefile */ 5387 1.2 christos xfr_write_after_update(xfr, env); 5388 1.2 christos return 1; 5389 1.2 christos } 5390 1.2 christos 5391 1.2 christos /** disown task_transfer. caller must hold xfr.lock */ 5392 1.2 christos static void 5393 1.2 christos xfr_transfer_disown(struct auth_xfer* xfr) 5394 1.2 christos { 5395 1.2 christos /* remove timer (from this worker's event base) */ 5396 1.2 christos comm_timer_delete(xfr->task_transfer->timer); 5397 1.2 christos xfr->task_transfer->timer = NULL; 5398 1.2 christos /* remove the commpoint */ 5399 1.2 christos comm_point_delete(xfr->task_transfer->cp); 5400 1.2 christos xfr->task_transfer->cp = NULL; 5401 1.2 christos /* we don't own this item anymore */ 5402 1.2 christos xfr->task_transfer->worker = NULL; 5403 1.2 christos xfr->task_transfer->env = NULL; 5404 1.2 christos } 5405 1.2 christos 5406 1.2 christos /** lookup a host name for its addresses, if needed */ 5407 1.2 christos static int 5408 1.2 christos xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env) 5409 1.2 christos { 5410 1.2 christos struct sockaddr_storage addr; 5411 1.2 christos socklen_t addrlen = 0; 5412 1.2 christos struct auth_master* master = xfr->task_transfer->lookup_target; 5413 1.2 christos struct query_info qinfo; 5414 1.2 christos uint16_t qflags = BIT_RD; 5415 1.2 christos uint8_t dname[LDNS_MAX_DOMAINLEN+1]; 5416 1.2 christos struct edns_data edns; 5417 1.2 christos sldns_buffer* buf = env->scratch_buffer; 5418 1.2 christos if(!master) return 0; 5419 1.3 christos if(extstrtoaddr(master->host, &addr, &addrlen, UNBOUND_DNS_PORT)) { 5420 1.2 christos /* not needed, host is in IP addr format */ 5421 1.2 christos return 0; 5422 1.2 christos } 5423 1.2 christos if(master->allow_notify) 5424 1.2 christos return 0; /* allow-notifies are not transferred from, no 5425 1.2 christos lookup is needed */ 5426 1.2 christos 5427 1.2 christos /* use mesh_new_callback to probe for non-addr hosts, 5428 1.2 christos * and then wait for them to be looked up (in cache, or query) */ 5429 1.2 christos qinfo.qname_len = sizeof(dname); 5430 1.2 christos if(sldns_str2wire_dname_buf(master->host, dname, &qinfo.qname_len) 5431 1.2 christos != 0) { 5432 1.2 christos log_err("cannot parse host name of master %s", master->host); 5433 1.2 christos return 0; 5434 1.2 christos } 5435 1.2 christos qinfo.qname = dname; 5436 1.2 christos qinfo.qclass = xfr->dclass; 5437 1.2 christos qinfo.qtype = LDNS_RR_TYPE_A; 5438 1.2 christos if(xfr->task_transfer->lookup_aaaa) 5439 1.2 christos qinfo.qtype = LDNS_RR_TYPE_AAAA; 5440 1.2 christos qinfo.local_alias = NULL; 5441 1.2 christos if(verbosity >= VERB_ALGO) { 5442 1.2 christos char buf1[512]; 5443 1.4 christos char buf2[LDNS_MAX_DOMAINLEN]; 5444 1.2 christos dname_str(xfr->name, buf2); 5445 1.2 christos snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup" 5446 1.2 christos " for task_transfer", buf2); 5447 1.2 christos log_query_info(VERB_ALGO, buf1, &qinfo); 5448 1.2 christos } 5449 1.2 christos edns.edns_present = 1; 5450 1.2 christos edns.ext_rcode = 0; 5451 1.2 christos edns.edns_version = 0; 5452 1.2 christos edns.bits = EDNS_DO; 5453 1.2 christos edns.opt_list_in = NULL; 5454 1.2 christos edns.opt_list_out = NULL; 5455 1.2 christos edns.opt_list_inplace_cb_out = NULL; 5456 1.2 christos edns.padding_block_size = 0; 5457 1.3 christos edns.cookie_present = 0; 5458 1.3 christos edns.cookie_valid = 0; 5459 1.2 christos if(sldns_buffer_capacity(buf) < 65535) 5460 1.2 christos edns.udp_size = (uint16_t)sldns_buffer_capacity(buf); 5461 1.2 christos else edns.udp_size = 65535; 5462 1.2 christos 5463 1.2 christos /* unlock xfr during mesh_new_callback() because the callback can be 5464 1.2 christos * called straight away */ 5465 1.2 christos lock_basic_unlock(&xfr->lock); 5466 1.2 christos if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, 5467 1.2 christos &auth_xfer_transfer_lookup_callback, xfr, 0)) { 5468 1.2 christos lock_basic_lock(&xfr->lock); 5469 1.2 christos log_err("out of memory lookup up master %s", master->host); 5470 1.2 christos return 0; 5471 1.2 christos } 5472 1.2 christos lock_basic_lock(&xfr->lock); 5473 1.2 christos return 1; 5474 1.2 christos } 5475 1.2 christos 5476 1.2 christos /** initiate TCP to the target and fetch zone. 5477 1.2 christos * returns true if that was successfully started, and timeout setup. */ 5478 1.2 christos static int 5479 1.2 christos xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) 5480 1.2 christos { 5481 1.2 christos struct sockaddr_storage addr; 5482 1.2 christos socklen_t addrlen = 0; 5483 1.2 christos struct auth_master* master = xfr->task_transfer->master; 5484 1.2 christos char *auth_name = NULL; 5485 1.2 christos struct timeval t; 5486 1.2 christos int timeout; 5487 1.2 christos if(!master) return 0; 5488 1.2 christos if(master->allow_notify) return 0; /* only for notify */ 5489 1.2 christos 5490 1.2 christos /* get master addr */ 5491 1.2 christos if(xfr->task_transfer->scan_addr) { 5492 1.2 christos addrlen = xfr->task_transfer->scan_addr->addrlen; 5493 1.2 christos memmove(&addr, &xfr->task_transfer->scan_addr->addr, addrlen); 5494 1.2 christos } else { 5495 1.2 christos if(!authextstrtoaddr(master->host, &addr, &addrlen, &auth_name)) { 5496 1.2 christos /* the ones that are not in addr format are supposed 5497 1.2 christos * to be looked up. The lookup has failed however, 5498 1.2 christos * so skip them */ 5499 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 5500 1.2 christos dname_str(xfr->name, zname); 5501 1.2 christos log_err("%s: failed lookup, cannot transfer from master %s", 5502 1.2 christos zname, master->host); 5503 1.2 christos return 0; 5504 1.2 christos } 5505 1.2 christos } 5506 1.2 christos 5507 1.2 christos /* remove previous TCP connection (if any) */ 5508 1.2 christos if(xfr->task_transfer->cp) { 5509 1.2 christos comm_point_delete(xfr->task_transfer->cp); 5510 1.2 christos xfr->task_transfer->cp = NULL; 5511 1.2 christos } 5512 1.2 christos if(!xfr->task_transfer->timer) { 5513 1.2 christos xfr->task_transfer->timer = comm_timer_create(env->worker_base, 5514 1.2 christos auth_xfer_transfer_timer_callback, xfr); 5515 1.2 christos if(!xfr->task_transfer->timer) { 5516 1.2 christos log_err("malloc failure"); 5517 1.2 christos return 0; 5518 1.2 christos } 5519 1.2 christos } 5520 1.2 christos timeout = AUTH_TRANSFER_TIMEOUT; 5521 1.2 christos #ifndef S_SPLINT_S 5522 1.2 christos t.tv_sec = timeout/1000; 5523 1.2 christos t.tv_usec = (timeout%1000)*1000; 5524 1.2 christos #endif 5525 1.2 christos 5526 1.2 christos if(master->http) { 5527 1.2 christos /* perform http fetch */ 5528 1.2 christos /* store http port number into sockaddr, 5529 1.2 christos * unless someone used unbound's host@port notation */ 5530 1.2 christos xfr->task_transfer->on_ixfr = 0; 5531 1.2 christos if(strchr(master->host, '@') == NULL) 5532 1.2 christos sockaddr_store_port(&addr, addrlen, master->port); 5533 1.2 christos xfr->task_transfer->cp = outnet_comm_point_for_http( 5534 1.2 christos env->outnet, auth_xfer_transfer_http_callback, xfr, 5535 1.2 christos &addr, addrlen, -1, master->ssl, master->host, 5536 1.2 christos master->file, env->cfg); 5537 1.2 christos if(!xfr->task_transfer->cp) { 5538 1.4 christos char zname[LDNS_MAX_DOMAINLEN], as[256]; 5539 1.2 christos dname_str(xfr->name, zname); 5540 1.4 christos addr_port_to_str(&addr, addrlen, as, sizeof(as)); 5541 1.2 christos verbose(VERB_ALGO, "cannot create http cp " 5542 1.2 christos "connection for %s to %s", zname, as); 5543 1.2 christos return 0; 5544 1.2 christos } 5545 1.2 christos comm_timer_set(xfr->task_transfer->timer, &t); 5546 1.2 christos if(verbosity >= VERB_ALGO) { 5547 1.4 christos char zname[LDNS_MAX_DOMAINLEN], as[256]; 5548 1.2 christos dname_str(xfr->name, zname); 5549 1.4 christos addr_port_to_str(&addr, addrlen, as, sizeof(as)); 5550 1.2 christos verbose(VERB_ALGO, "auth zone %s transfer next HTTP fetch from %s started", zname, as); 5551 1.2 christos } 5552 1.2 christos /* Create or refresh the list of allow_notify addrs */ 5553 1.2 christos probe_copy_masters_for_allow_notify(xfr); 5554 1.2 christos return 1; 5555 1.2 christos } 5556 1.2 christos 5557 1.2 christos /* perform AXFR/IXFR */ 5558 1.2 christos /* set the packet to be written */ 5559 1.2 christos /* create new ID */ 5560 1.2 christos xfr->task_transfer->id = GET_RANDOM_ID(env->rnd); 5561 1.2 christos xfr_create_ixfr_packet(xfr, env->scratch_buffer, 5562 1.2 christos xfr->task_transfer->id, master); 5563 1.2 christos 5564 1.2 christos /* connect on fd */ 5565 1.2 christos xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet, 5566 1.2 christos auth_xfer_transfer_tcp_callback, xfr, &addr, addrlen, 5567 1.2 christos env->scratch_buffer, -1, 5568 1.2 christos auth_name != NULL, auth_name); 5569 1.2 christos if(!xfr->task_transfer->cp) { 5570 1.4 christos char zname[LDNS_MAX_DOMAINLEN], as[256]; 5571 1.2 christos dname_str(xfr->name, zname); 5572 1.4 christos addr_port_to_str(&addr, addrlen, as, sizeof(as)); 5573 1.2 christos verbose(VERB_ALGO, "cannot create tcp cp connection for " 5574 1.2 christos "xfr %s to %s", zname, as); 5575 1.2 christos return 0; 5576 1.2 christos } 5577 1.2 christos comm_timer_set(xfr->task_transfer->timer, &t); 5578 1.2 christos if(verbosity >= VERB_ALGO) { 5579 1.4 christos char zname[LDNS_MAX_DOMAINLEN], as[256]; 5580 1.2 christos dname_str(xfr->name, zname); 5581 1.4 christos addr_port_to_str(&addr, addrlen, as, sizeof(as)); 5582 1.2 christos verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname, 5583 1.2 christos (xfr->task_transfer->on_ixfr?"IXFR":"AXFR"), as); 5584 1.2 christos } 5585 1.2 christos return 1; 5586 1.2 christos } 5587 1.2 christos 5588 1.2 christos /** perform next lookup, next transfer TCP, or end and resume wait time task */ 5589 1.2 christos static void 5590 1.2 christos xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env) 5591 1.2 christos { 5592 1.2 christos log_assert(xfr->task_transfer->worker == env->worker); 5593 1.2 christos 5594 1.2 christos /* are we performing lookups? */ 5595 1.2 christos while(xfr->task_transfer->lookup_target) { 5596 1.2 christos if(xfr_transfer_lookup_host(xfr, env)) { 5597 1.2 christos /* wait for lookup to finish, 5598 1.2 christos * note that the hostname may be in unbound's cache 5599 1.2 christos * and we may then get an instant cache response, 5600 1.2 christos * and that calls the callback just like a full 5601 1.2 christos * lookup and lookup failures also call callback */ 5602 1.2 christos if(verbosity >= VERB_ALGO) { 5603 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 5604 1.2 christos dname_str(xfr->name, zname); 5605 1.2 christos verbose(VERB_ALGO, "auth zone %s transfer next target lookup", zname); 5606 1.2 christos } 5607 1.2 christos lock_basic_unlock(&xfr->lock); 5608 1.2 christos return; 5609 1.2 christos } 5610 1.2 christos xfr_transfer_move_to_next_lookup(xfr, env); 5611 1.2 christos } 5612 1.2 christos 5613 1.2 christos /* initiate TCP and fetch the zone from the master */ 5614 1.2 christos /* and set timeout on it */ 5615 1.2 christos while(!xfr_transfer_end_of_list(xfr)) { 5616 1.2 christos xfr->task_transfer->master = xfr_transfer_current_master(xfr); 5617 1.2 christos if(xfr_transfer_init_fetch(xfr, env)) { 5618 1.2 christos /* successfully started, wait for callback */ 5619 1.2 christos lock_basic_unlock(&xfr->lock); 5620 1.2 christos return; 5621 1.2 christos } 5622 1.2 christos /* failed to fetch, next master */ 5623 1.2 christos xfr_transfer_nextmaster(xfr); 5624 1.2 christos } 5625 1.2 christos if(verbosity >= VERB_ALGO) { 5626 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 5627 1.2 christos dname_str(xfr->name, zname); 5628 1.2 christos verbose(VERB_ALGO, "auth zone %s transfer failed, wait", zname); 5629 1.2 christos } 5630 1.2 christos 5631 1.2 christos /* we failed to fetch the zone, move to wait task 5632 1.2 christos * use the shorter retry timeout */ 5633 1.2 christos xfr_transfer_disown(xfr); 5634 1.2 christos 5635 1.2 christos /* pick up the nextprobe task and wait */ 5636 1.2 christos if(xfr->task_nextprobe->worker == NULL) 5637 1.2 christos xfr_set_timeout(xfr, env, 1, 0); 5638 1.2 christos lock_basic_unlock(&xfr->lock); 5639 1.2 christos } 5640 1.2 christos 5641 1.2 christos /** add addrs from A or AAAA rrset to the master */ 5642 1.2 christos static void 5643 1.2 christos xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset, 5644 1.2 christos uint16_t rrtype) 5645 1.2 christos { 5646 1.2 christos size_t i; 5647 1.2 christos struct packed_rrset_data* data; 5648 1.2 christos if(!m || !rrset) return; 5649 1.2 christos if(rrtype != LDNS_RR_TYPE_A && rrtype != LDNS_RR_TYPE_AAAA) 5650 1.2 christos return; 5651 1.2 christos data = (struct packed_rrset_data*)rrset->entry.data; 5652 1.2 christos for(i=0; i<data->count; i++) { 5653 1.2 christos struct auth_addr* a; 5654 1.2 christos size_t len = data->rr_len[i] - 2; 5655 1.2 christos uint8_t* rdata = data->rr_data[i]+2; 5656 1.2 christos if(rrtype == LDNS_RR_TYPE_A && len != INET_SIZE) 5657 1.2 christos continue; /* wrong length for A */ 5658 1.2 christos if(rrtype == LDNS_RR_TYPE_AAAA && len != INET6_SIZE) 5659 1.2 christos continue; /* wrong length for AAAA */ 5660 1.2 christos 5661 1.2 christos /* add and alloc it */ 5662 1.2 christos a = (struct auth_addr*)calloc(1, sizeof(*a)); 5663 1.2 christos if(!a) { 5664 1.2 christos log_err("out of memory"); 5665 1.2 christos return; 5666 1.2 christos } 5667 1.2 christos if(rrtype == LDNS_RR_TYPE_A) { 5668 1.2 christos struct sockaddr_in* sa; 5669 1.2 christos a->addrlen = (socklen_t)sizeof(*sa); 5670 1.2 christos sa = (struct sockaddr_in*)&a->addr; 5671 1.2 christos sa->sin_family = AF_INET; 5672 1.2 christos sa->sin_port = (in_port_t)htons(UNBOUND_DNS_PORT); 5673 1.2 christos memmove(&sa->sin_addr, rdata, INET_SIZE); 5674 1.2 christos } else { 5675 1.2 christos struct sockaddr_in6* sa; 5676 1.2 christos a->addrlen = (socklen_t)sizeof(*sa); 5677 1.2 christos sa = (struct sockaddr_in6*)&a->addr; 5678 1.2 christos sa->sin6_family = AF_INET6; 5679 1.2 christos sa->sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT); 5680 1.2 christos memmove(&sa->sin6_addr, rdata, INET6_SIZE); 5681 1.2 christos } 5682 1.2 christos if(verbosity >= VERB_ALGO) { 5683 1.2 christos char s[64]; 5684 1.4 christos addr_port_to_str(&a->addr, a->addrlen, s, sizeof(s)); 5685 1.2 christos verbose(VERB_ALGO, "auth host %s lookup %s", 5686 1.2 christos m->host, s); 5687 1.2 christos } 5688 1.2 christos /* append to list */ 5689 1.2 christos a->next = m->list; 5690 1.2 christos m->list = a; 5691 1.2 christos } 5692 1.2 christos } 5693 1.2 christos 5694 1.2 christos /** callback for task_transfer lookup of host name, of A or AAAA */ 5695 1.2 christos void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf, 5696 1.2 christos enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus), 5697 1.2 christos int ATTR_UNUSED(was_ratelimited)) 5698 1.2 christos { 5699 1.2 christos struct auth_xfer* xfr = (struct auth_xfer*)arg; 5700 1.2 christos struct module_env* env; 5701 1.2 christos log_assert(xfr->task_transfer); 5702 1.2 christos lock_basic_lock(&xfr->lock); 5703 1.2 christos env = xfr->task_transfer->env; 5704 1.2 christos if(!env || env->outnet->want_to_quit) { 5705 1.2 christos lock_basic_unlock(&xfr->lock); 5706 1.2 christos return; /* stop on quit */ 5707 1.2 christos } 5708 1.2 christos 5709 1.2 christos /* process result */ 5710 1.2 christos if(rcode == LDNS_RCODE_NOERROR) { 5711 1.2 christos uint16_t wanted_qtype = LDNS_RR_TYPE_A; 5712 1.2 christos struct regional* temp = env->scratch; 5713 1.2 christos struct query_info rq; 5714 1.2 christos struct reply_info* rep; 5715 1.2 christos if(xfr->task_transfer->lookup_aaaa) 5716 1.2 christos wanted_qtype = LDNS_RR_TYPE_AAAA; 5717 1.2 christos memset(&rq, 0, sizeof(rq)); 5718 1.2 christos rep = parse_reply_in_temp_region(buf, temp, &rq); 5719 1.2 christos if(rep && rq.qtype == wanted_qtype && 5720 1.2 christos FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR) { 5721 1.2 christos /* parsed successfully */ 5722 1.2 christos struct ub_packed_rrset_key* answer = 5723 1.2 christos reply_find_answer_rrset(&rq, rep); 5724 1.2 christos if(answer) { 5725 1.2 christos xfr_master_add_addrs(xfr->task_transfer-> 5726 1.2 christos lookup_target, answer, wanted_qtype); 5727 1.2 christos } else { 5728 1.2 christos if(verbosity >= VERB_ALGO) { 5729 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 5730 1.2 christos dname_str(xfr->name, zname); 5731 1.2 christos verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has nodata", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); 5732 1.2 christos } 5733 1.2 christos } 5734 1.2 christos } else { 5735 1.2 christos if(verbosity >= VERB_ALGO) { 5736 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 5737 1.2 christos dname_str(xfr->name, zname); 5738 1.2 christos verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); 5739 1.2 christos } 5740 1.2 christos } 5741 1.2 christos regional_free_all(temp); 5742 1.2 christos } else { 5743 1.2 christos if(verbosity >= VERB_ALGO) { 5744 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 5745 1.2 christos dname_str(xfr->name, zname); 5746 1.2 christos verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup failed", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); 5747 1.2 christos } 5748 1.2 christos } 5749 1.2 christos if(xfr->task_transfer->lookup_target->list && 5750 1.2 christos xfr->task_transfer->lookup_target == xfr_transfer_current_master(xfr)) 5751 1.2 christos xfr->task_transfer->scan_addr = xfr->task_transfer->lookup_target->list; 5752 1.2 christos 5753 1.2 christos /* move to lookup AAAA after A lookup, move to next hostname lookup, 5754 1.2 christos * or move to fetch the zone, or, if nothing to do, end task_transfer */ 5755 1.2 christos xfr_transfer_move_to_next_lookup(xfr, env); 5756 1.2 christos xfr_transfer_nexttarget_or_end(xfr, env); 5757 1.2 christos } 5758 1.2 christos 5759 1.2 christos /** check if xfer (AXFR or IXFR) packet is OK. 5760 1.2 christos * return false if we lost connection (SERVFAIL, or unreadable). 5761 1.2 christos * return false if we need to move from IXFR to AXFR, with gonextonfail 5762 1.2 christos * set to false, so the same master is tried again, but with AXFR. 5763 1.2 christos * return true if fine to link into data. 5764 1.2 christos * return true with transferdone=true when the transfer has ended. 5765 1.2 christos */ 5766 1.2 christos static int 5767 1.2 christos check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr, 5768 1.2 christos int* gonextonfail, int* transferdone) 5769 1.2 christos { 5770 1.2 christos uint8_t* wire = sldns_buffer_begin(pkt); 5771 1.2 christos int i; 5772 1.2 christos if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) { 5773 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet too small", 5774 1.2 christos xfr->task_transfer->master->host); 5775 1.2 christos return 0; 5776 1.2 christos } 5777 1.2 christos if(!LDNS_QR_WIRE(wire)) { 5778 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet has no QR flag", 5779 1.2 christos xfr->task_transfer->master->host); 5780 1.2 christos return 0; 5781 1.2 christos } 5782 1.2 christos if(LDNS_TC_WIRE(wire)) { 5783 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet has TC flag", 5784 1.2 christos xfr->task_transfer->master->host); 5785 1.2 christos return 0; 5786 1.2 christos } 5787 1.2 christos /* check ID */ 5788 1.2 christos if(LDNS_ID_WIRE(wire) != xfr->task_transfer->id) { 5789 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet wrong ID", 5790 1.2 christos xfr->task_transfer->master->host); 5791 1.2 christos return 0; 5792 1.2 christos } 5793 1.2 christos if(LDNS_RCODE_WIRE(wire) != LDNS_RCODE_NOERROR) { 5794 1.2 christos char rcode[32]; 5795 1.2 christos sldns_wire2str_rcode_buf((int)LDNS_RCODE_WIRE(wire), rcode, 5796 1.2 christos sizeof(rcode)); 5797 1.2 christos /* if we are doing IXFR, check for fallback */ 5798 1.2 christos if(xfr->task_transfer->on_ixfr) { 5799 1.2 christos if(LDNS_RCODE_WIRE(wire) == LDNS_RCODE_NOTIMPL || 5800 1.2 christos LDNS_RCODE_WIRE(wire) == LDNS_RCODE_SERVFAIL || 5801 1.2 christos LDNS_RCODE_WIRE(wire) == LDNS_RCODE_REFUSED || 5802 1.2 christos LDNS_RCODE_WIRE(wire) == LDNS_RCODE_FORMERR) { 5803 1.2 christos verbose(VERB_ALGO, "xfr to %s, fallback " 5804 1.2 christos "from IXFR to AXFR (with rcode %s)", 5805 1.2 christos xfr->task_transfer->master->host, 5806 1.2 christos rcode); 5807 1.2 christos xfr->task_transfer->ixfr_fail = 1; 5808 1.2 christos *gonextonfail = 0; 5809 1.2 christos return 0; 5810 1.2 christos } 5811 1.2 christos } 5812 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with rcode %s", 5813 1.2 christos xfr->task_transfer->master->host, rcode); 5814 1.2 christos return 0; 5815 1.2 christos } 5816 1.2 christos if(LDNS_OPCODE_WIRE(wire) != LDNS_PACKET_QUERY) { 5817 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with bad opcode", 5818 1.2 christos xfr->task_transfer->master->host); 5819 1.2 christos return 0; 5820 1.2 christos } 5821 1.2 christos if(LDNS_QDCOUNT(wire) > 1) { 5822 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet has qdcount %d", 5823 1.2 christos xfr->task_transfer->master->host, 5824 1.2 christos (int)LDNS_QDCOUNT(wire)); 5825 1.2 christos return 0; 5826 1.2 christos } 5827 1.2 christos 5828 1.2 christos /* check qname */ 5829 1.2 christos sldns_buffer_set_position(pkt, LDNS_HEADER_SIZE); 5830 1.2 christos for(i=0; i<(int)LDNS_QDCOUNT(wire); i++) { 5831 1.2 christos size_t pos = sldns_buffer_position(pkt); 5832 1.2 christos uint16_t qtype, qclass; 5833 1.2 christos if(pkt_dname_len(pkt) == 0) { 5834 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 5835 1.2 christos "malformed dname", 5836 1.2 christos xfr->task_transfer->master->host); 5837 1.2 christos return 0; 5838 1.2 christos } 5839 1.2 christos if(dname_pkt_compare(pkt, sldns_buffer_at(pkt, pos), 5840 1.2 christos xfr->name) != 0) { 5841 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 5842 1.2 christos "wrong qname", 5843 1.2 christos xfr->task_transfer->master->host); 5844 1.2 christos return 0; 5845 1.2 christos } 5846 1.2 christos if(sldns_buffer_remaining(pkt) < 4) { 5847 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 5848 1.2 christos "truncated query RR", 5849 1.2 christos xfr->task_transfer->master->host); 5850 1.2 christos return 0; 5851 1.2 christos } 5852 1.2 christos qtype = sldns_buffer_read_u16(pkt); 5853 1.2 christos qclass = sldns_buffer_read_u16(pkt); 5854 1.2 christos if(qclass != xfr->dclass) { 5855 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 5856 1.2 christos "wrong qclass", 5857 1.2 christos xfr->task_transfer->master->host); 5858 1.2 christos return 0; 5859 1.2 christos } 5860 1.2 christos if(xfr->task_transfer->on_ixfr) { 5861 1.2 christos if(qtype != LDNS_RR_TYPE_IXFR) { 5862 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet " 5863 1.2 christos "with wrong qtype, expected IXFR", 5864 1.2 christos xfr->task_transfer->master->host); 5865 1.2 christos return 0; 5866 1.2 christos } 5867 1.2 christos } else { 5868 1.2 christos if(qtype != LDNS_RR_TYPE_AXFR) { 5869 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet " 5870 1.2 christos "with wrong qtype, expected AXFR", 5871 1.2 christos xfr->task_transfer->master->host); 5872 1.2 christos return 0; 5873 1.2 christos } 5874 1.2 christos } 5875 1.2 christos } 5876 1.2 christos 5877 1.2 christos /* check parse of RRs in packet, store first SOA serial 5878 1.2 christos * to be able to detect last SOA (with that serial) to see if done */ 5879 1.2 christos /* also check for IXFR 'zone up to date' reply */ 5880 1.2 christos for(i=0; i<(int)LDNS_ANCOUNT(wire); i++) { 5881 1.2 christos size_t pos = sldns_buffer_position(pkt); 5882 1.2 christos uint16_t tp, rdlen; 5883 1.2 christos if(pkt_dname_len(pkt) == 0) { 5884 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 5885 1.2 christos "malformed dname in answer section", 5886 1.2 christos xfr->task_transfer->master->host); 5887 1.2 christos return 0; 5888 1.2 christos } 5889 1.2 christos if(sldns_buffer_remaining(pkt) < 10) { 5890 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 5891 1.2 christos "truncated RR", 5892 1.2 christos xfr->task_transfer->master->host); 5893 1.2 christos return 0; 5894 1.2 christos } 5895 1.2 christos tp = sldns_buffer_read_u16(pkt); 5896 1.2 christos (void)sldns_buffer_read_u16(pkt); /* class */ 5897 1.2 christos (void)sldns_buffer_read_u32(pkt); /* ttl */ 5898 1.2 christos rdlen = sldns_buffer_read_u16(pkt); 5899 1.2 christos if(sldns_buffer_remaining(pkt) < rdlen) { 5900 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 5901 1.2 christos "truncated RR rdata", 5902 1.2 christos xfr->task_transfer->master->host); 5903 1.2 christos return 0; 5904 1.2 christos } 5905 1.2 christos 5906 1.2 christos /* RR parses (haven't checked rdata itself), now look at 5907 1.2 christos * SOA records to see serial number */ 5908 1.2 christos if(xfr->task_transfer->rr_scan_num == 0 && 5909 1.2 christos tp != LDNS_RR_TYPE_SOA) { 5910 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 5911 1.2 christos "malformed zone transfer, no start SOA", 5912 1.2 christos xfr->task_transfer->master->host); 5913 1.2 christos return 0; 5914 1.2 christos } 5915 1.2 christos if(xfr->task_transfer->rr_scan_num == 1 && 5916 1.2 christos tp != LDNS_RR_TYPE_SOA) { 5917 1.2 christos /* second RR is not a SOA record, this is not an IXFR 5918 1.2 christos * the master is replying with an AXFR */ 5919 1.2 christos xfr->task_transfer->on_ixfr_is_axfr = 1; 5920 1.2 christos } 5921 1.2 christos if(tp == LDNS_RR_TYPE_SOA) { 5922 1.2 christos uint32_t serial; 5923 1.2 christos if(rdlen < 22) { 5924 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet " 5925 1.2 christos "with SOA with malformed rdata", 5926 1.2 christos xfr->task_transfer->master->host); 5927 1.2 christos return 0; 5928 1.2 christos } 5929 1.2 christos if(dname_pkt_compare(pkt, sldns_buffer_at(pkt, pos), 5930 1.2 christos xfr->name) != 0) { 5931 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet " 5932 1.2 christos "with SOA with wrong dname", 5933 1.2 christos xfr->task_transfer->master->host); 5934 1.2 christos return 0; 5935 1.2 christos } 5936 1.2 christos 5937 1.2 christos /* read serial number of SOA */ 5938 1.2 christos serial = sldns_buffer_read_u32_at(pkt, 5939 1.2 christos sldns_buffer_position(pkt)+rdlen-20); 5940 1.2 christos 5941 1.2 christos /* check for IXFR 'zone has SOA x' reply */ 5942 1.2 christos if(xfr->task_transfer->on_ixfr && 5943 1.2 christos xfr->task_transfer->rr_scan_num == 0 && 5944 1.2 christos LDNS_ANCOUNT(wire)==1) { 5945 1.2 christos verbose(VERB_ALGO, "xfr to %s ended, " 5946 1.2 christos "IXFR reply that zone has serial %u," 5947 1.2 christos " fallback from IXFR to AXFR", 5948 1.2 christos xfr->task_transfer->master->host, 5949 1.2 christos (unsigned)serial); 5950 1.2 christos xfr->task_transfer->ixfr_fail = 1; 5951 1.2 christos *gonextonfail = 0; 5952 1.2 christos return 0; 5953 1.2 christos } 5954 1.2 christos 5955 1.2 christos /* if first SOA, store serial number */ 5956 1.2 christos if(xfr->task_transfer->got_xfr_serial == 0) { 5957 1.2 christos xfr->task_transfer->got_xfr_serial = 1; 5958 1.2 christos xfr->task_transfer->incoming_xfr_serial = 5959 1.2 christos serial; 5960 1.2 christos verbose(VERB_ALGO, "xfr %s: contains " 5961 1.2 christos "SOA serial %u", 5962 1.2 christos xfr->task_transfer->master->host, 5963 1.2 christos (unsigned)serial); 5964 1.2 christos /* see if end of AXFR */ 5965 1.2 christos } else if(!xfr->task_transfer->on_ixfr || 5966 1.2 christos xfr->task_transfer->on_ixfr_is_axfr) { 5967 1.2 christos /* second SOA with serial is the end 5968 1.2 christos * for AXFR */ 5969 1.2 christos *transferdone = 1; 5970 1.2 christos verbose(VERB_ALGO, "xfr %s: last AXFR packet", 5971 1.2 christos xfr->task_transfer->master->host); 5972 1.2 christos /* for IXFR, count SOA records with that serial */ 5973 1.2 christos } else if(xfr->task_transfer->incoming_xfr_serial == 5974 1.2 christos serial && xfr->task_transfer->got_xfr_serial 5975 1.2 christos == 1) { 5976 1.2 christos xfr->task_transfer->got_xfr_serial++; 5977 1.2 christos /* if not first soa, if serial==firstserial, the 5978 1.2 christos * third time we are at the end, for IXFR */ 5979 1.2 christos } else if(xfr->task_transfer->incoming_xfr_serial == 5980 1.2 christos serial && xfr->task_transfer->got_xfr_serial 5981 1.2 christos == 2) { 5982 1.2 christos verbose(VERB_ALGO, "xfr %s: last IXFR packet", 5983 1.2 christos xfr->task_transfer->master->host); 5984 1.2 christos *transferdone = 1; 5985 1.2 christos /* continue parse check, if that succeeds, 5986 1.2 christos * transfer is done */ 5987 1.2 christos } 5988 1.2 christos } 5989 1.2 christos xfr->task_transfer->rr_scan_num++; 5990 1.2 christos 5991 1.2 christos /* skip over RR rdata to go to the next RR */ 5992 1.2 christos sldns_buffer_skip(pkt, (ssize_t)rdlen); 5993 1.2 christos } 5994 1.2 christos 5995 1.2 christos /* check authority section */ 5996 1.2 christos /* we skip over the RRs checking packet format */ 5997 1.2 christos for(i=0; i<(int)LDNS_NSCOUNT(wire); i++) { 5998 1.2 christos uint16_t rdlen; 5999 1.2 christos if(pkt_dname_len(pkt) == 0) { 6000 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 6001 1.2 christos "malformed dname in authority section", 6002 1.2 christos xfr->task_transfer->master->host); 6003 1.2 christos return 0; 6004 1.2 christos } 6005 1.2 christos if(sldns_buffer_remaining(pkt) < 10) { 6006 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 6007 1.2 christos "truncated RR", 6008 1.2 christos xfr->task_transfer->master->host); 6009 1.2 christos return 0; 6010 1.2 christos } 6011 1.2 christos (void)sldns_buffer_read_u16(pkt); /* type */ 6012 1.2 christos (void)sldns_buffer_read_u16(pkt); /* class */ 6013 1.2 christos (void)sldns_buffer_read_u32(pkt); /* ttl */ 6014 1.2 christos rdlen = sldns_buffer_read_u16(pkt); 6015 1.2 christos if(sldns_buffer_remaining(pkt) < rdlen) { 6016 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 6017 1.2 christos "truncated RR rdata", 6018 1.2 christos xfr->task_transfer->master->host); 6019 1.2 christos return 0; 6020 1.2 christos } 6021 1.2 christos /* skip over RR rdata to go to the next RR */ 6022 1.2 christos sldns_buffer_skip(pkt, (ssize_t)rdlen); 6023 1.2 christos } 6024 1.2 christos 6025 1.2 christos /* check additional section */ 6026 1.2 christos for(i=0; i<(int)LDNS_ARCOUNT(wire); i++) { 6027 1.2 christos uint16_t rdlen; 6028 1.2 christos if(pkt_dname_len(pkt) == 0) { 6029 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 6030 1.2 christos "malformed dname in additional section", 6031 1.2 christos xfr->task_transfer->master->host); 6032 1.2 christos return 0; 6033 1.2 christos } 6034 1.2 christos if(sldns_buffer_remaining(pkt) < 10) { 6035 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 6036 1.2 christos "truncated RR", 6037 1.2 christos xfr->task_transfer->master->host); 6038 1.2 christos return 0; 6039 1.2 christos } 6040 1.2 christos (void)sldns_buffer_read_u16(pkt); /* type */ 6041 1.2 christos (void)sldns_buffer_read_u16(pkt); /* class */ 6042 1.2 christos (void)sldns_buffer_read_u32(pkt); /* ttl */ 6043 1.2 christos rdlen = sldns_buffer_read_u16(pkt); 6044 1.2 christos if(sldns_buffer_remaining(pkt) < rdlen) { 6045 1.2 christos verbose(VERB_ALGO, "xfr to %s failed, packet with " 6046 1.2 christos "truncated RR rdata", 6047 1.2 christos xfr->task_transfer->master->host); 6048 1.2 christos return 0; 6049 1.2 christos } 6050 1.2 christos /* skip over RR rdata to go to the next RR */ 6051 1.2 christos sldns_buffer_skip(pkt, (ssize_t)rdlen); 6052 1.2 christos } 6053 1.2 christos 6054 1.2 christos return 1; 6055 1.2 christos } 6056 1.2 christos 6057 1.2 christos /** Link the data from this packet into the worklist of transferred data */ 6058 1.2 christos static int 6059 1.2 christos xfer_link_data(sldns_buffer* pkt, struct auth_xfer* xfr) 6060 1.2 christos { 6061 1.2 christos /* alloc it */ 6062 1.2 christos struct auth_chunk* e; 6063 1.2 christos e = (struct auth_chunk*)calloc(1, sizeof(*e)); 6064 1.2 christos if(!e) return 0; 6065 1.2 christos e->next = NULL; 6066 1.2 christos e->len = sldns_buffer_limit(pkt); 6067 1.2 christos e->data = memdup(sldns_buffer_begin(pkt), e->len); 6068 1.2 christos if(!e->data) { 6069 1.2 christos free(e); 6070 1.2 christos return 0; 6071 1.2 christos } 6072 1.2 christos 6073 1.2 christos /* alloc succeeded, link into list */ 6074 1.2 christos if(!xfr->task_transfer->chunks_first) 6075 1.2 christos xfr->task_transfer->chunks_first = e; 6076 1.2 christos if(xfr->task_transfer->chunks_last) 6077 1.2 christos xfr->task_transfer->chunks_last->next = e; 6078 1.2 christos xfr->task_transfer->chunks_last = e; 6079 1.2 christos return 1; 6080 1.2 christos } 6081 1.2 christos 6082 1.2 christos /** task transfer. the list of data is complete. process it and if failed 6083 1.2 christos * move to next master, if succeeded, end the task transfer */ 6084 1.2 christos static void 6085 1.2 christos process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env) 6086 1.2 christos { 6087 1.2 christos int ixfr_fail = 0; 6088 1.2 christos if(xfr_process_chunk_list(xfr, env, &ixfr_fail)) { 6089 1.2 christos /* it worked! */ 6090 1.2 christos auth_chunks_delete(xfr->task_transfer); 6091 1.2 christos 6092 1.2 christos /* we fetched the zone, move to wait task */ 6093 1.2 christos xfr_transfer_disown(xfr); 6094 1.2 christos 6095 1.2 christos if(xfr->notify_received && (!xfr->notify_has_serial || 6096 1.2 christos (xfr->notify_has_serial && 6097 1.2 christos xfr_serial_means_update(xfr, xfr->notify_serial)))) { 6098 1.2 christos uint32_t sr = xfr->notify_serial; 6099 1.2 christos int has_sr = xfr->notify_has_serial; 6100 1.2 christos /* we received a notify while probe/transfer was 6101 1.2 christos * in progress. start a new probe and transfer */ 6102 1.2 christos xfr->notify_received = 0; 6103 1.2 christos xfr->notify_has_serial = 0; 6104 1.2 christos xfr->notify_serial = 0; 6105 1.2 christos if(!xfr_start_probe(xfr, env, NULL)) { 6106 1.2 christos /* if we couldn't start it, already in 6107 1.2 christos * progress; restore notify serial, 6108 1.2 christos * while xfr still locked */ 6109 1.2 christos xfr->notify_received = 1; 6110 1.2 christos xfr->notify_has_serial = has_sr; 6111 1.2 christos xfr->notify_serial = sr; 6112 1.2 christos lock_basic_unlock(&xfr->lock); 6113 1.2 christos } 6114 1.2 christos return; 6115 1.2 christos } else { 6116 1.2 christos /* pick up the nextprobe task and wait (normail wait time) */ 6117 1.2 christos if(xfr->task_nextprobe->worker == NULL) 6118 1.2 christos xfr_set_timeout(xfr, env, 0, 0); 6119 1.2 christos } 6120 1.2 christos lock_basic_unlock(&xfr->lock); 6121 1.2 christos return; 6122 1.2 christos } 6123 1.2 christos /* processing failed */ 6124 1.2 christos /* when done, delete data from list */ 6125 1.2 christos auth_chunks_delete(xfr->task_transfer); 6126 1.2 christos if(ixfr_fail) { 6127 1.2 christos xfr->task_transfer->ixfr_fail = 1; 6128 1.2 christos } else { 6129 1.2 christos xfr_transfer_nextmaster(xfr); 6130 1.2 christos } 6131 1.2 christos xfr_transfer_nexttarget_or_end(xfr, env); 6132 1.2 christos } 6133 1.2 christos 6134 1.2 christos /** callback for the task_transfer timer */ 6135 1.2 christos void 6136 1.2 christos auth_xfer_transfer_timer_callback(void* arg) 6137 1.2 christos { 6138 1.2 christos struct auth_xfer* xfr = (struct auth_xfer*)arg; 6139 1.2 christos struct module_env* env; 6140 1.2 christos int gonextonfail = 1; 6141 1.2 christos log_assert(xfr->task_transfer); 6142 1.2 christos lock_basic_lock(&xfr->lock); 6143 1.2 christos env = xfr->task_transfer->env; 6144 1.2 christos if(!env || env->outnet->want_to_quit) { 6145 1.2 christos lock_basic_unlock(&xfr->lock); 6146 1.2 christos return; /* stop on quit */ 6147 1.2 christos } 6148 1.2 christos 6149 1.2 christos verbose(VERB_ALGO, "xfr stopped, connection timeout to %s", 6150 1.2 christos xfr->task_transfer->master->host); 6151 1.2 christos 6152 1.2 christos /* see if IXFR caused the failure, if so, try AXFR */ 6153 1.2 christos if(xfr->task_transfer->on_ixfr) { 6154 1.2 christos xfr->task_transfer->ixfr_possible_timeout_count++; 6155 1.2 christos if(xfr->task_transfer->ixfr_possible_timeout_count >= 6156 1.2 christos NUM_TIMEOUTS_FALLBACK_IXFR) { 6157 1.2 christos verbose(VERB_ALGO, "xfr to %s, fallback " 6158 1.2 christos "from IXFR to AXFR (because of timeouts)", 6159 1.2 christos xfr->task_transfer->master->host); 6160 1.2 christos xfr->task_transfer->ixfr_fail = 1; 6161 1.2 christos gonextonfail = 0; 6162 1.2 christos } 6163 1.2 christos } 6164 1.2 christos 6165 1.2 christos /* delete transferred data from list */ 6166 1.2 christos auth_chunks_delete(xfr->task_transfer); 6167 1.2 christos comm_point_delete(xfr->task_transfer->cp); 6168 1.2 christos xfr->task_transfer->cp = NULL; 6169 1.2 christos if(gonextonfail) 6170 1.2 christos xfr_transfer_nextmaster(xfr); 6171 1.2 christos xfr_transfer_nexttarget_or_end(xfr, env); 6172 1.2 christos } 6173 1.2 christos 6174 1.2 christos /** callback for task_transfer tcp connections */ 6175 1.2 christos int 6176 1.2 christos auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err, 6177 1.2 christos struct comm_reply* ATTR_UNUSED(repinfo)) 6178 1.2 christos { 6179 1.2 christos struct auth_xfer* xfr = (struct auth_xfer*)arg; 6180 1.2 christos struct module_env* env; 6181 1.2 christos int gonextonfail = 1; 6182 1.2 christos int transferdone = 0; 6183 1.2 christos log_assert(xfr->task_transfer); 6184 1.2 christos lock_basic_lock(&xfr->lock); 6185 1.2 christos env = xfr->task_transfer->env; 6186 1.2 christos if(!env || env->outnet->want_to_quit) { 6187 1.2 christos lock_basic_unlock(&xfr->lock); 6188 1.2 christos return 0; /* stop on quit */ 6189 1.2 christos } 6190 1.2 christos /* stop the timer */ 6191 1.2 christos comm_timer_disable(xfr->task_transfer->timer); 6192 1.2 christos 6193 1.2 christos if(err != NETEVENT_NOERROR) { 6194 1.2 christos /* connection failed, closed, or timeout */ 6195 1.2 christos /* stop this transfer, cleanup 6196 1.2 christos * and continue task_transfer*/ 6197 1.2 christos verbose(VERB_ALGO, "xfr stopped, connection lost to %s", 6198 1.2 christos xfr->task_transfer->master->host); 6199 1.2 christos 6200 1.2 christos /* see if IXFR caused the failure, if so, try AXFR */ 6201 1.2 christos if(xfr->task_transfer->on_ixfr) { 6202 1.2 christos xfr->task_transfer->ixfr_possible_timeout_count++; 6203 1.2 christos if(xfr->task_transfer->ixfr_possible_timeout_count >= 6204 1.2 christos NUM_TIMEOUTS_FALLBACK_IXFR) { 6205 1.2 christos verbose(VERB_ALGO, "xfr to %s, fallback " 6206 1.2 christos "from IXFR to AXFR (because of timeouts)", 6207 1.2 christos xfr->task_transfer->master->host); 6208 1.2 christos xfr->task_transfer->ixfr_fail = 1; 6209 1.2 christos gonextonfail = 0; 6210 1.2 christos } 6211 1.2 christos } 6212 1.2 christos 6213 1.2 christos failed: 6214 1.2 christos /* delete transferred data from list */ 6215 1.2 christos auth_chunks_delete(xfr->task_transfer); 6216 1.2 christos comm_point_delete(xfr->task_transfer->cp); 6217 1.2 christos xfr->task_transfer->cp = NULL; 6218 1.2 christos if(gonextonfail) 6219 1.2 christos xfr_transfer_nextmaster(xfr); 6220 1.2 christos xfr_transfer_nexttarget_or_end(xfr, env); 6221 1.2 christos return 0; 6222 1.2 christos } 6223 1.2 christos /* note that IXFR worked without timeout */ 6224 1.2 christos if(xfr->task_transfer->on_ixfr) 6225 1.2 christos xfr->task_transfer->ixfr_possible_timeout_count = 0; 6226 1.2 christos 6227 1.2 christos /* handle returned packet */ 6228 1.2 christos /* if it fails, cleanup and end this transfer */ 6229 1.2 christos /* if it needs to fallback from IXFR to AXFR, do that */ 6230 1.2 christos if(!check_xfer_packet(c->buffer, xfr, &gonextonfail, &transferdone)) { 6231 1.2 christos goto failed; 6232 1.2 christos } 6233 1.2 christos /* if it is good, link it into the list of data */ 6234 1.2 christos /* if the link into list of data fails (malloc fail) cleanup and end */ 6235 1.2 christos if(!xfer_link_data(c->buffer, xfr)) { 6236 1.2 christos verbose(VERB_ALGO, "xfr stopped to %s, malloc failed", 6237 1.2 christos xfr->task_transfer->master->host); 6238 1.2 christos goto failed; 6239 1.2 christos } 6240 1.2 christos /* if the transfer is done now, disconnect and process the list */ 6241 1.2 christos if(transferdone) { 6242 1.2 christos comm_point_delete(xfr->task_transfer->cp); 6243 1.2 christos xfr->task_transfer->cp = NULL; 6244 1.2 christos process_list_end_transfer(xfr, env); 6245 1.2 christos return 0; 6246 1.2 christos } 6247 1.2 christos 6248 1.2 christos /* if we want to read more messages, setup the commpoint to read 6249 1.2 christos * a DNS packet, and the timeout */ 6250 1.2 christos lock_basic_unlock(&xfr->lock); 6251 1.2 christos c->tcp_is_reading = 1; 6252 1.2 christos sldns_buffer_clear(c->buffer); 6253 1.2 christos comm_point_start_listening(c, -1, AUTH_TRANSFER_TIMEOUT); 6254 1.2 christos return 0; 6255 1.2 christos } 6256 1.2 christos 6257 1.2 christos /** callback for task_transfer http connections */ 6258 1.2 christos int 6259 1.2 christos auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err, 6260 1.2 christos struct comm_reply* repinfo) 6261 1.2 christos { 6262 1.2 christos struct auth_xfer* xfr = (struct auth_xfer*)arg; 6263 1.2 christos struct module_env* env; 6264 1.2 christos log_assert(xfr->task_transfer); 6265 1.2 christos lock_basic_lock(&xfr->lock); 6266 1.2 christos env = xfr->task_transfer->env; 6267 1.2 christos if(!env || env->outnet->want_to_quit) { 6268 1.2 christos lock_basic_unlock(&xfr->lock); 6269 1.2 christos return 0; /* stop on quit */ 6270 1.2 christos } 6271 1.2 christos verbose(VERB_ALGO, "auth zone transfer http callback"); 6272 1.2 christos /* stop the timer */ 6273 1.2 christos comm_timer_disable(xfr->task_transfer->timer); 6274 1.2 christos 6275 1.2 christos if(err != NETEVENT_NOERROR && err != NETEVENT_DONE) { 6276 1.2 christos /* connection failed, closed, or timeout */ 6277 1.2 christos /* stop this transfer, cleanup 6278 1.2 christos * and continue task_transfer*/ 6279 1.2 christos verbose(VERB_ALGO, "http stopped, connection lost to %s", 6280 1.2 christos xfr->task_transfer->master->host); 6281 1.2 christos failed: 6282 1.2 christos /* delete transferred data from list */ 6283 1.2 christos auth_chunks_delete(xfr->task_transfer); 6284 1.2 christos if(repinfo) repinfo->c = NULL; /* signal cp deleted to 6285 1.2 christos the routine calling this callback */ 6286 1.2 christos comm_point_delete(xfr->task_transfer->cp); 6287 1.2 christos xfr->task_transfer->cp = NULL; 6288 1.2 christos xfr_transfer_nextmaster(xfr); 6289 1.2 christos xfr_transfer_nexttarget_or_end(xfr, env); 6290 1.2 christos return 0; 6291 1.2 christos } 6292 1.2 christos 6293 1.2 christos /* if it is good, link it into the list of data */ 6294 1.2 christos /* if the link into list of data fails (malloc fail) cleanup and end */ 6295 1.2 christos if(sldns_buffer_limit(c->buffer) > 0) { 6296 1.2 christos verbose(VERB_ALGO, "auth zone http queued up %d bytes", 6297 1.2 christos (int)sldns_buffer_limit(c->buffer)); 6298 1.2 christos if(!xfer_link_data(c->buffer, xfr)) { 6299 1.2 christos verbose(VERB_ALGO, "http stopped to %s, malloc failed", 6300 1.2 christos xfr->task_transfer->master->host); 6301 1.2 christos goto failed; 6302 1.2 christos } 6303 1.2 christos } 6304 1.2 christos /* if the transfer is done now, disconnect and process the list */ 6305 1.2 christos if(err == NETEVENT_DONE) { 6306 1.2 christos if(repinfo) repinfo->c = NULL; /* signal cp deleted to 6307 1.2 christos the routine calling this callback */ 6308 1.2 christos comm_point_delete(xfr->task_transfer->cp); 6309 1.2 christos xfr->task_transfer->cp = NULL; 6310 1.2 christos process_list_end_transfer(xfr, env); 6311 1.2 christos return 0; 6312 1.2 christos } 6313 1.2 christos 6314 1.2 christos /* if we want to read more messages, setup the commpoint to read 6315 1.2 christos * a DNS packet, and the timeout */ 6316 1.2 christos lock_basic_unlock(&xfr->lock); 6317 1.2 christos c->tcp_is_reading = 1; 6318 1.2 christos sldns_buffer_clear(c->buffer); 6319 1.2 christos comm_point_start_listening(c, -1, AUTH_TRANSFER_TIMEOUT); 6320 1.2 christos return 0; 6321 1.2 christos } 6322 1.2 christos 6323 1.2 christos 6324 1.2 christos /** start transfer task by this worker , xfr is locked. */ 6325 1.2 christos static void 6326 1.2 christos xfr_start_transfer(struct auth_xfer* xfr, struct module_env* env, 6327 1.2 christos struct auth_master* master) 6328 1.2 christos { 6329 1.2 christos log_assert(xfr->task_transfer != NULL); 6330 1.2 christos log_assert(xfr->task_transfer->worker == NULL); 6331 1.2 christos log_assert(xfr->task_transfer->chunks_first == NULL); 6332 1.2 christos log_assert(xfr->task_transfer->chunks_last == NULL); 6333 1.2 christos xfr->task_transfer->worker = env->worker; 6334 1.2 christos xfr->task_transfer->env = env; 6335 1.2 christos 6336 1.2 christos /* init transfer process */ 6337 1.2 christos /* find that master in the transfer's list of masters? */ 6338 1.2 christos xfr_transfer_start_list(xfr, master); 6339 1.2 christos /* start lookup for hostnames in transfer master list */ 6340 1.2 christos xfr_transfer_start_lookups(xfr); 6341 1.2 christos 6342 1.2 christos /* initiate TCP, and set timeout on it */ 6343 1.2 christos xfr_transfer_nexttarget_or_end(xfr, env); 6344 1.2 christos } 6345 1.2 christos 6346 1.2 christos /** disown task_probe. caller must hold xfr.lock */ 6347 1.2 christos static void 6348 1.2 christos xfr_probe_disown(struct auth_xfer* xfr) 6349 1.2 christos { 6350 1.2 christos /* remove timer (from this worker's event base) */ 6351 1.2 christos comm_timer_delete(xfr->task_probe->timer); 6352 1.2 christos xfr->task_probe->timer = NULL; 6353 1.2 christos /* remove the commpoint */ 6354 1.2 christos comm_point_delete(xfr->task_probe->cp); 6355 1.2 christos xfr->task_probe->cp = NULL; 6356 1.2 christos /* we don't own this item anymore */ 6357 1.2 christos xfr->task_probe->worker = NULL; 6358 1.2 christos xfr->task_probe->env = NULL; 6359 1.2 christos } 6360 1.2 christos 6361 1.2 christos /** send the UDP probe to the master, this is part of task_probe */ 6362 1.2 christos static int 6363 1.2 christos xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, 6364 1.2 christos int timeout) 6365 1.2 christos { 6366 1.2 christos struct sockaddr_storage addr; 6367 1.2 christos socklen_t addrlen = 0; 6368 1.2 christos struct timeval t; 6369 1.2 christos /* pick master */ 6370 1.2 christos struct auth_master* master = xfr_probe_current_master(xfr); 6371 1.2 christos char *auth_name = NULL; 6372 1.2 christos if(!master) return 0; 6373 1.2 christos if(master->allow_notify) return 0; /* only for notify */ 6374 1.2 christos if(master->http) return 0; /* only masters get SOA UDP probe, 6375 1.2 christos not urls, if those are in this list */ 6376 1.2 christos 6377 1.2 christos /* get master addr */ 6378 1.2 christos if(xfr->task_probe->scan_addr) { 6379 1.2 christos addrlen = xfr->task_probe->scan_addr->addrlen; 6380 1.2 christos memmove(&addr, &xfr->task_probe->scan_addr->addr, addrlen); 6381 1.2 christos } else { 6382 1.2 christos if(!authextstrtoaddr(master->host, &addr, &addrlen, &auth_name)) { 6383 1.2 christos /* the ones that are not in addr format are supposed 6384 1.2 christos * to be looked up. The lookup has failed however, 6385 1.2 christos * so skip them */ 6386 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6387 1.2 christos dname_str(xfr->name, zname); 6388 1.2 christos log_err("%s: failed lookup, cannot probe to master %s", 6389 1.2 christos zname, master->host); 6390 1.2 christos return 0; 6391 1.2 christos } 6392 1.2 christos if (auth_name != NULL) { 6393 1.2 christos if (addr.ss_family == AF_INET 6394 1.2 christos && (int)ntohs(((struct sockaddr_in *)&addr)->sin_port) 6395 1.2 christos == env->cfg->ssl_port) 6396 1.2 christos ((struct sockaddr_in *)&addr)->sin_port 6397 1.2 christos = htons((uint16_t)env->cfg->port); 6398 1.2 christos else if (addr.ss_family == AF_INET6 6399 1.2 christos && (int)ntohs(((struct sockaddr_in6 *)&addr)->sin6_port) 6400 1.2 christos == env->cfg->ssl_port) 6401 1.2 christos ((struct sockaddr_in6 *)&addr)->sin6_port 6402 1.2 christos = htons((uint16_t)env->cfg->port); 6403 1.2 christos } 6404 1.2 christos } 6405 1.2 christos 6406 1.2 christos /* create packet */ 6407 1.2 christos /* create new ID for new probes, but not on timeout retries, 6408 1.2 christos * this means we'll accept replies to previous retries to same ip */ 6409 1.2 christos if(timeout == AUTH_PROBE_TIMEOUT) 6410 1.2 christos xfr->task_probe->id = GET_RANDOM_ID(env->rnd); 6411 1.2 christos xfr_create_soa_probe_packet(xfr, env->scratch_buffer, 6412 1.2 christos xfr->task_probe->id); 6413 1.2 christos /* we need to remove the cp if we have a different ip4/ip6 type now */ 6414 1.2 christos if(xfr->task_probe->cp && 6415 1.2 christos ((xfr->task_probe->cp_is_ip6 && !addr_is_ip6(&addr, addrlen)) || 6416 1.2 christos (!xfr->task_probe->cp_is_ip6 && addr_is_ip6(&addr, addrlen))) 6417 1.2 christos ) { 6418 1.2 christos comm_point_delete(xfr->task_probe->cp); 6419 1.2 christos xfr->task_probe->cp = NULL; 6420 1.2 christos } 6421 1.2 christos if(!xfr->task_probe->cp) { 6422 1.2 christos if(addr_is_ip6(&addr, addrlen)) 6423 1.2 christos xfr->task_probe->cp_is_ip6 = 1; 6424 1.2 christos else xfr->task_probe->cp_is_ip6 = 0; 6425 1.2 christos xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet, 6426 1.2 christos auth_xfer_probe_udp_callback, xfr, &addr, addrlen); 6427 1.2 christos if(!xfr->task_probe->cp) { 6428 1.4 christos char zname[LDNS_MAX_DOMAINLEN], as[256]; 6429 1.2 christos dname_str(xfr->name, zname); 6430 1.4 christos addr_port_to_str(&addr, addrlen, as, sizeof(as)); 6431 1.2 christos verbose(VERB_ALGO, "cannot create udp cp for " 6432 1.2 christos "probe %s to %s", zname, as); 6433 1.2 christos return 0; 6434 1.2 christos } 6435 1.2 christos } 6436 1.2 christos if(!xfr->task_probe->timer) { 6437 1.2 christos xfr->task_probe->timer = comm_timer_create(env->worker_base, 6438 1.2 christos auth_xfer_probe_timer_callback, xfr); 6439 1.2 christos if(!xfr->task_probe->timer) { 6440 1.2 christos log_err("malloc failure"); 6441 1.2 christos return 0; 6442 1.2 christos } 6443 1.2 christos } 6444 1.2 christos 6445 1.2 christos /* send udp packet */ 6446 1.2 christos if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer, 6447 1.2 christos (struct sockaddr*)&addr, addrlen, 0)) { 6448 1.4 christos char zname[LDNS_MAX_DOMAINLEN], as[256]; 6449 1.2 christos dname_str(xfr->name, zname); 6450 1.4 christos addr_port_to_str(&addr, addrlen, as, sizeof(as)); 6451 1.2 christos verbose(VERB_ALGO, "failed to send soa probe for %s to %s", 6452 1.2 christos zname, as); 6453 1.2 christos return 0; 6454 1.2 christos } 6455 1.2 christos if(verbosity >= VERB_ALGO) { 6456 1.4 christos char zname[LDNS_MAX_DOMAINLEN], as[256]; 6457 1.2 christos dname_str(xfr->name, zname); 6458 1.4 christos addr_port_to_str(&addr, addrlen, as, sizeof(as)); 6459 1.2 christos verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname, 6460 1.2 christos as); 6461 1.2 christos } 6462 1.2 christos xfr->task_probe->timeout = timeout; 6463 1.2 christos #ifndef S_SPLINT_S 6464 1.2 christos t.tv_sec = timeout/1000; 6465 1.2 christos t.tv_usec = (timeout%1000)*1000; 6466 1.2 christos #endif 6467 1.2 christos comm_timer_set(xfr->task_probe->timer, &t); 6468 1.2 christos 6469 1.2 christos return 1; 6470 1.2 christos } 6471 1.2 christos 6472 1.2 christos /** callback for task_probe timer */ 6473 1.2 christos void 6474 1.2 christos auth_xfer_probe_timer_callback(void* arg) 6475 1.2 christos { 6476 1.2 christos struct auth_xfer* xfr = (struct auth_xfer*)arg; 6477 1.2 christos struct module_env* env; 6478 1.2 christos log_assert(xfr->task_probe); 6479 1.2 christos lock_basic_lock(&xfr->lock); 6480 1.2 christos env = xfr->task_probe->env; 6481 1.2 christos if(!env || env->outnet->want_to_quit) { 6482 1.2 christos lock_basic_unlock(&xfr->lock); 6483 1.2 christos return; /* stop on quit */ 6484 1.2 christos } 6485 1.2 christos 6486 1.2 christos if(verbosity >= VERB_ALGO) { 6487 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6488 1.2 christos dname_str(xfr->name, zname); 6489 1.2 christos verbose(VERB_ALGO, "auth zone %s soa probe timeout", zname); 6490 1.2 christos } 6491 1.2 christos if(xfr->task_probe->timeout <= AUTH_PROBE_TIMEOUT_STOP) { 6492 1.2 christos /* try again with bigger timeout */ 6493 1.2 christos if(xfr_probe_send_probe(xfr, env, xfr->task_probe->timeout*2)) { 6494 1.2 christos lock_basic_unlock(&xfr->lock); 6495 1.2 christos return; 6496 1.2 christos } 6497 1.2 christos } 6498 1.2 christos /* delete commpoint so a new one is created, with a fresh port nr */ 6499 1.2 christos comm_point_delete(xfr->task_probe->cp); 6500 1.2 christos xfr->task_probe->cp = NULL; 6501 1.2 christos 6502 1.2 christos /* too many timeouts (or fail to send), move to next or end */ 6503 1.2 christos xfr_probe_nextmaster(xfr); 6504 1.2 christos xfr_probe_send_or_end(xfr, env); 6505 1.2 christos } 6506 1.2 christos 6507 1.2 christos /** callback for task_probe udp packets */ 6508 1.2 christos int 6509 1.2 christos auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err, 6510 1.2 christos struct comm_reply* repinfo) 6511 1.2 christos { 6512 1.2 christos struct auth_xfer* xfr = (struct auth_xfer*)arg; 6513 1.2 christos struct module_env* env; 6514 1.2 christos log_assert(xfr->task_probe); 6515 1.2 christos lock_basic_lock(&xfr->lock); 6516 1.2 christos env = xfr->task_probe->env; 6517 1.2 christos if(!env || env->outnet->want_to_quit) { 6518 1.2 christos lock_basic_unlock(&xfr->lock); 6519 1.2 christos return 0; /* stop on quit */ 6520 1.2 christos } 6521 1.2 christos 6522 1.2 christos /* the comm_point_udp_callback is in a for loop for NUM_UDP_PER_SELECT 6523 1.2 christos * and we set rep.c=NULL to stop if from looking inside the commpoint*/ 6524 1.2 christos repinfo->c = NULL; 6525 1.2 christos /* stop the timer */ 6526 1.2 christos comm_timer_disable(xfr->task_probe->timer); 6527 1.2 christos 6528 1.2 christos /* see if we got a packet and what that means */ 6529 1.2 christos if(err == NETEVENT_NOERROR) { 6530 1.2 christos uint32_t serial = 0; 6531 1.2 christos if(check_packet_ok(c->buffer, LDNS_RR_TYPE_SOA, xfr, 6532 1.2 christos &serial)) { 6533 1.2 christos /* successful lookup */ 6534 1.2 christos if(verbosity >= VERB_ALGO) { 6535 1.4 christos char buf[LDNS_MAX_DOMAINLEN]; 6536 1.2 christos dname_str(xfr->name, buf); 6537 1.2 christos verbose(VERB_ALGO, "auth zone %s: soa probe " 6538 1.2 christos "serial is %u", buf, (unsigned)serial); 6539 1.2 christos } 6540 1.2 christos /* see if this serial indicates that the zone has 6541 1.2 christos * to be updated */ 6542 1.2 christos if(xfr_serial_means_update(xfr, serial)) { 6543 1.2 christos /* if updated, start the transfer task, if needed */ 6544 1.2 christos verbose(VERB_ALGO, "auth_zone updated, start transfer"); 6545 1.2 christos if(xfr->task_transfer->worker == NULL) { 6546 1.2 christos struct auth_master* master = 6547 1.2 christos xfr_probe_current_master(xfr); 6548 1.2 christos /* if we have download URLs use them 6549 1.2 christos * in preference to this master we 6550 1.2 christos * just probed the SOA from */ 6551 1.2 christos if(xfr->task_transfer->masters && 6552 1.2 christos xfr->task_transfer->masters->http) 6553 1.2 christos master = NULL; 6554 1.2 christos xfr_probe_disown(xfr); 6555 1.2 christos xfr_start_transfer(xfr, env, master); 6556 1.2 christos return 0; 6557 1.2 christos 6558 1.2 christos } 6559 1.2 christos /* other tasks are running, we don't do this anymore */ 6560 1.2 christos xfr_probe_disown(xfr); 6561 1.2 christos lock_basic_unlock(&xfr->lock); 6562 1.2 christos /* return, we don't sent a reply to this udp packet, 6563 1.2 christos * and we setup the tasks to do next */ 6564 1.2 christos return 0; 6565 1.2 christos } else { 6566 1.2 christos verbose(VERB_ALGO, "auth_zone master reports unchanged soa serial"); 6567 1.2 christos /* we if cannot find updates amongst the 6568 1.2 christos * masters, this means we then have a new lease 6569 1.2 christos * on the zone */ 6570 1.2 christos xfr->task_probe->have_new_lease = 1; 6571 1.2 christos } 6572 1.2 christos } else { 6573 1.2 christos if(verbosity >= VERB_ALGO) { 6574 1.4 christos char buf[LDNS_MAX_DOMAINLEN]; 6575 1.2 christos dname_str(xfr->name, buf); 6576 1.2 christos verbose(VERB_ALGO, "auth zone %s: bad reply to soa probe", buf); 6577 1.2 christos } 6578 1.2 christos } 6579 1.2 christos } else { 6580 1.2 christos if(verbosity >= VERB_ALGO) { 6581 1.4 christos char buf[LDNS_MAX_DOMAINLEN]; 6582 1.2 christos dname_str(xfr->name, buf); 6583 1.2 christos verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf); 6584 1.2 christos } 6585 1.2 christos } 6586 1.2 christos 6587 1.2 christos /* failed lookup or not an update */ 6588 1.2 christos /* delete commpoint so a new one is created, with a fresh port nr */ 6589 1.2 christos comm_point_delete(xfr->task_probe->cp); 6590 1.2 christos xfr->task_probe->cp = NULL; 6591 1.2 christos 6592 1.2 christos /* if the result was not a successful probe, we need 6593 1.2 christos * to send the next one */ 6594 1.2 christos xfr_probe_nextmaster(xfr); 6595 1.2 christos xfr_probe_send_or_end(xfr, env); 6596 1.2 christos return 0; 6597 1.2 christos } 6598 1.2 christos 6599 1.2 christos /** lookup a host name for its addresses, if needed */ 6600 1.2 christos static int 6601 1.2 christos xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env) 6602 1.2 christos { 6603 1.2 christos struct sockaddr_storage addr; 6604 1.2 christos socklen_t addrlen = 0; 6605 1.2 christos struct auth_master* master = xfr->task_probe->lookup_target; 6606 1.2 christos struct query_info qinfo; 6607 1.2 christos uint16_t qflags = BIT_RD; 6608 1.2 christos uint8_t dname[LDNS_MAX_DOMAINLEN+1]; 6609 1.2 christos struct edns_data edns; 6610 1.2 christos sldns_buffer* buf = env->scratch_buffer; 6611 1.2 christos if(!master) return 0; 6612 1.3 christos if(extstrtoaddr(master->host, &addr, &addrlen, UNBOUND_DNS_PORT)) { 6613 1.2 christos /* not needed, host is in IP addr format */ 6614 1.2 christos return 0; 6615 1.2 christos } 6616 1.2 christos if(master->allow_notify && !master->http && 6617 1.2 christos strchr(master->host, '/') != NULL && 6618 1.2 christos strchr(master->host, '/') == strrchr(master->host, '/')) { 6619 1.2 christos return 0; /* is IP/prefix format, not something to look up */ 6620 1.2 christos } 6621 1.2 christos 6622 1.2 christos /* use mesh_new_callback to probe for non-addr hosts, 6623 1.2 christos * and then wait for them to be looked up (in cache, or query) */ 6624 1.2 christos qinfo.qname_len = sizeof(dname); 6625 1.2 christos if(sldns_str2wire_dname_buf(master->host, dname, &qinfo.qname_len) 6626 1.2 christos != 0) { 6627 1.2 christos log_err("cannot parse host name of master %s", master->host); 6628 1.2 christos return 0; 6629 1.2 christos } 6630 1.2 christos qinfo.qname = dname; 6631 1.2 christos qinfo.qclass = xfr->dclass; 6632 1.2 christos qinfo.qtype = LDNS_RR_TYPE_A; 6633 1.2 christos if(xfr->task_probe->lookup_aaaa) 6634 1.2 christos qinfo.qtype = LDNS_RR_TYPE_AAAA; 6635 1.2 christos qinfo.local_alias = NULL; 6636 1.2 christos if(verbosity >= VERB_ALGO) { 6637 1.2 christos char buf1[512]; 6638 1.4 christos char buf2[LDNS_MAX_DOMAINLEN]; 6639 1.2 christos dname_str(xfr->name, buf2); 6640 1.2 christos snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup" 6641 1.2 christos " for task_probe", buf2); 6642 1.2 christos log_query_info(VERB_ALGO, buf1, &qinfo); 6643 1.2 christos } 6644 1.2 christos edns.edns_present = 1; 6645 1.2 christos edns.ext_rcode = 0; 6646 1.2 christos edns.edns_version = 0; 6647 1.2 christos edns.bits = EDNS_DO; 6648 1.2 christos edns.opt_list_in = NULL; 6649 1.2 christos edns.opt_list_out = NULL; 6650 1.2 christos edns.opt_list_inplace_cb_out = NULL; 6651 1.2 christos edns.padding_block_size = 0; 6652 1.3 christos edns.cookie_present = 0; 6653 1.3 christos edns.cookie_valid = 0; 6654 1.2 christos if(sldns_buffer_capacity(buf) < 65535) 6655 1.2 christos edns.udp_size = (uint16_t)sldns_buffer_capacity(buf); 6656 1.2 christos else edns.udp_size = 65535; 6657 1.2 christos 6658 1.2 christos /* unlock xfr during mesh_new_callback() because the callback can be 6659 1.2 christos * called straight away */ 6660 1.2 christos lock_basic_unlock(&xfr->lock); 6661 1.2 christos if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, 6662 1.2 christos &auth_xfer_probe_lookup_callback, xfr, 0)) { 6663 1.2 christos lock_basic_lock(&xfr->lock); 6664 1.2 christos log_err("out of memory lookup up master %s", master->host); 6665 1.2 christos return 0; 6666 1.2 christos } 6667 1.2 christos lock_basic_lock(&xfr->lock); 6668 1.2 christos return 1; 6669 1.2 christos } 6670 1.2 christos 6671 1.2 christos /** move to sending the probe packets, next if fails. task_probe */ 6672 1.2 christos static void 6673 1.2 christos xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) 6674 1.2 christos { 6675 1.2 christos /* are we doing hostname lookups? */ 6676 1.2 christos while(xfr->task_probe->lookup_target) { 6677 1.2 christos if(xfr_probe_lookup_host(xfr, env)) { 6678 1.2 christos /* wait for lookup to finish, 6679 1.2 christos * note that the hostname may be in unbound's cache 6680 1.2 christos * and we may then get an instant cache response, 6681 1.2 christos * and that calls the callback just like a full 6682 1.2 christos * lookup and lookup failures also call callback */ 6683 1.2 christos if(verbosity >= VERB_ALGO) { 6684 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6685 1.2 christos dname_str(xfr->name, zname); 6686 1.2 christos verbose(VERB_ALGO, "auth zone %s probe next target lookup", zname); 6687 1.2 christos } 6688 1.2 christos lock_basic_unlock(&xfr->lock); 6689 1.2 christos return; 6690 1.2 christos } 6691 1.2 christos xfr_probe_move_to_next_lookup(xfr, env); 6692 1.2 christos } 6693 1.2 christos /* probe of list has ended. Create or refresh the list of of 6694 1.2 christos * allow_notify addrs */ 6695 1.2 christos probe_copy_masters_for_allow_notify(xfr); 6696 1.2 christos if(verbosity >= VERB_ALGO) { 6697 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6698 1.2 christos dname_str(xfr->name, zname); 6699 1.2 christos verbose(VERB_ALGO, "auth zone %s probe: notify addrs updated", zname); 6700 1.2 christos } 6701 1.2 christos if(xfr->task_probe->only_lookup) { 6702 1.2 christos /* only wanted lookups for copy, stop probe and start wait */ 6703 1.2 christos xfr->task_probe->only_lookup = 0; 6704 1.2 christos if(verbosity >= VERB_ALGO) { 6705 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6706 1.2 christos dname_str(xfr->name, zname); 6707 1.2 christos verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname); 6708 1.2 christos } 6709 1.2 christos xfr_probe_disown(xfr); 6710 1.2 christos if(xfr->task_nextprobe->worker == NULL) 6711 1.2 christos xfr_set_timeout(xfr, env, 0, 0); 6712 1.2 christos lock_basic_unlock(&xfr->lock); 6713 1.2 christos return; 6714 1.2 christos } 6715 1.2 christos 6716 1.2 christos /* send probe packets */ 6717 1.2 christos while(!xfr_probe_end_of_list(xfr)) { 6718 1.2 christos if(xfr_probe_send_probe(xfr, env, AUTH_PROBE_TIMEOUT)) { 6719 1.2 christos /* successfully sent probe, wait for callback */ 6720 1.2 christos lock_basic_unlock(&xfr->lock); 6721 1.2 christos return; 6722 1.2 christos } 6723 1.2 christos /* failed to send probe, next master */ 6724 1.2 christos xfr_probe_nextmaster(xfr); 6725 1.2 christos } 6726 1.2 christos 6727 1.2 christos /* done with probe sequence, wait */ 6728 1.2 christos if(xfr->task_probe->have_new_lease) { 6729 1.2 christos /* if zone not updated, start the wait timer again */ 6730 1.2 christos if(verbosity >= VERB_ALGO) { 6731 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6732 1.2 christos dname_str(xfr->name, zname); 6733 1.2 christos verbose(VERB_ALGO, "auth_zone %s unchanged, new lease, wait", zname); 6734 1.2 christos } 6735 1.2 christos xfr_probe_disown(xfr); 6736 1.2 christos if(xfr->have_zone) 6737 1.2 christos xfr->lease_time = *env->now; 6738 1.2 christos if(xfr->task_nextprobe->worker == NULL) 6739 1.2 christos xfr_set_timeout(xfr, env, 0, 0); 6740 1.2 christos } else { 6741 1.2 christos if(verbosity >= VERB_ALGO) { 6742 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6743 1.2 christos dname_str(xfr->name, zname); 6744 1.2 christos verbose(VERB_ALGO, "auth zone %s soa probe failed, wait to retry", zname); 6745 1.2 christos } 6746 1.2 christos /* we failed to send this as well, move to the wait task, 6747 1.2 christos * use the shorter retry timeout */ 6748 1.2 christos xfr_probe_disown(xfr); 6749 1.2 christos /* pick up the nextprobe task and wait */ 6750 1.2 christos if(xfr->task_nextprobe->worker == NULL) 6751 1.2 christos xfr_set_timeout(xfr, env, 1, 0); 6752 1.2 christos } 6753 1.2 christos 6754 1.2 christos lock_basic_unlock(&xfr->lock); 6755 1.2 christos } 6756 1.2 christos 6757 1.2 christos /** callback for task_probe lookup of host name, of A or AAAA */ 6758 1.2 christos void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf, 6759 1.2 christos enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus), 6760 1.2 christos int ATTR_UNUSED(was_ratelimited)) 6761 1.2 christos { 6762 1.2 christos struct auth_xfer* xfr = (struct auth_xfer*)arg; 6763 1.2 christos struct module_env* env; 6764 1.2 christos log_assert(xfr->task_probe); 6765 1.2 christos lock_basic_lock(&xfr->lock); 6766 1.2 christos env = xfr->task_probe->env; 6767 1.2 christos if(!env || env->outnet->want_to_quit) { 6768 1.2 christos lock_basic_unlock(&xfr->lock); 6769 1.2 christos return; /* stop on quit */ 6770 1.2 christos } 6771 1.2 christos 6772 1.2 christos /* process result */ 6773 1.2 christos if(rcode == LDNS_RCODE_NOERROR) { 6774 1.2 christos uint16_t wanted_qtype = LDNS_RR_TYPE_A; 6775 1.2 christos struct regional* temp = env->scratch; 6776 1.2 christos struct query_info rq; 6777 1.2 christos struct reply_info* rep; 6778 1.2 christos if(xfr->task_probe->lookup_aaaa) 6779 1.2 christos wanted_qtype = LDNS_RR_TYPE_AAAA; 6780 1.2 christos memset(&rq, 0, sizeof(rq)); 6781 1.2 christos rep = parse_reply_in_temp_region(buf, temp, &rq); 6782 1.2 christos if(rep && rq.qtype == wanted_qtype && 6783 1.2 christos FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR) { 6784 1.2 christos /* parsed successfully */ 6785 1.2 christos struct ub_packed_rrset_key* answer = 6786 1.2 christos reply_find_answer_rrset(&rq, rep); 6787 1.2 christos if(answer) { 6788 1.2 christos xfr_master_add_addrs(xfr->task_probe-> 6789 1.2 christos lookup_target, answer, wanted_qtype); 6790 1.2 christos } else { 6791 1.2 christos if(verbosity >= VERB_ALGO) { 6792 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6793 1.2 christos dname_str(xfr->name, zname); 6794 1.2 christos verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has nodata", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); 6795 1.2 christos } 6796 1.2 christos } 6797 1.2 christos } else { 6798 1.2 christos if(verbosity >= VERB_ALGO) { 6799 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6800 1.2 christos dname_str(xfr->name, zname); 6801 1.2 christos verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); 6802 1.2 christos } 6803 1.2 christos } 6804 1.2 christos regional_free_all(temp); 6805 1.2 christos } else { 6806 1.2 christos if(verbosity >= VERB_ALGO) { 6807 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6808 1.2 christos dname_str(xfr->name, zname); 6809 1.2 christos verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup failed", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); 6810 1.2 christos } 6811 1.2 christos } 6812 1.2 christos if(xfr->task_probe->lookup_target->list && 6813 1.2 christos xfr->task_probe->lookup_target == xfr_probe_current_master(xfr)) 6814 1.2 christos xfr->task_probe->scan_addr = xfr->task_probe->lookup_target->list; 6815 1.2 christos 6816 1.2 christos /* move to lookup AAAA after A lookup, move to next hostname lookup, 6817 1.2 christos * or move to send the probes, or, if nothing to do, end task_probe */ 6818 1.2 christos xfr_probe_move_to_next_lookup(xfr, env); 6819 1.2 christos xfr_probe_send_or_end(xfr, env); 6820 1.2 christos } 6821 1.2 christos 6822 1.2 christos /** disown task_nextprobe. caller must hold xfr.lock */ 6823 1.2 christos static void 6824 1.2 christos xfr_nextprobe_disown(struct auth_xfer* xfr) 6825 1.2 christos { 6826 1.2 christos /* delete the timer, because the next worker to pick this up may 6827 1.2 christos * not have the same event base */ 6828 1.2 christos comm_timer_delete(xfr->task_nextprobe->timer); 6829 1.2 christos xfr->task_nextprobe->timer = NULL; 6830 1.2 christos xfr->task_nextprobe->next_probe = 0; 6831 1.2 christos /* we don't own this item anymore */ 6832 1.2 christos xfr->task_nextprobe->worker = NULL; 6833 1.2 christos xfr->task_nextprobe->env = NULL; 6834 1.2 christos } 6835 1.2 christos 6836 1.2 christos /** xfer nextprobe timeout callback, this is part of task_nextprobe */ 6837 1.2 christos void 6838 1.2 christos auth_xfer_timer(void* arg) 6839 1.2 christos { 6840 1.2 christos struct auth_xfer* xfr = (struct auth_xfer*)arg; 6841 1.2 christos struct module_env* env; 6842 1.2 christos log_assert(xfr->task_nextprobe); 6843 1.2 christos lock_basic_lock(&xfr->lock); 6844 1.2 christos env = xfr->task_nextprobe->env; 6845 1.2 christos if(!env || env->outnet->want_to_quit) { 6846 1.2 christos lock_basic_unlock(&xfr->lock); 6847 1.2 christos return; /* stop on quit */ 6848 1.2 christos } 6849 1.2 christos 6850 1.2 christos /* see if zone has expired, and if so, also set auth_zone expired */ 6851 1.2 christos if(xfr->have_zone && !xfr->zone_expired && 6852 1.2 christos *env->now >= xfr->lease_time + xfr->expiry) { 6853 1.2 christos lock_basic_unlock(&xfr->lock); 6854 1.2 christos auth_xfer_set_expired(xfr, env, 1); 6855 1.2 christos lock_basic_lock(&xfr->lock); 6856 1.2 christos } 6857 1.2 christos 6858 1.2 christos xfr_nextprobe_disown(xfr); 6859 1.2 christos 6860 1.2 christos if(!xfr_start_probe(xfr, env, NULL)) { 6861 1.2 christos /* not started because already in progress */ 6862 1.2 christos lock_basic_unlock(&xfr->lock); 6863 1.2 christos } 6864 1.2 christos } 6865 1.2 christos 6866 1.2 christos /** return true if there are probe (SOA UDP query) targets in the master list*/ 6867 1.2 christos static int 6868 1.2 christos have_probe_targets(struct auth_master* list) 6869 1.2 christos { 6870 1.2 christos struct auth_master* p; 6871 1.2 christos for(p=list; p; p = p->next) { 6872 1.2 christos if(!p->allow_notify && p->host) 6873 1.2 christos return 1; 6874 1.2 christos } 6875 1.2 christos return 0; 6876 1.2 christos } 6877 1.2 christos 6878 1.2 christos /** start task_probe if possible, if no masters for probe start task_transfer 6879 1.2 christos * returns true if task has been started, and false if the task is already 6880 1.2 christos * in progress. */ 6881 1.2 christos static int 6882 1.2 christos xfr_start_probe(struct auth_xfer* xfr, struct module_env* env, 6883 1.2 christos struct auth_master* spec) 6884 1.2 christos { 6885 1.2 christos /* see if we need to start a probe (or maybe it is already in 6886 1.2 christos * progress (due to notify)) */ 6887 1.2 christos if(xfr->task_probe->worker == NULL) { 6888 1.2 christos if(!have_probe_targets(xfr->task_probe->masters) && 6889 1.2 christos !(xfr->task_probe->only_lookup && 6890 1.2 christos xfr->task_probe->masters != NULL)) { 6891 1.2 christos /* useless to pick up task_probe, no masters to 6892 1.2 christos * probe. Instead attempt to pick up task transfer */ 6893 1.2 christos if(xfr->task_transfer->worker == NULL) { 6894 1.2 christos xfr_start_transfer(xfr, env, spec); 6895 1.2 christos return 1; 6896 1.2 christos } 6897 1.2 christos /* task transfer already in progress */ 6898 1.2 christos return 0; 6899 1.2 christos } 6900 1.2 christos 6901 1.2 christos /* pick up the probe task ourselves */ 6902 1.2 christos xfr->task_probe->worker = env->worker; 6903 1.2 christos xfr->task_probe->env = env; 6904 1.2 christos xfr->task_probe->cp = NULL; 6905 1.2 christos 6906 1.2 christos /* start the task */ 6907 1.2 christos /* have not seen a new lease yet, this scan */ 6908 1.2 christos xfr->task_probe->have_new_lease = 0; 6909 1.2 christos /* if this was a timeout, no specific first master to scan */ 6910 1.2 christos /* otherwise, spec is nonNULL the notified master, scan 6911 1.2 christos * first and also transfer first from it */ 6912 1.2 christos xfr_probe_start_list(xfr, spec); 6913 1.2 christos /* setup to start the lookup of hostnames of masters afresh */ 6914 1.2 christos xfr_probe_start_lookups(xfr); 6915 1.2 christos /* send the probe packet or next send, or end task */ 6916 1.2 christos xfr_probe_send_or_end(xfr, env); 6917 1.2 christos return 1; 6918 1.2 christos } 6919 1.2 christos return 0; 6920 1.2 christos } 6921 1.2 christos 6922 1.2 christos /** for task_nextprobe. 6923 1.2 christos * determine next timeout for auth_xfer. Also (re)sets timer. 6924 1.2 christos * @param xfr: task structure 6925 1.2 christos * @param env: module environment, with worker and time. 6926 1.2 christos * @param failure: set true if timer should be set for failure retry. 6927 1.2 christos * @param lookup_only: only perform lookups when timer done, 0 sec timeout 6928 1.2 christos */ 6929 1.2 christos static void 6930 1.2 christos xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, 6931 1.2 christos int failure, int lookup_only) 6932 1.2 christos { 6933 1.2 christos struct timeval tv; 6934 1.2 christos log_assert(xfr->task_nextprobe != NULL); 6935 1.2 christos log_assert(xfr->task_nextprobe->worker == NULL || 6936 1.2 christos xfr->task_nextprobe->worker == env->worker); 6937 1.2 christos /* normally, nextprobe = startoflease + refresh, 6938 1.2 christos * but if expiry is sooner, use that one. 6939 1.2 christos * after a failure, use the retry timer instead. */ 6940 1.2 christos xfr->task_nextprobe->next_probe = *env->now; 6941 1.2 christos if(xfr->lease_time && !failure) 6942 1.2 christos xfr->task_nextprobe->next_probe = xfr->lease_time; 6943 1.2 christos 6944 1.2 christos if(!failure) { 6945 1.2 christos xfr->task_nextprobe->backoff = 0; 6946 1.2 christos } else { 6947 1.2 christos if(xfr->task_nextprobe->backoff == 0) 6948 1.2 christos xfr->task_nextprobe->backoff = 3; 6949 1.2 christos else xfr->task_nextprobe->backoff *= 2; 6950 1.2 christos if(xfr->task_nextprobe->backoff > AUTH_TRANSFER_MAX_BACKOFF) 6951 1.2 christos xfr->task_nextprobe->backoff = 6952 1.2 christos AUTH_TRANSFER_MAX_BACKOFF; 6953 1.2 christos } 6954 1.2 christos 6955 1.2 christos if(xfr->have_zone) { 6956 1.2 christos time_t wait = xfr->refresh; 6957 1.2 christos if(failure) wait = xfr->retry; 6958 1.2 christos if(xfr->expiry < wait) 6959 1.2 christos xfr->task_nextprobe->next_probe += xfr->expiry; 6960 1.2 christos else xfr->task_nextprobe->next_probe += wait; 6961 1.2 christos if(failure) 6962 1.2 christos xfr->task_nextprobe->next_probe += 6963 1.2 christos xfr->task_nextprobe->backoff; 6964 1.2 christos /* put the timer exactly on expiry, if possible */ 6965 1.2 christos if(xfr->lease_time && xfr->lease_time+xfr->expiry < 6966 1.2 christos xfr->task_nextprobe->next_probe && 6967 1.2 christos xfr->lease_time+xfr->expiry > *env->now) 6968 1.2 christos xfr->task_nextprobe->next_probe = 6969 1.2 christos xfr->lease_time+xfr->expiry; 6970 1.2 christos } else { 6971 1.2 christos xfr->task_nextprobe->next_probe += 6972 1.2 christos xfr->task_nextprobe->backoff; 6973 1.2 christos } 6974 1.2 christos 6975 1.2 christos if(!xfr->task_nextprobe->timer) { 6976 1.2 christos xfr->task_nextprobe->timer = comm_timer_create( 6977 1.2 christos env->worker_base, auth_xfer_timer, xfr); 6978 1.2 christos if(!xfr->task_nextprobe->timer) { 6979 1.2 christos /* failed to malloc memory. likely zone transfer 6980 1.2 christos * also fails for that. skip the timeout */ 6981 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 6982 1.2 christos dname_str(xfr->name, zname); 6983 1.2 christos log_err("cannot allocate timer, no refresh for %s", 6984 1.2 christos zname); 6985 1.2 christos return; 6986 1.2 christos } 6987 1.2 christos } 6988 1.2 christos xfr->task_nextprobe->worker = env->worker; 6989 1.2 christos xfr->task_nextprobe->env = env; 6990 1.2 christos if(*(xfr->task_nextprobe->env->now) <= xfr->task_nextprobe->next_probe) 6991 1.2 christos tv.tv_sec = xfr->task_nextprobe->next_probe - 6992 1.2 christos *(xfr->task_nextprobe->env->now); 6993 1.2 christos else tv.tv_sec = 0; 6994 1.2 christos if(tv.tv_sec != 0 && lookup_only && xfr->task_probe->masters) { 6995 1.2 christos /* don't lookup_only, if lookup timeout is 0 anyway, 6996 1.2 christos * or if we don't have masters to lookup */ 6997 1.2 christos tv.tv_sec = 0; 6998 1.2 christos if(xfr->task_probe->worker == NULL) 6999 1.2 christos xfr->task_probe->only_lookup = 1; 7000 1.2 christos } 7001 1.2 christos if(verbosity >= VERB_ALGO) { 7002 1.4 christos char zname[LDNS_MAX_DOMAINLEN]; 7003 1.2 christos dname_str(xfr->name, zname); 7004 1.2 christos verbose(VERB_ALGO, "auth zone %s timeout in %d seconds", 7005 1.2 christos zname, (int)tv.tv_sec); 7006 1.2 christos } 7007 1.2 christos tv.tv_usec = 0; 7008 1.2 christos comm_timer_set(xfr->task_nextprobe->timer, &tv); 7009 1.2 christos } 7010 1.2 christos 7011 1.5 christos void auth_zone_pickup_initial_zone(struct auth_zone* z, struct module_env* env) 7012 1.5 christos { 7013 1.5 christos /* Set the time, because we now have timestamp in env, 7014 1.5 christos * (not earlier during startup and apply_cfg), and this 7015 1.5 christos * notes the start time when the data was acquired. */ 7016 1.5 christos z->soa_zone_acquired = *env->now; 7017 1.5 christos } 7018 1.5 christos 7019 1.4 christos void auth_xfer_pickup_initial_zone(struct auth_xfer* x, struct module_env* env) 7020 1.4 christos { 7021 1.4 christos /* set lease_time, because we now have timestamp in env, 7022 1.4 christos * (not earlier during startup and apply_cfg), and this 7023 1.4 christos * notes the start time when the data was acquired */ 7024 1.5 christos if(x->have_zone) { 7025 1.4 christos x->lease_time = *env->now; 7026 1.5 christos x->soa_zone_acquired = *env->now; 7027 1.5 christos } 7028 1.4 christos if(x->task_nextprobe && x->task_nextprobe->worker == NULL) { 7029 1.4 christos xfr_set_timeout(x, env, 0, 1); 7030 1.4 christos } 7031 1.4 christos } 7032 1.4 christos 7033 1.2 christos /** initial pick up of worker timeouts, ties events to worker event loop */ 7034 1.2 christos void 7035 1.2 christos auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env) 7036 1.2 christos { 7037 1.2 christos struct auth_xfer* x; 7038 1.5 christos struct auth_zone* z; 7039 1.2 christos lock_rw_wrlock(&az->lock); 7040 1.5 christos RBTREE_FOR(z, struct auth_zone*, &az->ztree) { 7041 1.5 christos lock_rw_wrlock(&z->lock); 7042 1.5 christos auth_zone_pickup_initial_zone(z, env); 7043 1.5 christos lock_rw_unlock(&z->lock); 7044 1.5 christos } 7045 1.2 christos RBTREE_FOR(x, struct auth_xfer*, &az->xtree) { 7046 1.2 christos lock_basic_lock(&x->lock); 7047 1.4 christos auth_xfer_pickup_initial_zone(x, env); 7048 1.2 christos lock_basic_unlock(&x->lock); 7049 1.2 christos } 7050 1.2 christos lock_rw_unlock(&az->lock); 7051 1.2 christos } 7052 1.2 christos 7053 1.2 christos void auth_zones_cleanup(struct auth_zones* az) 7054 1.2 christos { 7055 1.2 christos struct auth_xfer* x; 7056 1.2 christos lock_rw_wrlock(&az->lock); 7057 1.2 christos RBTREE_FOR(x, struct auth_xfer*, &az->xtree) { 7058 1.2 christos lock_basic_lock(&x->lock); 7059 1.2 christos if(x->task_nextprobe && x->task_nextprobe->worker != NULL) { 7060 1.2 christos xfr_nextprobe_disown(x); 7061 1.2 christos } 7062 1.2 christos if(x->task_probe && x->task_probe->worker != NULL) { 7063 1.2 christos xfr_probe_disown(x); 7064 1.2 christos } 7065 1.2 christos if(x->task_transfer && x->task_transfer->worker != NULL) { 7066 1.2 christos auth_chunks_delete(x->task_transfer); 7067 1.2 christos xfr_transfer_disown(x); 7068 1.2 christos } 7069 1.2 christos lock_basic_unlock(&x->lock); 7070 1.2 christos } 7071 1.2 christos lock_rw_unlock(&az->lock); 7072 1.2 christos } 7073 1.2 christos 7074 1.2 christos /** 7075 1.2 christos * malloc the xfer and tasks 7076 1.2 christos * @param z: auth_zone with name of zone. 7077 1.2 christos */ 7078 1.2 christos static struct auth_xfer* 7079 1.2 christos auth_xfer_new(struct auth_zone* z) 7080 1.2 christos { 7081 1.2 christos struct auth_xfer* xfr; 7082 1.2 christos xfr = (struct auth_xfer*)calloc(1, sizeof(*xfr)); 7083 1.2 christos if(!xfr) return NULL; 7084 1.2 christos xfr->name = memdup(z->name, z->namelen); 7085 1.2 christos if(!xfr->name) { 7086 1.2 christos free(xfr); 7087 1.2 christos return NULL; 7088 1.2 christos } 7089 1.2 christos xfr->node.key = xfr; 7090 1.2 christos xfr->namelen = z->namelen; 7091 1.2 christos xfr->namelabs = z->namelabs; 7092 1.2 christos xfr->dclass = z->dclass; 7093 1.2 christos 7094 1.2 christos xfr->task_nextprobe = (struct auth_nextprobe*)calloc(1, 7095 1.2 christos sizeof(struct auth_nextprobe)); 7096 1.2 christos if(!xfr->task_nextprobe) { 7097 1.2 christos free(xfr->name); 7098 1.2 christos free(xfr); 7099 1.2 christos return NULL; 7100 1.2 christos } 7101 1.2 christos xfr->task_probe = (struct auth_probe*)calloc(1, 7102 1.2 christos sizeof(struct auth_probe)); 7103 1.2 christos if(!xfr->task_probe) { 7104 1.2 christos free(xfr->task_nextprobe); 7105 1.2 christos free(xfr->name); 7106 1.2 christos free(xfr); 7107 1.2 christos return NULL; 7108 1.2 christos } 7109 1.2 christos xfr->task_transfer = (struct auth_transfer*)calloc(1, 7110 1.2 christos sizeof(struct auth_transfer)); 7111 1.2 christos if(!xfr->task_transfer) { 7112 1.2 christos free(xfr->task_probe); 7113 1.2 christos free(xfr->task_nextprobe); 7114 1.2 christos free(xfr->name); 7115 1.2 christos free(xfr); 7116 1.2 christos return NULL; 7117 1.2 christos } 7118 1.2 christos 7119 1.2 christos lock_basic_init(&xfr->lock); 7120 1.2 christos lock_protect(&xfr->lock, &xfr->name, sizeof(xfr->name)); 7121 1.2 christos lock_protect(&xfr->lock, &xfr->namelen, sizeof(xfr->namelen)); 7122 1.2 christos lock_protect(&xfr->lock, xfr->name, xfr->namelen); 7123 1.2 christos lock_protect(&xfr->lock, &xfr->namelabs, sizeof(xfr->namelabs)); 7124 1.2 christos lock_protect(&xfr->lock, &xfr->dclass, sizeof(xfr->dclass)); 7125 1.2 christos lock_protect(&xfr->lock, &xfr->notify_received, sizeof(xfr->notify_received)); 7126 1.2 christos lock_protect(&xfr->lock, &xfr->notify_serial, sizeof(xfr->notify_serial)); 7127 1.2 christos lock_protect(&xfr->lock, &xfr->zone_expired, sizeof(xfr->zone_expired)); 7128 1.2 christos lock_protect(&xfr->lock, &xfr->have_zone, sizeof(xfr->have_zone)); 7129 1.5 christos lock_protect(&xfr->lock, &xfr->soa_zone_acquired, sizeof(xfr->soa_zone_acquired)); 7130 1.2 christos lock_protect(&xfr->lock, &xfr->serial, sizeof(xfr->serial)); 7131 1.2 christos lock_protect(&xfr->lock, &xfr->retry, sizeof(xfr->retry)); 7132 1.2 christos lock_protect(&xfr->lock, &xfr->refresh, sizeof(xfr->refresh)); 7133 1.2 christos lock_protect(&xfr->lock, &xfr->expiry, sizeof(xfr->expiry)); 7134 1.2 christos lock_protect(&xfr->lock, &xfr->lease_time, sizeof(xfr->lease_time)); 7135 1.2 christos lock_protect(&xfr->lock, &xfr->task_nextprobe->worker, 7136 1.2 christos sizeof(xfr->task_nextprobe->worker)); 7137 1.2 christos lock_protect(&xfr->lock, &xfr->task_probe->worker, 7138 1.2 christos sizeof(xfr->task_probe->worker)); 7139 1.2 christos lock_protect(&xfr->lock, &xfr->task_transfer->worker, 7140 1.2 christos sizeof(xfr->task_transfer->worker)); 7141 1.2 christos lock_basic_lock(&xfr->lock); 7142 1.2 christos return xfr; 7143 1.2 christos } 7144 1.2 christos 7145 1.2 christos /** Create auth_xfer structure. 7146 1.2 christos * This populates the have_zone, soa values, and so on times. 7147 1.2 christos * and sets the timeout, if a zone transfer is needed a short timeout is set. 7148 1.2 christos * For that the auth_zone itself must exist (and read in zonefile) 7149 1.2 christos * returns false on alloc failure. */ 7150 1.2 christos struct auth_xfer* 7151 1.2 christos auth_xfer_create(struct auth_zones* az, struct auth_zone* z) 7152 1.2 christos { 7153 1.2 christos struct auth_xfer* xfr; 7154 1.2 christos 7155 1.2 christos /* malloc it */ 7156 1.2 christos xfr = auth_xfer_new(z); 7157 1.2 christos if(!xfr) { 7158 1.2 christos log_err("malloc failure"); 7159 1.2 christos return NULL; 7160 1.2 christos } 7161 1.2 christos /* insert in tree */ 7162 1.2 christos (void)rbtree_insert(&az->xtree, &xfr->node); 7163 1.2 christos return xfr; 7164 1.2 christos } 7165 1.2 christos 7166 1.2 christos /** create new auth_master structure */ 7167 1.2 christos static struct auth_master* 7168 1.2 christos auth_master_new(struct auth_master*** list) 7169 1.2 christos { 7170 1.2 christos struct auth_master *m; 7171 1.2 christos m = (struct auth_master*)calloc(1, sizeof(*m)); 7172 1.2 christos if(!m) { 7173 1.2 christos log_err("malloc failure"); 7174 1.2 christos return NULL; 7175 1.2 christos } 7176 1.2 christos /* set first pointer to m, or next pointer of previous element to m */ 7177 1.2 christos (**list) = m; 7178 1.2 christos /* store m's next pointer as future point to store at */ 7179 1.2 christos (*list) = &(m->next); 7180 1.2 christos return m; 7181 1.2 christos } 7182 1.2 christos 7183 1.2 christos /** dup_prefix : create string from initial part of other string, malloced */ 7184 1.2 christos static char* 7185 1.2 christos dup_prefix(char* str, size_t num) 7186 1.2 christos { 7187 1.2 christos char* result; 7188 1.2 christos size_t len = strlen(str); 7189 1.2 christos if(len < num) num = len; /* not more than strlen */ 7190 1.2 christos result = (char*)malloc(num+1); 7191 1.2 christos if(!result) { 7192 1.2 christos log_err("malloc failure"); 7193 1.2 christos return result; 7194 1.2 christos } 7195 1.2 christos memmove(result, str, num); 7196 1.2 christos result[num] = 0; 7197 1.2 christos return result; 7198 1.2 christos } 7199 1.2 christos 7200 1.2 christos /** dup string and print error on error */ 7201 1.2 christos static char* 7202 1.2 christos dup_all(char* str) 7203 1.2 christos { 7204 1.2 christos char* result = strdup(str); 7205 1.2 christos if(!result) { 7206 1.2 christos log_err("malloc failure"); 7207 1.2 christos return NULL; 7208 1.2 christos } 7209 1.2 christos return result; 7210 1.2 christos } 7211 1.2 christos 7212 1.2 christos /** find first of two characters */ 7213 1.2 christos static char* 7214 1.2 christos str_find_first_of_chars(char* s, char a, char b) 7215 1.2 christos { 7216 1.2 christos char* ra = strchr(s, a); 7217 1.2 christos char* rb = strchr(s, b); 7218 1.2 christos if(!ra) return rb; 7219 1.2 christos if(!rb) return ra; 7220 1.2 christos if(ra < rb) return ra; 7221 1.2 christos return rb; 7222 1.2 christos } 7223 1.2 christos 7224 1.2 christos /** parse URL into host and file parts, false on malloc or parse error */ 7225 1.2 christos static int 7226 1.2 christos parse_url(char* url, char** host, char** file, int* port, int* ssl) 7227 1.2 christos { 7228 1.2 christos char* p = url; 7229 1.2 christos /* parse http://www.example.com/file.htm 7230 1.2 christos * or http://127.0.0.1 (index.html) 7231 1.2 christos * or https://[::1@1234]/a/b/c/d */ 7232 1.2 christos *ssl = 1; 7233 1.2 christos *port = AUTH_HTTPS_PORT; 7234 1.2 christos 7235 1.2 christos /* parse http:// or https:// */ 7236 1.2 christos if(strncmp(p, "http://", 7) == 0) { 7237 1.2 christos p += 7; 7238 1.2 christos *ssl = 0; 7239 1.2 christos *port = AUTH_HTTP_PORT; 7240 1.2 christos } else if(strncmp(p, "https://", 8) == 0) { 7241 1.2 christos p += 8; 7242 1.2 christos } else if(strstr(p, "://") && strchr(p, '/') > strstr(p, "://") && 7243 1.2 christos strchr(p, ':') >= strstr(p, "://")) { 7244 1.2 christos char* uri = dup_prefix(p, (size_t)(strstr(p, "://")-p)); 7245 1.2 christos log_err("protocol %s:// not supported (for url %s)", 7246 1.2 christos uri?uri:"", p); 7247 1.2 christos free(uri); 7248 1.2 christos return 0; 7249 1.2 christos } 7250 1.2 christos 7251 1.2 christos /* parse hostname part */ 7252 1.2 christos if(p[0] == '[') { 7253 1.2 christos char* end = strchr(p, ']'); 7254 1.2 christos p++; /* skip over [ */ 7255 1.2 christos if(end) { 7256 1.2 christos *host = dup_prefix(p, (size_t)(end-p)); 7257 1.2 christos if(!*host) return 0; 7258 1.2 christos p = end+1; /* skip over ] */ 7259 1.2 christos } else { 7260 1.2 christos *host = dup_all(p); 7261 1.2 christos if(!*host) return 0; 7262 1.2 christos p = end; 7263 1.2 christos } 7264 1.2 christos } else { 7265 1.2 christos char* end = str_find_first_of_chars(p, ':', '/'); 7266 1.2 christos if(end) { 7267 1.2 christos *host = dup_prefix(p, (size_t)(end-p)); 7268 1.2 christos if(!*host) return 0; 7269 1.2 christos } else { 7270 1.2 christos *host = dup_all(p); 7271 1.2 christos if(!*host) return 0; 7272 1.2 christos } 7273 1.2 christos p = end; /* at next : or / or NULL */ 7274 1.2 christos } 7275 1.2 christos 7276 1.2 christos /* parse port number */ 7277 1.2 christos if(p && p[0] == ':') { 7278 1.2 christos char* end = NULL; 7279 1.2 christos *port = strtol(p+1, &end, 10); 7280 1.2 christos p = end; 7281 1.2 christos } 7282 1.2 christos 7283 1.2 christos /* parse filename part */ 7284 1.2 christos while(p && *p == '/') 7285 1.2 christos p++; 7286 1.2 christos if(!p || p[0] == 0) 7287 1.2 christos *file = strdup("/"); 7288 1.2 christos else *file = strdup(p); 7289 1.2 christos if(!*file) { 7290 1.2 christos log_err("malloc failure"); 7291 1.2 christos return 0; 7292 1.2 christos } 7293 1.2 christos return 1; 7294 1.2 christos } 7295 1.2 christos 7296 1.2 christos int 7297 1.2 christos xfer_set_masters(struct auth_master** list, struct config_auth* c, 7298 1.2 christos int with_http) 7299 1.2 christos { 7300 1.2 christos struct auth_master* m; 7301 1.2 christos struct config_strlist* p; 7302 1.2 christos /* list points to the first, or next pointer for the new element */ 7303 1.2 christos while(*list) { 7304 1.2 christos list = &( (*list)->next ); 7305 1.2 christos } 7306 1.2 christos if(with_http) 7307 1.2 christos for(p = c->urls; p; p = p->next) { 7308 1.2 christos m = auth_master_new(&list); 7309 1.2 christos if(!m) return 0; 7310 1.2 christos m->http = 1; 7311 1.2 christos if(!parse_url(p->str, &m->host, &m->file, &m->port, &m->ssl)) 7312 1.2 christos return 0; 7313 1.2 christos } 7314 1.2 christos for(p = c->masters; p; p = p->next) { 7315 1.2 christos m = auth_master_new(&list); 7316 1.2 christos if(!m) return 0; 7317 1.2 christos m->ixfr = 1; /* this flag is not configurable */ 7318 1.2 christos m->host = strdup(p->str); 7319 1.2 christos if(!m->host) { 7320 1.2 christos log_err("malloc failure"); 7321 1.2 christos return 0; 7322 1.2 christos } 7323 1.2 christos } 7324 1.2 christos for(p = c->allow_notify; p; p = p->next) { 7325 1.2 christos m = auth_master_new(&list); 7326 1.2 christos if(!m) return 0; 7327 1.2 christos m->allow_notify = 1; 7328 1.2 christos m->host = strdup(p->str); 7329 1.2 christos if(!m->host) { 7330 1.2 christos log_err("malloc failure"); 7331 1.2 christos return 0; 7332 1.2 christos } 7333 1.2 christos } 7334 1.2 christos return 1; 7335 1.2 christos } 7336 1.2 christos 7337 1.2 christos #define SERIAL_BITS 32 7338 1.2 christos int 7339 1.2 christos compare_serial(uint32_t a, uint32_t b) 7340 1.2 christos { 7341 1.2 christos const uint32_t cutoff = ((uint32_t) 1 << (SERIAL_BITS - 1)); 7342 1.2 christos 7343 1.2 christos if (a == b) { 7344 1.2 christos return 0; 7345 1.2 christos } else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) { 7346 1.2 christos return -1; 7347 1.2 christos } else { 7348 1.2 christos return 1; 7349 1.2 christos } 7350 1.2 christos } 7351 1.2 christos 7352 1.2 christos int zonemd_hashalgo_supported(int hashalgo) 7353 1.2 christos { 7354 1.2 christos if(hashalgo == ZONEMD_ALGO_SHA384) return 1; 7355 1.2 christos if(hashalgo == ZONEMD_ALGO_SHA512) return 1; 7356 1.2 christos return 0; 7357 1.2 christos } 7358 1.2 christos 7359 1.2 christos int zonemd_scheme_supported(int scheme) 7360 1.2 christos { 7361 1.2 christos if(scheme == ZONEMD_SCHEME_SIMPLE) return 1; 7362 1.2 christos return 0; 7363 1.2 christos } 7364 1.2 christos 7365 1.2 christos /** initialize hash for hashing with zonemd hash algo */ 7366 1.2 christos static struct secalgo_hash* zonemd_digest_init(int hashalgo, char** reason) 7367 1.2 christos { 7368 1.2 christos struct secalgo_hash *h; 7369 1.2 christos if(hashalgo == ZONEMD_ALGO_SHA384) { 7370 1.2 christos /* sha384 */ 7371 1.2 christos h = secalgo_hash_create_sha384(); 7372 1.2 christos if(!h) 7373 1.2 christos *reason = "digest sha384 could not be created"; 7374 1.2 christos return h; 7375 1.2 christos } else if(hashalgo == ZONEMD_ALGO_SHA512) { 7376 1.2 christos /* sha512 */ 7377 1.2 christos h = secalgo_hash_create_sha512(); 7378 1.2 christos if(!h) 7379 1.2 christos *reason = "digest sha512 could not be created"; 7380 1.2 christos return h; 7381 1.2 christos } 7382 1.2 christos /* unknown hash algo */ 7383 1.2 christos *reason = "unsupported algorithm"; 7384 1.2 christos return NULL; 7385 1.2 christos } 7386 1.2 christos 7387 1.2 christos /** update the hash for zonemd */ 7388 1.2 christos static int zonemd_digest_update(int hashalgo, struct secalgo_hash* h, 7389 1.2 christos uint8_t* data, size_t len, char** reason) 7390 1.2 christos { 7391 1.2 christos if(hashalgo == ZONEMD_ALGO_SHA384) { 7392 1.2 christos if(!secalgo_hash_update(h, data, len)) { 7393 1.2 christos *reason = "digest sha384 failed"; 7394 1.2 christos return 0; 7395 1.2 christos } 7396 1.2 christos return 1; 7397 1.2 christos } else if(hashalgo == ZONEMD_ALGO_SHA512) { 7398 1.2 christos if(!secalgo_hash_update(h, data, len)) { 7399 1.2 christos *reason = "digest sha512 failed"; 7400 1.2 christos return 0; 7401 1.2 christos } 7402 1.2 christos return 1; 7403 1.2 christos } 7404 1.2 christos /* unknown hash algo */ 7405 1.2 christos *reason = "unsupported algorithm"; 7406 1.2 christos return 0; 7407 1.2 christos } 7408 1.2 christos 7409 1.2 christos /** finish the hash for zonemd */ 7410 1.2 christos static int zonemd_digest_finish(int hashalgo, struct secalgo_hash* h, 7411 1.2 christos uint8_t* result, size_t hashlen, size_t* resultlen, char** reason) 7412 1.2 christos { 7413 1.2 christos if(hashalgo == ZONEMD_ALGO_SHA384) { 7414 1.2 christos if(hashlen < 384/8) { 7415 1.2 christos *reason = "digest buffer too small for sha384"; 7416 1.2 christos return 0; 7417 1.2 christos } 7418 1.2 christos if(!secalgo_hash_final(h, result, hashlen, resultlen)) { 7419 1.2 christos *reason = "digest sha384 finish failed"; 7420 1.2 christos return 0; 7421 1.2 christos } 7422 1.2 christos return 1; 7423 1.2 christos } else if(hashalgo == ZONEMD_ALGO_SHA512) { 7424 1.2 christos if(hashlen < 512/8) { 7425 1.2 christos *reason = "digest buffer too small for sha512"; 7426 1.2 christos return 0; 7427 1.2 christos } 7428 1.2 christos if(!secalgo_hash_final(h, result, hashlen, resultlen)) { 7429 1.2 christos *reason = "digest sha512 finish failed"; 7430 1.2 christos return 0; 7431 1.2 christos } 7432 1.2 christos return 1; 7433 1.2 christos } 7434 1.2 christos /* unknown algo */ 7435 1.2 christos *reason = "unsupported algorithm"; 7436 1.2 christos return 0; 7437 1.2 christos } 7438 1.2 christos 7439 1.2 christos /** add rrsets from node to the list */ 7440 1.2 christos static size_t authdata_rrsets_to_list(struct auth_rrset** array, 7441 1.2 christos size_t arraysize, struct auth_rrset* first) 7442 1.2 christos { 7443 1.2 christos struct auth_rrset* rrset = first; 7444 1.2 christos size_t num = 0; 7445 1.2 christos while(rrset) { 7446 1.2 christos if(num >= arraysize) 7447 1.2 christos return num; 7448 1.2 christos array[num] = rrset; 7449 1.2 christos num++; 7450 1.2 christos rrset = rrset->next; 7451 1.2 christos } 7452 1.2 christos return num; 7453 1.2 christos } 7454 1.2 christos 7455 1.2 christos /** compare rr list entries */ 7456 1.2 christos static int rrlist_compare(const void* arg1, const void* arg2) 7457 1.2 christos { 7458 1.2 christos struct auth_rrset* r1 = *(struct auth_rrset**)arg1; 7459 1.2 christos struct auth_rrset* r2 = *(struct auth_rrset**)arg2; 7460 1.2 christos uint16_t t1, t2; 7461 1.2 christos if(r1 == NULL) t1 = LDNS_RR_TYPE_RRSIG; 7462 1.2 christos else t1 = r1->type; 7463 1.2 christos if(r2 == NULL) t2 = LDNS_RR_TYPE_RRSIG; 7464 1.2 christos else t2 = r2->type; 7465 1.2 christos if(t1 < t2) 7466 1.2 christos return -1; 7467 1.2 christos if(t1 > t2) 7468 1.2 christos return 1; 7469 1.2 christos return 0; 7470 1.2 christos } 7471 1.2 christos 7472 1.2 christos /** add type RRSIG to rr list if not one there already, 7473 1.2 christos * this is to perform RRSIG collate processing at that point. */ 7474 1.2 christos static void addrrsigtype_if_needed(struct auth_rrset** array, 7475 1.2 christos size_t arraysize, size_t* rrnum, struct auth_data* node) 7476 1.2 christos { 7477 1.2 christos if(az_domain_rrset(node, LDNS_RR_TYPE_RRSIG)) 7478 1.2 christos return; /* already one there */ 7479 1.2 christos if((*rrnum) >= arraysize) 7480 1.2 christos return; /* array too small? */ 7481 1.2 christos array[*rrnum] = NULL; /* nothing there, but need entry in list */ 7482 1.2 christos (*rrnum)++; 7483 1.2 christos } 7484 1.2 christos 7485 1.2 christos /** collate the RRs in an RRset using the simple scheme */ 7486 1.2 christos static int zonemd_simple_rrset(struct auth_zone* z, int hashalgo, 7487 1.2 christos struct secalgo_hash* h, struct auth_data* node, 7488 1.2 christos struct auth_rrset* rrset, struct regional* region, 7489 1.2 christos struct sldns_buffer* buf, char** reason) 7490 1.2 christos { 7491 1.2 christos /* canonicalize */ 7492 1.2 christos struct ub_packed_rrset_key key; 7493 1.2 christos memset(&key, 0, sizeof(key)); 7494 1.2 christos key.entry.key = &key; 7495 1.2 christos key.entry.data = rrset->data; 7496 1.2 christos key.rk.dname = node->name; 7497 1.2 christos key.rk.dname_len = node->namelen; 7498 1.2 christos key.rk.type = htons(rrset->type); 7499 1.2 christos key.rk.rrset_class = htons(z->dclass); 7500 1.2 christos if(!rrset_canonicalize_to_buffer(region, buf, &key)) { 7501 1.2 christos *reason = "out of memory"; 7502 1.2 christos return 0; 7503 1.2 christos } 7504 1.2 christos regional_free_all(region); 7505 1.2 christos 7506 1.2 christos /* hash */ 7507 1.2 christos if(!zonemd_digest_update(hashalgo, h, sldns_buffer_begin(buf), 7508 1.2 christos sldns_buffer_limit(buf), reason)) { 7509 1.2 christos return 0; 7510 1.2 christos } 7511 1.2 christos return 1; 7512 1.2 christos } 7513 1.2 christos 7514 1.2 christos /** count number of RRSIGs in a domain name rrset list */ 7515 1.2 christos static size_t zonemd_simple_count_rrsig(struct auth_rrset* rrset, 7516 1.2 christos struct auth_rrset** rrlist, size_t rrnum, 7517 1.2 christos struct auth_zone* z, struct auth_data* node) 7518 1.2 christos { 7519 1.2 christos size_t i, count = 0; 7520 1.2 christos if(rrset) { 7521 1.2 christos size_t j; 7522 1.2 christos for(j = 0; j<rrset->data->count; j++) { 7523 1.2 christos if(rrsig_rdata_get_type_covered(rrset->data-> 7524 1.2 christos rr_data[j], rrset->data->rr_len[j]) == 7525 1.2 christos LDNS_RR_TYPE_ZONEMD && 7526 1.2 christos query_dname_compare(z->name, node->name)==0) { 7527 1.2 christos /* omit RRSIGs over type ZONEMD at apex */ 7528 1.2 christos continue; 7529 1.2 christos } 7530 1.2 christos count++; 7531 1.2 christos } 7532 1.2 christos } 7533 1.2 christos for(i=0; i<rrnum; i++) { 7534 1.2 christos if(rrlist[i] && rrlist[i]->type == LDNS_RR_TYPE_ZONEMD && 7535 1.2 christos query_dname_compare(z->name, node->name)==0) { 7536 1.2 christos /* omit RRSIGs over type ZONEMD at apex */ 7537 1.2 christos continue; 7538 1.2 christos } 7539 1.2 christos count += (rrlist[i]?rrlist[i]->data->rrsig_count:0); 7540 1.2 christos } 7541 1.2 christos return count; 7542 1.2 christos } 7543 1.2 christos 7544 1.2 christos /** allocate sparse rrset data for the number of entries in tepm region */ 7545 1.2 christos static int zonemd_simple_rrsig_allocs(struct regional* region, 7546 1.2 christos struct packed_rrset_data* data, size_t count) 7547 1.2 christos { 7548 1.2 christos data->rr_len = regional_alloc(region, sizeof(*data->rr_len) * count); 7549 1.2 christos if(!data->rr_len) { 7550 1.2 christos return 0; 7551 1.2 christos } 7552 1.2 christos data->rr_ttl = regional_alloc(region, sizeof(*data->rr_ttl) * count); 7553 1.2 christos if(!data->rr_ttl) { 7554 1.2 christos return 0; 7555 1.2 christos } 7556 1.2 christos data->rr_data = regional_alloc(region, sizeof(*data->rr_data) * count); 7557 1.2 christos if(!data->rr_data) { 7558 1.2 christos return 0; 7559 1.2 christos } 7560 1.2 christos return 1; 7561 1.2 christos } 7562 1.2 christos 7563 1.2 christos /** add the RRSIGs from the rrs in the domain into the data */ 7564 1.2 christos static void add_rrlist_rrsigs_into_data(struct packed_rrset_data* data, 7565 1.2 christos size_t* done, struct auth_rrset** rrlist, size_t rrnum, 7566 1.2 christos struct auth_zone* z, struct auth_data* node) 7567 1.2 christos { 7568 1.2 christos size_t i; 7569 1.2 christos for(i=0; i<rrnum; i++) { 7570 1.2 christos size_t j; 7571 1.2 christos if(!rrlist[i]) 7572 1.2 christos continue; 7573 1.3 christos if(rrlist[i]->type == LDNS_RR_TYPE_ZONEMD && 7574 1.2 christos query_dname_compare(z->name, node->name)==0) { 7575 1.2 christos /* omit RRSIGs over type ZONEMD at apex */ 7576 1.2 christos continue; 7577 1.2 christos } 7578 1.2 christos for(j = 0; j<rrlist[i]->data->rrsig_count; j++) { 7579 1.2 christos data->rr_len[*done] = rrlist[i]->data->rr_len[rrlist[i]->data->count + j]; 7580 1.2 christos data->rr_ttl[*done] = rrlist[i]->data->rr_ttl[rrlist[i]->data->count + j]; 7581 1.2 christos /* reference the rdata in the rrset, no need to 7582 1.2 christos * copy it, it is no longer needed at the end of 7583 1.2 christos * the routine */ 7584 1.2 christos data->rr_data[*done] = rrlist[i]->data->rr_data[rrlist[i]->data->count + j]; 7585 1.2 christos (*done)++; 7586 1.2 christos } 7587 1.2 christos } 7588 1.2 christos } 7589 1.2 christos 7590 1.2 christos static void add_rrset_into_data(struct packed_rrset_data* data, 7591 1.2 christos size_t* done, struct auth_rrset* rrset, 7592 1.2 christos struct auth_zone* z, struct auth_data* node) 7593 1.2 christos { 7594 1.2 christos if(rrset) { 7595 1.2 christos size_t j; 7596 1.2 christos for(j = 0; j<rrset->data->count; j++) { 7597 1.2 christos if(rrsig_rdata_get_type_covered(rrset->data-> 7598 1.2 christos rr_data[j], rrset->data->rr_len[j]) == 7599 1.2 christos LDNS_RR_TYPE_ZONEMD && 7600 1.2 christos query_dname_compare(z->name, node->name)==0) { 7601 1.2 christos /* omit RRSIGs over type ZONEMD at apex */ 7602 1.2 christos continue; 7603 1.2 christos } 7604 1.2 christos data->rr_len[*done] = rrset->data->rr_len[j]; 7605 1.2 christos data->rr_ttl[*done] = rrset->data->rr_ttl[j]; 7606 1.2 christos /* reference the rdata in the rrset, no need to 7607 1.2 christos * copy it, it is no longer need at the end of 7608 1.2 christos * the routine */ 7609 1.2 christos data->rr_data[*done] = rrset->data->rr_data[j]; 7610 1.2 christos (*done)++; 7611 1.2 christos } 7612 1.2 christos } 7613 1.2 christos } 7614 1.2 christos 7615 1.2 christos /** collate the RRSIGs using the simple scheme */ 7616 1.2 christos static int zonemd_simple_rrsig(struct auth_zone* z, int hashalgo, 7617 1.2 christos struct secalgo_hash* h, struct auth_data* node, 7618 1.2 christos struct auth_rrset* rrset, struct auth_rrset** rrlist, size_t rrnum, 7619 1.2 christos struct regional* region, struct sldns_buffer* buf, char** reason) 7620 1.2 christos { 7621 1.2 christos /* the rrset pointer can be NULL, this means it is type RRSIG and 7622 1.2 christos * there is no ordinary type RRSIG there. The RRSIGs are stored 7623 1.2 christos * with the RRsets in their data. 7624 1.2 christos * 7625 1.2 christos * The RRset pointer can be nonNULL. This happens if there is 7626 1.2 christos * no RR that is covered by the RRSIG for the domain. Then this 7627 1.2 christos * RRSIG RR is stored in an rrset of type RRSIG. The other RRSIGs 7628 1.2 christos * are stored in the rrset entries for the RRs in the rr list for 7629 1.2 christos * the domain node. We need to collate the rrset's data, if any, and 7630 1.2 christos * the rrlist's rrsigs */ 7631 1.2 christos /* if this is the apex, omit RRSIGs that cover type ZONEMD */ 7632 1.2 christos /* build rrsig rrset */ 7633 1.2 christos size_t done = 0; 7634 1.2 christos struct ub_packed_rrset_key key; 7635 1.2 christos struct packed_rrset_data data; 7636 1.2 christos memset(&key, 0, sizeof(key)); 7637 1.2 christos memset(&data, 0, sizeof(data)); 7638 1.2 christos key.entry.key = &key; 7639 1.2 christos key.entry.data = &data; 7640 1.2 christos key.rk.dname = node->name; 7641 1.2 christos key.rk.dname_len = node->namelen; 7642 1.2 christos key.rk.type = htons(LDNS_RR_TYPE_RRSIG); 7643 1.2 christos key.rk.rrset_class = htons(z->dclass); 7644 1.2 christos data.count = zonemd_simple_count_rrsig(rrset, rrlist, rrnum, z, node); 7645 1.2 christos if(!zonemd_simple_rrsig_allocs(region, &data, data.count)) { 7646 1.2 christos *reason = "out of memory"; 7647 1.2 christos regional_free_all(region); 7648 1.2 christos return 0; 7649 1.2 christos } 7650 1.2 christos /* all the RRSIGs stored in the other rrsets for this domain node */ 7651 1.2 christos add_rrlist_rrsigs_into_data(&data, &done, rrlist, rrnum, z, node); 7652 1.2 christos /* plus the RRSIGs stored in an rrset of type RRSIG for this node */ 7653 1.2 christos add_rrset_into_data(&data, &done, rrset, z, node); 7654 1.2 christos 7655 1.2 christos /* canonicalize */ 7656 1.2 christos if(!rrset_canonicalize_to_buffer(region, buf, &key)) { 7657 1.2 christos *reason = "out of memory"; 7658 1.2 christos regional_free_all(region); 7659 1.2 christos return 0; 7660 1.2 christos } 7661 1.2 christos regional_free_all(region); 7662 1.2 christos 7663 1.2 christos /* hash */ 7664 1.2 christos if(!zonemd_digest_update(hashalgo, h, sldns_buffer_begin(buf), 7665 1.2 christos sldns_buffer_limit(buf), reason)) { 7666 1.2 christos return 0; 7667 1.2 christos } 7668 1.2 christos return 1; 7669 1.2 christos } 7670 1.2 christos 7671 1.2 christos /** collate a domain's rrsets using the simple scheme */ 7672 1.2 christos static int zonemd_simple_domain(struct auth_zone* z, int hashalgo, 7673 1.2 christos struct secalgo_hash* h, struct auth_data* node, 7674 1.2 christos struct regional* region, struct sldns_buffer* buf, char** reason) 7675 1.2 christos { 7676 1.2 christos #define rrlistsize 65536 7677 1.2 christos struct auth_rrset* rrlist[rrlistsize]; 7678 1.2 christos size_t i, rrnum = 0; 7679 1.2 christos /* see if the domain is out of scope, the zone origin, 7680 1.2 christos * that would be omitted */ 7681 1.2 christos if(!dname_subdomain_c(node->name, z->name)) 7682 1.2 christos return 1; /* continue */ 7683 1.2 christos /* loop over the rrsets in ascending order. */ 7684 1.2 christos rrnum = authdata_rrsets_to_list(rrlist, rrlistsize, node->rrsets); 7685 1.2 christos addrrsigtype_if_needed(rrlist, rrlistsize, &rrnum, node); 7686 1.2 christos qsort(rrlist, rrnum, sizeof(*rrlist), rrlist_compare); 7687 1.2 christos for(i=0; i<rrnum; i++) { 7688 1.2 christos if(rrlist[i] && rrlist[i]->type == LDNS_RR_TYPE_ZONEMD && 7689 1.2 christos query_dname_compare(z->name, node->name) == 0) { 7690 1.2 christos /* omit type ZONEMD at apex */ 7691 1.2 christos continue; 7692 1.2 christos } 7693 1.2 christos if(rrlist[i] == NULL || rrlist[i]->type == 7694 1.2 christos LDNS_RR_TYPE_RRSIG) { 7695 1.2 christos if(!zonemd_simple_rrsig(z, hashalgo, h, node, 7696 1.2 christos rrlist[i], rrlist, rrnum, region, buf, reason)) 7697 1.2 christos return 0; 7698 1.2 christos } else if(!zonemd_simple_rrset(z, hashalgo, h, node, 7699 1.2 christos rrlist[i], region, buf, reason)) { 7700 1.2 christos return 0; 7701 1.2 christos } 7702 1.2 christos } 7703 1.2 christos return 1; 7704 1.2 christos } 7705 1.2 christos 7706 1.2 christos /** collate the zone using the simple scheme */ 7707 1.2 christos static int zonemd_simple_collate(struct auth_zone* z, int hashalgo, 7708 1.2 christos struct secalgo_hash* h, struct regional* region, 7709 1.2 christos struct sldns_buffer* buf, char** reason) 7710 1.2 christos { 7711 1.2 christos /* our tree is sorted in canonical order, so we can just loop over 7712 1.2 christos * the tree */ 7713 1.2 christos struct auth_data* n; 7714 1.2 christos RBTREE_FOR(n, struct auth_data*, &z->data) { 7715 1.2 christos if(!zonemd_simple_domain(z, hashalgo, h, n, region, buf, 7716 1.2 christos reason)) 7717 1.2 christos return 0; 7718 1.2 christos } 7719 1.2 christos return 1; 7720 1.2 christos } 7721 1.2 christos 7722 1.2 christos int auth_zone_generate_zonemd_hash(struct auth_zone* z, int scheme, 7723 1.2 christos int hashalgo, uint8_t* hash, size_t hashlen, size_t* resultlen, 7724 1.2 christos struct regional* region, struct sldns_buffer* buf, char** reason) 7725 1.2 christos { 7726 1.2 christos struct secalgo_hash* h = zonemd_digest_init(hashalgo, reason); 7727 1.2 christos if(!h) { 7728 1.2 christos if(!*reason) 7729 1.2 christos *reason = "digest init fail"; 7730 1.2 christos return 0; 7731 1.2 christos } 7732 1.2 christos if(scheme == ZONEMD_SCHEME_SIMPLE) { 7733 1.2 christos if(!zonemd_simple_collate(z, hashalgo, h, region, buf, reason)) { 7734 1.2 christos if(!*reason) *reason = "scheme simple collate fail"; 7735 1.2 christos secalgo_hash_delete(h); 7736 1.2 christos return 0; 7737 1.2 christos } 7738 1.2 christos } 7739 1.2 christos if(!zonemd_digest_finish(hashalgo, h, hash, hashlen, resultlen, 7740 1.2 christos reason)) { 7741 1.2 christos secalgo_hash_delete(h); 7742 1.2 christos *reason = "digest finish fail"; 7743 1.2 christos return 0; 7744 1.2 christos } 7745 1.2 christos secalgo_hash_delete(h); 7746 1.2 christos return 1; 7747 1.2 christos } 7748 1.2 christos 7749 1.2 christos int auth_zone_generate_zonemd_check(struct auth_zone* z, int scheme, 7750 1.2 christos int hashalgo, uint8_t* hash, size_t hashlen, struct regional* region, 7751 1.2 christos struct sldns_buffer* buf, char** reason) 7752 1.2 christos { 7753 1.2 christos uint8_t gen[512]; 7754 1.2 christos size_t genlen = 0; 7755 1.2 christos *reason = NULL; 7756 1.2 christos if(!zonemd_hashalgo_supported(hashalgo)) { 7757 1.2 christos /* allow it */ 7758 1.2 christos *reason = "unsupported algorithm"; 7759 1.2 christos return 1; 7760 1.2 christos } 7761 1.2 christos if(!zonemd_scheme_supported(scheme)) { 7762 1.2 christos /* allow it */ 7763 1.2 christos *reason = "unsupported scheme"; 7764 1.2 christos return 1; 7765 1.2 christos } 7766 1.2 christos if(hashlen < 12) { 7767 1.2 christos /* the ZONEMD draft requires digests to fail if too small */ 7768 1.2 christos *reason = "digest length too small, less than 12"; 7769 1.2 christos return 0; 7770 1.2 christos } 7771 1.2 christos /* generate digest */ 7772 1.2 christos if(!auth_zone_generate_zonemd_hash(z, scheme, hashalgo, gen, 7773 1.2 christos sizeof(gen), &genlen, region, buf, reason)) { 7774 1.2 christos /* reason filled in by zonemd hash routine */ 7775 1.2 christos return 0; 7776 1.2 christos } 7777 1.2 christos /* check digest length */ 7778 1.2 christos if(hashlen != genlen) { 7779 1.2 christos *reason = "incorrect digest length"; 7780 1.2 christos if(verbosity >= VERB_ALGO) { 7781 1.2 christos verbose(VERB_ALGO, "zonemd scheme=%d hashalgo=%d", 7782 1.2 christos scheme, hashalgo); 7783 1.2 christos log_hex("ZONEMD should be ", gen, genlen); 7784 1.2 christos log_hex("ZONEMD to check is", hash, hashlen); 7785 1.2 christos } 7786 1.2 christos return 0; 7787 1.2 christos } 7788 1.2 christos /* check digest */ 7789 1.2 christos if(memcmp(hash, gen, genlen) != 0) { 7790 1.2 christos *reason = "incorrect digest"; 7791 1.2 christos if(verbosity >= VERB_ALGO) { 7792 1.2 christos verbose(VERB_ALGO, "zonemd scheme=%d hashalgo=%d", 7793 1.2 christos scheme, hashalgo); 7794 1.2 christos log_hex("ZONEMD should be ", gen, genlen); 7795 1.2 christos log_hex("ZONEMD to check is", hash, hashlen); 7796 1.2 christos } 7797 1.2 christos return 0; 7798 1.2 christos } 7799 1.2 christos return 1; 7800 1.2 christos } 7801 1.2 christos 7802 1.2 christos /** log auth zone message with zone name in front. */ 7803 1.2 christos static void auth_zone_log(uint8_t* name, enum verbosity_value level, 7804 1.2 christos const char* format, ...) ATTR_FORMAT(printf, 3, 4); 7805 1.2 christos static void auth_zone_log(uint8_t* name, enum verbosity_value level, 7806 1.2 christos const char* format, ...) 7807 1.2 christos { 7808 1.2 christos va_list args; 7809 1.2 christos va_start(args, format); 7810 1.2 christos if(verbosity >= level) { 7811 1.4 christos char str[LDNS_MAX_DOMAINLEN]; 7812 1.2 christos char msg[MAXSYSLOGMSGLEN]; 7813 1.2 christos dname_str(name, str); 7814 1.2 christos vsnprintf(msg, sizeof(msg), format, args); 7815 1.2 christos verbose(level, "auth zone %s %s", str, msg); 7816 1.2 christos } 7817 1.2 christos va_end(args); 7818 1.2 christos } 7819 1.2 christos 7820 1.2 christos /** ZONEMD, dnssec verify the rrset with the dnskey */ 7821 1.2 christos static int zonemd_dnssec_verify_rrset(struct auth_zone* z, 7822 1.2 christos struct module_env* env, struct module_stack* mods, 7823 1.2 christos struct ub_packed_rrset_key* dnskey, struct auth_data* node, 7824 1.4 christos struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg, 7825 1.4 christos char* reasonbuf, size_t reasonlen) 7826 1.2 christos { 7827 1.2 christos struct ub_packed_rrset_key pk; 7828 1.2 christos enum sec_status sec; 7829 1.2 christos struct val_env* ve; 7830 1.2 christos int m; 7831 1.3 christos int verified = 0; 7832 1.2 christos m = modstack_find(mods, "validator"); 7833 1.2 christos if(m == -1) { 7834 1.2 christos auth_zone_log(z->name, VERB_ALGO, "zonemd dnssec verify: have " 7835 1.2 christos "DNSKEY chain of trust, but no validator module"); 7836 1.2 christos return 0; 7837 1.2 christos } 7838 1.2 christos ve = (struct val_env*)env->modinfo[m]; 7839 1.2 christos 7840 1.2 christos memset(&pk, 0, sizeof(pk)); 7841 1.2 christos pk.entry.key = &pk; 7842 1.2 christos pk.entry.data = rrset->data; 7843 1.2 christos pk.rk.dname = node->name; 7844 1.2 christos pk.rk.dname_len = node->namelen; 7845 1.2 christos pk.rk.type = htons(rrset->type); 7846 1.2 christos pk.rk.rrset_class = htons(z->dclass); 7847 1.2 christos if(verbosity >= VERB_ALGO) { 7848 1.2 christos char typestr[32]; 7849 1.2 christos typestr[0]=0; 7850 1.2 christos sldns_wire2str_type_buf(rrset->type, typestr, sizeof(typestr)); 7851 1.2 christos auth_zone_log(z->name, VERB_ALGO, 7852 1.2 christos "zonemd: verify %s RRset with DNSKEY", typestr); 7853 1.2 christos } 7854 1.2 christos sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL, 7855 1.4 christos LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf, reasonlen); 7856 1.2 christos if(sec == sec_status_secure) { 7857 1.2 christos return 1; 7858 1.2 christos } 7859 1.2 christos if(why_bogus) 7860 1.2 christos auth_zone_log(z->name, VERB_ALGO, "DNSSEC verify was bogus: %s", *why_bogus); 7861 1.2 christos return 0; 7862 1.2 christos } 7863 1.2 christos 7864 1.2 christos /** check for nsec3, the RR with params equal, if bitmap has the type */ 7865 1.2 christos static int nsec3_of_param_has_type(struct auth_rrset* nsec3, int algo, 7866 1.2 christos size_t iter, uint8_t* salt, size_t saltlen, uint16_t rrtype) 7867 1.2 christos { 7868 1.2 christos int i, count = (int)nsec3->data->count; 7869 1.2 christos struct ub_packed_rrset_key pk; 7870 1.2 christos memset(&pk, 0, sizeof(pk)); 7871 1.2 christos pk.entry.data = nsec3->data; 7872 1.2 christos for(i=0; i<count; i++) { 7873 1.2 christos int rralgo; 7874 1.2 christos size_t rriter, rrsaltlen; 7875 1.2 christos uint8_t* rrsalt; 7876 1.2 christos if(!nsec3_get_params(&pk, i, &rralgo, &rriter, &rrsalt, 7877 1.2 christos &rrsaltlen)) 7878 1.2 christos continue; /* no parameters, malformed */ 7879 1.2 christos if(rralgo != algo || rriter != iter || rrsaltlen != saltlen) 7880 1.2 christos continue; /* different parameters */ 7881 1.2 christos if(saltlen != 0) { 7882 1.2 christos if(rrsalt == NULL || salt == NULL) 7883 1.2 christos continue; 7884 1.2 christos if(memcmp(rrsalt, salt, saltlen) != 0) 7885 1.2 christos continue; /* different salt parameters */ 7886 1.2 christos } 7887 1.2 christos if(nsec3_has_type(&pk, i, rrtype)) 7888 1.2 christos return 1; 7889 1.2 christos } 7890 1.2 christos return 0; 7891 1.2 christos } 7892 1.2 christos 7893 1.2 christos /** Verify the absence of ZONEMD with DNSSEC by checking NSEC, NSEC3 type flag. 7894 1.2 christos * return false on failure, reason contains description of failure. */ 7895 1.2 christos static int zonemd_check_dnssec_absence(struct auth_zone* z, 7896 1.2 christos struct module_env* env, struct module_stack* mods, 7897 1.2 christos struct ub_packed_rrset_key* dnskey, struct auth_data* apex, 7898 1.4 christos char** reason, char** why_bogus, uint8_t* sigalg, char* reasonbuf, 7899 1.4 christos size_t reasonlen) 7900 1.2 christos { 7901 1.2 christos struct auth_rrset* nsec = NULL; 7902 1.2 christos if(!apex) { 7903 1.2 christos *reason = "zone has no apex domain but ZONEMD missing"; 7904 1.2 christos return 0; 7905 1.2 christos } 7906 1.2 christos nsec = az_domain_rrset(apex, LDNS_RR_TYPE_NSEC); 7907 1.2 christos if(nsec) { 7908 1.2 christos struct ub_packed_rrset_key pk; 7909 1.2 christos /* dnssec verify the NSEC */ 7910 1.2 christos if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, 7911 1.4 christos nsec, why_bogus, sigalg, reasonbuf, reasonlen)) { 7912 1.2 christos *reason = "DNSSEC verify failed for NSEC RRset"; 7913 1.2 christos return 0; 7914 1.2 christos } 7915 1.2 christos /* check type bitmap */ 7916 1.2 christos memset(&pk, 0, sizeof(pk)); 7917 1.2 christos pk.entry.data = nsec->data; 7918 1.2 christos if(nsec_has_type(&pk, LDNS_RR_TYPE_ZONEMD)) { 7919 1.2 christos *reason = "DNSSEC NSEC bitmap says type ZONEMD exists"; 7920 1.2 christos return 0; 7921 1.2 christos } 7922 1.2 christos auth_zone_log(z->name, VERB_ALGO, "zonemd DNSSEC NSEC verification of absence of ZONEMD secure"); 7923 1.2 christos } else { 7924 1.2 christos /* NSEC3 perhaps ? */ 7925 1.2 christos int algo; 7926 1.2 christos size_t iter, saltlen; 7927 1.2 christos uint8_t* salt; 7928 1.2 christos struct auth_rrset* nsec3param = az_domain_rrset(apex, 7929 1.2 christos LDNS_RR_TYPE_NSEC3PARAM); 7930 1.2 christos struct auth_data* match; 7931 1.2 christos struct auth_rrset* nsec3; 7932 1.2 christos if(!nsec3param) { 7933 1.2 christos *reason = "zone has no NSEC information but ZONEMD missing"; 7934 1.2 christos return 0; 7935 1.2 christos } 7936 1.2 christos if(!az_nsec3_param(z, &algo, &iter, &salt, &saltlen)) { 7937 1.2 christos *reason = "zone has no NSEC information but ZONEMD missing"; 7938 1.2 christos return 0; 7939 1.2 christos } 7940 1.2 christos /* find the NSEC3 record */ 7941 1.2 christos match = az_nsec3_find_exact(z, z->name, z->namelen, algo, 7942 1.2 christos iter, salt, saltlen); 7943 1.2 christos if(!match) { 7944 1.2 christos *reason = "zone has no NSEC3 domain for the apex but ZONEMD missing"; 7945 1.2 christos return 0; 7946 1.2 christos } 7947 1.2 christos nsec3 = az_domain_rrset(match, LDNS_RR_TYPE_NSEC3); 7948 1.2 christos if(!nsec3) { 7949 1.2 christos *reason = "zone has no NSEC3 RRset for the apex but ZONEMD missing"; 7950 1.2 christos return 0; 7951 1.2 christos } 7952 1.2 christos /* dnssec verify the NSEC3 */ 7953 1.2 christos if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, match, 7954 1.4 christos nsec3, why_bogus, sigalg, reasonbuf, reasonlen)) { 7955 1.2 christos *reason = "DNSSEC verify failed for NSEC3 RRset"; 7956 1.2 christos return 0; 7957 1.2 christos } 7958 1.2 christos /* check type bitmap */ 7959 1.2 christos if(nsec3_of_param_has_type(nsec3, algo, iter, salt, saltlen, 7960 1.2 christos LDNS_RR_TYPE_ZONEMD)) { 7961 1.2 christos *reason = "DNSSEC NSEC3 bitmap says type ZONEMD exists"; 7962 1.2 christos return 0; 7963 1.2 christos } 7964 1.2 christos auth_zone_log(z->name, VERB_ALGO, "zonemd DNSSEC NSEC3 verification of absence of ZONEMD secure"); 7965 1.2 christos } 7966 1.2 christos 7967 1.2 christos return 1; 7968 1.2 christos } 7969 1.2 christos 7970 1.2 christos /** Verify the SOA and ZONEMD DNSSEC signatures. 7971 1.2 christos * return false on failure, reason contains description of failure. */ 7972 1.2 christos static int zonemd_check_dnssec_soazonemd(struct auth_zone* z, 7973 1.2 christos struct module_env* env, struct module_stack* mods, 7974 1.2 christos struct ub_packed_rrset_key* dnskey, struct auth_data* apex, 7975 1.2 christos struct auth_rrset* zonemd_rrset, char** reason, char** why_bogus, 7976 1.4 christos uint8_t* sigalg, char* reasonbuf, size_t reasonlen) 7977 1.2 christos { 7978 1.2 christos struct auth_rrset* soa; 7979 1.2 christos if(!apex) { 7980 1.2 christos *reason = "zone has no apex domain"; 7981 1.2 christos return 0; 7982 1.2 christos } 7983 1.2 christos soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA); 7984 1.2 christos if(!soa) { 7985 1.2 christos *reason = "zone has no SOA RRset"; 7986 1.2 christos return 0; 7987 1.2 christos } 7988 1.2 christos if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, soa, 7989 1.4 christos why_bogus, sigalg, reasonbuf, reasonlen)) { 7990 1.2 christos *reason = "DNSSEC verify failed for SOA RRset"; 7991 1.2 christos return 0; 7992 1.2 christos } 7993 1.2 christos if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, 7994 1.4 christos zonemd_rrset, why_bogus, sigalg, reasonbuf, reasonlen)) { 7995 1.2 christos *reason = "DNSSEC verify failed for ZONEMD RRset"; 7996 1.2 christos return 0; 7997 1.2 christos } 7998 1.2 christos auth_zone_log(z->name, VERB_ALGO, "zonemd DNSSEC verification of SOA and ZONEMD RRsets secure"); 7999 1.2 christos return 1; 8000 1.2 christos } 8001 1.2 christos 8002 1.2 christos /** 8003 1.2 christos * Fail the ZONEMD verification. 8004 1.2 christos * @param z: auth zone that fails. 8005 1.2 christos * @param env: environment with config, to ignore failure or not. 8006 1.2 christos * @param reason: failure string description. 8007 1.2 christos * @param why_bogus: failure string for DNSSEC verification failure. 8008 1.2 christos * @param result: strdup result in here if not NULL. 8009 1.2 christos */ 8010 1.2 christos static void auth_zone_zonemd_fail(struct auth_zone* z, struct module_env* env, 8011 1.2 christos char* reason, char* why_bogus, char** result) 8012 1.2 christos { 8013 1.4 christos char zstr[LDNS_MAX_DOMAINLEN]; 8014 1.2 christos /* if fail: log reason, and depending on config also take action 8015 1.2 christos * and drop the zone, eg. it is gone from memory, set zone_expired */ 8016 1.2 christos dname_str(z->name, zstr); 8017 1.2 christos if(!reason) reason = "verification failed"; 8018 1.2 christos if(result) { 8019 1.2 christos if(why_bogus) { 8020 1.2 christos char res[1024]; 8021 1.2 christos snprintf(res, sizeof(res), "%s: %s", reason, 8022 1.2 christos why_bogus); 8023 1.2 christos *result = strdup(res); 8024 1.2 christos } else { 8025 1.2 christos *result = strdup(reason); 8026 1.2 christos } 8027 1.2 christos if(!*result) log_err("out of memory"); 8028 1.2 christos } else { 8029 1.2 christos log_warn("auth zone %s: ZONEMD verification failed: %s", zstr, reason); 8030 1.2 christos } 8031 1.2 christos 8032 1.2 christos if(env->cfg->zonemd_permissive_mode) { 8033 1.2 christos verbose(VERB_ALGO, "zonemd-permissive-mode enabled, " 8034 1.2 christos "not blocking zone %s", zstr); 8035 1.2 christos return; 8036 1.2 christos } 8037 1.2 christos 8038 1.2 christos /* expired means the zone gives servfail and is not used by 8039 1.2 christos * lookup if fallback_enabled*/ 8040 1.2 christos z->zone_expired = 1; 8041 1.2 christos } 8042 1.2 christos 8043 1.2 christos /** 8044 1.2 christos * Verify the zonemd with DNSSEC and hash check, with given key. 8045 1.2 christos * @param z: auth zone. 8046 1.2 christos * @param env: environment with config and temp buffers. 8047 1.2 christos * @param mods: module stack with validator env for verification. 8048 1.2 christos * @param dnskey: dnskey that we can use, or NULL. If nonnull, the key 8049 1.2 christos * has been verified and is the start of the chain of trust. 8050 1.2 christos * @param is_insecure: if true, the dnskey is not used, the zone is insecure. 8051 1.2 christos * And dnssec is not used. It is DNSSEC secure insecure or not under 8052 1.2 christos * a trust anchor. 8053 1.2 christos * @param sigalg: if nonNULL provide algorithm downgrade protection. 8054 1.2 christos * Otherwise one algorithm is enough. Must have space of ALGO_NEEDS_MAX+1. 8055 1.2 christos * @param result: if not NULL result reason copied here. 8056 1.2 christos */ 8057 1.2 christos static void 8058 1.2 christos auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env, 8059 1.2 christos struct module_stack* mods, struct ub_packed_rrset_key* dnskey, 8060 1.2 christos int is_insecure, char** result, uint8_t* sigalg) 8061 1.2 christos { 8062 1.4 christos char reasonbuf[256]; 8063 1.2 christos char* reason = NULL, *why_bogus = NULL; 8064 1.2 christos struct auth_data* apex = NULL; 8065 1.2 christos struct auth_rrset* zonemd_rrset = NULL; 8066 1.2 christos int zonemd_absent = 0, zonemd_absence_dnssecok = 0; 8067 1.2 christos 8068 1.2 christos /* see if ZONEMD is present or absent. */ 8069 1.2 christos apex = az_find_name(z, z->name, z->namelen); 8070 1.2 christos if(!apex) { 8071 1.2 christos zonemd_absent = 1; 8072 1.2 christos } else { 8073 1.2 christos zonemd_rrset = az_domain_rrset(apex, LDNS_RR_TYPE_ZONEMD); 8074 1.2 christos if(!zonemd_rrset || zonemd_rrset->data->count==0) { 8075 1.2 christos zonemd_absent = 1; 8076 1.2 christos zonemd_rrset = NULL; 8077 1.2 christos } 8078 1.2 christos } 8079 1.2 christos 8080 1.2 christos /* if no DNSSEC, done. */ 8081 1.2 christos /* if no ZONEMD, and DNSSEC, use DNSKEY to verify NSEC or NSEC3 for 8082 1.2 christos * zone apex. Check ZONEMD bit is turned off or else fail */ 8083 1.2 christos /* if ZONEMD, and DNSSEC, check DNSSEC signature on SOA and ZONEMD, 8084 1.2 christos * or else fail */ 8085 1.2 christos if(!dnskey && !is_insecure) { 8086 1.2 christos auth_zone_zonemd_fail(z, env, "DNSKEY missing", NULL, result); 8087 1.2 christos return; 8088 1.2 christos } else if(!zonemd_rrset && dnskey && !is_insecure) { 8089 1.2 christos /* fetch, DNSSEC verify, and check NSEC/NSEC3 */ 8090 1.2 christos if(!zonemd_check_dnssec_absence(z, env, mods, dnskey, apex, 8091 1.4 christos &reason, &why_bogus, sigalg, reasonbuf, 8092 1.4 christos sizeof(reasonbuf))) { 8093 1.2 christos auth_zone_zonemd_fail(z, env, reason, why_bogus, result); 8094 1.2 christos return; 8095 1.2 christos } 8096 1.2 christos zonemd_absence_dnssecok = 1; 8097 1.2 christos } else if(zonemd_rrset && dnskey && !is_insecure) { 8098 1.2 christos /* check DNSSEC verify of SOA and ZONEMD */ 8099 1.2 christos if(!zonemd_check_dnssec_soazonemd(z, env, mods, dnskey, apex, 8100 1.4 christos zonemd_rrset, &reason, &why_bogus, sigalg, reasonbuf, 8101 1.4 christos sizeof(reasonbuf))) { 8102 1.2 christos auth_zone_zonemd_fail(z, env, reason, why_bogus, result); 8103 1.2 christos return; 8104 1.2 christos } 8105 1.2 christos } 8106 1.2 christos 8107 1.2 christos if(zonemd_absent && z->zonemd_reject_absence) { 8108 1.2 christos auth_zone_zonemd_fail(z, env, "ZONEMD absent and that is not allowed by config", NULL, result); 8109 1.2 christos return; 8110 1.2 christos } 8111 1.2 christos if(zonemd_absent && zonemd_absence_dnssecok) { 8112 1.2 christos auth_zone_log(z->name, VERB_ALGO, "DNSSEC verified nonexistence of ZONEMD"); 8113 1.2 christos if(result) { 8114 1.2 christos *result = strdup("DNSSEC verified nonexistence of ZONEMD"); 8115 1.2 christos if(!*result) log_err("out of memory"); 8116 1.2 christos } 8117 1.2 christos return; 8118 1.2 christos } 8119 1.2 christos if(zonemd_absent) { 8120 1.2 christos auth_zone_log(z->name, VERB_ALGO, "no ZONEMD present"); 8121 1.2 christos if(result) { 8122 1.2 christos *result = strdup("no ZONEMD present"); 8123 1.2 christos if(!*result) log_err("out of memory"); 8124 1.2 christos } 8125 1.2 christos return; 8126 1.2 christos } 8127 1.2 christos 8128 1.2 christos /* check ZONEMD checksum and report or else fail. */ 8129 1.2 christos if(!auth_zone_zonemd_check_hash(z, env, &reason)) { 8130 1.2 christos auth_zone_zonemd_fail(z, env, reason, NULL, result); 8131 1.2 christos return; 8132 1.2 christos } 8133 1.2 christos 8134 1.2 christos /* success! log the success */ 8135 1.2 christos if(reason) 8136 1.2 christos auth_zone_log(z->name, VERB_ALGO, "ZONEMD %s", reason); 8137 1.2 christos else auth_zone_log(z->name, VERB_ALGO, "ZONEMD verification successful"); 8138 1.2 christos if(result) { 8139 1.2 christos if(reason) 8140 1.2 christos *result = strdup(reason); 8141 1.2 christos else *result = strdup("ZONEMD verification successful"); 8142 1.2 christos if(!*result) log_err("out of memory"); 8143 1.2 christos } 8144 1.2 christos } 8145 1.2 christos 8146 1.2 christos /** 8147 1.2 christos * verify the zone DNSKEY rrset from the trust anchor 8148 1.2 christos * This is possible because the anchor is for the zone itself, and can 8149 1.2 christos * thus apply straight to the zone DNSKEY set. 8150 1.2 christos * @param z: the auth zone. 8151 1.2 christos * @param env: environment with time and temp buffers. 8152 1.2 christos * @param mods: module stack for validator environment for dnssec validation. 8153 1.2 christos * @param anchor: trust anchor to use 8154 1.2 christos * @param is_insecure: returned, true if the zone is securely insecure. 8155 1.2 christos * @param why_bogus: if the routine fails, returns the failure reason. 8156 1.2 christos * @param keystorage: where to store the ub_packed_rrset_key that is created 8157 1.2 christos * on success. A pointer to it is returned on success. 8158 1.4 christos * @param reasonbuf: buffer to use for fail reason string print. 8159 1.4 christos * @param reasonlen: length of reasonbuf. 8160 1.2 christos * @return the dnskey RRset, reference to zone data and keystorage, or 8161 1.2 christos * NULL on failure. 8162 1.2 christos */ 8163 1.2 christos static struct ub_packed_rrset_key* 8164 1.2 christos zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env, 8165 1.2 christos struct module_stack* mods, struct trust_anchor* anchor, 8166 1.2 christos int* is_insecure, char** why_bogus, 8167 1.4 christos struct ub_packed_rrset_key* keystorage, char* reasonbuf, 8168 1.4 christos size_t reasonlen) 8169 1.2 christos { 8170 1.2 christos struct auth_data* apex; 8171 1.2 christos struct auth_rrset* dnskey_rrset; 8172 1.2 christos enum sec_status sec; 8173 1.2 christos struct val_env* ve; 8174 1.2 christos int m; 8175 1.2 christos 8176 1.2 christos apex = az_find_name(z, z->name, z->namelen); 8177 1.2 christos if(!apex) { 8178 1.2 christos *why_bogus = "have trust anchor, but zone has no apex domain for DNSKEY"; 8179 1.2 christos return 0; 8180 1.2 christos } 8181 1.2 christos dnskey_rrset = az_domain_rrset(apex, LDNS_RR_TYPE_DNSKEY); 8182 1.2 christos if(!dnskey_rrset || dnskey_rrset->data->count==0) { 8183 1.2 christos *why_bogus = "have trust anchor, but zone has no DNSKEY"; 8184 1.2 christos return 0; 8185 1.2 christos } 8186 1.2 christos 8187 1.2 christos m = modstack_find(mods, "validator"); 8188 1.2 christos if(m == -1) { 8189 1.2 christos *why_bogus = "have trust anchor, but no validator module"; 8190 1.2 christos return 0; 8191 1.2 christos } 8192 1.2 christos ve = (struct val_env*)env->modinfo[m]; 8193 1.2 christos 8194 1.2 christos memset(keystorage, 0, sizeof(*keystorage)); 8195 1.2 christos keystorage->entry.key = keystorage; 8196 1.2 christos keystorage->entry.data = dnskey_rrset->data; 8197 1.2 christos keystorage->rk.dname = apex->name; 8198 1.2 christos keystorage->rk.dname_len = apex->namelen; 8199 1.2 christos keystorage->rk.type = htons(LDNS_RR_TYPE_DNSKEY); 8200 1.2 christos keystorage->rk.rrset_class = htons(z->dclass); 8201 1.2 christos auth_zone_log(z->name, VERB_QUERY, 8202 1.2 christos "zonemd: verify DNSKEY RRset with trust anchor"); 8203 1.2 christos sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset, 8204 1.4 christos anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL, reasonbuf, 8205 1.4 christos reasonlen); 8206 1.2 christos regional_free_all(env->scratch); 8207 1.2 christos if(sec == sec_status_secure) { 8208 1.2 christos /* success */ 8209 1.2 christos *is_insecure = 0; 8210 1.2 christos return keystorage; 8211 1.2 christos } else if(sec == sec_status_insecure) { 8212 1.2 christos /* insecure */ 8213 1.2 christos *is_insecure = 1; 8214 1.2 christos } else { 8215 1.2 christos /* bogus */ 8216 1.2 christos *is_insecure = 0; 8217 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8218 1.2 christos "zonemd: verify DNSKEY RRset with trust anchor failed: %s", *why_bogus); 8219 1.2 christos } 8220 1.2 christos return NULL; 8221 1.2 christos } 8222 1.2 christos 8223 1.2 christos /** verify the DNSKEY from the zone with looked up DS record */ 8224 1.2 christos static struct ub_packed_rrset_key* 8225 1.2 christos auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z, 8226 1.2 christos struct module_env* env, struct module_stack* mods, 8227 1.2 christos struct ub_packed_rrset_key* ds, int* is_insecure, char** why_bogus, 8228 1.4 christos struct ub_packed_rrset_key* keystorage, uint8_t* sigalg, 8229 1.4 christos char* reasonbuf, size_t reasonlen) 8230 1.2 christos { 8231 1.2 christos struct auth_data* apex; 8232 1.2 christos struct auth_rrset* dnskey_rrset; 8233 1.2 christos enum sec_status sec; 8234 1.2 christos struct val_env* ve; 8235 1.2 christos int m; 8236 1.2 christos 8237 1.2 christos /* fetch DNSKEY from zone data */ 8238 1.2 christos apex = az_find_name(z, z->name, z->namelen); 8239 1.2 christos if(!apex) { 8240 1.2 christos *why_bogus = "in verifywithDS, zone has no apex"; 8241 1.2 christos return NULL; 8242 1.2 christos } 8243 1.2 christos dnskey_rrset = az_domain_rrset(apex, LDNS_RR_TYPE_DNSKEY); 8244 1.2 christos if(!dnskey_rrset || dnskey_rrset->data->count==0) { 8245 1.2 christos *why_bogus = "in verifywithDS, zone has no DNSKEY"; 8246 1.2 christos return NULL; 8247 1.2 christos } 8248 1.2 christos 8249 1.2 christos m = modstack_find(mods, "validator"); 8250 1.2 christos if(m == -1) { 8251 1.2 christos *why_bogus = "in verifywithDS, have no validator module"; 8252 1.2 christos return NULL; 8253 1.2 christos } 8254 1.2 christos ve = (struct val_env*)env->modinfo[m]; 8255 1.2 christos 8256 1.2 christos memset(keystorage, 0, sizeof(*keystorage)); 8257 1.2 christos keystorage->entry.key = keystorage; 8258 1.2 christos keystorage->entry.data = dnskey_rrset->data; 8259 1.2 christos keystorage->rk.dname = apex->name; 8260 1.2 christos keystorage->rk.dname_len = apex->namelen; 8261 1.2 christos keystorage->rk.type = htons(LDNS_RR_TYPE_DNSKEY); 8262 1.2 christos keystorage->rk.rrset_class = htons(z->dclass); 8263 1.2 christos auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS"); 8264 1.2 christos sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg, 8265 1.4 christos why_bogus, NULL, NULL, reasonbuf, reasonlen); 8266 1.2 christos regional_free_all(env->scratch); 8267 1.2 christos if(sec == sec_status_secure) { 8268 1.2 christos /* success */ 8269 1.2 christos return keystorage; 8270 1.2 christos } else if(sec == sec_status_insecure) { 8271 1.2 christos /* insecure */ 8272 1.2 christos *is_insecure = 1; 8273 1.2 christos } else { 8274 1.2 christos /* bogus */ 8275 1.2 christos *is_insecure = 0; 8276 1.2 christos if(*why_bogus == NULL) 8277 1.2 christos *why_bogus = "verify failed"; 8278 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8279 1.2 christos "zonemd: verify DNSKEY RRset with DS failed: %s", 8280 1.2 christos *why_bogus); 8281 1.2 christos } 8282 1.2 christos return NULL; 8283 1.2 christos } 8284 1.2 christos 8285 1.2 christos /** callback for ZONEMD lookup of DNSKEY */ 8286 1.2 christos void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf, 8287 1.2 christos enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited)) 8288 1.2 christos { 8289 1.2 christos struct auth_zone* z = (struct auth_zone*)arg; 8290 1.2 christos struct module_env* env; 8291 1.4 christos char reasonbuf[256]; 8292 1.2 christos char* reason = NULL, *ds_bogus = NULL, *typestr="DNSKEY"; 8293 1.2 christos struct ub_packed_rrset_key* dnskey = NULL, *ds = NULL; 8294 1.2 christos int is_insecure = 0, downprot; 8295 1.2 christos struct ub_packed_rrset_key keystorage; 8296 1.2 christos uint8_t sigalg[ALGO_NEEDS_MAX+1]; 8297 1.2 christos 8298 1.2 christos lock_rw_wrlock(&z->lock); 8299 1.2 christos env = z->zonemd_callback_env; 8300 1.2 christos /* release the env variable so another worker can pick up the 8301 1.2 christos * ZONEMD verification task if it wants to */ 8302 1.2 christos z->zonemd_callback_env = NULL; 8303 1.2 christos if(!env || env->outnet->want_to_quit || z->zone_deleted) { 8304 1.2 christos lock_rw_unlock(&z->lock); 8305 1.2 christos return; /* stop on quit */ 8306 1.2 christos } 8307 1.2 christos if(z->zonemd_callback_qtype == LDNS_RR_TYPE_DS) 8308 1.2 christos typestr = "DS"; 8309 1.2 christos downprot = env->cfg->harden_algo_downgrade; 8310 1.2 christos 8311 1.2 christos /* process result */ 8312 1.2 christos if(sec == sec_status_bogus) { 8313 1.2 christos reason = why_bogus; 8314 1.2 christos if(!reason) { 8315 1.2 christos if(z->zonemd_callback_qtype == LDNS_RR_TYPE_DNSKEY) 8316 1.2 christos reason = "lookup of DNSKEY was bogus"; 8317 1.2 christos else reason = "lookup of DS was bogus"; 8318 1.2 christos } 8319 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8320 1.2 christos "zonemd lookup of %s was bogus: %s", typestr, reason); 8321 1.2 christos } else if(rcode == LDNS_RCODE_NOERROR) { 8322 1.2 christos uint16_t wanted_qtype = z->zonemd_callback_qtype; 8323 1.2 christos struct regional* temp = env->scratch; 8324 1.2 christos struct query_info rq; 8325 1.2 christos struct reply_info* rep; 8326 1.2 christos memset(&rq, 0, sizeof(rq)); 8327 1.2 christos rep = parse_reply_in_temp_region(buf, temp, &rq); 8328 1.2 christos if(rep && rq.qtype == wanted_qtype && 8329 1.2 christos query_dname_compare(z->name, rq.qname) == 0 && 8330 1.2 christos FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR) { 8331 1.2 christos /* parsed successfully */ 8332 1.2 christos struct ub_packed_rrset_key* answer = 8333 1.2 christos reply_find_answer_rrset(&rq, rep); 8334 1.2 christos if(answer && sec == sec_status_secure) { 8335 1.2 christos if(z->zonemd_callback_qtype == LDNS_RR_TYPE_DNSKEY) 8336 1.2 christos dnskey = answer; 8337 1.2 christos else ds = answer; 8338 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8339 1.2 christos "zonemd lookup of %s was secure", typestr); 8340 1.2 christos } else if(sec == sec_status_secure && !answer) { 8341 1.2 christos is_insecure = 1; 8342 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8343 1.2 christos "zonemd lookup of %s has no content, but is secure, treat as insecure", typestr); 8344 1.2 christos } else if(sec == sec_status_insecure) { 8345 1.2 christos is_insecure = 1; 8346 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8347 1.2 christos "zonemd lookup of %s was insecure", typestr); 8348 1.2 christos } else if(sec == sec_status_indeterminate) { 8349 1.2 christos is_insecure = 1; 8350 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8351 1.2 christos "zonemd lookup of %s was indeterminate, treat as insecure", typestr); 8352 1.2 christos } else { 8353 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8354 1.2 christos "zonemd lookup of %s has nodata", typestr); 8355 1.2 christos if(z->zonemd_callback_qtype == LDNS_RR_TYPE_DNSKEY) 8356 1.2 christos reason = "lookup of DNSKEY has nodata"; 8357 1.2 christos else reason = "lookup of DS has nodata"; 8358 1.2 christos } 8359 1.2 christos } else if(rep && rq.qtype == wanted_qtype && 8360 1.2 christos query_dname_compare(z->name, rq.qname) == 0 && 8361 1.2 christos FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN && 8362 1.2 christos sec == sec_status_secure) { 8363 1.2 christos /* secure nxdomain, so the zone is like some RPZ zone 8364 1.2 christos * that does not exist in the wider internet, with 8365 1.2 christos * a secure nxdomain answer outside of it. So we 8366 1.2 christos * treat the zonemd zone without a dnssec chain of 8367 1.2 christos * trust, as insecure. */ 8368 1.2 christos is_insecure = 1; 8369 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8370 1.2 christos "zonemd lookup of %s was secure NXDOMAIN, treat as insecure", typestr); 8371 1.2 christos } else if(rep && rq.qtype == wanted_qtype && 8372 1.2 christos query_dname_compare(z->name, rq.qname) == 0 && 8373 1.2 christos FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN && 8374 1.2 christos sec == sec_status_insecure) { 8375 1.2 christos is_insecure = 1; 8376 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8377 1.2 christos "zonemd lookup of %s was insecure NXDOMAIN, treat as insecure", typestr); 8378 1.2 christos } else if(rep && rq.qtype == wanted_qtype && 8379 1.2 christos query_dname_compare(z->name, rq.qname) == 0 && 8380 1.2 christos FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN && 8381 1.2 christos sec == sec_status_indeterminate) { 8382 1.2 christos is_insecure = 1; 8383 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8384 1.2 christos "zonemd lookup of %s was indeterminate NXDOMAIN, treat as insecure", typestr); 8385 1.2 christos } else { 8386 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8387 1.2 christos "zonemd lookup of %s has no answer", typestr); 8388 1.2 christos if(z->zonemd_callback_qtype == LDNS_RR_TYPE_DNSKEY) 8389 1.2 christos reason = "lookup of DNSKEY has no answer"; 8390 1.2 christos else reason = "lookup of DS has no answer"; 8391 1.2 christos } 8392 1.2 christos } else { 8393 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8394 1.2 christos "zonemd lookup of %s failed", typestr); 8395 1.2 christos if(z->zonemd_callback_qtype == LDNS_RR_TYPE_DNSKEY) 8396 1.2 christos reason = "lookup of DNSKEY failed"; 8397 1.2 christos else reason = "lookup of DS failed"; 8398 1.2 christos } 8399 1.2 christos 8400 1.2 christos if(!reason && !is_insecure && !dnskey && ds) { 8401 1.2 christos dnskey = auth_zone_verify_zonemd_key_with_ds(z, env, 8402 1.2 christos &env->mesh->mods, ds, &is_insecure, &ds_bogus, 8403 1.4 christos &keystorage, downprot?sigalg:NULL, reasonbuf, 8404 1.4 christos sizeof(reasonbuf)); 8405 1.2 christos if(!dnskey && !is_insecure && !reason) 8406 1.2 christos reason = "DNSKEY verify with DS failed"; 8407 1.2 christos } 8408 1.2 christos 8409 1.2 christos if(reason) { 8410 1.2 christos auth_zone_zonemd_fail(z, env, reason, ds_bogus, NULL); 8411 1.2 christos lock_rw_unlock(&z->lock); 8412 1.4 christos regional_free_all(env->scratch); 8413 1.2 christos return; 8414 1.2 christos } 8415 1.2 christos 8416 1.2 christos auth_zone_verify_zonemd_with_key(z, env, &env->mesh->mods, dnskey, 8417 1.2 christos is_insecure, NULL, downprot?sigalg:NULL); 8418 1.2 christos regional_free_all(env->scratch); 8419 1.2 christos lock_rw_unlock(&z->lock); 8420 1.2 christos } 8421 1.2 christos 8422 1.2 christos /** lookup DNSKEY for ZONEMD verification */ 8423 1.2 christos static int 8424 1.2 christos zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env) 8425 1.2 christos { 8426 1.2 christos struct query_info qinfo; 8427 1.2 christos uint16_t qflags = BIT_RD; 8428 1.2 christos struct edns_data edns; 8429 1.2 christos sldns_buffer* buf = env->scratch_buffer; 8430 1.2 christos int fetch_ds = 0; 8431 1.2 christos 8432 1.2 christos if(!z->fallback_enabled) { 8433 1.2 christos /* we cannot actually get the DNSKEY, because it is in the 8434 1.2 christos * zone we have ourselves, and it is not served yet 8435 1.2 christos * (possibly), so fetch type DS */ 8436 1.2 christos fetch_ds = 1; 8437 1.2 christos } 8438 1.2 christos if(z->zonemd_callback_env) { 8439 1.2 christos /* another worker is already working on the callback 8440 1.2 christos * for the DNSKEY lookup for ZONEMD verification. 8441 1.2 christos * We do not also have to do ZONEMD verification, let that 8442 1.2 christos * worker do it */ 8443 1.2 christos auth_zone_log(z->name, VERB_ALGO, 8444 1.2 christos "zonemd needs lookup of %s and that already is worked on by another worker", (fetch_ds?"DS":"DNSKEY")); 8445 1.2 christos return 1; 8446 1.2 christos } 8447 1.2 christos 8448 1.2 christos /* use mesh_new_callback to lookup the DNSKEY, 8449 1.2 christos * and then wait for them to be looked up (in cache, or query) */ 8450 1.2 christos qinfo.qname_len = z->namelen; 8451 1.2 christos qinfo.qname = z->name; 8452 1.2 christos qinfo.qclass = z->dclass; 8453 1.2 christos if(fetch_ds) 8454 1.2 christos qinfo.qtype = LDNS_RR_TYPE_DS; 8455 1.2 christos else qinfo.qtype = LDNS_RR_TYPE_DNSKEY; 8456 1.2 christos qinfo.local_alias = NULL; 8457 1.2 christos if(verbosity >= VERB_ALGO) { 8458 1.2 christos char buf1[512]; 8459 1.4 christos char buf2[LDNS_MAX_DOMAINLEN]; 8460 1.2 christos dname_str(z->name, buf2); 8461 1.2 christos snprintf(buf1, sizeof(buf1), "auth zone %s: lookup %s " 8462 1.2 christos "for zonemd verification", buf2, 8463 1.2 christos (fetch_ds?"DS":"DNSKEY")); 8464 1.2 christos log_query_info(VERB_ALGO, buf1, &qinfo); 8465 1.2 christos } 8466 1.2 christos edns.edns_present = 1; 8467 1.2 christos edns.ext_rcode = 0; 8468 1.2 christos edns.edns_version = 0; 8469 1.2 christos edns.bits = EDNS_DO; 8470 1.2 christos edns.opt_list_in = NULL; 8471 1.2 christos edns.opt_list_out = NULL; 8472 1.2 christos edns.opt_list_inplace_cb_out = NULL; 8473 1.2 christos if(sldns_buffer_capacity(buf) < 65535) 8474 1.2 christos edns.udp_size = (uint16_t)sldns_buffer_capacity(buf); 8475 1.2 christos else edns.udp_size = 65535; 8476 1.2 christos 8477 1.2 christos /* store the worker-specific module env for the callback. 8478 1.2 christos * We can then reference this when the callback executes */ 8479 1.2 christos z->zonemd_callback_env = env; 8480 1.2 christos z->zonemd_callback_qtype = qinfo.qtype; 8481 1.2 christos /* the callback can be called straight away */ 8482 1.2 christos lock_rw_unlock(&z->lock); 8483 1.2 christos if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, 8484 1.2 christos &auth_zonemd_dnskey_lookup_callback, z, 0)) { 8485 1.2 christos lock_rw_wrlock(&z->lock); 8486 1.2 christos log_err("out of memory lookup of %s for zonemd", 8487 1.2 christos (fetch_ds?"DS":"DNSKEY")); 8488 1.2 christos return 0; 8489 1.2 christos } 8490 1.2 christos lock_rw_wrlock(&z->lock); 8491 1.2 christos return 1; 8492 1.2 christos } 8493 1.2 christos 8494 1.2 christos void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env, 8495 1.2 christos struct module_stack* mods, char** result, int offline, int only_online) 8496 1.2 christos { 8497 1.4 christos char reasonbuf[256]; 8498 1.2 christos char* reason = NULL, *why_bogus = NULL; 8499 1.2 christos struct trust_anchor* anchor = NULL; 8500 1.2 christos struct ub_packed_rrset_key* dnskey = NULL; 8501 1.2 christos struct ub_packed_rrset_key keystorage; 8502 1.2 christos int is_insecure = 0; 8503 1.2 christos /* verify the ZONEMD if present. 8504 1.2 christos * If not present check if absence is allowed by DNSSEC */ 8505 1.2 christos if(!z->zonemd_check) 8506 1.2 christos return; 8507 1.2 christos if(z->data.count == 0) 8508 1.2 christos return; /* no data */ 8509 1.2 christos 8510 1.2 christos /* if zone is under a trustanchor */ 8511 1.2 christos /* is it equal to trustanchor - get dnskey's verified */ 8512 1.2 christos /* else, find chain of trust by fetching DNSKEYs lookup for zone */ 8513 1.2 christos /* result if that, if insecure, means no DNSSEC for the ZONEMD, 8514 1.2 christos * otherwise we have the zone DNSKEY for the DNSSEC verification. */ 8515 1.2 christos if(env->anchors) 8516 1.2 christos anchor = anchors_lookup(env->anchors, z->name, z->namelen, 8517 1.2 christos z->dclass); 8518 1.2 christos if(anchor && anchor->numDS == 0 && anchor->numDNSKEY == 0) { 8519 1.2 christos /* domain-insecure trust anchor for unsigned zones */ 8520 1.2 christos lock_basic_unlock(&anchor->lock); 8521 1.2 christos if(only_online) 8522 1.2 christos return; 8523 1.2 christos dnskey = NULL; 8524 1.2 christos is_insecure = 1; 8525 1.2 christos } else if(anchor && query_dname_compare(z->name, anchor->name) == 0) { 8526 1.2 christos if(only_online) { 8527 1.2 christos lock_basic_unlock(&anchor->lock); 8528 1.2 christos return; 8529 1.2 christos } 8530 1.2 christos /* equal to trustanchor, no need for online lookups */ 8531 1.2 christos dnskey = zonemd_get_dnskey_from_anchor(z, env, mods, anchor, 8532 1.4 christos &is_insecure, &why_bogus, &keystorage, reasonbuf, 8533 1.4 christos sizeof(reasonbuf)); 8534 1.2 christos lock_basic_unlock(&anchor->lock); 8535 1.2 christos if(!dnskey && !reason && !is_insecure) { 8536 1.2 christos reason = "verify DNSKEY RRset with trust anchor failed"; 8537 1.2 christos } 8538 1.2 christos } else if(anchor) { 8539 1.2 christos lock_basic_unlock(&anchor->lock); 8540 1.2 christos /* perform online lookups */ 8541 1.2 christos if(offline) 8542 1.2 christos return; 8543 1.2 christos /* setup online lookups, and wait for them */ 8544 1.2 christos if(zonemd_lookup_dnskey(z, env)) { 8545 1.2 christos /* wait for the lookup */ 8546 1.2 christos return; 8547 1.2 christos } 8548 1.2 christos reason = "could not lookup DNSKEY for chain of trust"; 8549 1.2 christos } else { 8550 1.2 christos /* the zone is not under a trust anchor */ 8551 1.2 christos if(only_online) 8552 1.2 christos return; 8553 1.2 christos dnskey = NULL; 8554 1.2 christos is_insecure = 1; 8555 1.2 christos } 8556 1.2 christos 8557 1.2 christos if(reason) { 8558 1.2 christos auth_zone_zonemd_fail(z, env, reason, why_bogus, result); 8559 1.4 christos regional_free_all(env->scratch); 8560 1.2 christos return; 8561 1.2 christos } 8562 1.2 christos 8563 1.2 christos auth_zone_verify_zonemd_with_key(z, env, mods, dnskey, is_insecure, 8564 1.2 christos result, NULL); 8565 1.2 christos regional_free_all(env->scratch); 8566 1.2 christos } 8567 1.2 christos 8568 1.2 christos void auth_zones_pickup_zonemd_verify(struct auth_zones* az, 8569 1.2 christos struct module_env* env) 8570 1.2 christos { 8571 1.2 christos struct auth_zone key; 8572 1.2 christos uint8_t savezname[255+1]; 8573 1.2 christos size_t savezname_len; 8574 1.2 christos struct auth_zone* z; 8575 1.2 christos key.node.key = &key; 8576 1.2 christos lock_rw_rdlock(&az->lock); 8577 1.2 christos RBTREE_FOR(z, struct auth_zone*, &az->ztree) { 8578 1.2 christos lock_rw_wrlock(&z->lock); 8579 1.2 christos if(!z->zonemd_check) { 8580 1.2 christos lock_rw_unlock(&z->lock); 8581 1.2 christos continue; 8582 1.2 christos } 8583 1.2 christos key.dclass = z->dclass; 8584 1.2 christos key.namelabs = z->namelabs; 8585 1.2 christos if(z->namelen > sizeof(savezname)) { 8586 1.2 christos lock_rw_unlock(&z->lock); 8587 1.2 christos log_err("auth_zones_pickup_zonemd_verify: zone name too long"); 8588 1.2 christos continue; 8589 1.2 christos } 8590 1.2 christos savezname_len = z->namelen; 8591 1.2 christos memmove(savezname, z->name, z->namelen); 8592 1.2 christos lock_rw_unlock(&az->lock); 8593 1.2 christos auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 1); 8594 1.2 christos lock_rw_unlock(&z->lock); 8595 1.2 christos lock_rw_rdlock(&az->lock); 8596 1.2 christos /* find the zone we had before, it is not deleted, 8597 1.2 christos * because we have a flag for that that is processed at 8598 1.2 christos * apply_cfg time */ 8599 1.2 christos key.namelen = savezname_len; 8600 1.2 christos key.name = savezname; 8601 1.2 christos z = (struct auth_zone*)rbtree_search(&az->ztree, &key); 8602 1.2 christos if(!z) 8603 1.2 christos break; 8604 1.2 christos } 8605 1.2 christos lock_rw_unlock(&az->lock); 8606 1.2 christos } 8607 1.4 christos 8608 1.4 christos /** Get memory usage of auth rrset */ 8609 1.4 christos static size_t 8610 1.4 christos auth_rrset_get_mem(struct auth_rrset* rrset) 8611 1.4 christos { 8612 1.4 christos size_t m = sizeof(*rrset) + packed_rrset_sizeof(rrset->data); 8613 1.4 christos return m; 8614 1.4 christos } 8615 1.4 christos 8616 1.4 christos /** Get memory usage of auth data */ 8617 1.4 christos static size_t 8618 1.4 christos auth_data_get_mem(struct auth_data* node) 8619 1.4 christos { 8620 1.4 christos size_t m = sizeof(*node) + node->namelen; 8621 1.4 christos struct auth_rrset* rrset; 8622 1.4 christos for(rrset = node->rrsets; rrset; rrset = rrset->next) { 8623 1.4 christos m += auth_rrset_get_mem(rrset); 8624 1.4 christos } 8625 1.4 christos return m; 8626 1.4 christos } 8627 1.4 christos 8628 1.4 christos /** Get memory usage of auth zone */ 8629 1.4 christos static size_t 8630 1.4 christos auth_zone_get_mem(struct auth_zone* z) 8631 1.4 christos { 8632 1.4 christos size_t m = sizeof(*z) + z->namelen; 8633 1.4 christos struct auth_data* node; 8634 1.4 christos if(z->zonefile) 8635 1.4 christos m += strlen(z->zonefile)+1; 8636 1.4 christos RBTREE_FOR(node, struct auth_data*, &z->data) { 8637 1.4 christos m += auth_data_get_mem(node); 8638 1.4 christos } 8639 1.4 christos if(z->rpz) 8640 1.4 christos m += rpz_get_mem(z->rpz); 8641 1.4 christos return m; 8642 1.4 christos } 8643 1.4 christos 8644 1.4 christos /** Get memory usage of list of auth addr */ 8645 1.4 christos static size_t 8646 1.4 christos auth_addrs_get_mem(struct auth_addr* list) 8647 1.4 christos { 8648 1.4 christos size_t m = 0; 8649 1.4 christos struct auth_addr* a; 8650 1.4 christos for(a = list; a; a = a->next) { 8651 1.4 christos m += sizeof(*a); 8652 1.4 christos } 8653 1.4 christos return m; 8654 1.4 christos } 8655 1.4 christos 8656 1.4 christos /** Get memory usage of list of primaries for auth xfer */ 8657 1.4 christos static size_t 8658 1.4 christos auth_primaries_get_mem(struct auth_master* list) 8659 1.4 christos { 8660 1.4 christos size_t m = 0; 8661 1.4 christos struct auth_master* n; 8662 1.4 christos for(n = list; n; n = n->next) { 8663 1.4 christos m += sizeof(*n); 8664 1.4 christos m += auth_addrs_get_mem(n->list); 8665 1.4 christos if(n->host) 8666 1.4 christos m += strlen(n->host)+1; 8667 1.4 christos if(n->file) 8668 1.4 christos m += strlen(n->file)+1; 8669 1.4 christos } 8670 1.4 christos return m; 8671 1.4 christos } 8672 1.4 christos 8673 1.4 christos /** Get memory usage or list of auth chunks */ 8674 1.4 christos static size_t 8675 1.4 christos auth_chunks_get_mem(struct auth_chunk* list) 8676 1.4 christos { 8677 1.4 christos size_t m = 0; 8678 1.4 christos struct auth_chunk* chunk; 8679 1.4 christos for(chunk = list; chunk; chunk = chunk->next) { 8680 1.4 christos m += sizeof(*chunk) + chunk->len; 8681 1.4 christos } 8682 1.4 christos return m; 8683 1.4 christos } 8684 1.4 christos 8685 1.4 christos /** Get memory usage of auth xfer */ 8686 1.4 christos static size_t 8687 1.4 christos auth_xfer_get_mem(struct auth_xfer* xfr) 8688 1.4 christos { 8689 1.4 christos size_t m = sizeof(*xfr) + xfr->namelen; 8690 1.4 christos 8691 1.4 christos /* auth_nextprobe */ 8692 1.4 christos m += comm_timer_get_mem(xfr->task_nextprobe->timer); 8693 1.4 christos 8694 1.4 christos /* auth_probe */ 8695 1.4 christos m += auth_primaries_get_mem(xfr->task_probe->masters); 8696 1.4 christos m += comm_point_get_mem(xfr->task_probe->cp); 8697 1.4 christos m += comm_timer_get_mem(xfr->task_probe->timer); 8698 1.4 christos 8699 1.4 christos /* auth_transfer */ 8700 1.4 christos m += auth_chunks_get_mem(xfr->task_transfer->chunks_first); 8701 1.4 christos m += auth_primaries_get_mem(xfr->task_transfer->masters); 8702 1.4 christos m += comm_point_get_mem(xfr->task_transfer->cp); 8703 1.4 christos m += comm_timer_get_mem(xfr->task_transfer->timer); 8704 1.4 christos 8705 1.4 christos /* allow_notify_list */ 8706 1.4 christos m += auth_primaries_get_mem(xfr->allow_notify_list); 8707 1.4 christos 8708 1.4 christos return m; 8709 1.4 christos } 8710 1.4 christos 8711 1.4 christos /** Get memory usage of auth zones ztree */ 8712 1.4 christos static size_t 8713 1.4 christos az_ztree_get_mem(struct auth_zones* az) 8714 1.4 christos { 8715 1.4 christos size_t m = 0; 8716 1.4 christos struct auth_zone* z; 8717 1.4 christos RBTREE_FOR(z, struct auth_zone*, &az->ztree) { 8718 1.4 christos lock_rw_rdlock(&z->lock); 8719 1.4 christos m += auth_zone_get_mem(z); 8720 1.4 christos lock_rw_unlock(&z->lock); 8721 1.4 christos } 8722 1.4 christos return m; 8723 1.4 christos } 8724 1.4 christos 8725 1.4 christos /** Get memory usage of auth zones xtree */ 8726 1.4 christos static size_t 8727 1.4 christos az_xtree_get_mem(struct auth_zones* az) 8728 1.4 christos { 8729 1.4 christos size_t m = 0; 8730 1.4 christos struct auth_xfer* xfr; 8731 1.4 christos RBTREE_FOR(xfr, struct auth_xfer*, &az->xtree) { 8732 1.4 christos lock_basic_lock(&xfr->lock); 8733 1.4 christos m += auth_xfer_get_mem(xfr); 8734 1.4 christos lock_basic_unlock(&xfr->lock); 8735 1.4 christos } 8736 1.4 christos return m; 8737 1.4 christos } 8738 1.4 christos 8739 1.4 christos size_t auth_zones_get_mem(struct auth_zones* zones) 8740 1.4 christos { 8741 1.4 christos size_t m; 8742 1.4 christos if(!zones) return 0; 8743 1.4 christos m = sizeof(*zones); 8744 1.4 christos lock_rw_rdlock(&zones->rpz_lock); 8745 1.4 christos lock_rw_rdlock(&zones->lock); 8746 1.4 christos m += az_ztree_get_mem(zones); 8747 1.4 christos m += az_xtree_get_mem(zones); 8748 1.4 christos lock_rw_unlock(&zones->lock); 8749 1.4 christos lock_rw_unlock(&zones->rpz_lock); 8750 1.4 christos return m; 8751 1.4 christos } 8752 1.4 christos 8753 1.4 christos void xfr_disown_tasks(struct auth_xfer* xfr, struct worker* worker) 8754 1.4 christos { 8755 1.4 christos if(xfr->task_nextprobe->worker == worker) { 8756 1.4 christos xfr_nextprobe_disown(xfr); 8757 1.4 christos } 8758 1.4 christos if(xfr->task_probe->worker == worker) { 8759 1.4 christos xfr_probe_disown(xfr); 8760 1.4 christos } 8761 1.4 christos if(xfr->task_transfer->worker == worker) { 8762 1.4 christos xfr_transfer_disown(xfr); 8763 1.4 christos } 8764 1.4 christos } 8765