1 /* 2 * respip/respip.c - filtering response IP module 3 */ 4 5 /** 6 * \file 7 * 8 * This file contains a module that inspects a result of recursive resolution 9 * to see if any IP address record should trigger a special action. 10 * If applicable these actions can modify the original response. 11 */ 12 #include "config.h" 13 14 #include "services/localzone.h" 15 #include "services/cache/dns.h" 16 #include "sldns/str2wire.h" 17 #include "util/config_file.h" 18 #include "util/fptr_wlist.h" 19 #include "util/module.h" 20 #include "util/net_help.h" 21 #include "util/regional.h" 22 #include "util/data/msgreply.h" 23 #include "util/storage/dnstree.h" 24 #include "respip/respip.h" 25 #include "services/view.h" 26 #include "sldns/rrdef.h" 27 28 /** 29 * Conceptual set of IP addresses for response AAAA or A records that should 30 * trigger special actions. 31 */ 32 struct respip_set { 33 struct regional* region; 34 struct rbtree_type ip_tree; 35 char* const* tagname; /* shallow copy of tag names, for logging */ 36 int num_tags; /* number of tagname entries */ 37 }; 38 39 /** An address span with response control information */ 40 struct resp_addr { 41 /** node in address tree */ 42 struct addr_tree_node node; 43 /** tag bitlist */ 44 uint8_t* taglist; 45 /** length of the taglist (in bytes) */ 46 size_t taglen; 47 /** action for this address span */ 48 enum respip_action action; 49 /** "local data" for this node */ 50 struct ub_packed_rrset_key* data; 51 }; 52 53 /** Subset of resp_addr.node, used for inform-variant logging */ 54 struct respip_addr_info { 55 struct sockaddr_storage addr; 56 socklen_t addrlen; 57 int net; 58 }; 59 60 /** Query state regarding the response-ip module. */ 61 enum respip_state { 62 /** 63 * The general state. Unless CNAME chasing takes place, all processing 64 * is completed in this state without any other asynchronous event. 65 */ 66 RESPIP_INIT = 0, 67 68 /** 69 * A subquery for CNAME chasing is completed. 70 */ 71 RESPIP_SUBQUERY_FINISHED 72 }; 73 74 /** Per query state for the response-ip module. */ 75 struct respip_qstate { 76 enum respip_state state; 77 }; 78 79 struct respip_set* 80 respip_set_create(void) 81 { 82 struct respip_set* set = calloc(1, sizeof(*set)); 83 if(!set) 84 return NULL; 85 set->region = regional_create(); 86 if(!set->region) { 87 free(set); 88 return NULL; 89 } 90 addr_tree_init(&set->ip_tree); 91 return set; 92 } 93 94 void 95 respip_set_delete(struct respip_set* set) 96 { 97 if(!set) 98 return; 99 regional_destroy(set->region); 100 free(set); 101 } 102 103 struct rbtree_type* 104 respip_set_get_tree(struct respip_set* set) 105 { 106 if(!set) 107 return NULL; 108 return &set->ip_tree; 109 } 110 111 /** returns the node in the address tree for the specified netblock string; 112 * non-existent node will be created if 'create' is true */ 113 static struct resp_addr* 114 respip_find_or_create(struct respip_set* set, const char* ipstr, int create) 115 { 116 struct resp_addr* node; 117 struct sockaddr_storage addr; 118 int net; 119 socklen_t addrlen; 120 121 if(!netblockstrtoaddr(ipstr, 0, &addr, &addrlen, &net)) { 122 log_err("cannot parse netblock: '%s'", ipstr); 123 return NULL; 124 } 125 node = (struct resp_addr*)addr_tree_find(&set->ip_tree, &addr, addrlen, net); 126 if(!node && create) { 127 node = regional_alloc_zero(set->region, sizeof(*node)); 128 if(!node) { 129 log_err("out of memory"); 130 return NULL; 131 } 132 node->action = respip_none; 133 if(!addr_tree_insert(&set->ip_tree, &node->node, &addr, 134 addrlen, net)) { 135 /* We know we didn't find it, so this should be 136 * impossible. */ 137 log_warn("unexpected: duplicate address: %s", ipstr); 138 } 139 } 140 return node; 141 } 142 143 static int 144 respip_tag_cfg(struct respip_set* set, const char* ipstr, 145 const uint8_t* taglist, size_t taglen) 146 { 147 struct resp_addr* node; 148 149 if(!(node=respip_find_or_create(set, ipstr, 1))) 150 return 0; 151 if(node->taglist) { 152 log_warn("duplicate response-address-tag for '%s', overridden.", 153 ipstr); 154 } 155 node->taglist = regional_alloc_init(set->region, taglist, taglen); 156 if(!node->taglist) { 157 log_err("out of memory"); 158 return 0; 159 } 160 node->taglen = taglen; 161 return 1; 162 } 163 164 /** set action for the node specified by the netblock string */ 165 static int 166 respip_action_cfg(struct respip_set* set, const char* ipstr, 167 const char* actnstr) 168 { 169 struct resp_addr* node; 170 enum respip_action action; 171 172 if(!(node=respip_find_or_create(set, ipstr, 1))) 173 return 0; 174 if(node->action != respip_none) { 175 verbose(VERB_QUERY, "duplicate response-ip action for '%s', overridden.", 176 ipstr); 177 } 178 if(strcmp(actnstr, "deny") == 0) 179 action = respip_deny; 180 else if(strcmp(actnstr, "redirect") == 0) 181 action = respip_redirect; 182 else if(strcmp(actnstr, "inform") == 0) 183 action = respip_inform; 184 else if(strcmp(actnstr, "inform_deny") == 0) 185 action = respip_inform_deny; 186 else if(strcmp(actnstr, "always_transparent") == 0) 187 action = respip_always_transparent; 188 else if(strcmp(actnstr, "always_refuse") == 0) 189 action = respip_always_refuse; 190 else if(strcmp(actnstr, "always_nxdomain") == 0) 191 action = respip_always_nxdomain; 192 else { 193 log_err("unknown response-ip action %s", actnstr); 194 return 0; 195 } 196 node->action = action; 197 return 1; 198 } 199 200 /** allocate and initialize an rrset structure; this function is based 201 * on new_local_rrset() from the localzone.c module */ 202 static struct ub_packed_rrset_key* 203 new_rrset(struct regional* region, uint16_t rrtype, uint16_t rrclass) 204 { 205 struct packed_rrset_data* pd; 206 struct ub_packed_rrset_key* rrset = regional_alloc_zero( 207 region, sizeof(*rrset)); 208 if(!rrset) { 209 log_err("out of memory"); 210 return NULL; 211 } 212 rrset->entry.key = rrset; 213 pd = regional_alloc_zero(region, sizeof(*pd)); 214 if(!pd) { 215 log_err("out of memory"); 216 return NULL; 217 } 218 pd->trust = rrset_trust_prim_noglue; 219 pd->security = sec_status_insecure; 220 rrset->entry.data = pd; 221 rrset->rk.dname = regional_alloc_zero(region, 1); 222 if(!rrset->rk.dname) { 223 log_err("out of memory"); 224 return NULL; 225 } 226 rrset->rk.dname_len = 1; 227 rrset->rk.type = htons(rrtype); 228 rrset->rk.rrset_class = htons(rrclass); 229 return rrset; 230 } 231 232 /** enter local data as resource records into a response-ip node */ 233 static int 234 respip_enter_rr(struct regional* region, struct resp_addr* raddr, 235 const char* rrstr, const char* netblock) 236 { 237 uint8_t* nm; 238 uint16_t rrtype = 0, rrclass = 0; 239 time_t ttl = 0; 240 uint8_t rr[LDNS_RR_BUF_SIZE]; 241 uint8_t* rdata = NULL; 242 size_t rdata_len = 0; 243 char buf[65536]; 244 char bufshort[64]; 245 struct packed_rrset_data* pd; 246 struct sockaddr* sa; 247 int ret; 248 if(raddr->action != respip_redirect) { 249 log_err("cannot parse response-ip-data %s: response-ip " 250 "action for %s is not redirect", rrstr, netblock); 251 return 0; 252 } 253 ret = snprintf(buf, sizeof(buf), ". %s", rrstr); 254 if(ret < 0 || ret >= (int)sizeof(buf)) { 255 strlcpy(bufshort, rrstr, sizeof(bufshort)); 256 log_err("bad response-ip-data: %s...", bufshort); 257 return 0; 258 } 259 if(!rrstr_get_rr_content(buf, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr), 260 &rdata, &rdata_len)) { 261 log_err("bad response-ip-data: %s", rrstr); 262 return 0; 263 } 264 free(nm); 265 sa = (struct sockaddr*)&raddr->node.addr; 266 if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) { 267 log_err("CNAME response-ip data (%s) can not co-exist with other " 268 "response-ip data for netblock %s", rrstr, netblock); 269 return 0; 270 } else if (raddr->data && 271 raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) { 272 log_err("response-ip data (%s) can not be added; CNAME response-ip " 273 "data already in place for netblock %s", rrstr, netblock); 274 return 0; 275 } else if((rrtype != LDNS_RR_TYPE_CNAME) && 276 ((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) || 277 (sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) { 278 log_err("response-ip data %s record type does not correspond " 279 "to netblock %s address family", rrstr, netblock); 280 return 0; 281 } 282 283 if(!raddr->data) { 284 raddr->data = new_rrset(region, rrtype, rrclass); 285 if(!raddr->data) 286 return 0; 287 } 288 pd = raddr->data->entry.data; 289 return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr); 290 } 291 292 static int 293 respip_data_cfg(struct respip_set* set, const char* ipstr, const char* rrstr) 294 { 295 struct resp_addr* node; 296 297 node=respip_find_or_create(set, ipstr, 0); 298 if(!node || node->action == respip_none) { 299 log_err("cannot parse response-ip-data %s: " 300 "response-ip node for %s not found", rrstr, ipstr); 301 return 0; 302 } 303 return respip_enter_rr(set->region, node, rrstr, ipstr); 304 } 305 306 static int 307 respip_set_apply_cfg(struct respip_set* set, char* const* tagname, int num_tags, 308 struct config_strbytelist* respip_tags, 309 struct config_str2list* respip_actions, 310 struct config_str2list* respip_data) 311 { 312 struct config_strbytelist* p; 313 struct config_str2list* pa; 314 struct config_str2list* pd; 315 316 set->tagname = tagname; 317 set->num_tags = num_tags; 318 319 p = respip_tags; 320 while(p) { 321 struct config_strbytelist* np = p->next; 322 323 log_assert(p->str && p->str2); 324 if(!respip_tag_cfg(set, p->str, p->str2, p->str2len)) { 325 config_del_strbytelist(p); 326 return 0; 327 } 328 free(p->str); 329 free(p->str2); 330 free(p); 331 p = np; 332 } 333 334 pa = respip_actions; 335 while(pa) { 336 struct config_str2list* np = pa->next; 337 log_assert(pa->str && pa->str2); 338 if(!respip_action_cfg(set, pa->str, pa->str2)) { 339 config_deldblstrlist(pa); 340 return 0; 341 } 342 free(pa->str); 343 free(pa->str2); 344 free(pa); 345 pa = np; 346 } 347 348 pd = respip_data; 349 while(pd) { 350 struct config_str2list* np = pd->next; 351 log_assert(pd->str && pd->str2); 352 if(!respip_data_cfg(set, pd->str, pd->str2)) { 353 config_deldblstrlist(pd); 354 return 0; 355 } 356 free(pd->str); 357 free(pd->str2); 358 free(pd); 359 pd = np; 360 } 361 362 return 1; 363 } 364 365 int 366 respip_global_apply_cfg(struct respip_set* set, struct config_file* cfg) 367 { 368 int ret = respip_set_apply_cfg(set, cfg->tagname, cfg->num_tags, 369 cfg->respip_tags, cfg->respip_actions, cfg->respip_data); 370 cfg->respip_data = NULL; 371 cfg->respip_actions = NULL; 372 cfg->respip_tags = NULL; 373 return ret; 374 } 375 376 /** Iterate through raw view data and apply the view-specific respip 377 * configuration; at this point we should have already seen all the views, 378 * so if any of the views that respip data refer to does not exist, that's 379 * an error. This additional iteration through view configuration data 380 * is expected to not have significant performance impact (or rather, its 381 * performance impact is not expected to be prohibitive in the configuration 382 * processing phase). 383 */ 384 int 385 respip_views_apply_cfg(struct views* vs, struct config_file* cfg, 386 int* have_view_respip_cfg) 387 { 388 struct config_view* cv; 389 struct view* v; 390 int ret; 391 392 for(cv = cfg->views; cv; cv = cv->next) { 393 394 /** if no respip config for this view then there's 395 * nothing to do; note that even though respip data must go 396 * with respip action, we're checking for both here because 397 * we want to catch the case where the respip action is missing 398 * while the data is present */ 399 if(!cv->respip_actions && !cv->respip_data) 400 continue; 401 402 if(!(v = views_find_view(vs, cv->name, 1))) { 403 log_err("view '%s' unexpectedly missing", cv->name); 404 return 0; 405 } 406 if(!v->respip_set) { 407 v->respip_set = respip_set_create(); 408 if(!v->respip_set) { 409 log_err("out of memory"); 410 lock_rw_unlock(&v->lock); 411 return 0; 412 } 413 } 414 ret = respip_set_apply_cfg(v->respip_set, NULL, 0, NULL, 415 cv->respip_actions, cv->respip_data); 416 lock_rw_unlock(&v->lock); 417 if(!ret) { 418 log_err("Error while applying respip configuration " 419 "for view '%s'", cv->name); 420 return 0; 421 } 422 *have_view_respip_cfg = (*have_view_respip_cfg || 423 v->respip_set->ip_tree.count); 424 cv->respip_actions = NULL; 425 cv->respip_data = NULL; 426 } 427 return 1; 428 } 429 430 /** 431 * make a deep copy of 'key' in 'region'. 432 * This is largely derived from packed_rrset_copy_region() and 433 * packed_rrset_ptr_fixup(), but differs in the following points: 434 * 435 * - It doesn't assume all data in 'key' are in a contiguous memory region. 436 * Although that would be the case in most cases, 'key' can be passed from 437 * a lower-level module and it might not build the rrset to meet the 438 * assumption. In fact, an rrset specified as response-ip-data or generated 439 * in local_data_find_tag_datas() breaks the assumption. So it would be 440 * safer not to naively rely on the assumption. On the other hand, this 441 * function ensures the copied rrset data are in a contiguous region so 442 * that it won't cause a disruption even if an upper layer module naively 443 * assumes the memory layout. 444 * - It doesn't copy RRSIGs (if any) in 'key'. The rrset will be used in 445 * a reply that was already faked, so it doesn't make much sense to provide 446 * partial sigs even if they are valid themselves. 447 * - It doesn't adjust TTLs as it basically has to be a verbatim copy of 'key' 448 * just allocated in 'region' (the assumption is necessary TTL adjustment 449 * has been already done in 'key'). 450 * 451 * This function returns the copied rrset key on success, and NULL on memory 452 * allocation failure. 453 */ 454 static struct ub_packed_rrset_key* 455 copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region) 456 { 457 struct ub_packed_rrset_key* ck = regional_alloc(region, 458 sizeof(struct ub_packed_rrset_key)); 459 struct packed_rrset_data* d; 460 struct packed_rrset_data* data = key->entry.data; 461 size_t dsize, i; 462 uint8_t* nextrdata; 463 464 /* derived from packed_rrset_copy_region(), but don't use 465 * packed_rrset_sizeof() and do exclude RRSIGs */ 466 if(!ck) 467 return NULL; 468 ck->id = key->id; 469 memset(&ck->entry, 0, sizeof(ck->entry)); 470 ck->entry.hash = key->entry.hash; 471 ck->entry.key = ck; 472 ck->rk = key->rk; 473 ck->rk.dname = regional_alloc_init(region, key->rk.dname, 474 key->rk.dname_len); 475 if(!ck->rk.dname) 476 return NULL; 477 478 dsize = sizeof(struct packed_rrset_data) + data->count * 479 (sizeof(size_t)+sizeof(uint8_t*)+sizeof(time_t)); 480 for(i=0; i<data->count; i++) 481 dsize += data->rr_len[i]; 482 d = regional_alloc(region, dsize); 483 if(!d) 484 return NULL; 485 *d = *data; 486 d->rrsig_count = 0; 487 ck->entry.data = d; 488 489 /* derived from packed_rrset_ptr_fixup() with copying the data */ 490 d->rr_len = (size_t*)((uint8_t*)d + sizeof(struct packed_rrset_data)); 491 d->rr_data = (uint8_t**)&(d->rr_len[d->count]); 492 d->rr_ttl = (time_t*)&(d->rr_data[d->count]); 493 nextrdata = (uint8_t*)&(d->rr_ttl[d->count]); 494 for(i=0; i<d->count; i++) { 495 d->rr_len[i] = data->rr_len[i]; 496 d->rr_ttl[i] = data->rr_ttl[i]; 497 d->rr_data[i] = nextrdata; 498 memcpy(d->rr_data[i], data->rr_data[i], data->rr_len[i]); 499 nextrdata += d->rr_len[i]; 500 } 501 502 return ck; 503 } 504 505 int 506 respip_init(struct module_env* env, int id) 507 { 508 (void)env; 509 (void)id; 510 return 1; 511 } 512 513 void 514 respip_deinit(struct module_env* env, int id) 515 { 516 (void)env; 517 (void)id; 518 } 519 520 /** Convert a packed AAAA or A RRset to sockaddr. */ 521 static int 522 rdata2sockaddr(const struct packed_rrset_data* rd, uint16_t rtype, size_t i, 523 struct sockaddr_storage* ss, socklen_t* addrlenp) 524 { 525 /* unbound can accept and cache odd-length AAAA/A records, so we have 526 * to validate the length. */ 527 if(rtype == LDNS_RR_TYPE_A && rd->rr_len[i] == 6) { 528 struct sockaddr_in* sa4 = (struct sockaddr_in*)ss; 529 530 memset(sa4, 0, sizeof(*sa4)); 531 sa4->sin_family = AF_INET; 532 memcpy(&sa4->sin_addr, rd->rr_data[i] + 2, 533 sizeof(sa4->sin_addr)); 534 *addrlenp = sizeof(*sa4); 535 return 1; 536 } else if(rtype == LDNS_RR_TYPE_AAAA && rd->rr_len[i] == 18) { 537 struct sockaddr_in6* sa6 = (struct sockaddr_in6*)ss; 538 539 memset(sa6, 0, sizeof(*sa6)); 540 sa6->sin6_family = AF_INET6; 541 memcpy(&sa6->sin6_addr, rd->rr_data[i] + 2, 542 sizeof(sa6->sin6_addr)); 543 *addrlenp = sizeof(*sa6); 544 return 1; 545 } 546 return 0; 547 } 548 549 /** 550 * Search the given 'iptree' for response address information that matches 551 * any of the IP addresses in an AAAA or A in the answer section of the 552 * response (stored in 'rep'). If found, a pointer to the matched resp_addr 553 * structure will be returned, and '*rrset_id' is set to the index in 554 * rep->rrsets for the RRset that contains the matching IP address record 555 * (the index is normally 0, but can be larger than that if this is a CNAME 556 * chain or type-ANY response). 557 */ 558 static const struct resp_addr* 559 respip_addr_lookup(const struct reply_info *rep, struct rbtree_type* iptree, 560 size_t* rrset_id) 561 { 562 size_t i; 563 struct resp_addr* ra; 564 struct sockaddr_storage ss; 565 socklen_t addrlen; 566 567 for(i=0; i<rep->an_numrrsets; i++) { 568 size_t j; 569 const struct packed_rrset_data* rd; 570 uint16_t rtype = ntohs(rep->rrsets[i]->rk.type); 571 572 if(rtype != LDNS_RR_TYPE_A && rtype != LDNS_RR_TYPE_AAAA) 573 continue; 574 rd = rep->rrsets[i]->entry.data; 575 for(j = 0; j < rd->count; j++) { 576 if(!rdata2sockaddr(rd, rtype, j, &ss, &addrlen)) 577 continue; 578 ra = (struct resp_addr*)addr_tree_lookup(iptree, &ss, 579 addrlen); 580 if(ra) { 581 *rrset_id = i; 582 return ra; 583 } 584 } 585 } 586 587 return NULL; 588 } 589 590 /* 591 * Create a new reply_info based on 'rep'. The new info is based on 592 * the passed 'rep', but ignores any rrsets except for the first 'an_numrrsets' 593 * RRsets in the answer section. These answer rrsets are copied to the 594 * new info, up to 'copy_rrsets' rrsets (which must not be larger than 595 * 'an_numrrsets'). If an_numrrsets > copy_rrsets, the remaining rrsets array 596 * entries will be kept empty so the caller can fill them later. When rrsets 597 * are copied, they are shallow copied. The caller must ensure that the 598 * copied rrsets are valid throughout its lifetime and must provide appropriate 599 * mutex if it can be shared by multiple threads. 600 */ 601 static struct reply_info * 602 make_new_reply_info(const struct reply_info* rep, struct regional* region, 603 size_t an_numrrsets, size_t copy_rrsets) 604 { 605 struct reply_info* new_rep; 606 size_t i; 607 608 /* create a base struct. we specify 'insecure' security status as 609 * the modified response won't be DNSSEC-valid. In our faked response 610 * the authority and additional sections will be empty (except possible 611 * EDNS0 OPT RR in the additional section appended on sending it out), 612 * so the total number of RRsets is an_numrrsets. */ 613 new_rep = construct_reply_info_base(region, rep->flags, 614 rep->qdcount, rep->ttl, rep->prefetch_ttl, 615 rep->serve_expired_ttl, an_numrrsets, 0, 0, an_numrrsets, 616 sec_status_insecure); 617 if(!new_rep) 618 return NULL; 619 if(!reply_info_alloc_rrset_keys(new_rep, NULL, region)) 620 return NULL; 621 for(i=0; i<copy_rrsets; i++) 622 new_rep->rrsets[i] = rep->rrsets[i]; 623 624 return new_rep; 625 } 626 627 /** 628 * See if response-ip or tag data should override the original answer rrset 629 * (which is rep->rrsets[rrset_id]) and if so override it. 630 * This is (mostly) equivalent to localzone.c:local_data_answer() but for 631 * response-ip actions. 632 * Note that this function distinguishes error conditions from "success but 633 * not overridden". This is because we want to avoid accidentally applying 634 * the "no data" action in case of error. 635 * @param raddr: address span that requires an action 636 * @param action: action to apply 637 * @param qtype: original query type 638 * @param rep: original reply message 639 * @param rrset_id: the rrset ID in 'rep' to which the action should apply 640 * @param new_repp: see respip_rewrite_reply 641 * @param tag: if >= 0 the tag ID used to determine the action and data 642 * @param tag_datas: data corresponding to 'tag'. 643 * @param tag_datas_size: size of 'tag_datas' 644 * @param tagname: array of tag names, used for logging 645 * @param num_tags: size of 'tagname', used for logging 646 * @param redirect_rrsetp: ptr to redirect record 647 * @param region: region for building new reply 648 * @return 1 if overridden, 0 if not overridden, -1 on error. 649 */ 650 static int 651 respip_data_answer(const struct resp_addr* raddr, enum respip_action action, 652 uint16_t qtype, const struct reply_info* rep, 653 size_t rrset_id, struct reply_info** new_repp, int tag, 654 struct config_strlist** tag_datas, size_t tag_datas_size, 655 char* const* tagname, int num_tags, 656 struct ub_packed_rrset_key** redirect_rrsetp, struct regional* region) 657 { 658 struct ub_packed_rrset_key* rp = raddr->data; 659 struct reply_info* new_rep; 660 *redirect_rrsetp = NULL; 661 662 if(action == respip_redirect && tag != -1 && 663 (size_t)tag<tag_datas_size && tag_datas[tag]) { 664 struct query_info dataqinfo; 665 struct ub_packed_rrset_key r; 666 667 /* Extract parameters of the original answer rrset that can be 668 * rewritten below, in the form of query_info. Note that these 669 * can be different from the info of the original query if the 670 * rrset is a CNAME target.*/ 671 memset(&dataqinfo, 0, sizeof(dataqinfo)); 672 dataqinfo.qname = rep->rrsets[rrset_id]->rk.dname; 673 dataqinfo.qname_len = rep->rrsets[rrset_id]->rk.dname_len; 674 dataqinfo.qtype = ntohs(rep->rrsets[rrset_id]->rk.type); 675 dataqinfo.qclass = ntohs(rep->rrsets[rrset_id]->rk.rrset_class); 676 677 memset(&r, 0, sizeof(r)); 678 if(local_data_find_tag_datas(&dataqinfo, tag_datas[tag], &r, 679 region)) { 680 verbose(VERB_ALGO, 681 "response-ip redirect with tag data [%d] %s", 682 tag, (tag<num_tags?tagname[tag]:"null")); 683 /* use copy_rrset() to 'normalize' memory layout */ 684 rp = copy_rrset(&r, region); 685 if(!rp) 686 return -1; 687 } 688 } 689 if(!rp) 690 return 0; 691 692 /* If we are using response-ip-data, we need to make a copy of rrset 693 * to replace the rrset's dname. Note that, unlike local data, we 694 * rename the dname for other actions than redirect. This is because 695 * response-ip-data isn't associated to any specific name. */ 696 if(rp == raddr->data) { 697 rp = copy_rrset(rp, region); 698 if(!rp) 699 return -1; 700 rp->rk.dname = rep->rrsets[rrset_id]->rk.dname; 701 rp->rk.dname_len = rep->rrsets[rrset_id]->rk.dname_len; 702 } 703 704 /* Build a new reply with redirect rrset. We keep any preceding CNAMEs 705 * and replace the address rrset that triggers the action. If it's 706 * type ANY query, however, no other answer records should be kept 707 * (note that it can't be a CNAME chain in this case due to 708 * sanitizing). */ 709 if(qtype == LDNS_RR_TYPE_ANY) 710 rrset_id = 0; 711 new_rep = make_new_reply_info(rep, region, rrset_id + 1, rrset_id); 712 if(!new_rep) 713 return -1; 714 rp->rk.flags |= PACKED_RRSET_FIXEDTTL; /* avoid adjusting TTL */ 715 new_rep->rrsets[rrset_id] = rp; 716 717 *redirect_rrsetp = rp; 718 *new_repp = new_rep; 719 return 1; 720 } 721 722 /** 723 * apply response ip action in case where no action data is provided. 724 * this is similar to localzone.c:lz_zone_answer() but simplified due to 725 * the characteristics of response ip: 726 * - 'deny' variants will be handled at the caller side 727 * - no specific processing for 'transparent' variants: unlike local zones, 728 * there is no such a case of 'no data but name existing'. so all variants 729 * just mean 'transparent if no data'. 730 * @param qtype: query type 731 * @param action: found action 732 * @param rep: 733 * @param new_repp 734 * @param rrset_id 735 * @param region: region for building new reply 736 * @return 1 on success, 0 on error. 737 */ 738 static int 739 respip_nodata_answer(uint16_t qtype, enum respip_action action, 740 const struct reply_info *rep, size_t rrset_id, 741 struct reply_info** new_repp, struct regional* region) 742 { 743 struct reply_info* new_rep; 744 745 if(action == respip_refuse || action == respip_always_refuse) { 746 new_rep = make_new_reply_info(rep, region, 0, 0); 747 if(!new_rep) 748 return 0; 749 FLAGS_SET_RCODE(new_rep->flags, LDNS_RCODE_REFUSED); 750 *new_repp = new_rep; 751 return 1; 752 } else if(action == respip_static || action == respip_redirect || 753 action == respip_always_nxdomain) { 754 /* Since we don't know about other types of the owner name, 755 * we generally return NOERROR/NODATA unless an NXDOMAIN action 756 * is explicitly specified. */ 757 int rcode = (action == respip_always_nxdomain)? 758 LDNS_RCODE_NXDOMAIN:LDNS_RCODE_NOERROR; 759 760 /* We should empty the answer section except for any preceding 761 * CNAMEs (in that case rrset_id > 0). Type-ANY case is 762 * special as noted in respip_data_answer(). */ 763 if(qtype == LDNS_RR_TYPE_ANY) 764 rrset_id = 0; 765 new_rep = make_new_reply_info(rep, region, rrset_id, rrset_id); 766 if(!new_rep) 767 return 0; 768 FLAGS_SET_RCODE(new_rep->flags, rcode); 769 *new_repp = new_rep; 770 return 1; 771 } 772 773 return 1; 774 } 775 776 /** Populate action info structure with the results of response-ip action 777 * processing, iff as the result of response-ip processing we are actually 778 * taking some action. Only action is set if action_only is true. 779 * Returns true on success, false on failure. 780 */ 781 static int 782 populate_action_info(struct respip_action_info* actinfo, 783 enum respip_action action, const struct resp_addr* raddr, 784 const struct ub_packed_rrset_key* ATTR_UNUSED(rrset), 785 int ATTR_UNUSED(tag), const struct respip_set* ATTR_UNUSED(ipset), 786 int ATTR_UNUSED(action_only), struct regional* region) 787 { 788 if(action == respip_none || !raddr) 789 return 1; 790 actinfo->action = action; 791 792 /* for inform variants, make a copy of the matched address block for 793 * later logging. We make a copy to proactively avoid disruption if 794 * and when we allow a dynamic update to the respip tree. */ 795 if(action == respip_inform || action == respip_inform_deny) { 796 struct respip_addr_info* a = 797 regional_alloc_zero(region, sizeof(*a)); 798 if(!a) { 799 log_err("out of memory"); 800 return 0; 801 } 802 a->addr = raddr->node.addr; 803 a->addrlen = raddr->node.addrlen; 804 a->net = raddr->node.net; 805 actinfo->addrinfo = a; 806 } 807 808 return 1; 809 } 810 811 int 812 respip_rewrite_reply(const struct query_info* qinfo, 813 const struct respip_client_info* cinfo, const struct reply_info* rep, 814 struct reply_info** new_repp, struct respip_action_info* actinfo, 815 struct ub_packed_rrset_key** alias_rrset, int search_only, 816 struct regional* region) 817 { 818 const uint8_t* ctaglist; 819 size_t ctaglen; 820 const uint8_t* tag_actions; 821 size_t tag_actions_size; 822 struct config_strlist** tag_datas; 823 size_t tag_datas_size; 824 struct view* view = NULL; 825 struct respip_set* ipset = NULL; 826 size_t rrset_id = 0; 827 enum respip_action action = respip_none; 828 int tag = -1; 829 const struct resp_addr* raddr = NULL; 830 int ret = 1; 831 struct ub_packed_rrset_key* redirect_rrset = NULL; 832 833 if(!cinfo) 834 goto done; 835 ctaglist = cinfo->taglist; 836 ctaglen = cinfo->taglen; 837 tag_actions = cinfo->tag_actions; 838 tag_actions_size = cinfo->tag_actions_size; 839 tag_datas = cinfo->tag_datas; 840 tag_datas_size = cinfo->tag_datas_size; 841 view = cinfo->view; 842 ipset = cinfo->respip_set; 843 844 /** Try to use response-ip config from the view first; use 845 * global response-ip config if we don't have the view or we don't 846 * have the matching per-view config (and the view allows the use 847 * of global data in this case). 848 * Note that we lock the view even if we only use view members that 849 * currently don't change after creation. This is for safety for 850 * future possible changes as the view documentation seems to expect 851 * any of its member can change in the view's lifetime. 852 * Note also that we assume 'view' is valid in this function, which 853 * should be safe (see unbound bug #1191) */ 854 if(view) { 855 lock_rw_rdlock(&view->lock); 856 if(view->respip_set) { 857 if((raddr = respip_addr_lookup(rep, 858 &view->respip_set->ip_tree, &rrset_id))) { 859 /** for per-view respip directives the action 860 * can only be direct (i.e. not tag-based) */ 861 action = raddr->action; 862 } 863 } 864 if(!raddr && !view->isfirst) 865 goto done; 866 } 867 if(!raddr && ipset && (raddr = respip_addr_lookup(rep, &ipset->ip_tree, 868 &rrset_id))) { 869 action = (enum respip_action)local_data_find_tag_action( 870 raddr->taglist, raddr->taglen, ctaglist, ctaglen, 871 tag_actions, tag_actions_size, 872 (enum localzone_type)raddr->action, &tag, 873 ipset->tagname, ipset->num_tags); 874 } 875 if(raddr && !search_only) { 876 int result = 0; 877 878 /* first, see if we have response-ip or tag action for the 879 * action except for 'always' variants. */ 880 if(action != respip_always_refuse 881 && action != respip_always_transparent 882 && action != respip_always_nxdomain 883 && (result = respip_data_answer(raddr, action, 884 qinfo->qtype, rep, rrset_id, new_repp, tag, tag_datas, 885 tag_datas_size, ipset->tagname, ipset->num_tags, 886 &redirect_rrset, region)) < 0) { 887 ret = 0; 888 goto done; 889 } 890 891 /* if no action data applied, take action specific to the 892 * action without data. */ 893 if(!result && !respip_nodata_answer(qinfo->qtype, action, rep, 894 rrset_id, new_repp, region)) { 895 ret = 0; 896 goto done; 897 } 898 } 899 done: 900 if(view) { 901 lock_rw_unlock(&view->lock); 902 } 903 if(ret) { 904 /* If we're redirecting the original answer to a 905 * CNAME, record the CNAME rrset so the caller can take 906 * the appropriate action. Note that we don't check the 907 * action type; it should normally be 'redirect', but it 908 * can be of other type when a data-dependent tag action 909 * uses redirect response-ip data. 910 */ 911 if(redirect_rrset && 912 redirect_rrset->rk.type == ntohs(LDNS_RR_TYPE_CNAME) && 913 qinfo->qtype != LDNS_RR_TYPE_ANY) 914 *alias_rrset = redirect_rrset; 915 /* on success, populate respip result structure */ 916 ret = populate_action_info(actinfo, action, raddr, 917 redirect_rrset, tag, ipset, search_only, region); 918 } 919 return ret; 920 } 921 922 static int 923 generate_cname_request(struct module_qstate* qstate, 924 struct ub_packed_rrset_key* alias_rrset) 925 { 926 struct module_qstate* subq = NULL; 927 struct query_info subqi; 928 929 memset(&subqi, 0, sizeof(subqi)); 930 get_cname_target(alias_rrset, &subqi.qname, &subqi.qname_len); 931 if(!subqi.qname) 932 return 0; /* unexpected: not a valid CNAME RDATA */ 933 subqi.qtype = qstate->qinfo.qtype; 934 subqi.qclass = qstate->qinfo.qclass; 935 fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); 936 return (*qstate->env->attach_sub)(qstate, &subqi, BIT_RD, 0, 0, &subq); 937 } 938 939 void 940 respip_operate(struct module_qstate* qstate, enum module_ev event, int id, 941 struct outbound_entry* outbound) 942 { 943 struct respip_qstate* rq = (struct respip_qstate*)qstate->minfo[id]; 944 945 log_query_info(VERB_QUERY, "respip operate: query", &qstate->qinfo); 946 (void)outbound; 947 948 if(event == module_event_new || event == module_event_pass) { 949 if(!rq) { 950 rq = regional_alloc_zero(qstate->region, sizeof(*rq)); 951 if(!rq) 952 goto servfail; 953 rq->state = RESPIP_INIT; 954 qstate->minfo[id] = rq; 955 } 956 if(rq->state == RESPIP_SUBQUERY_FINISHED) { 957 qstate->ext_state[id] = module_finished; 958 return; 959 } 960 verbose(VERB_ALGO, "respip: pass to next module"); 961 qstate->ext_state[id] = module_wait_module; 962 } else if(event == module_event_moddone) { 963 /* If the reply may be subject to response-ip rewriting 964 * according to the query type, check the actions. If a 965 * rewrite is necessary, we'll replace the reply in qstate 966 * with the new one. */ 967 enum module_ext_state next_state = module_finished; 968 969 if((qstate->qinfo.qtype == LDNS_RR_TYPE_A || 970 qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA || 971 qstate->qinfo.qtype == LDNS_RR_TYPE_ANY) && 972 qstate->return_msg && qstate->return_msg->rep) { 973 struct respip_action_info actinfo = {respip_none, NULL}; 974 struct reply_info* new_rep = qstate->return_msg->rep; 975 struct ub_packed_rrset_key* alias_rrset = NULL; 976 977 if(!respip_rewrite_reply(&qstate->qinfo, 978 qstate->client_info, qstate->return_msg->rep, 979 &new_rep, &actinfo, &alias_rrset, 0, 980 qstate->region)) { 981 goto servfail; 982 } 983 if(actinfo.action != respip_none) { 984 /* save action info for logging on a 985 * per-front-end-query basis */ 986 if(!(qstate->respip_action_info = 987 regional_alloc_init(qstate->region, 988 &actinfo, sizeof(actinfo)))) 989 { 990 log_err("out of memory"); 991 goto servfail; 992 } 993 } else { 994 qstate->respip_action_info = NULL; 995 } 996 if (new_rep == qstate->return_msg->rep && 997 (actinfo.action == respip_deny || 998 actinfo.action == respip_inform_deny)) { 999 /* for deny-variant actions (unless response-ip 1000 * data is applied), mark the query state so 1001 * the response will be dropped for all 1002 * clients. */ 1003 qstate->is_drop = 1; 1004 } else if(alias_rrset) { 1005 if(!generate_cname_request(qstate, alias_rrset)) 1006 goto servfail; 1007 next_state = module_wait_subquery; 1008 } 1009 qstate->return_msg->rep = new_rep; 1010 } 1011 qstate->ext_state[id] = next_state; 1012 } else 1013 qstate->ext_state[id] = module_finished; 1014 1015 return; 1016 1017 servfail: 1018 qstate->return_rcode = LDNS_RCODE_SERVFAIL; 1019 qstate->return_msg = NULL; 1020 } 1021 1022 int 1023 respip_merge_cname(struct reply_info* base_rep, 1024 const struct query_info* qinfo, const struct reply_info* tgt_rep, 1025 const struct respip_client_info* cinfo, int must_validate, 1026 struct reply_info** new_repp, struct regional* region) 1027 { 1028 struct reply_info* new_rep; 1029 struct reply_info* tmp_rep = NULL; /* just a placeholder */ 1030 struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */ 1031 uint16_t tgt_rcode; 1032 size_t i, j; 1033 struct respip_action_info actinfo = {respip_none, NULL}; 1034 1035 /* If the query for the CNAME target would result in an unusual rcode, 1036 * we generally translate it as a failure for the base query 1037 * (which would then be translated into SERVFAIL). The only exception 1038 * is NXDOMAIN and YXDOMAIN, which are passed to the end client(s). 1039 * The YXDOMAIN case would be rare but still possible (when 1040 * DNSSEC-validated DNAME has been cached but synthesizing CNAME 1041 * can't be generated due to length limitation) */ 1042 tgt_rcode = FLAGS_GET_RCODE(tgt_rep->flags); 1043 if((tgt_rcode != LDNS_RCODE_NOERROR && 1044 tgt_rcode != LDNS_RCODE_NXDOMAIN && 1045 tgt_rcode != LDNS_RCODE_YXDOMAIN) || 1046 (must_validate && tgt_rep->security <= sec_status_bogus)) { 1047 return 0; 1048 } 1049 1050 /* see if the target reply would be subject to a response-ip action. */ 1051 if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo, 1052 &alias_rrset, 1, region)) 1053 return 0; 1054 if(actinfo.action != respip_none) { 1055 log_info("CNAME target of redirect response-ip action would " 1056 "be subject to response-ip action, too; stripped"); 1057 *new_repp = base_rep; 1058 return 1; 1059 } 1060 1061 /* Append target reply to the base. Since we cannot assume 1062 * tgt_rep->rrsets is valid throughout the lifetime of new_rep 1063 * or it can be safely shared by multiple threads, we need to make a 1064 * deep copy. */ 1065 new_rep = make_new_reply_info(base_rep, region, 1066 base_rep->an_numrrsets + tgt_rep->an_numrrsets, 1067 base_rep->an_numrrsets); 1068 if(!new_rep) 1069 return 0; 1070 for(i=0,j=base_rep->an_numrrsets; i<tgt_rep->an_numrrsets; i++,j++) { 1071 new_rep->rrsets[j] = copy_rrset(tgt_rep->rrsets[i], region); 1072 if(!new_rep->rrsets[j]) 1073 return 0; 1074 } 1075 1076 FLAGS_SET_RCODE(new_rep->flags, tgt_rcode); 1077 *new_repp = new_rep; 1078 return 1; 1079 } 1080 1081 void 1082 respip_inform_super(struct module_qstate* qstate, int id, 1083 struct module_qstate* super) 1084 { 1085 struct respip_qstate* rq = (struct respip_qstate*)super->minfo[id]; 1086 struct reply_info* new_rep = NULL; 1087 1088 rq->state = RESPIP_SUBQUERY_FINISHED; 1089 1090 /* respip subquery should have always been created with a valid reply 1091 * in super. */ 1092 log_assert(super->return_msg && super->return_msg->rep); 1093 1094 /* return_msg can be NULL when, e.g., the sub query resulted in 1095 * SERVFAIL, in which case we regard it as a failure of the original 1096 * query. Other checks are probably redundant, but we check them 1097 * for safety. */ 1098 if(!qstate->return_msg || !qstate->return_msg->rep || 1099 qstate->return_rcode != LDNS_RCODE_NOERROR) 1100 goto fail; 1101 1102 if(!respip_merge_cname(super->return_msg->rep, &qstate->qinfo, 1103 qstate->return_msg->rep, super->client_info, 1104 super->env->need_to_validate, &new_rep, super->region)) 1105 goto fail; 1106 super->return_msg->rep = new_rep; 1107 return; 1108 1109 fail: 1110 super->return_rcode = LDNS_RCODE_SERVFAIL; 1111 super->return_msg = NULL; 1112 return; 1113 } 1114 1115 void 1116 respip_clear(struct module_qstate* qstate, int id) 1117 { 1118 qstate->minfo[id] = NULL; 1119 } 1120 1121 size_t 1122 respip_get_mem(struct module_env* env, int id) 1123 { 1124 (void)env; 1125 (void)id; 1126 return 0; 1127 } 1128 1129 /** 1130 * The response-ip function block 1131 */ 1132 static struct module_func_block respip_block = { 1133 "respip", 1134 &respip_init, &respip_deinit, &respip_operate, &respip_inform_super, 1135 &respip_clear, &respip_get_mem 1136 }; 1137 1138 struct module_func_block* 1139 respip_get_funcblock(void) 1140 { 1141 return &respip_block; 1142 } 1143 1144 enum respip_action 1145 resp_addr_get_action(const struct resp_addr* addr) 1146 { 1147 return addr ? addr->action : respip_none; 1148 } 1149 1150 struct ub_packed_rrset_key* 1151 resp_addr_get_rrset(struct resp_addr* addr) 1152 { 1153 return addr ? addr->data : NULL; 1154 } 1155 1156 int 1157 respip_set_is_empty(const struct respip_set* set) 1158 { 1159 return set ? set->ip_tree.count == 0 : 1; 1160 } 1161 1162 void 1163 respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname, 1164 uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias, 1165 struct comm_reply* repinfo) 1166 { 1167 char srcip[128], respip[128], txt[512]; 1168 unsigned port; 1169 1170 if(local_alias) 1171 qname = local_alias->rrset->rk.dname; 1172 port = (unsigned)((repinfo->addr.ss_family == AF_INET) ? 1173 ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port) : 1174 ntohs(((struct sockaddr_in6*)&repinfo->addr)->sin6_port)); 1175 addr_to_str(&repinfo->addr, repinfo->addrlen, srcip, sizeof(srcip)); 1176 addr_to_str(&respip_addr->addr, respip_addr->addrlen, 1177 respip, sizeof(respip)); 1178 snprintf(txt, sizeof(txt), "%s/%d inform %s@%u", respip, 1179 respip_addr->net, srcip, port); 1180 log_nametypeclass(0, txt, qname, qtype, qclass); 1181 } 1182