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 log_warn("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, an_numrrsets, 615 0, 0, an_numrrsets, sec_status_insecure); 616 if(!new_rep) 617 return NULL; 618 if(!reply_info_alloc_rrset_keys(new_rep, NULL, region)) 619 return NULL; 620 for(i=0; i<copy_rrsets; i++) 621 new_rep->rrsets[i] = rep->rrsets[i]; 622 623 return new_rep; 624 } 625 626 /** 627 * See if response-ip or tag data should override the original answer rrset 628 * (which is rep->rrsets[rrset_id]) and if so override it. 629 * This is (mostly) equivalent to localzone.c:local_data_answer() but for 630 * response-ip actions. 631 * Note that this function distinguishes error conditions from "success but 632 * not overridden". This is because we want to avoid accidentally applying 633 * the "no data" action in case of error. 634 * @param raddr: address span that requires an action 635 * @param action: action to apply 636 * @param qtype: original query type 637 * @param rep: original reply message 638 * @param rrset_id: the rrset ID in 'rep' to which the action should apply 639 * @param new_repp: see respip_rewrite_reply 640 * @param tag: if >= 0 the tag ID used to determine the action and data 641 * @param tag_datas: data corresponding to 'tag'. 642 * @param tag_datas_size: size of 'tag_datas' 643 * @param tagname: array of tag names, used for logging 644 * @param num_tags: size of 'tagname', used for logging 645 * @param redirect_rrsetp: ptr to redirect record 646 * @param region: region for building new reply 647 * @return 1 if overridden, 0 if not overridden, -1 on error. 648 */ 649 static int 650 respip_data_answer(const struct resp_addr* raddr, enum respip_action action, 651 uint16_t qtype, const struct reply_info* rep, 652 size_t rrset_id, struct reply_info** new_repp, int tag, 653 struct config_strlist** tag_datas, size_t tag_datas_size, 654 char* const* tagname, int num_tags, 655 struct ub_packed_rrset_key** redirect_rrsetp, struct regional* region) 656 { 657 struct ub_packed_rrset_key* rp = raddr->data; 658 struct reply_info* new_rep; 659 *redirect_rrsetp = NULL; 660 661 if(action == respip_redirect && tag != -1 && 662 (size_t)tag<tag_datas_size && tag_datas[tag]) { 663 struct query_info dataqinfo; 664 struct ub_packed_rrset_key r; 665 666 /* Extract parameters of the original answer rrset that can be 667 * rewritten below, in the form of query_info. Note that these 668 * can be different from the info of the original query if the 669 * rrset is a CNAME target.*/ 670 memset(&dataqinfo, 0, sizeof(dataqinfo)); 671 dataqinfo.qname = rep->rrsets[rrset_id]->rk.dname; 672 dataqinfo.qname_len = rep->rrsets[rrset_id]->rk.dname_len; 673 dataqinfo.qtype = ntohs(rep->rrsets[rrset_id]->rk.type); 674 dataqinfo.qclass = ntohs(rep->rrsets[rrset_id]->rk.rrset_class); 675 676 memset(&r, 0, sizeof(r)); 677 if(local_data_find_tag_datas(&dataqinfo, tag_datas[tag], &r, 678 region)) { 679 verbose(VERB_ALGO, 680 "response-ip redirect with tag data [%d] %s", 681 tag, (tag<num_tags?tagname[tag]:"null")); 682 /* use copy_rrset() to 'normalize' memory layout */ 683 rp = copy_rrset(&r, region); 684 if(!rp) 685 return -1; 686 } 687 } 688 if(!rp) 689 return 0; 690 691 /* If we are using response-ip-data, we need to make a copy of rrset 692 * to replace the rrset's dname. Note that, unlike local data, we 693 * rename the dname for other actions than redirect. This is because 694 * response-ip-data isn't associated to any specific name. */ 695 if(rp == raddr->data) { 696 rp = copy_rrset(rp, region); 697 if(!rp) 698 return -1; 699 rp->rk.dname = rep->rrsets[rrset_id]->rk.dname; 700 rp->rk.dname_len = rep->rrsets[rrset_id]->rk.dname_len; 701 } 702 703 /* Build a new reply with redirect rrset. We keep any preceding CNAMEs 704 * and replace the address rrset that triggers the action. If it's 705 * type ANY query, however, no other answer records should be kept 706 * (note that it can't be a CNAME chain in this case due to 707 * sanitizing). */ 708 if(qtype == LDNS_RR_TYPE_ANY) 709 rrset_id = 0; 710 new_rep = make_new_reply_info(rep, region, rrset_id + 1, rrset_id); 711 if(!new_rep) 712 return -1; 713 rp->rk.flags |= PACKED_RRSET_FIXEDTTL; /* avoid adjusting TTL */ 714 new_rep->rrsets[rrset_id] = rp; 715 716 *redirect_rrsetp = rp; 717 *new_repp = new_rep; 718 return 1; 719 } 720 721 /** 722 * apply response ip action in case where no action data is provided. 723 * this is similar to localzone.c:lz_zone_answer() but simplified due to 724 * the characteristics of response ip: 725 * - 'deny' variants will be handled at the caller side 726 * - no specific processing for 'transparent' variants: unlike local zones, 727 * there is no such a case of 'no data but name existing'. so all variants 728 * just mean 'transparent if no data'. 729 * @param qtype: query type 730 * @param action: found action 731 * @param rep: 732 * @param new_repp 733 * @param rrset_id 734 * @param region: region for building new reply 735 * @return 1 on success, 0 on error. 736 */ 737 static int 738 respip_nodata_answer(uint16_t qtype, enum respip_action action, 739 const struct reply_info *rep, size_t rrset_id, 740 struct reply_info** new_repp, struct regional* region) 741 { 742 struct reply_info* new_rep; 743 744 if(action == respip_refuse || action == respip_always_refuse) { 745 new_rep = make_new_reply_info(rep, region, 0, 0); 746 if(!new_rep) 747 return 0; 748 FLAGS_SET_RCODE(new_rep->flags, LDNS_RCODE_REFUSED); 749 *new_repp = new_rep; 750 return 1; 751 } else if(action == respip_static || action == respip_redirect || 752 action == respip_always_nxdomain) { 753 /* Since we don't know about other types of the owner name, 754 * we generally return NOERROR/NODATA unless an NXDOMAIN action 755 * is explicitly specified. */ 756 int rcode = (action == respip_always_nxdomain)? 757 LDNS_RCODE_NXDOMAIN:LDNS_RCODE_NOERROR; 758 759 /* We should empty the answer section except for any preceding 760 * CNAMEs (in that case rrset_id > 0). Type-ANY case is 761 * special as noted in respip_data_answer(). */ 762 if(qtype == LDNS_RR_TYPE_ANY) 763 rrset_id = 0; 764 new_rep = make_new_reply_info(rep, region, rrset_id, rrset_id); 765 if(!new_rep) 766 return 0; 767 FLAGS_SET_RCODE(new_rep->flags, rcode); 768 *new_repp = new_rep; 769 return 1; 770 } 771 772 return 1; 773 } 774 775 /** Populate action info structure with the results of response-ip action 776 * processing, iff as the result of response-ip processing we are actually 777 * taking some action. Only action is set if action_only is true. 778 * Returns true on success, false on failure. 779 */ 780 static int 781 populate_action_info(struct respip_action_info* actinfo, 782 enum respip_action action, const struct resp_addr* raddr, 783 const struct ub_packed_rrset_key* ATTR_UNUSED(rrset), 784 int ATTR_UNUSED(tag), const struct respip_set* ATTR_UNUSED(ipset), 785 int ATTR_UNUSED(action_only), struct regional* region) 786 { 787 if(action == respip_none || !raddr) 788 return 1; 789 actinfo->action = action; 790 791 /* for inform variants, make a copy of the matched address block for 792 * later logging. We make a copy to proactively avoid disruption if 793 * and when we allow a dynamic update to the respip tree. */ 794 if(action == respip_inform || action == respip_inform_deny) { 795 struct respip_addr_info* a = 796 regional_alloc_zero(region, sizeof(*a)); 797 if(!a) { 798 log_err("out of memory"); 799 return 0; 800 } 801 a->addr = raddr->node.addr; 802 a->addrlen = raddr->node.addrlen; 803 a->net = raddr->node.net; 804 actinfo->addrinfo = a; 805 } 806 807 return 1; 808 } 809 810 int 811 respip_rewrite_reply(const struct query_info* qinfo, 812 const struct respip_client_info* cinfo, const struct reply_info* rep, 813 struct reply_info** new_repp, struct respip_action_info* actinfo, 814 struct ub_packed_rrset_key** alias_rrset, int search_only, 815 struct regional* region) 816 { 817 const uint8_t* ctaglist; 818 size_t ctaglen; 819 const uint8_t* tag_actions; 820 size_t tag_actions_size; 821 struct config_strlist** tag_datas; 822 size_t tag_datas_size; 823 struct view* view = NULL; 824 struct respip_set* ipset = NULL; 825 size_t rrset_id = 0; 826 enum respip_action action = respip_none; 827 int tag = -1; 828 const struct resp_addr* raddr = NULL; 829 int ret = 1; 830 struct ub_packed_rrset_key* redirect_rrset = NULL; 831 832 if(!cinfo) 833 goto done; 834 ctaglist = cinfo->taglist; 835 ctaglen = cinfo->taglen; 836 tag_actions = cinfo->tag_actions; 837 tag_actions_size = cinfo->tag_actions_size; 838 tag_datas = cinfo->tag_datas; 839 tag_datas_size = cinfo->tag_datas_size; 840 view = cinfo->view; 841 ipset = cinfo->respip_set; 842 843 /** Try to use response-ip config from the view first; use 844 * global response-ip config if we don't have the view or we don't 845 * have the matching per-view config (and the view allows the use 846 * of global data in this case). 847 * Note that we lock the view even if we only use view members that 848 * currently don't change after creation. This is for safety for 849 * future possible changes as the view documentation seems to expect 850 * any of its member can change in the view's lifetime. 851 * Note also that we assume 'view' is valid in this function, which 852 * should be safe (see unbound bug #1191) */ 853 if(view) { 854 lock_rw_rdlock(&view->lock); 855 if(view->respip_set) { 856 if((raddr = respip_addr_lookup(rep, 857 &view->respip_set->ip_tree, &rrset_id))) { 858 /** for per-view respip directives the action 859 * can only be direct (i.e. not tag-based) */ 860 action = raddr->action; 861 } 862 } 863 if(!raddr && !view->isfirst) 864 goto done; 865 } 866 if(!raddr && ipset && (raddr = respip_addr_lookup(rep, &ipset->ip_tree, 867 &rrset_id))) { 868 action = (enum respip_action)local_data_find_tag_action( 869 raddr->taglist, raddr->taglen, ctaglist, ctaglen, 870 tag_actions, tag_actions_size, 871 (enum localzone_type)raddr->action, &tag, 872 ipset->tagname, ipset->num_tags); 873 } 874 if(raddr && !search_only) { 875 int result = 0; 876 877 /* first, see if we have response-ip or tag action for the 878 * action except for 'always' variants. */ 879 if(action != respip_always_refuse 880 && action != respip_always_transparent 881 && action != respip_always_nxdomain 882 && (result = respip_data_answer(raddr, action, 883 qinfo->qtype, rep, rrset_id, new_repp, tag, tag_datas, 884 tag_datas_size, ipset->tagname, ipset->num_tags, 885 &redirect_rrset, region)) < 0) { 886 ret = 0; 887 goto done; 888 } 889 890 /* if no action data applied, take action specific to the 891 * action without data. */ 892 if(!result && !respip_nodata_answer(qinfo->qtype, action, rep, 893 rrset_id, new_repp, region)) { 894 ret = 0; 895 goto done; 896 } 897 } 898 done: 899 if(view) { 900 lock_rw_unlock(&view->lock); 901 } 902 if(ret) { 903 /* If we're redirecting the original answer to a 904 * CNAME, record the CNAME rrset so the caller can take 905 * the appropriate action. Note that we don't check the 906 * action type; it should normally be 'redirect', but it 907 * can be of other type when a data-dependent tag action 908 * uses redirect response-ip data. 909 */ 910 if(redirect_rrset && 911 redirect_rrset->rk.type == ntohs(LDNS_RR_TYPE_CNAME) && 912 qinfo->qtype != LDNS_RR_TYPE_ANY) 913 *alias_rrset = redirect_rrset; 914 /* on success, populate respip result structure */ 915 ret = populate_action_info(actinfo, action, raddr, 916 redirect_rrset, tag, ipset, search_only, region); 917 } 918 return ret; 919 } 920 921 static int 922 generate_cname_request(struct module_qstate* qstate, 923 struct ub_packed_rrset_key* alias_rrset) 924 { 925 struct module_qstate* subq = NULL; 926 struct query_info subqi; 927 928 memset(&subqi, 0, sizeof(subqi)); 929 get_cname_target(alias_rrset, &subqi.qname, &subqi.qname_len); 930 if(!subqi.qname) 931 return 0; /* unexpected: not a valid CNAME RDATA */ 932 subqi.qtype = qstate->qinfo.qtype; 933 subqi.qclass = qstate->qinfo.qclass; 934 fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); 935 return (*qstate->env->attach_sub)(qstate, &subqi, BIT_RD, 0, 0, &subq); 936 } 937 938 void 939 respip_operate(struct module_qstate* qstate, enum module_ev event, int id, 940 struct outbound_entry* outbound) 941 { 942 struct respip_qstate* rq = (struct respip_qstate*)qstate->minfo[id]; 943 944 log_query_info(VERB_QUERY, "respip operate: query", &qstate->qinfo); 945 (void)outbound; 946 947 if(event == module_event_new || event == module_event_pass) { 948 if(!rq) { 949 rq = regional_alloc_zero(qstate->region, sizeof(*rq)); 950 if(!rq) 951 goto servfail; 952 rq->state = RESPIP_INIT; 953 qstate->minfo[id] = rq; 954 } 955 if(rq->state == RESPIP_SUBQUERY_FINISHED) { 956 qstate->ext_state[id] = module_finished; 957 return; 958 } 959 verbose(VERB_ALGO, "respip: pass to next module"); 960 qstate->ext_state[id] = module_wait_module; 961 } else if(event == module_event_moddone) { 962 /* If the reply may be subject to response-ip rewriting 963 * according to the query type, check the actions. If a 964 * rewrite is necessary, we'll replace the reply in qstate 965 * with the new one. */ 966 enum module_ext_state next_state = module_finished; 967 968 if((qstate->qinfo.qtype == LDNS_RR_TYPE_A || 969 qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA || 970 qstate->qinfo.qtype == LDNS_RR_TYPE_ANY) && 971 qstate->return_msg && qstate->return_msg->rep) { 972 struct respip_action_info actinfo = {respip_none, NULL}; 973 struct reply_info* new_rep = qstate->return_msg->rep; 974 struct ub_packed_rrset_key* alias_rrset = NULL; 975 976 if(!respip_rewrite_reply(&qstate->qinfo, 977 qstate->client_info, qstate->return_msg->rep, 978 &new_rep, &actinfo, &alias_rrset, 0, 979 qstate->region)) { 980 goto servfail; 981 } 982 if(actinfo.action != respip_none) { 983 /* save action info for logging on a 984 * per-front-end-query basis */ 985 if(!(qstate->respip_action_info = 986 regional_alloc_init(qstate->region, 987 &actinfo, sizeof(actinfo)))) 988 { 989 log_err("out of memory"); 990 goto servfail; 991 } 992 } else { 993 qstate->respip_action_info = NULL; 994 } 995 if (new_rep == qstate->return_msg->rep && 996 (actinfo.action == respip_deny || 997 actinfo.action == respip_inform_deny)) { 998 /* for deny-variant actions (unless response-ip 999 * data is applied), mark the query state so 1000 * the response will be dropped for all 1001 * clients. */ 1002 qstate->is_drop = 1; 1003 } else if(alias_rrset) { 1004 if(!generate_cname_request(qstate, alias_rrset)) 1005 goto servfail; 1006 next_state = module_wait_subquery; 1007 } 1008 qstate->return_msg->rep = new_rep; 1009 } 1010 qstate->ext_state[id] = next_state; 1011 } else 1012 qstate->ext_state[id] = module_finished; 1013 1014 return; 1015 1016 servfail: 1017 qstate->return_rcode = LDNS_RCODE_SERVFAIL; 1018 qstate->return_msg = NULL; 1019 } 1020 1021 int 1022 respip_merge_cname(struct reply_info* base_rep, 1023 const struct query_info* qinfo, const struct reply_info* tgt_rep, 1024 const struct respip_client_info* cinfo, int must_validate, 1025 struct reply_info** new_repp, struct regional* region) 1026 { 1027 struct reply_info* new_rep; 1028 struct reply_info* tmp_rep = NULL; /* just a placeholder */ 1029 struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */ 1030 uint16_t tgt_rcode; 1031 size_t i, j; 1032 struct respip_action_info actinfo = {respip_none, NULL}; 1033 1034 /* If the query for the CNAME target would result in an unusual rcode, 1035 * we generally translate it as a failure for the base query 1036 * (which would then be translated into SERVFAIL). The only exception 1037 * is NXDOMAIN and YXDOMAIN, which are passed to the end client(s). 1038 * The YXDOMAIN case would be rare but still possible (when 1039 * DNSSEC-validated DNAME has been cached but synthesizing CNAME 1040 * can't be generated due to length limitation) */ 1041 tgt_rcode = FLAGS_GET_RCODE(tgt_rep->flags); 1042 if((tgt_rcode != LDNS_RCODE_NOERROR && 1043 tgt_rcode != LDNS_RCODE_NXDOMAIN && 1044 tgt_rcode != LDNS_RCODE_YXDOMAIN) || 1045 (must_validate && tgt_rep->security <= sec_status_bogus)) { 1046 return 0; 1047 } 1048 1049 /* see if the target reply would be subject to a response-ip action. */ 1050 if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo, 1051 &alias_rrset, 1, region)) 1052 return 0; 1053 if(actinfo.action != respip_none) { 1054 log_info("CNAME target of redirect response-ip action would " 1055 "be subject to response-ip action, too; stripped"); 1056 *new_repp = base_rep; 1057 return 1; 1058 } 1059 1060 /* Append target reply to the base. Since we cannot assume 1061 * tgt_rep->rrsets is valid throughout the lifetime of new_rep 1062 * or it can be safely shared by multiple threads, we need to make a 1063 * deep copy. */ 1064 new_rep = make_new_reply_info(base_rep, region, 1065 base_rep->an_numrrsets + tgt_rep->an_numrrsets, 1066 base_rep->an_numrrsets); 1067 if(!new_rep) 1068 return 0; 1069 for(i=0,j=base_rep->an_numrrsets; i<tgt_rep->an_numrrsets; i++,j++) { 1070 new_rep->rrsets[j] = copy_rrset(tgt_rep->rrsets[i], region); 1071 if(!new_rep->rrsets[j]) 1072 return 0; 1073 } 1074 1075 FLAGS_SET_RCODE(new_rep->flags, tgt_rcode); 1076 *new_repp = new_rep; 1077 return 1; 1078 } 1079 1080 void 1081 respip_inform_super(struct module_qstate* qstate, int id, 1082 struct module_qstate* super) 1083 { 1084 struct respip_qstate* rq = (struct respip_qstate*)super->minfo[id]; 1085 struct reply_info* new_rep = NULL; 1086 1087 rq->state = RESPIP_SUBQUERY_FINISHED; 1088 1089 /* respip subquery should have always been created with a valid reply 1090 * in super. */ 1091 log_assert(super->return_msg && super->return_msg->rep); 1092 1093 /* return_msg can be NULL when, e.g., the sub query resulted in 1094 * SERVFAIL, in which case we regard it as a failure of the original 1095 * query. Other checks are probably redundant, but we check them 1096 * for safety. */ 1097 if(!qstate->return_msg || !qstate->return_msg->rep || 1098 qstate->return_rcode != LDNS_RCODE_NOERROR) 1099 goto fail; 1100 1101 if(!respip_merge_cname(super->return_msg->rep, &qstate->qinfo, 1102 qstate->return_msg->rep, super->client_info, 1103 super->env->need_to_validate, &new_rep, super->region)) 1104 goto fail; 1105 super->return_msg->rep = new_rep; 1106 return; 1107 1108 fail: 1109 super->return_rcode = LDNS_RCODE_SERVFAIL; 1110 super->return_msg = NULL; 1111 return; 1112 } 1113 1114 void 1115 respip_clear(struct module_qstate* qstate, int id) 1116 { 1117 qstate->minfo[id] = NULL; 1118 } 1119 1120 size_t 1121 respip_get_mem(struct module_env* env, int id) 1122 { 1123 (void)env; 1124 (void)id; 1125 return 0; 1126 } 1127 1128 /** 1129 * The response-ip function block 1130 */ 1131 static struct module_func_block respip_block = { 1132 "respip", 1133 &respip_init, &respip_deinit, &respip_operate, &respip_inform_super, 1134 &respip_clear, &respip_get_mem 1135 }; 1136 1137 struct module_func_block* 1138 respip_get_funcblock(void) 1139 { 1140 return &respip_block; 1141 } 1142 1143 enum respip_action 1144 resp_addr_get_action(const struct resp_addr* addr) 1145 { 1146 return addr ? addr->action : respip_none; 1147 } 1148 1149 struct ub_packed_rrset_key* 1150 resp_addr_get_rrset(struct resp_addr* addr) 1151 { 1152 return addr ? addr->data : NULL; 1153 } 1154 1155 int 1156 respip_set_is_empty(const struct respip_set* set) 1157 { 1158 return set ? set->ip_tree.count == 0 : 1; 1159 } 1160 1161 void 1162 respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname, 1163 uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias, 1164 struct comm_reply* repinfo) 1165 { 1166 char srcip[128], respip[128], txt[512]; 1167 unsigned port; 1168 1169 if(local_alias) 1170 qname = local_alias->rrset->rk.dname; 1171 port = (unsigned)((repinfo->addr.ss_family == AF_INET) ? 1172 ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port) : 1173 ntohs(((struct sockaddr_in6*)&repinfo->addr)->sin6_port)); 1174 addr_to_str(&repinfo->addr, repinfo->addrlen, srcip, sizeof(srcip)); 1175 addr_to_str(&respip_addr->addr, respip_addr->addrlen, 1176 respip, sizeof(respip)); 1177 snprintf(txt, sizeof(txt), "%s/%d inform %s@%u", respip, 1178 respip_addr->net, srcip, port); 1179 log_nametypeclass(0, txt, qname, qtype, qclass); 1180 } 1181