1 /* 2 * services/rpz.c - rpz service 3 * 4 * Copyright (c) 2019, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /** 37 * \file 38 * 39 * This file contains functions to enable RPZ service. 40 */ 41 42 #include "config.h" 43 #include "services/rpz.h" 44 #include "util/config_file.h" 45 #include "sldns/wire2str.h" 46 #include "sldns/str2wire.h" 47 #include "util/data/dname.h" 48 #include "util/net_help.h" 49 #include "util/log.h" 50 #include "util/data/dname.h" 51 #include "util/locks.h" 52 #include "util/regional.h" 53 #include "util/data/msgencode.h" 54 #include "services/cache/dns.h" 55 #include "iterator/iterator.h" 56 #include "iterator/iter_delegpt.h" 57 #include "daemon/worker.h" 58 59 typedef struct resp_addr rpz_aclnode_type; 60 61 struct matched_delegation_point { 62 uint8_t* dname; 63 size_t dname_len; 64 }; 65 66 /** string for RPZ action enum */ 67 const char* 68 rpz_action_to_string(enum rpz_action a) 69 { 70 switch(a) { 71 case RPZ_NXDOMAIN_ACTION: return "rpz-nxdomain"; 72 case RPZ_NODATA_ACTION: return "rpz-nodata"; 73 case RPZ_PASSTHRU_ACTION: return "rpz-passthru"; 74 case RPZ_DROP_ACTION: return "rpz-drop"; 75 case RPZ_TCP_ONLY_ACTION: return "rpz-tcp-only"; 76 case RPZ_INVALID_ACTION: return "rpz-invalid"; 77 case RPZ_LOCAL_DATA_ACTION: return "rpz-local-data"; 78 case RPZ_DISABLED_ACTION: return "rpz-disabled"; 79 case RPZ_CNAME_OVERRIDE_ACTION: return "rpz-cname-override"; 80 case RPZ_NO_OVERRIDE_ACTION: return "rpz-no-override"; 81 default: return "rpz-unknown-action"; 82 } 83 } 84 85 /** RPZ action enum for config string */ 86 static enum rpz_action 87 rpz_config_to_action(char* a) 88 { 89 if(strcmp(a, "nxdomain") == 0) return RPZ_NXDOMAIN_ACTION; 90 else if(strcmp(a, "nodata") == 0) return RPZ_NODATA_ACTION; 91 else if(strcmp(a, "passthru") == 0) return RPZ_PASSTHRU_ACTION; 92 else if(strcmp(a, "drop") == 0) return RPZ_DROP_ACTION; 93 else if(strcmp(a, "tcp_only") == 0) return RPZ_TCP_ONLY_ACTION; 94 else if(strcmp(a, "cname") == 0) return RPZ_CNAME_OVERRIDE_ACTION; 95 else if(strcmp(a, "disabled") == 0) return RPZ_DISABLED_ACTION; 96 else return RPZ_INVALID_ACTION; 97 } 98 99 /** string for RPZ trigger enum */ 100 static const char* 101 rpz_trigger_to_string(enum rpz_trigger r) 102 { 103 switch(r) { 104 case RPZ_QNAME_TRIGGER: return "rpz-qname"; 105 case RPZ_CLIENT_IP_TRIGGER: return "rpz-client-ip"; 106 case RPZ_RESPONSE_IP_TRIGGER: return "rpz-response-ip"; 107 case RPZ_NSDNAME_TRIGGER: return "rpz-nsdname"; 108 case RPZ_NSIP_TRIGGER: return "rpz-nsip"; 109 case RPZ_INVALID_TRIGGER: return "rpz-invalid"; 110 default: return "rpz-unknown-trigger"; 111 } 112 } 113 114 /** 115 * Get the label that is just before the root label. 116 * @param dname: dname to work on 117 * @param maxdnamelen: maximum length of the dname 118 * @return: pointer to TLD label, NULL if not found or invalid dname 119 */ 120 static uint8_t* 121 get_tld_label(uint8_t* dname, size_t maxdnamelen) 122 { 123 uint8_t* prevlab = dname; 124 size_t dnamelen = 0; 125 126 /* one byte needed for label length */ 127 if(dnamelen+1 > maxdnamelen) 128 return NULL; 129 130 /* only root label */ 131 if(*dname == 0) 132 return NULL; 133 134 while(*dname) { 135 dnamelen += ((size_t)*dname)+1; 136 if(dnamelen+1 > maxdnamelen) 137 return NULL; 138 dname = dname+((size_t)*dname)+1; 139 if(*dname != 0) 140 prevlab = dname; 141 } 142 return prevlab; 143 } 144 145 /** 146 * The RR types that are to be ignored. 147 * DNSSEC RRs at the apex, and SOA and NS are ignored. 148 */ 149 static int 150 rpz_type_ignored(uint16_t rr_type) 151 { 152 switch(rr_type) { 153 case LDNS_RR_TYPE_SOA: 154 case LDNS_RR_TYPE_NS: 155 case LDNS_RR_TYPE_DNAME: 156 /* all DNSSEC-related RRs must be ignored */ 157 case LDNS_RR_TYPE_DNSKEY: 158 case LDNS_RR_TYPE_DS: 159 case LDNS_RR_TYPE_RRSIG: 160 case LDNS_RR_TYPE_NSEC: 161 case LDNS_RR_TYPE_NSEC3: 162 case LDNS_RR_TYPE_NSEC3PARAM: 163 return 1; 164 default: 165 break; 166 } 167 return 0; 168 } 169 170 /** 171 * Classify RPZ action for RR type/rdata 172 * @param rr_type: the RR type 173 * @param rdatawl: RDATA with 2 bytes length 174 * @param rdatalen: the length of rdatawl (including its 2 bytes length) 175 * @return: the RPZ action 176 */ 177 static enum rpz_action 178 rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 179 { 180 char* endptr; 181 uint8_t* rdata; 182 int rdatalabs; 183 uint8_t* tldlab = NULL; 184 185 switch(rr_type) { 186 case LDNS_RR_TYPE_SOA: 187 case LDNS_RR_TYPE_NS: 188 case LDNS_RR_TYPE_DNAME: 189 /* all DNSSEC-related RRs must be ignored */ 190 case LDNS_RR_TYPE_DNSKEY: 191 case LDNS_RR_TYPE_DS: 192 case LDNS_RR_TYPE_RRSIG: 193 case LDNS_RR_TYPE_NSEC: 194 case LDNS_RR_TYPE_NSEC3: 195 case LDNS_RR_TYPE_NSEC3PARAM: 196 return RPZ_INVALID_ACTION; 197 case LDNS_RR_TYPE_CNAME: 198 break; 199 default: 200 return RPZ_LOCAL_DATA_ACTION; 201 } 202 203 /* use CNAME target to determine RPZ action */ 204 log_assert(rr_type == LDNS_RR_TYPE_CNAME); 205 if(rdatalen < 3) 206 return RPZ_INVALID_ACTION; 207 208 rdata = rdatawl + 2; /* 2 bytes of rdata length */ 209 if(dname_valid(rdata, rdatalen-2) != rdatalen-2) 210 return RPZ_INVALID_ACTION; 211 212 rdatalabs = dname_count_labels(rdata); 213 if(rdatalabs == 1) 214 return RPZ_NXDOMAIN_ACTION; 215 else if(rdatalabs == 2) { 216 if(dname_subdomain_c(rdata, (uint8_t*)&"\001*\000")) 217 return RPZ_NODATA_ACTION; 218 else if(dname_subdomain_c(rdata, 219 (uint8_t*)&"\014rpz-passthru\000")) 220 return RPZ_PASSTHRU_ACTION; 221 else if(dname_subdomain_c(rdata, (uint8_t*)&"\010rpz-drop\000")) 222 return RPZ_DROP_ACTION; 223 else if(dname_subdomain_c(rdata, 224 (uint8_t*)&"\014rpz-tcp-only\000")) 225 return RPZ_TCP_ONLY_ACTION; 226 } 227 228 /* all other TLDs starting with "rpz-" are invalid */ 229 tldlab = get_tld_label(rdata, rdatalen-2); 230 if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr)) 231 return RPZ_INVALID_ACTION; 232 233 /* no special label found */ 234 return RPZ_LOCAL_DATA_ACTION; 235 } 236 237 static enum localzone_type 238 rpz_action_to_localzone_type(enum rpz_action a) 239 { 240 switch(a) { 241 case RPZ_NXDOMAIN_ACTION: return local_zone_always_nxdomain; 242 case RPZ_NODATA_ACTION: return local_zone_always_nodata; 243 case RPZ_DROP_ACTION: return local_zone_always_deny; 244 case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent; 245 case RPZ_LOCAL_DATA_ACTION: /* fallthrough */ 246 case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect; 247 case RPZ_TCP_ONLY_ACTION: return local_zone_truncate; 248 case RPZ_INVALID_ACTION: /* fallthrough */ 249 default: return local_zone_invalid; 250 } 251 } 252 253 enum respip_action 254 rpz_action_to_respip_action(enum rpz_action a) 255 { 256 switch(a) { 257 case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain; 258 case RPZ_NODATA_ACTION: return respip_always_nodata; 259 case RPZ_DROP_ACTION: return respip_always_deny; 260 case RPZ_PASSTHRU_ACTION: return respip_always_transparent; 261 case RPZ_LOCAL_DATA_ACTION: /* fallthrough */ 262 case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect; 263 case RPZ_TCP_ONLY_ACTION: return respip_truncate; 264 case RPZ_INVALID_ACTION: /* fallthrough */ 265 default: return respip_invalid; 266 } 267 } 268 269 static enum rpz_action 270 localzone_type_to_rpz_action(enum localzone_type lzt) 271 { 272 switch(lzt) { 273 case local_zone_always_nxdomain: return RPZ_NXDOMAIN_ACTION; 274 case local_zone_always_nodata: return RPZ_NODATA_ACTION; 275 case local_zone_always_deny: return RPZ_DROP_ACTION; 276 case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION; 277 case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION; 278 case local_zone_truncate: return RPZ_TCP_ONLY_ACTION; 279 case local_zone_invalid: /* fallthrough */ 280 default: return RPZ_INVALID_ACTION; 281 } 282 } 283 284 enum rpz_action 285 respip_action_to_rpz_action(enum respip_action a) 286 { 287 switch(a) { 288 case respip_always_nxdomain: return RPZ_NXDOMAIN_ACTION; 289 case respip_always_nodata: return RPZ_NODATA_ACTION; 290 case respip_always_deny: return RPZ_DROP_ACTION; 291 case respip_always_transparent: return RPZ_PASSTHRU_ACTION; 292 case respip_redirect: return RPZ_LOCAL_DATA_ACTION; 293 case respip_truncate: return RPZ_TCP_ONLY_ACTION; 294 case respip_invalid: /* fallthrough */ 295 default: return RPZ_INVALID_ACTION; 296 } 297 } 298 299 /** 300 * Get RPZ trigger for dname 301 * @param dname: dname containing RPZ trigger 302 * @param dname_len: length of the dname 303 * @return: RPZ trigger enum 304 */ 305 static enum rpz_trigger 306 rpz_dname_to_trigger(uint8_t* dname, size_t dname_len) 307 { 308 uint8_t* tldlab; 309 char* endptr; 310 311 if(dname_valid(dname, dname_len) != dname_len) 312 return RPZ_INVALID_TRIGGER; 313 314 tldlab = get_tld_label(dname, dname_len); 315 if(!tldlab || !dname_lab_startswith(tldlab, "rpz-", &endptr)) 316 return RPZ_QNAME_TRIGGER; 317 318 if(dname_subdomain_c(tldlab, 319 (uint8_t*)&"\015rpz-client-ip\000")) 320 return RPZ_CLIENT_IP_TRIGGER; 321 else if(dname_subdomain_c(tldlab, (uint8_t*)&"\006rpz-ip\000")) 322 return RPZ_RESPONSE_IP_TRIGGER; 323 else if(dname_subdomain_c(tldlab, (uint8_t*)&"\013rpz-nsdname\000")) 324 return RPZ_NSDNAME_TRIGGER; 325 else if(dname_subdomain_c(tldlab, (uint8_t*)&"\010rpz-nsip\000")) 326 return RPZ_NSIP_TRIGGER; 327 328 return RPZ_QNAME_TRIGGER; 329 } 330 331 static inline struct clientip_synthesized_rrset* 332 rpz_clientip_synthesized_set_create(void) 333 { 334 struct clientip_synthesized_rrset* set = calloc(1, sizeof(*set)); 335 if(set == NULL) { 336 return NULL; 337 } 338 set->region = regional_create(); 339 if(set->region == NULL) { 340 free(set); 341 return NULL; 342 } 343 addr_tree_init(&set->entries); 344 lock_rw_init(&set->lock); 345 return set; 346 } 347 348 static void 349 rpz_clientip_synthesized_rr_delete(rbnode_type* n, void* ATTR_UNUSED(arg)) 350 { 351 struct clientip_synthesized_rr* r = (struct clientip_synthesized_rr*)n->key; 352 lock_rw_destroy(&r->lock); 353 #ifdef THREADS_DISABLED 354 (void)r; 355 #endif 356 } 357 358 static inline void 359 rpz_clientip_synthesized_set_delete(struct clientip_synthesized_rrset* set) 360 { 361 if(set == NULL) { 362 return; 363 } 364 lock_rw_destroy(&set->lock); 365 traverse_postorder(&set->entries, rpz_clientip_synthesized_rr_delete, NULL); 366 regional_destroy(set->region); 367 free(set); 368 } 369 370 void 371 rpz_delete(struct rpz* r) 372 { 373 if(!r) 374 return; 375 local_zones_delete(r->local_zones); 376 local_zones_delete(r->nsdname_zones); 377 respip_set_delete(r->respip_set); 378 rpz_clientip_synthesized_set_delete(r->client_set); 379 rpz_clientip_synthesized_set_delete(r->ns_set); 380 regional_destroy(r->region); 381 free(r->taglist); 382 free(r->log_name); 383 free(r); 384 } 385 386 int 387 rpz_clear(struct rpz* r) 388 { 389 /* must hold write lock on auth_zone */ 390 local_zones_delete(r->local_zones); 391 r->local_zones = NULL; 392 local_zones_delete(r->nsdname_zones); 393 r->nsdname_zones = NULL; 394 respip_set_delete(r->respip_set); 395 r->respip_set = NULL; 396 rpz_clientip_synthesized_set_delete(r->client_set); 397 r->client_set = NULL; 398 rpz_clientip_synthesized_set_delete(r->ns_set); 399 r->ns_set = NULL; 400 if(!(r->local_zones = local_zones_create())){ 401 return 0; 402 } 403 r->nsdname_zones = local_zones_create(); 404 if(r->nsdname_zones == NULL) { 405 return 0; 406 } 407 if(!(r->respip_set = respip_set_create())) { 408 return 0; 409 } 410 if(!(r->client_set = rpz_clientip_synthesized_set_create())) { 411 return 0; 412 } 413 if(!(r->ns_set = rpz_clientip_synthesized_set_create())) { 414 return 0; 415 } 416 return 1; 417 } 418 419 void 420 rpz_finish_config(struct rpz* r) 421 { 422 lock_rw_wrlock(&r->respip_set->lock); 423 addr_tree_init_parents(&r->respip_set->ip_tree); 424 lock_rw_unlock(&r->respip_set->lock); 425 426 lock_rw_wrlock(&r->client_set->lock); 427 addr_tree_init_parents(&r->client_set->entries); 428 lock_rw_unlock(&r->client_set->lock); 429 430 lock_rw_wrlock(&r->ns_set->lock); 431 addr_tree_init_parents(&r->ns_set->entries); 432 lock_rw_unlock(&r->ns_set->lock); 433 } 434 435 /** new rrset containing CNAME override, does not yet contain a dname */ 436 static struct ub_packed_rrset_key* 437 new_cname_override(struct regional* region, uint8_t* ct, size_t ctlen) 438 { 439 struct ub_packed_rrset_key* rrset; 440 struct packed_rrset_data* pd; 441 uint16_t rdlength = htons(ctlen); 442 rrset = (struct ub_packed_rrset_key*)regional_alloc_zero(region, 443 sizeof(*rrset)); 444 if(!rrset) { 445 log_err("out of memory"); 446 return NULL; 447 } 448 rrset->entry.key = rrset; 449 pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd)); 450 if(!pd) { 451 log_err("out of memory"); 452 return NULL; 453 } 454 pd->trust = rrset_trust_prim_noglue; 455 pd->security = sec_status_insecure; 456 457 pd->count = 1; 458 pd->rr_len = regional_alloc_zero(region, sizeof(*pd->rr_len)); 459 pd->rr_ttl = regional_alloc_zero(region, sizeof(*pd->rr_ttl)); 460 pd->rr_data = regional_alloc_zero(region, sizeof(*pd->rr_data)); 461 if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) { 462 log_err("out of memory"); 463 return NULL; 464 } 465 pd->rr_len[0] = ctlen+2; 466 pd->rr_ttl[0] = 3600; 467 pd->rr_data[0] = regional_alloc_zero(region, 2 /* rdlength */ + ctlen); 468 if(!pd->rr_data[0]) { 469 log_err("out of memory"); 470 return NULL; 471 } 472 memmove(pd->rr_data[0], &rdlength, 2); 473 memmove(pd->rr_data[0]+2, ct, ctlen); 474 475 rrset->entry.data = pd; 476 rrset->rk.type = htons(LDNS_RR_TYPE_CNAME); 477 rrset->rk.rrset_class = htons(LDNS_RR_CLASS_IN); 478 return rrset; 479 } 480 481 /** delete the cname override */ 482 static void 483 delete_cname_override(struct rpz* r) 484 { 485 if(r->cname_override) { 486 /* The cname override is what is allocated in the region. */ 487 regional_free_all(r->region); 488 r->cname_override = NULL; 489 } 490 } 491 492 /** Apply rpz config elements to the rpz structure, false on failure. */ 493 static int 494 rpz_apply_cfg_elements(struct rpz* r, struct config_auth* p) 495 { 496 if(p->rpz_taglist && p->rpz_taglistlen) { 497 r->taglistlen = p->rpz_taglistlen; 498 r->taglist = memdup(p->rpz_taglist, r->taglistlen); 499 if(!r->taglist) { 500 log_err("malloc failure on RPZ taglist alloc"); 501 return 0; 502 } 503 } 504 505 if(p->rpz_action_override) { 506 r->action_override = rpz_config_to_action(p->rpz_action_override); 507 } 508 else 509 r->action_override = RPZ_NO_OVERRIDE_ACTION; 510 511 if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { 512 uint8_t nm[LDNS_MAX_DOMAINLEN+1]; 513 size_t nmlen = sizeof(nm); 514 515 if(!p->rpz_cname) { 516 log_err("rpz: override with cname action found, but no " 517 "rpz-cname-override configured"); 518 return 0; 519 } 520 521 if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) { 522 log_err("rpz: cannot parse cname override: %s", 523 p->rpz_cname); 524 return 0; 525 } 526 r->cname_override = new_cname_override(r->region, nm, nmlen); 527 if(!r->cname_override) { 528 return 0; 529 } 530 } 531 r->log = p->rpz_log; 532 r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra; 533 if(p->rpz_log_name) { 534 if(!(r->log_name = strdup(p->rpz_log_name))) { 535 log_err("malloc failure on RPZ log_name strdup"); 536 return 0; 537 } 538 } 539 return 1; 540 } 541 542 struct rpz* 543 rpz_create(struct config_auth* p) 544 { 545 struct rpz* r = calloc(1, sizeof(*r)); 546 if(!r) 547 goto err; 548 549 r->region = regional_create_custom(sizeof(struct regional)); 550 if(!r->region) { 551 goto err; 552 } 553 554 if(!(r->local_zones = local_zones_create())){ 555 goto err; 556 } 557 558 r->nsdname_zones = local_zones_create(); 559 if(r->local_zones == NULL){ 560 goto err; 561 } 562 563 if(!(r->respip_set = respip_set_create())) { 564 goto err; 565 } 566 567 r->client_set = rpz_clientip_synthesized_set_create(); 568 if(r->client_set == NULL) { 569 goto err; 570 } 571 572 r->ns_set = rpz_clientip_synthesized_set_create(); 573 if(r->ns_set == NULL) { 574 goto err; 575 } 576 577 if(!rpz_apply_cfg_elements(r, p)) 578 goto err; 579 return r; 580 err: 581 if(r) { 582 if(r->local_zones) 583 local_zones_delete(r->local_zones); 584 if(r->nsdname_zones) 585 local_zones_delete(r->nsdname_zones); 586 if(r->respip_set) 587 respip_set_delete(r->respip_set); 588 if(r->client_set != NULL) 589 rpz_clientip_synthesized_set_delete(r->client_set); 590 if(r->ns_set != NULL) 591 rpz_clientip_synthesized_set_delete(r->ns_set); 592 if(r->taglist) 593 free(r->taglist); 594 if(r->region) 595 regional_destroy(r->region); 596 free(r); 597 } 598 return NULL; 599 } 600 601 int 602 rpz_config(struct rpz* r, struct config_auth* p) 603 { 604 /* If the zonefile changes, it is read later, after which 605 * rpz_clear and rpz_finish_config is called. */ 606 607 /* free taglist, if any */ 608 if(r->taglist) { 609 free(r->taglist); 610 r->taglist = NULL; 611 r->taglistlen = 0; 612 } 613 614 /* free logname, if any */ 615 if(r->log_name) { 616 free(r->log_name); 617 r->log_name = NULL; 618 } 619 620 delete_cname_override(r); 621 622 if(!rpz_apply_cfg_elements(r, p)) 623 return 0; 624 return 1; 625 } 626 627 /** 628 * Remove RPZ zone name from dname 629 * Copy dname to newdname, without the originlen number of trailing bytes 630 */ 631 static size_t 632 strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen, 633 uint8_t* newdname, size_t maxnewdnamelen) 634 { 635 size_t newdnamelen; 636 if(dnamelen < originlen) 637 return 0; 638 newdnamelen = dnamelen - originlen; 639 if(newdnamelen+1 > maxnewdnamelen) 640 return 0; 641 memmove(newdname, dname, newdnamelen); 642 newdname[newdnamelen] = 0; 643 return newdnamelen + 1; /* + 1 for root label */ 644 } 645 646 static void 647 rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname, 648 size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass, 649 uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 650 { 651 struct local_zone* z; 652 enum localzone_type tp = local_zone_always_transparent; 653 int dnamelabs = dname_count_labels(dname); 654 int newzone = 0; 655 656 if(a == RPZ_INVALID_ACTION) { 657 char str[255+1]; 658 if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS || 659 rrtype == LDNS_RR_TYPE_DNAME || 660 rrtype == LDNS_RR_TYPE_DNSKEY || 661 rrtype == LDNS_RR_TYPE_RRSIG || 662 rrtype == LDNS_RR_TYPE_NSEC || 663 rrtype == LDNS_RR_TYPE_NSEC3PARAM || 664 rrtype == LDNS_RR_TYPE_NSEC3 || 665 rrtype == LDNS_RR_TYPE_DS) { 666 free(dname); 667 return; /* no need to log these types as unsupported */ 668 } 669 dname_str(dname, str); 670 verbose(VERB_ALGO, "rpz: qname trigger, %s skipping unsupported action: %s", 671 str, rpz_action_to_string(a)); 672 free(dname); 673 return; 674 } 675 676 lock_rw_wrlock(&lz->lock); 677 /* exact match */ 678 z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN); 679 if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) { 680 char* rrstr = sldns_wire2str_rr(rr, rr_len); 681 if(rrstr == NULL) { 682 log_err("malloc error while inserting rpz nsdname trigger"); 683 free(dname); 684 lock_rw_unlock(&lz->lock); 685 return; 686 } 687 if(rrstr[0]) 688 rrstr[strlen(rrstr)-1]=0; /* remove newline */ 689 verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr); 690 free(rrstr); 691 free(dname); 692 lock_rw_unlock(&lz->lock); 693 return; 694 } 695 if(z == NULL) { 696 tp = rpz_action_to_localzone_type(a); 697 z = local_zones_add_zone(lz, dname, dnamelen, 698 dnamelabs, rrclass, tp); 699 if(z == NULL) { 700 log_warn("rpz: create failed"); 701 lock_rw_unlock(&lz->lock); 702 /* dname will be free'd in failed local_zone_create() */ 703 return; 704 } 705 newzone = 1; 706 } 707 if(a == RPZ_LOCAL_DATA_ACTION) { 708 char* rrstr = sldns_wire2str_rr(rr, rr_len); 709 if(rrstr == NULL) { 710 log_err("malloc error while inserting rpz nsdname trigger"); 711 free(dname); 712 lock_rw_unlock(&lz->lock); 713 return; 714 } 715 lock_rw_wrlock(&z->lock); 716 local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype, 717 rrclass, ttl, rdata, rdata_len, rrstr); 718 lock_rw_unlock(&z->lock); 719 free(rrstr); 720 } 721 if(!newzone) { 722 free(dname); 723 } 724 lock_rw_unlock(&lz->lock); 725 } 726 727 static void 728 rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len) 729 { 730 char buf[LDNS_MAX_DOMAINLEN+1]; 731 (void)dname_len; 732 dname_str(dname, buf); 733 verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf); 734 } 735 736 static void 737 rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 738 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 739 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 740 { 741 if(a == RPZ_INVALID_ACTION) { 742 verbose(VERB_ALGO, "rpz: skipping invalid action"); 743 free(dname); 744 return; 745 } 746 747 rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype, 748 rrclass, ttl, rdata, rdata_len, rr, rr_len); 749 } 750 751 static int 752 rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen, 753 uint8_t** stripdname, size_t* stripdnamelen) 754 { 755 uint8_t* tldstart = get_tld_label(dname, maxdnamelen); 756 uint8_t swap; 757 if(tldstart == NULL) { 758 if(dname == NULL) { 759 *stripdname = NULL; 760 *stripdnamelen = 0; 761 return 0; 762 } 763 *stripdname = memdup(dname, maxdnamelen); 764 if(!*stripdname) { 765 *stripdnamelen = 0; 766 log_err("malloc failure for rpz strip suffix"); 767 return 0; 768 } 769 *stripdnamelen = maxdnamelen; 770 return 1; 771 } 772 /* shorten the domain name briefly, 773 * then we allocate a new name with the correct length */ 774 swap = *tldstart; 775 *tldstart = 0; 776 (void)dname_count_size_labels(dname, stripdnamelen); 777 *stripdname = memdup(dname, *stripdnamelen); 778 *tldstart = swap; 779 if(!*stripdname) { 780 *stripdnamelen = 0; 781 log_err("malloc failure for rpz strip suffix"); 782 return 0; 783 } 784 return 1; 785 } 786 787 static void 788 rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 789 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 790 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 791 { 792 uint8_t* dname_stripped = NULL; 793 size_t dnamelen_stripped = 0; 794 795 rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped, 796 &dnamelen_stripped); 797 if(a == RPZ_INVALID_ACTION) { 798 verbose(VERB_ALGO, "rpz: skipping invalid action"); 799 free(dname_stripped); 800 return; 801 } 802 803 /* dname_stripped is consumed or freed by the insert routine */ 804 rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped, 805 dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len, 806 rr, rr_len); 807 } 808 809 static int 810 rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr, 811 socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype, 812 uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len, 813 uint8_t* rr, size_t rr_len) 814 { 815 struct resp_addr* node; 816 char* rrstr; 817 enum respip_action respa = rpz_action_to_respip_action(a); 818 819 lock_rw_wrlock(&set->lock); 820 rrstr = sldns_wire2str_rr(rr, rr_len); 821 if(rrstr == NULL) { 822 log_err("malloc error while inserting rpz ipaddr based trigger"); 823 lock_rw_unlock(&set->lock); 824 return 0; 825 } 826 827 node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr); 828 if(node == NULL) { 829 lock_rw_unlock(&set->lock); 830 free(rrstr); 831 return 0; 832 } 833 834 lock_rw_wrlock(&node->lock); 835 lock_rw_unlock(&set->lock); 836 837 node->action = respa; 838 839 if(a == RPZ_LOCAL_DATA_ACTION) { 840 respip_enter_rr(set->region, node, rrtype, 841 rrclass, ttl, rdata, rdata_len, rrstr, ""); 842 } 843 844 lock_rw_unlock(&node->lock); 845 free(rrstr); 846 return 1; 847 } 848 849 static inline struct clientip_synthesized_rr* 850 rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set, 851 struct sockaddr_storage* addr, socklen_t addrlen, int net) 852 { 853 int insert_ok; 854 struct clientip_synthesized_rr* node = 855 (struct clientip_synthesized_rr*)addr_tree_find(&set->entries, 856 addr, addrlen, net); 857 858 if(node != NULL) { return node; } 859 860 /* node does not yet exist => allocate one */ 861 node = regional_alloc_zero(set->region, sizeof(*node)); 862 if(node == NULL) { 863 log_err("out of memory"); 864 return NULL; 865 } 866 867 lock_rw_init(&node->lock); 868 node->action = RPZ_INVALID_ACTION; 869 insert_ok = addr_tree_insert(&set->entries, &node->node, 870 addr, addrlen, net); 871 if (!insert_ok) { 872 log_warn("rpz: unexpected: unable to insert clientip address node"); 873 /* we can not free the just allocated node. 874 * theoretically a memleak */ 875 return NULL; 876 } 877 878 return node; 879 } 880 881 static void 882 rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) { 883 char* rrstr = sldns_wire2str_rr(rr, rr_len); 884 if(rrstr == NULL) { 885 log_err("malloc error while inserting rpz clientip based record"); 886 return; 887 } 888 log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr); 889 free(rrstr); 890 } 891 892 /* from localzone.c; difference is we don't have a dname */ 893 static struct local_rrset* 894 rpz_clientip_new_rrset(struct regional* region, 895 struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass) 896 { 897 struct packed_rrset_data* pd; 898 struct local_rrset* rrset = (struct local_rrset*) 899 regional_alloc_zero(region, sizeof(*rrset)); 900 if(rrset == NULL) { 901 log_err("out of memory"); 902 return NULL; 903 } 904 rrset->next = raddr->data; 905 raddr->data = rrset; 906 rrset->rrset = (struct ub_packed_rrset_key*) 907 regional_alloc_zero(region, sizeof(*rrset->rrset)); 908 if(rrset->rrset == NULL) { 909 log_err("out of memory"); 910 return NULL; 911 } 912 rrset->rrset->entry.key = rrset->rrset; 913 pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd)); 914 if(pd == NULL) { 915 log_err("out of memory"); 916 return NULL; 917 } 918 pd->trust = rrset_trust_prim_noglue; 919 pd->security = sec_status_insecure; 920 rrset->rrset->entry.data = pd; 921 rrset->rrset->rk.type = htons(rrtype); 922 rrset->rrset->rk.rrset_class = htons(rrclass); 923 rrset->rrset->rk.dname = regional_alloc_zero(region, 1); 924 if(rrset->rrset->rk.dname == NULL) { 925 log_err("out of memory"); 926 return NULL; 927 } 928 rrset->rrset->rk.dname_len = 1; 929 return rrset; 930 } 931 932 static int 933 rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* raddr, 934 uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata, 935 size_t rdata_len) 936 { 937 struct local_rrset* rrset; 938 if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data != NULL) { 939 log_err("CNAME response-ip data can not co-exist with other " 940 "client-ip data"); 941 return 0; 942 } 943 944 rrset = rpz_clientip_new_rrset(region, raddr, rrtype, rrclass); 945 if(raddr->data == NULL) { 946 return 0; 947 } 948 949 return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, ""); 950 } 951 952 static int 953 rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr, 954 socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype, 955 uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len, 956 uint8_t* rr, size_t rr_len) 957 { 958 struct clientip_synthesized_rr* node; 959 960 lock_rw_wrlock(&set->lock); 961 962 node = rpz_clientip_ensure_entry(set, addr, addrlen, net); 963 if(node == NULL) { 964 lock_rw_unlock(&set->lock); 965 rpz_report_rrset_error("client ip address", rr, rr_len); 966 return 0; 967 } 968 969 lock_rw_wrlock(&node->lock); 970 lock_rw_unlock(&set->lock); 971 972 node->action = a; 973 if(a == RPZ_LOCAL_DATA_ACTION) { 974 if(!rpz_clientip_enter_rr(set->region, node, rrtype, 975 rrclass, ttl, rdata, rdata_len)) { 976 verbose(VERB_ALGO, "rpz: unable to insert clientip rr"); 977 lock_rw_unlock(&node->lock); 978 return 0; 979 } 980 981 } 982 983 lock_rw_unlock(&node->lock); 984 985 return 1; 986 } 987 988 static int 989 rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 990 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 991 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 992 { 993 struct sockaddr_storage addr; 994 socklen_t addrlen; 995 int net, af; 996 997 if(a == RPZ_INVALID_ACTION) { 998 return 0; 999 } 1000 1001 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 1002 verbose(VERB_ALGO, "rpz: unable to parse client ip"); 1003 return 0; 1004 } 1005 1006 return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net, 1007 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 1008 } 1009 1010 static int 1011 rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1012 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 1013 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 1014 { 1015 struct sockaddr_storage addr; 1016 socklen_t addrlen; 1017 int net, af; 1018 1019 if(a == RPZ_INVALID_ACTION) { 1020 return 0; 1021 } 1022 1023 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 1024 verbose(VERB_ALGO, "rpz: unable to parse ns ip"); 1025 return 0; 1026 } 1027 1028 return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net, 1029 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 1030 } 1031 1032 /** Insert RR into RPZ's respip_set */ 1033 static int 1034 rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1035 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 1036 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 1037 { 1038 struct sockaddr_storage addr; 1039 socklen_t addrlen; 1040 int net, af; 1041 1042 if(a == RPZ_INVALID_ACTION) { 1043 return 0; 1044 } 1045 1046 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 1047 verbose(VERB_ALGO, "rpz: unable to parse response ip"); 1048 return 0; 1049 } 1050 1051 if(a == RPZ_INVALID_ACTION || 1052 rpz_action_to_respip_action(a) == respip_invalid) { 1053 char str[255+1]; 1054 dname_str(dname, str); 1055 verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s", 1056 str, rpz_action_to_string(a)); 1057 return 0; 1058 } 1059 1060 return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net, 1061 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 1062 } 1063 1064 int 1065 rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname, 1066 size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl, 1067 uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len) 1068 { 1069 size_t policydnamelen; 1070 /* name is free'd in local_zone delete */ 1071 enum rpz_trigger t; 1072 enum rpz_action a; 1073 uint8_t* policydname; 1074 1075 if(rpz_type_ignored(rr_type)) { 1076 /* this rpz action is not valid, eg. this is the SOA or NS RR */ 1077 return 1; 1078 } 1079 if(!dname_subdomain_c(dname, azname)) { 1080 char* dname_str = sldns_wire2str_dname(dname, dnamelen); 1081 char* azname_str = sldns_wire2str_dname(azname, aznamelen); 1082 if(dname_str && azname_str) { 1083 log_err("rpz: name of record (%s) to insert into RPZ is not a " 1084 "subdomain of the configured name of the RPZ zone (%s)", 1085 dname_str, azname_str); 1086 } else { 1087 log_err("rpz: name of record to insert into RPZ is not a " 1088 "subdomain of the configured name of the RPZ zone"); 1089 } 1090 free(dname_str); 1091 free(azname_str); 1092 return 0; 1093 } 1094 1095 log_assert(dnamelen >= aznamelen); 1096 if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) { 1097 log_err("malloc error while inserting RPZ RR"); 1098 return 0; 1099 } 1100 1101 a = rpz_rr_to_action(rr_type, rdatawl, rdatalen); 1102 if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen, 1103 policydname, (dnamelen-aznamelen)+1))) { 1104 free(policydname); 1105 return 0; 1106 } 1107 t = rpz_dname_to_trigger(policydname, policydnamelen); 1108 if(t == RPZ_INVALID_TRIGGER) { 1109 free(policydname); 1110 verbose(VERB_ALGO, "rpz: skipping invalid trigger"); 1111 return 1; 1112 } 1113 if(t == RPZ_QNAME_TRIGGER) { 1114 /* policydname will be consumed, no free */ 1115 rpz_insert_qname_trigger(r, policydname, policydnamelen, 1116 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1117 rr_len); 1118 } else if(t == RPZ_RESPONSE_IP_TRIGGER) { 1119 rpz_insert_response_ip_trigger(r, policydname, policydnamelen, 1120 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1121 rr_len); 1122 free(policydname); 1123 } else if(t == RPZ_CLIENT_IP_TRIGGER) { 1124 rpz_insert_clientip_trigger(r, policydname, policydnamelen, 1125 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1126 rr_len); 1127 free(policydname); 1128 } else if(t == RPZ_NSIP_TRIGGER) { 1129 rpz_insert_nsip_trigger(r, policydname, policydnamelen, 1130 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1131 rr_len); 1132 free(policydname); 1133 } else if(t == RPZ_NSDNAME_TRIGGER) { 1134 rpz_insert_nsdname_trigger(r, policydname, policydnamelen, 1135 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1136 rr_len); 1137 free(policydname); 1138 } else { 1139 free(policydname); 1140 verbose(VERB_ALGO, "rpz: skipping unsupported trigger: %s", 1141 rpz_trigger_to_string(t)); 1142 } 1143 return 1; 1144 } 1145 1146 /** 1147 * Find RPZ local-zone by qname. 1148 * @param zones: local-zone tree 1149 * @param qname: qname 1150 * @param qname_len: length of qname 1151 * @param qclass: qclass 1152 * @param only_exact: if 1 only exact (non wildcard) matches are returned 1153 * @param wr: get write lock for local-zone if 1, read lock if 0 1154 * @param zones_keep_lock: if set do not release the r->local_zones lock, this 1155 * makes the caller of this function responsible for releasing the lock. 1156 * @return: NULL or local-zone holding rd or wr lock 1157 */ 1158 static struct local_zone* 1159 rpz_find_zone(struct local_zones* zones, uint8_t* qname, size_t qname_len, uint16_t qclass, 1160 int only_exact, int wr, int zones_keep_lock) 1161 { 1162 uint8_t* ce; 1163 size_t ce_len; 1164 int ce_labs; 1165 uint8_t wc[LDNS_MAX_DOMAINLEN+1]; 1166 int exact; 1167 struct local_zone* z = NULL; 1168 1169 if(wr) { 1170 lock_rw_wrlock(&zones->lock); 1171 } else { 1172 lock_rw_rdlock(&zones->lock); 1173 } 1174 z = local_zones_find_le(zones, qname, qname_len, 1175 dname_count_labels(qname), 1176 LDNS_RR_CLASS_IN, &exact); 1177 if(!z || (only_exact && !exact)) { 1178 if(!zones_keep_lock) { 1179 lock_rw_unlock(&zones->lock); 1180 } 1181 return NULL; 1182 } 1183 if(wr) { 1184 lock_rw_wrlock(&z->lock); 1185 } else { 1186 lock_rw_rdlock(&z->lock); 1187 } 1188 if(!zones_keep_lock) { 1189 lock_rw_unlock(&zones->lock); 1190 } 1191 1192 if(exact) 1193 return z; 1194 1195 /* No exact match found, lookup wildcard. closest encloser must 1196 * be the shared parent between the qname and the best local 1197 * zone match, append '*' to that and do another lookup. */ 1198 1199 ce = dname_get_shared_topdomain(z->name, qname); 1200 if(!ce /* should not happen */) { 1201 lock_rw_unlock(&z->lock); 1202 if(zones_keep_lock) { 1203 lock_rw_unlock(&zones->lock); 1204 } 1205 return NULL; 1206 } 1207 ce_labs = dname_count_size_labels(ce, &ce_len); 1208 if(ce_len+2 > sizeof(wc)) { 1209 lock_rw_unlock(&z->lock); 1210 if(zones_keep_lock) { 1211 lock_rw_unlock(&zones->lock); 1212 } 1213 return NULL; 1214 } 1215 wc[0] = 1; /* length of wildcard label */ 1216 wc[1] = (uint8_t)'*'; /* wildcard label */ 1217 memmove(wc+2, ce, ce_len); 1218 lock_rw_unlock(&z->lock); 1219 1220 if(!zones_keep_lock) { 1221 if(wr) { 1222 lock_rw_wrlock(&zones->lock); 1223 } else { 1224 lock_rw_rdlock(&zones->lock); 1225 } 1226 } 1227 z = local_zones_find_le(zones, wc, 1228 ce_len+2, ce_labs+1, qclass, &exact); 1229 if(!z || !exact) { 1230 lock_rw_unlock(&zones->lock); 1231 return NULL; 1232 } 1233 if(wr) { 1234 lock_rw_wrlock(&z->lock); 1235 } else { 1236 lock_rw_rdlock(&z->lock); 1237 } 1238 if(!zones_keep_lock) { 1239 lock_rw_unlock(&zones->lock); 1240 } 1241 return z; 1242 } 1243 1244 /** Find entry for RR type in the list of rrsets for the clientip. */ 1245 static struct local_rrset* 1246 rpz_find_synthesized_rrset(uint16_t qtype, 1247 struct clientip_synthesized_rr* data, int alias_ok) 1248 { 1249 struct local_rrset* cursor = data->data, *cname = NULL; 1250 while( cursor != NULL) { 1251 struct packed_rrset_key* packed_rrset = &cursor->rrset->rk; 1252 if(htons(qtype) == packed_rrset->type) { 1253 return cursor; 1254 } 1255 if(ntohs(packed_rrset->type) == LDNS_RR_TYPE_CNAME && alias_ok) 1256 cname = cursor; 1257 cursor = cursor->next; 1258 } 1259 if(alias_ok) 1260 return cname; 1261 return NULL; 1262 } 1263 1264 /** 1265 * Remove RR from RPZ's local-data 1266 * @param z: local-zone for RPZ, holding write lock 1267 * @param policydname: dname of RR to remove 1268 * @param policydnamelen: length of policydname 1269 * @param rr_type: RR type of RR to remove 1270 * @param rdata: rdata of RR to remove 1271 * @param rdatalen: length of rdata 1272 * @return: 1 if zone must be removed after RR deletion 1273 */ 1274 static int 1275 rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname, 1276 size_t policydnamelen, uint16_t rr_type, uint8_t* rdata, 1277 size_t rdatalen) 1278 { 1279 struct local_data* ld; 1280 struct packed_rrset_data* d; 1281 size_t index; 1282 ld = local_zone_find_data(z, policydname, policydnamelen, 1283 dname_count_labels(policydname)); 1284 if(ld) { 1285 struct local_rrset* prev=NULL, *p=ld->rrsets; 1286 while(p && ntohs(p->rrset->rk.type) != rr_type) { 1287 prev = p; 1288 p = p->next; 1289 } 1290 if(!p) 1291 return 0; 1292 d = (struct packed_rrset_data*)p->rrset->entry.data; 1293 if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) { 1294 if(d->count == 1) { 1295 /* no memory recycling for zone deletions ... */ 1296 if(prev) prev->next = p->next; 1297 else ld->rrsets = p->next; 1298 } 1299 if(d->count > 1) { 1300 if(!local_rrset_remove_rr(d, index)) 1301 return 0; 1302 } 1303 } 1304 } 1305 if(ld && ld->rrsets) 1306 return 0; 1307 return 1; 1308 } 1309 1310 /** 1311 * Remove RR from RPZ's respip set 1312 * @param raddr: respip node 1313 * @param rr_type: RR type of RR to remove 1314 * @param rdata: rdata of RR to remove 1315 * @param rdatalen: length of rdata 1316 * @return: 1 if zone must be removed after RR deletion 1317 */ 1318 static int 1319 rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata, 1320 size_t rdatalen) 1321 { 1322 size_t index; 1323 struct packed_rrset_data* d; 1324 if(!raddr->data) 1325 return 1; 1326 d = raddr->data->entry.data; 1327 if(ntohs(raddr->data->rk.type) != rr_type) { 1328 return 0; 1329 } 1330 if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) { 1331 if(d->count == 1) { 1332 /* regional alloc'd */ 1333 raddr->data->entry.data = NULL; 1334 raddr->data = NULL; 1335 return 1; 1336 } 1337 if(d->count > 1) { 1338 if(!local_rrset_remove_rr(d, index)) 1339 return 0; 1340 } 1341 } 1342 return 0; 1343 1344 } 1345 1346 /** Remove RR from rpz localzones structure */ 1347 static void 1348 rpz_remove_local_zones_trigger(struct local_zones* zones, uint8_t* dname, 1349 size_t dnamelen, enum rpz_action a, uint16_t rr_type, 1350 uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen) 1351 { 1352 struct local_zone* z; 1353 int delete_zone = 1; 1354 z = rpz_find_zone(zones, dname, dnamelen, rr_class, 1355 1 /* only exact */, 1 /* wr lock */, 1 /* keep lock*/); 1356 if(!z) { 1357 verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, " 1358 "RPZ domain not found"); 1359 return; 1360 } 1361 if(a == RPZ_LOCAL_DATA_ACTION) 1362 delete_zone = rpz_data_delete_rr(z, dname, 1363 dnamelen, rr_type, rdatawl, rdatalen); 1364 else if(a != localzone_type_to_rpz_action(z->type)) { 1365 lock_rw_unlock(&z->lock); 1366 lock_rw_unlock(&zones->lock); 1367 return; 1368 } 1369 lock_rw_unlock(&z->lock); 1370 if(delete_zone) { 1371 local_zones_del_zone(zones, z); 1372 } 1373 lock_rw_unlock(&zones->lock); 1374 } 1375 1376 /** Remove RR from RPZ's local-zone */ 1377 static void 1378 rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1379 enum rpz_action a, uint16_t rr_type, uint16_t rr_class, 1380 uint8_t* rdatawl, size_t rdatalen) 1381 { 1382 rpz_remove_local_zones_trigger(r->local_zones, dname, dnamelen, 1383 a, rr_type, rr_class, rdatawl, rdatalen); 1384 } 1385 1386 static void 1387 rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1388 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1389 { 1390 struct resp_addr* node; 1391 struct sockaddr_storage addr; 1392 socklen_t addrlen; 1393 int net, af; 1394 int delete_respip = 1; 1395 1396 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) 1397 return; 1398 1399 lock_rw_wrlock(&r->respip_set->lock); 1400 if(!(node = (struct resp_addr*)addr_tree_find( 1401 &r->respip_set->ip_tree, &addr, addrlen, net))) { 1402 verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, " 1403 "RPZ domain not found"); 1404 lock_rw_unlock(&r->respip_set->lock); 1405 return; 1406 } 1407 1408 lock_rw_wrlock(&node->lock); 1409 if(a == RPZ_LOCAL_DATA_ACTION) { 1410 /* remove RR, signal whether RR can be removed */ 1411 delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl, 1412 rdatalen); 1413 } 1414 lock_rw_unlock(&node->lock); 1415 if(delete_respip) 1416 respip_sockaddr_delete(r->respip_set, node); 1417 lock_rw_unlock(&r->respip_set->lock); 1418 } 1419 1420 /** find and remove type from list of local_rrset entries*/ 1421 static void 1422 del_local_rrset_from_list(struct local_rrset** list_head, uint16_t dtype) 1423 { 1424 struct local_rrset* prev=NULL, *p=*list_head; 1425 while(p && ntohs(p->rrset->rk.type) != dtype) { 1426 prev = p; 1427 p = p->next; 1428 } 1429 if(!p) 1430 return; /* rrset type not found */ 1431 /* unlink it */ 1432 if(prev) prev->next = p->next; 1433 else *list_head = p->next; 1434 /* no memory recycling for zone deletions ... */ 1435 } 1436 1437 /** Delete client-ip trigger RR from its RRset and perhaps also the rrset 1438 * from the linked list. Returns if the local data is empty and the node can 1439 * be deleted too, or not. */ 1440 static int rpz_remove_clientip_rr(struct clientip_synthesized_rr* node, 1441 uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1442 { 1443 struct local_rrset* rrset; 1444 struct packed_rrset_data* d; 1445 size_t index; 1446 rrset = rpz_find_synthesized_rrset(rr_type, node, 0); 1447 if(rrset == NULL) 1448 return 0; /* type not found, ignore */ 1449 d = (struct packed_rrset_data*)rrset->rrset->entry.data; 1450 if(!packed_rrset_find_rr(d, rdatawl, rdatalen, &index)) 1451 return 0; /* RR not found, ignore */ 1452 if(d->count == 1) { 1453 /* regional alloc'd */ 1454 /* delete the type entry from the list */ 1455 del_local_rrset_from_list(&node->data, rr_type); 1456 /* if the list is empty, the node can be removed too */ 1457 if(node->data == NULL) 1458 return 1; 1459 } else if (d->count > 1) { 1460 if(!local_rrset_remove_rr(d, index)) 1461 return 0; 1462 } 1463 return 0; 1464 } 1465 1466 /** remove trigger RR from clientip_syntheized set tree. */ 1467 static void 1468 rpz_clientip_remove_trigger_rr(struct clientip_synthesized_rrset* set, 1469 struct sockaddr_storage* addr, socklen_t addrlen, int net, 1470 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1471 { 1472 struct clientip_synthesized_rr* node; 1473 int delete_node = 1; 1474 1475 lock_rw_wrlock(&set->lock); 1476 node = (struct clientip_synthesized_rr*)addr_tree_find(&set->entries, 1477 addr, addrlen, net); 1478 if(node == NULL) { 1479 /* netblock not found */ 1480 verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, " 1481 "RPZ address, netblock not found"); 1482 lock_rw_unlock(&set->lock); 1483 return; 1484 } 1485 lock_rw_wrlock(&node->lock); 1486 if(a == RPZ_LOCAL_DATA_ACTION) { 1487 /* remove RR, signal whether entry can be removed */ 1488 delete_node = rpz_remove_clientip_rr(node, rr_type, rdatawl, 1489 rdatalen); 1490 } else if(a != node->action) { 1491 /* ignore the RR with different action specification */ 1492 delete_node = 0; 1493 } 1494 if(delete_node) { 1495 rbtree_delete(&set->entries, node->node.node.key); 1496 } 1497 lock_rw_unlock(&set->lock); 1498 lock_rw_unlock(&node->lock); 1499 if(delete_node) { 1500 lock_rw_destroy(&node->lock); 1501 } 1502 } 1503 1504 /** Remove clientip trigger RR from RPZ. */ 1505 static void 1506 rpz_remove_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1507 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1508 { 1509 struct sockaddr_storage addr; 1510 socklen_t addrlen; 1511 int net, af; 1512 if(a == RPZ_INVALID_ACTION) 1513 return; 1514 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) 1515 return; 1516 rpz_clientip_remove_trigger_rr(r->client_set, &addr, addrlen, net, 1517 a, rr_type, rdatawl, rdatalen); 1518 } 1519 1520 /** Remove nsip trigger RR from RPZ. */ 1521 static void 1522 rpz_remove_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1523 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1524 { 1525 struct sockaddr_storage addr; 1526 socklen_t addrlen; 1527 int net, af; 1528 if(a == RPZ_INVALID_ACTION) 1529 return; 1530 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) 1531 return; 1532 rpz_clientip_remove_trigger_rr(r->ns_set, &addr, addrlen, net, 1533 a, rr_type, rdatawl, rdatalen); 1534 } 1535 1536 /** Remove nsdname trigger RR from RPZ. */ 1537 static void 1538 rpz_remove_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1539 enum rpz_action a, uint16_t rr_type, uint16_t rr_class, 1540 uint8_t* rdatawl, size_t rdatalen) 1541 { 1542 uint8_t* dname_stripped = NULL; 1543 size_t dnamelen_stripped = 0; 1544 if(a == RPZ_INVALID_ACTION) 1545 return; 1546 if(!rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped, 1547 &dnamelen_stripped)) 1548 return; 1549 rpz_remove_local_zones_trigger(r->nsdname_zones, dname_stripped, 1550 dnamelen_stripped, a, rr_type, rr_class, rdatawl, rdatalen); 1551 free(dname_stripped); 1552 } 1553 1554 void 1555 rpz_remove_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname, 1556 size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl, 1557 size_t rdatalen) 1558 { 1559 size_t policydnamelen; 1560 enum rpz_trigger t; 1561 enum rpz_action a; 1562 uint8_t* policydname; 1563 1564 if(rpz_type_ignored(rr_type)) { 1565 /* this rpz action is not valid, eg. this is the SOA or NS RR */ 1566 return; 1567 } 1568 if(!dname_subdomain_c(dname, azname)) { 1569 /* not subdomain of the RPZ zone. */ 1570 return; 1571 } 1572 1573 if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1))) 1574 return; 1575 1576 a = rpz_rr_to_action(rr_type, rdatawl, rdatalen); 1577 if(a == RPZ_INVALID_ACTION) { 1578 free(policydname); 1579 return; 1580 } 1581 if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen, 1582 policydname, LDNS_MAX_DOMAINLEN + 1))) { 1583 free(policydname); 1584 return; 1585 } 1586 t = rpz_dname_to_trigger(policydname, policydnamelen); 1587 if(t == RPZ_INVALID_TRIGGER) { 1588 /* skipping invalid trigger */ 1589 free(policydname); 1590 return; 1591 } 1592 if(t == RPZ_QNAME_TRIGGER) { 1593 rpz_remove_qname_trigger(r, policydname, policydnamelen, a, 1594 rr_type, rr_class, rdatawl, rdatalen); 1595 } else if(t == RPZ_RESPONSE_IP_TRIGGER) { 1596 rpz_remove_response_ip_trigger(r, policydname, policydnamelen, 1597 a, rr_type, rdatawl, rdatalen); 1598 } else if(t == RPZ_CLIENT_IP_TRIGGER) { 1599 rpz_remove_clientip_trigger(r, policydname, policydnamelen, a, 1600 rr_type, rdatawl, rdatalen); 1601 } else if(t == RPZ_NSIP_TRIGGER) { 1602 rpz_remove_nsip_trigger(r, policydname, policydnamelen, a, 1603 rr_type, rdatawl, rdatalen); 1604 } else if(t == RPZ_NSDNAME_TRIGGER) { 1605 rpz_remove_nsdname_trigger(r, policydname, policydnamelen, a, 1606 rr_type, rr_class, rdatawl, rdatalen); 1607 } 1608 /* else it was an unsupported trigger, also skipped. */ 1609 free(policydname); 1610 } 1611 1612 /** print log information for an applied RPZ policy. Based on local-zone's 1613 * lz_inform_print(). 1614 * The repinfo contains the reply address. If it is NULL, the module 1615 * state is used to report the first IP address (if any). 1616 * The dname is used, for the applied rpz, if NULL, addrnode is used. 1617 */ 1618 static void 1619 log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode, 1620 enum rpz_action a, struct query_info* qinfo, 1621 struct comm_reply* repinfo, struct module_qstate* ms, char* log_name) 1622 { 1623 char ip[128], txt[512], portstr[32]; 1624 char dnamestr[LDNS_MAX_DOMAINLEN+1]; 1625 uint16_t port = 0; 1626 if(dname) { 1627 dname_str(dname, dnamestr); 1628 } else if(addrnode) { 1629 char addrbuf[128]; 1630 addr_to_str(&addrnode->addr, addrnode->addrlen, addrbuf, sizeof(addrbuf)); 1631 snprintf(dnamestr, sizeof(dnamestr), "%s/%d", addrbuf, addrnode->net); 1632 } else { 1633 dnamestr[0]=0; 1634 } 1635 if(repinfo) { 1636 addr_to_str(&repinfo->client_addr, repinfo->client_addrlen, ip, sizeof(ip)); 1637 port = ntohs(((struct sockaddr_in*)&repinfo->client_addr)->sin_port); 1638 } else if(ms && ms->mesh_info && ms->mesh_info->reply_list) { 1639 addr_to_str(&ms->mesh_info->reply_list->query_reply.client_addr, 1640 ms->mesh_info->reply_list->query_reply.client_addrlen, 1641 ip, sizeof(ip)); 1642 port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.client_addr)->sin_port); 1643 } else { 1644 ip[0]=0; 1645 port = 0; 1646 } 1647 snprintf(portstr, sizeof(portstr), "@%u", (unsigned)port); 1648 snprintf(txt, sizeof(txt), "rpz: applied %s%s%s%s%s%s %s %s%s", 1649 (log_name?"[":""), (log_name?log_name:""), (log_name?"] ":""), 1650 (strcmp(trigger,"qname")==0?"":trigger), 1651 (strcmp(trigger,"qname")==0?"":" "), 1652 dnamestr, rpz_action_to_string(a), 1653 (ip[0]?ip:""), (ip[0]?portstr:"")); 1654 log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); 1655 } 1656 1657 static struct clientip_synthesized_rr* 1658 rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set, 1659 struct sockaddr_storage* addr, socklen_t addrlen, char* triggername) 1660 { 1661 struct clientip_synthesized_rr* raddr = NULL; 1662 enum rpz_action action = RPZ_INVALID_ACTION; 1663 1664 lock_rw_rdlock(&set->lock); 1665 1666 raddr = (struct clientip_synthesized_rr*)addr_tree_lookup(&set->entries, 1667 addr, addrlen); 1668 if(raddr != NULL) { 1669 lock_rw_rdlock(&raddr->lock); 1670 action = raddr->action; 1671 if(verbosity >= VERB_ALGO) { 1672 char ip[256], net[256]; 1673 addr_to_str(addr, addrlen, ip, sizeof(ip)); 1674 addr_to_str(&raddr->node.addr, raddr->node.addrlen, 1675 net, sizeof(net)); 1676 verbose(VERB_ALGO, "rpz: trigger %s %s/%d on %s action=%s", 1677 triggername, net, raddr->node.net, ip, rpz_action_to_string(action)); 1678 } 1679 } 1680 lock_rw_unlock(&set->lock); 1681 1682 return raddr; 1683 } 1684 1685 static inline 1686 struct clientip_synthesized_rr* 1687 rpz_resolve_client_action_and_zone(struct auth_zones* az, struct query_info* qinfo, 1688 struct comm_reply* repinfo, uint8_t* taglist, size_t taglen, 1689 struct ub_server_stats* stats, 1690 /* output parameters */ 1691 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out) 1692 { 1693 struct clientip_synthesized_rr* node = NULL; 1694 struct auth_zone* a = NULL; 1695 struct rpz* r = NULL; 1696 struct local_zone* z = NULL; 1697 1698 lock_rw_rdlock(&az->rpz_lock); 1699 1700 for(a = az->rpz_first; a; a = a->rpz_az_next) { 1701 lock_rw_rdlock(&a->lock); 1702 r = a->rpz; 1703 if(r->disabled) { 1704 lock_rw_unlock(&a->lock); 1705 continue; 1706 } 1707 if(r->taglist && !taglist_intersect(r->taglist, 1708 r->taglistlen, taglist, taglen)) { 1709 lock_rw_unlock(&a->lock); 1710 continue; 1711 } 1712 z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len, 1713 qinfo->qclass, 0, 0, 0); 1714 node = rpz_ipbased_trigger_lookup(r->client_set, 1715 &repinfo->client_addr, repinfo->client_addrlen, 1716 "clientip"); 1717 if((z || node) && r->action_override == RPZ_DISABLED_ACTION) { 1718 if(r->log) 1719 log_rpz_apply((node?"clientip":"qname"), 1720 (z?z->name:NULL), 1721 (node?&node->node:NULL), 1722 r->action_override, 1723 qinfo, repinfo, NULL, r->log_name); 1724 stats->rpz_action[r->action_override]++; 1725 if(z != NULL) { 1726 lock_rw_unlock(&z->lock); 1727 z = NULL; 1728 } 1729 if(node != NULL) { 1730 lock_rw_unlock(&node->lock); 1731 node = NULL; 1732 } 1733 } 1734 if(z || node) { 1735 break; 1736 } 1737 /* not found in this auth_zone */ 1738 lock_rw_unlock(&a->lock); 1739 } 1740 1741 lock_rw_unlock(&az->rpz_lock); 1742 1743 *r_out = r; 1744 *a_out = a; 1745 *z_out = z; 1746 1747 return node; 1748 } 1749 1750 static inline int 1751 rpz_is_udp_query(struct comm_reply* repinfo) { 1752 return repinfo != NULL 1753 ? (repinfo->c != NULL 1754 ? repinfo->c->type == comm_udp 1755 : 0) 1756 : 0; 1757 } 1758 1759 /** encode answer consisting of 1 rrset */ 1760 static int 1761 rpz_local_encode(struct module_env* env, struct query_info* qinfo, 1762 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1763 struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, 1764 int rcode, struct ub_packed_rrset_key* soa_rrset) 1765 { 1766 struct reply_info rep; 1767 uint16_t udpsize; 1768 struct ub_packed_rrset_key* rrsetlist[3]; 1769 1770 memset(&rep, 0, sizeof(rep)); 1771 rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode); 1772 rep.qdcount = 1; 1773 rep.rrset_count = ansec; 1774 rep.rrsets = rrsetlist; 1775 if(ansec > 0) { 1776 rep.an_numrrsets = 1; 1777 rep.rrsets[0] = rrset; 1778 rep.ttl = ((struct packed_rrset_data*)rrset->entry.data)->rr_ttl[0]; 1779 } 1780 if(soa_rrset != NULL) { 1781 rep.ar_numrrsets = 1; 1782 rep.rrsets[rep.rrset_count] = soa_rrset; 1783 rep.rrset_count ++; 1784 if(rep.ttl < ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]) { 1785 rep.ttl = ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]; 1786 } 1787 } 1788 1789 udpsize = edns->udp_size; 1790 edns->edns_version = EDNS_ADVERTISED_VERSION; 1791 edns->udp_size = EDNS_ADVERTISED_SIZE; 1792 edns->ext_rcode = 0; 1793 edns->bits &= EDNS_DO; 1794 if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, 1795 repinfo, temp, env->now_tv) || 1796 !reply_info_answer_encode(qinfo, &rep, 1797 *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), 1798 buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) { 1799 error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, 1800 *(uint16_t*)sldns_buffer_begin(buf), 1801 sldns_buffer_read_u16_at(buf, 2), edns); 1802 } 1803 1804 return 1; 1805 } 1806 1807 /** allocate SOA record ubrrsetkey in region */ 1808 static struct ub_packed_rrset_key* 1809 make_soa_ubrrset(struct auth_zone* auth_zone, struct auth_rrset* soa, 1810 struct regional* temp) 1811 { 1812 struct ub_packed_rrset_key csoa; 1813 if(!soa) 1814 return NULL; 1815 memset(&csoa, 0, sizeof(csoa)); 1816 csoa.entry.key = &csoa; 1817 csoa.rk.rrset_class = htons(LDNS_RR_CLASS_IN); 1818 csoa.rk.type = htons(LDNS_RR_TYPE_SOA); 1819 csoa.rk.flags |= PACKED_RRSET_FIXEDTTL 1820 | PACKED_RRSET_RPZ; 1821 csoa.rk.dname = auth_zone->name; 1822 csoa.rk.dname_len = auth_zone->namelen; 1823 csoa.entry.hash = rrset_key_hash(&csoa.rk); 1824 csoa.entry.data = soa->data; 1825 return respip_copy_rrset(&csoa, temp); 1826 } 1827 1828 static void 1829 rpz_apply_clientip_localdata_action(struct clientip_synthesized_rr* raddr, 1830 struct module_env* env, struct query_info* qinfo, 1831 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1832 struct regional* temp, struct auth_zone* auth_zone) 1833 { 1834 struct local_rrset* rrset; 1835 enum rpz_action action = RPZ_INVALID_ACTION; 1836 struct ub_packed_rrset_key* rp = NULL; 1837 struct ub_packed_rrset_key* rsoa = NULL; 1838 int rcode = LDNS_RCODE_NOERROR|BIT_AA; 1839 int rrset_count = 1; 1840 1841 /* prepare synthesized answer for client */ 1842 action = raddr->action; 1843 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL ) { 1844 verbose(VERB_ALGO, "rpz: bug: local-data action but no local data"); 1845 return; 1846 } 1847 1848 /* check query type / rr type */ 1849 rrset = rpz_find_synthesized_rrset(qinfo->qtype, raddr, 1); 1850 if(rrset == NULL) { 1851 verbose(VERB_ALGO, "rpz: unable to find local-data for query"); 1852 rrset_count = 0; 1853 goto nodata; 1854 } 1855 1856 rp = respip_copy_rrset(rrset->rrset, temp); 1857 if(!rp) { 1858 verbose(VERB_ALGO, "rpz: local data action: out of memory"); 1859 return; 1860 } 1861 1862 rp->rk.flags |= PACKED_RRSET_FIXEDTTL | PACKED_RRSET_RPZ; 1863 rp->rk.dname = qinfo->qname; 1864 rp->rk.dname_len = qinfo->qname_len; 1865 rp->entry.hash = rrset_key_hash(&rp->rk); 1866 nodata: 1867 if(auth_zone) { 1868 struct auth_rrset* soa = NULL; 1869 soa = auth_zone_get_soa_rrset(auth_zone); 1870 if(soa) { 1871 rsoa = make_soa_ubrrset(auth_zone, soa, temp); 1872 if(!rsoa) { 1873 verbose(VERB_ALGO, "rpz: local data action soa: out of memory"); 1874 return; 1875 } 1876 } 1877 } 1878 1879 rpz_local_encode(env, qinfo, edns, repinfo, buf, temp, rp, 1880 rrset_count, rcode, rsoa); 1881 } 1882 1883 /** Apply the cname override action, during worker request callback. 1884 * false on failure. */ 1885 static int 1886 rpz_apply_cname_override_action(struct rpz* r, 1887 struct query_info* qinfo, struct regional* temp) 1888 { 1889 if(!r) 1890 return 0; 1891 qinfo->local_alias = regional_alloc_zero(temp, 1892 sizeof(struct local_rrset)); 1893 if(qinfo->local_alias == NULL) 1894 return 0; /* out of memory */ 1895 qinfo->local_alias->rrset = respip_copy_rrset(r->cname_override, temp); 1896 if(qinfo->local_alias->rrset == NULL) { 1897 qinfo->local_alias = NULL; 1898 return 0; /* out of memory */ 1899 } 1900 qinfo->local_alias->rrset->rk.dname = qinfo->qname; 1901 qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; 1902 return 1; 1903 } 1904 1905 /** add additional section SOA record to the reply. 1906 * Since this gets fed into the normal iterator answer creation, it 1907 * gets minimal-responses applied to it, that can remove the additional SOA 1908 * again. */ 1909 static int 1910 rpz_add_soa(struct reply_info* rep, struct module_qstate* ms, 1911 struct auth_zone* az) 1912 { 1913 struct auth_rrset* soa = NULL; 1914 struct ub_packed_rrset_key* rsoa = NULL; 1915 struct ub_packed_rrset_key** prevrrsets; 1916 if(!az) return 1; 1917 soa = auth_zone_get_soa_rrset(az); 1918 if(!soa) return 1; 1919 if(!rep) return 0; 1920 rsoa = make_soa_ubrrset(az, soa, ms->region); 1921 if(!rsoa) return 0; 1922 prevrrsets = rep->rrsets; 1923 rep->rrsets = regional_alloc_zero(ms->region, 1924 sizeof(*rep->rrsets)*(rep->rrset_count+1)); 1925 if(!rep->rrsets) 1926 return 0; 1927 if(prevrrsets && rep->rrset_count > 0) 1928 memcpy(rep->rrsets, prevrrsets, rep->rrset_count*sizeof(*rep->rrsets)); 1929 rep->rrset_count++; 1930 rep->ar_numrrsets++; 1931 rep->rrsets[rep->rrset_count-1] = rsoa; 1932 return 1; 1933 } 1934 1935 static inline struct dns_msg* 1936 rpz_dns_msg_new(struct regional* region) 1937 { 1938 struct dns_msg* msg = 1939 (struct dns_msg*)regional_alloc(region, 1940 sizeof(struct dns_msg)); 1941 if(msg == NULL) { return NULL; } 1942 memset(msg, 0, sizeof(struct dns_msg)); 1943 1944 return msg; 1945 } 1946 1947 static inline struct dns_msg* 1948 rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 1949 struct query_info* qinfo, struct auth_zone* az) 1950 { 1951 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1952 if(msg == NULL) { return msg; } 1953 msg->qinfo = *qinfo; 1954 msg->rep = construct_reply_info_base(ms->region, 1955 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 1956 1, /* qd */ 1957 0, /* ttl */ 1958 0, /* prettl */ 1959 0, /* expttl */ 1960 0, /* an */ 1961 0, /* ns */ 1962 0, /* ar */ 1963 0, /* total */ 1964 sec_status_insecure, 1965 LDNS_EDE_NONE); 1966 if(msg->rep) 1967 msg->rep->authoritative = 1; 1968 if(!rpz_add_soa(msg->rep, ms, az)) 1969 return NULL; 1970 return msg; 1971 } 1972 1973 static inline struct dns_msg* 1974 rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms, 1975 struct query_info* qinfo, struct auth_zone* az) 1976 { 1977 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1978 uint16_t flags; 1979 if(msg == NULL) { return msg; } 1980 msg->qinfo = *qinfo; 1981 flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA; 1982 if(r->signal_nxdomain_ra) 1983 flags &= ~BIT_RA; 1984 msg->rep = construct_reply_info_base(ms->region, 1985 flags, 1986 1, /* qd */ 1987 0, /* ttl */ 1988 0, /* prettl */ 1989 0, /* expttl */ 1990 0, /* an */ 1991 0, /* ns */ 1992 0, /* ar */ 1993 0, /* total */ 1994 sec_status_insecure, 1995 LDNS_EDE_NONE); 1996 if(msg->rep) 1997 msg->rep->authoritative = 1; 1998 if(!rpz_add_soa(msg->rep, ms, az)) 1999 return NULL; 2000 return msg; 2001 } 2002 2003 static inline struct dns_msg* 2004 rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 2005 struct query_info* qi, struct local_rrset* rrset, struct auth_zone* az) 2006 { 2007 struct dns_msg* msg = NULL; 2008 struct reply_info* new_reply_info; 2009 struct ub_packed_rrset_key* rp; 2010 2011 2012 msg = rpz_dns_msg_new(ms->region); 2013 if(msg == NULL) { return NULL; } 2014 2015 msg->qinfo = *qi; 2016 new_reply_info = construct_reply_info_base(ms->region, 2017 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 2018 1, /* qd */ 2019 0, /* ttl */ 2020 0, /* prettl */ 2021 0, /* expttl */ 2022 1, /* an */ 2023 0, /* ns */ 2024 0, /* ar */ 2025 1, /* total */ 2026 sec_status_insecure, 2027 LDNS_EDE_NONE); 2028 if(new_reply_info == NULL) { 2029 log_err("out of memory"); 2030 return NULL; 2031 } 2032 new_reply_info->authoritative = 1; 2033 rp = respip_copy_rrset(rrset->rrset, ms->region); 2034 if(rp == NULL) { 2035 log_err("out of memory"); 2036 return NULL; 2037 } 2038 rp->rk.dname = qi->qname; 2039 rp->rk.dname_len = qi->qname_len; 2040 /* this rrset is from the rpz data, or synthesized. 2041 * It is not actually from the network, so we flag it with this 2042 * flags as a fake RRset. If later the cache is used to look up 2043 * rrsets, then the fake ones are not returned (if you look without 2044 * the flag). For like CNAME lookups from the iterator or A, AAAA 2045 * lookups for nameserver targets, it would use the without flag 2046 * actual data. So that the actual network data and fake data 2047 * are kept track of separately. */ 2048 rp->rk.flags |= PACKED_RRSET_RPZ; 2049 new_reply_info->rrsets[0] = rp; 2050 msg->rep = new_reply_info; 2051 if(!rpz_add_soa(msg->rep, ms, az)) 2052 return NULL; 2053 return msg; 2054 } 2055 2056 static inline struct dns_msg* 2057 rpz_synthesize_nsip_localdata(struct rpz* r, struct module_qstate* ms, 2058 struct query_info* qi, struct clientip_synthesized_rr* data, 2059 struct auth_zone* az) 2060 { 2061 struct local_rrset* rrset; 2062 2063 rrset = rpz_find_synthesized_rrset(qi->qtype, data, 1); 2064 if(rrset == NULL) { 2065 verbose(VERB_ALGO, "rpz: nsip: no matching local data found"); 2066 return NULL; 2067 } 2068 2069 return rpz_synthesize_localdata_from_rrset(r, ms, qi, rrset, az); 2070 } 2071 2072 /* copy'n'paste from localzone.c */ 2073 static struct local_rrset* 2074 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok) 2075 { 2076 struct local_rrset* p, *cname = NULL; 2077 type = htons(type); 2078 for(p = data->rrsets; p; p = p->next) { 2079 if(p->rrset->rk.type == type) 2080 return p; 2081 if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) 2082 cname = p; 2083 } 2084 if(alias_ok) 2085 return cname; 2086 return NULL; 2087 } 2088 2089 /* based on localzone.c:local_data_answer() */ 2090 static inline struct dns_msg* 2091 rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms, 2092 struct query_info* qi, struct local_zone* z, 2093 struct matched_delegation_point const* match, struct auth_zone* az) 2094 { 2095 struct local_data key; 2096 struct local_data* ld; 2097 struct local_rrset* rrset; 2098 2099 if(match->dname == NULL) { return NULL; } 2100 2101 key.node.key = &key; 2102 key.name = match->dname; 2103 key.namelen = match->dname_len; 2104 key.namelabs = dname_count_labels(match->dname); 2105 2106 rpz_log_dname("nsdname local data", key.name, key.namelen); 2107 2108 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 2109 if(ld == NULL) { 2110 verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found"); 2111 return NULL; 2112 } 2113 2114 rrset = local_data_find_type(ld, qi->qtype, 1); 2115 if(rrset == NULL) { 2116 verbose(VERB_ALGO, "rpz: nsdname: no matching local data found"); 2117 return NULL; 2118 } 2119 2120 return rpz_synthesize_localdata_from_rrset(r, ms, qi, rrset, az); 2121 } 2122 2123 /* like local_data_answer for qname triggers after a cname */ 2124 static struct dns_msg* 2125 rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms, 2126 struct query_info* qinfo, struct local_zone* z, struct auth_zone* az) 2127 { 2128 struct local_data key; 2129 struct local_data* ld; 2130 struct local_rrset* rrset; 2131 key.node.key = &key; 2132 key.name = qinfo->qname; 2133 key.namelen = qinfo->qname_len; 2134 key.namelabs = dname_count_labels(qinfo->qname); 2135 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 2136 if(ld == NULL) { 2137 verbose(VERB_ALGO, "rpz: qname: name not found"); 2138 return NULL; 2139 } 2140 rrset = local_data_find_type(ld, qinfo->qtype, 1); 2141 if(rrset == NULL) { 2142 verbose(VERB_ALGO, "rpz: qname: type not found"); 2143 return NULL; 2144 } 2145 return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az); 2146 } 2147 2148 /** Synthesize a CNAME message for RPZ action override */ 2149 static struct dns_msg* 2150 rpz_synthesize_cname_override_msg(struct rpz* r, struct module_qstate* ms, 2151 struct query_info* qinfo) 2152 { 2153 struct dns_msg* msg = NULL; 2154 struct reply_info* new_reply_info; 2155 struct ub_packed_rrset_key* rp; 2156 2157 msg = rpz_dns_msg_new(ms->region); 2158 if(msg == NULL) { return NULL; } 2159 2160 msg->qinfo = *qinfo; 2161 new_reply_info = construct_reply_info_base(ms->region, 2162 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 2163 1, /* qd */ 2164 0, /* ttl */ 2165 0, /* prettl */ 2166 0, /* expttl */ 2167 1, /* an */ 2168 0, /* ns */ 2169 0, /* ar */ 2170 1, /* total */ 2171 sec_status_insecure, 2172 LDNS_EDE_NONE); 2173 if(new_reply_info == NULL) { 2174 log_err("out of memory"); 2175 return NULL; 2176 } 2177 new_reply_info->authoritative = 1; 2178 2179 rp = respip_copy_rrset(r->cname_override, ms->region); 2180 if(rp == NULL) { 2181 log_err("out of memory"); 2182 return NULL; 2183 } 2184 rp->rk.dname = qinfo->qname; 2185 rp->rk.dname_len = qinfo->qname_len; 2186 /* this rrset is from the rpz data, or synthesized. 2187 * It is not actually from the network, so we flag it with this 2188 * flags as a fake RRset. If later the cache is used to look up 2189 * rrsets, then the fake ones are not returned (if you look without 2190 * the flag). For like CNAME lookups from the iterator or A, AAAA 2191 * lookups for nameserver targets, it would use the without flag 2192 * actual data. So that the actual network data and fake data 2193 * are kept track of separately. */ 2194 rp->rk.flags |= PACKED_RRSET_RPZ; 2195 new_reply_info->rrsets[0] = rp; 2196 2197 msg->rep = new_reply_info; 2198 return msg; 2199 } 2200 2201 static int 2202 rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r, 2203 struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo, 2204 struct edns_data* edns, sldns_buffer* buf, struct regional* temp, 2205 struct comm_reply* repinfo, struct ub_server_stats* stats) 2206 { 2207 struct local_data* ld = NULL; 2208 int ret = 0; 2209 if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { 2210 if(!rpz_apply_cname_override_action(r, qinfo, temp)) 2211 return 0; 2212 if(r->log) { 2213 log_rpz_apply("qname", z->name, NULL, RPZ_CNAME_OVERRIDE_ACTION, 2214 qinfo, repinfo, NULL, r->log_name); 2215 } 2216 stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++; 2217 return 0; 2218 } 2219 2220 if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo, 2221 edns, repinfo, buf, temp, dname_count_labels(qinfo->qname), 2222 &ld, lzt, -1, NULL, 0, NULL, 0)) { 2223 if(r->log) { 2224 log_rpz_apply("qname", z->name, NULL, 2225 localzone_type_to_rpz_action(lzt), qinfo, 2226 repinfo, NULL, r->log_name); 2227 } 2228 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 2229 return !qinfo->local_alias; 2230 } 2231 2232 ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, 2233 0 /* no local data used */, lzt); 2234 if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 2235 == LDNS_RCODE_NXDOMAIN) 2236 LDNS_RA_CLR(sldns_buffer_begin(buf)); 2237 if(r->log) { 2238 log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt), 2239 qinfo, repinfo, NULL, r->log_name); 2240 } 2241 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 2242 return ret; 2243 } 2244 2245 static struct clientip_synthesized_rr* 2246 rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is) 2247 { 2248 struct delegpt_addr* cursor; 2249 struct clientip_synthesized_rr* action = NULL; 2250 if(is->dp == NULL) { return NULL; } 2251 for(cursor = is->dp->target_list; 2252 cursor != NULL; 2253 cursor = cursor->next_target) { 2254 if(cursor->bogus) { continue; } 2255 action = rpz_ipbased_trigger_lookup(rpz->ns_set, &cursor->addr, 2256 cursor->addrlen, "nsip"); 2257 if(action != NULL) { return action; } 2258 } 2259 return NULL; 2260 } 2261 2262 static struct dns_msg* 2263 rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase, 2264 struct rpz* r, struct clientip_synthesized_rr* raddr, 2265 struct auth_zone* az) 2266 { 2267 enum rpz_action action = raddr->action; 2268 struct dns_msg* ret = NULL; 2269 2270 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 2271 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 2272 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 2273 action = r->action_override; 2274 } 2275 2276 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) { 2277 verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data"); 2278 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2279 goto done; 2280 } 2281 2282 switch(action) { 2283 case RPZ_NXDOMAIN_ACTION: 2284 ret = rpz_synthesize_nxdomain(r, ms, qchase, az); 2285 break; 2286 case RPZ_NODATA_ACTION: 2287 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2288 break; 2289 case RPZ_TCP_ONLY_ACTION: 2290 /* basically a passthru here but the tcp-only will be 2291 * honored before the query gets sent. */ 2292 ms->tcp_required = 1; 2293 ret = NULL; 2294 break; 2295 case RPZ_DROP_ACTION: 2296 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2297 ms->is_drop = 1; 2298 break; 2299 case RPZ_LOCAL_DATA_ACTION: 2300 ret = rpz_synthesize_nsip_localdata(r, ms, qchase, raddr, az); 2301 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); } 2302 break; 2303 case RPZ_PASSTHRU_ACTION: 2304 ret = NULL; 2305 ms->rpz_passthru = 1; 2306 break; 2307 case RPZ_CNAME_OVERRIDE_ACTION: 2308 ret = rpz_synthesize_cname_override_msg(r, ms, qchase); 2309 break; 2310 default: 2311 verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'", 2312 rpz_action_to_string(action)); 2313 ret = NULL; 2314 } 2315 2316 done: 2317 if(r->log) 2318 log_rpz_apply("nsip", NULL, &raddr->node, 2319 action, &ms->qinfo, NULL, ms, r->log_name); 2320 if(ms->env->worker) 2321 ms->env->worker->stats.rpz_action[action]++; 2322 lock_rw_unlock(&raddr->lock); 2323 return ret; 2324 } 2325 2326 static struct dns_msg* 2327 rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase, 2328 struct rpz* r, struct local_zone* z, 2329 struct matched_delegation_point const* match, struct auth_zone* az) 2330 { 2331 struct dns_msg* ret = NULL; 2332 enum rpz_action action = localzone_type_to_rpz_action(z->type); 2333 2334 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 2335 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 2336 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 2337 action = r->action_override; 2338 } 2339 2340 switch(action) { 2341 case RPZ_NXDOMAIN_ACTION: 2342 ret = rpz_synthesize_nxdomain(r, ms, qchase, az); 2343 break; 2344 case RPZ_NODATA_ACTION: 2345 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2346 break; 2347 case RPZ_TCP_ONLY_ACTION: 2348 /* basically a passthru here but the tcp-only will be 2349 * honored before the query gets sent. */ 2350 ms->tcp_required = 1; 2351 ret = NULL; 2352 break; 2353 case RPZ_DROP_ACTION: 2354 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2355 ms->is_drop = 1; 2356 break; 2357 case RPZ_LOCAL_DATA_ACTION: 2358 ret = rpz_synthesize_nsdname_localdata(r, ms, qchase, z, match, az); 2359 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); } 2360 break; 2361 case RPZ_PASSTHRU_ACTION: 2362 ret = NULL; 2363 ms->rpz_passthru = 1; 2364 break; 2365 case RPZ_CNAME_OVERRIDE_ACTION: 2366 ret = rpz_synthesize_cname_override_msg(r, ms, qchase); 2367 break; 2368 default: 2369 verbose(VERB_ALGO, "rpz: nsdname: bug: unhandled or invalid action: '%s'", 2370 rpz_action_to_string(action)); 2371 ret = NULL; 2372 } 2373 2374 if(r->log) 2375 log_rpz_apply("nsdname", match->dname, NULL, 2376 action, &ms->qinfo, NULL, ms, r->log_name); 2377 if(ms->env->worker) 2378 ms->env->worker->stats.rpz_action[action]++; 2379 lock_rw_unlock(&z->lock); 2380 return ret; 2381 } 2382 2383 static struct local_zone* 2384 rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones, 2385 uint16_t qclass, 2386 /* output parameter */ 2387 struct matched_delegation_point* match) 2388 { 2389 struct delegpt_ns* nameserver; 2390 struct local_zone* z = NULL; 2391 2392 /* the rpz specs match the nameserver names (NS records), not the 2393 * name of the delegation point itself, to the nsdname triggers */ 2394 for(nameserver = dp->nslist; 2395 nameserver != NULL; 2396 nameserver = nameserver->next) { 2397 z = rpz_find_zone(zones, nameserver->name, nameserver->namelen, 2398 qclass, 0, 0, 0); 2399 if(z != NULL) { 2400 match->dname = nameserver->name; 2401 match->dname_len = nameserver->namelen; 2402 if(verbosity >= VERB_ALGO) { 2403 char nm[255+1], zn[255+1]; 2404 dname_str(match->dname, nm); 2405 dname_str(z->name, zn); 2406 if(strcmp(nm, zn) != 0) 2407 verbose(VERB_ALGO, "rpz: trigger nsdname %s on %s action=%s", 2408 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2409 else 2410 verbose(VERB_ALGO, "rpz: trigger nsdname %s action=%s", 2411 nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2412 } 2413 break; 2414 } 2415 } 2416 2417 return z; 2418 } 2419 2420 struct dns_msg* 2421 rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate* is) 2422 { 2423 struct auth_zones* az; 2424 struct auth_zone* a; 2425 struct clientip_synthesized_rr* raddr = NULL; 2426 struct rpz* r = NULL; 2427 struct local_zone* z = NULL; 2428 struct matched_delegation_point match = {0}; 2429 2430 if(ms->rpz_passthru) { 2431 verbose(VERB_ALGO, "query is rpz_passthru, no further processing"); 2432 return NULL; 2433 } 2434 2435 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2436 2437 az = ms->env->auth_zones; 2438 2439 verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL); 2440 2441 lock_rw_rdlock(&az->rpz_lock); 2442 2443 /* precedence of RPZ works, loosely, like this: 2444 * CNAMEs in order of the CNAME chain. rpzs in the order they are 2445 * configured. In an RPZ: first client-IP addr, then QNAME, then 2446 * response IP, then NSDNAME, then NSIP. Longest match first. Smallest 2447 * one from a set. */ 2448 /* we use the precedence rules for the topics and triggers that 2449 * are pertinent at this stage of the resolve processing */ 2450 for(a = az->rpz_first; a != NULL; a = a->rpz_az_next) { 2451 lock_rw_rdlock(&a->lock); 2452 r = a->rpz; 2453 if(r->disabled) { 2454 lock_rw_unlock(&a->lock); 2455 continue; 2456 } 2457 2458 /* the nsdname has precedence over the nsip triggers */ 2459 z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones, 2460 is->qchase.qclass, &match); 2461 if(z != NULL) { 2462 lock_rw_unlock(&a->lock); 2463 break; 2464 } 2465 2466 raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is); 2467 if(raddr != NULL) { 2468 lock_rw_unlock(&a->lock); 2469 break; 2470 } 2471 lock_rw_unlock(&a->lock); 2472 } 2473 2474 lock_rw_unlock(&az->rpz_lock); 2475 2476 if(raddr == NULL && z == NULL) 2477 return NULL; 2478 2479 if(raddr != NULL) { 2480 if(z) { 2481 lock_rw_unlock(&z->lock); 2482 } 2483 return rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a); 2484 } 2485 return rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a); 2486 } 2487 2488 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms, 2489 struct iter_qstate* is) 2490 { 2491 struct auth_zones* az; 2492 struct auth_zone* a = NULL; 2493 struct rpz* r = NULL; 2494 struct local_zone* z = NULL; 2495 enum localzone_type lzt; 2496 struct dns_msg* ret = NULL; 2497 2498 if(ms->rpz_passthru) { 2499 verbose(VERB_ALGO, "query is rpz_passthru, no further processing"); 2500 return NULL; 2501 } 2502 2503 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2504 az = ms->env->auth_zones; 2505 2506 lock_rw_rdlock(&az->rpz_lock); 2507 2508 for(a = az->rpz_first; a; a = a->rpz_az_next) { 2509 lock_rw_rdlock(&a->lock); 2510 r = a->rpz; 2511 if(r->disabled) { 2512 lock_rw_unlock(&a->lock); 2513 continue; 2514 } 2515 z = rpz_find_zone(r->local_zones, is->qchase.qname, 2516 is->qchase.qname_len, is->qchase.qclass, 0, 0, 0); 2517 if(z && r->action_override == RPZ_DISABLED_ACTION) { 2518 if(r->log) 2519 log_rpz_apply("qname", z->name, NULL, 2520 r->action_override, 2521 &ms->qinfo, NULL, ms, r->log_name); 2522 if(ms->env->worker) 2523 ms->env->worker->stats.rpz_action[r->action_override]++; 2524 lock_rw_unlock(&z->lock); 2525 z = NULL; 2526 } 2527 if(z) { 2528 break; 2529 } 2530 /* not found in this auth_zone */ 2531 lock_rw_unlock(&a->lock); 2532 } 2533 lock_rw_unlock(&az->rpz_lock); 2534 2535 if(z == NULL) 2536 return NULL; 2537 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2538 lzt = z->type; 2539 } else { 2540 lzt = rpz_action_to_localzone_type(r->action_override); 2541 } 2542 2543 if(verbosity >= VERB_ALGO) { 2544 char nm[255+1], zn[255+1]; 2545 dname_str(is->qchase.qname, nm); 2546 dname_str(z->name, zn); 2547 if(strcmp(zn, nm) != 0) 2548 verbose(VERB_ALGO, "rpz: qname trigger %s on %s, with action=%s", 2549 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2550 else 2551 verbose(VERB_ALGO, "rpz: qname trigger %s, with action=%s", 2552 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2553 } 2554 switch(localzone_type_to_rpz_action(lzt)) { 2555 case RPZ_NXDOMAIN_ACTION: 2556 ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a); 2557 break; 2558 case RPZ_NODATA_ACTION: 2559 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2560 break; 2561 case RPZ_TCP_ONLY_ACTION: 2562 /* basically a passthru here but the tcp-only will be 2563 * honored before the query gets sent. */ 2564 ms->tcp_required = 1; 2565 ret = NULL; 2566 break; 2567 case RPZ_DROP_ACTION: 2568 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2569 ms->is_drop = 1; 2570 break; 2571 case RPZ_LOCAL_DATA_ACTION: 2572 ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a); 2573 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); } 2574 break; 2575 case RPZ_PASSTHRU_ACTION: 2576 ret = NULL; 2577 ms->rpz_passthru = 1; 2578 break; 2579 default: 2580 verbose(VERB_ALGO, "rpz: qname trigger: bug: unhandled or invalid action: '%s'", 2581 rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2582 ret = NULL; 2583 } 2584 if(r->log) 2585 log_rpz_apply("qname", (z?z->name:NULL), NULL, 2586 localzone_type_to_rpz_action(lzt), 2587 &is->qchase, NULL, ms, r->log_name); 2588 lock_rw_unlock(&z->lock); 2589 lock_rw_unlock(&a->lock); 2590 return ret; 2591 } 2592 2593 static int 2594 rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env, 2595 struct query_info* qinfo, struct edns_data* edns, struct comm_reply* repinfo, 2596 uint8_t* taglist, size_t taglen, struct ub_server_stats* stats, 2597 sldns_buffer* buf, struct regional* temp, 2598 /* output parameters */ 2599 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out, 2600 int* passthru) 2601 { 2602 int ret = 0; 2603 enum rpz_action client_action; 2604 struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone( 2605 az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out); 2606 2607 client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action); 2608 if(node != NULL && *r_out && 2609 (*r_out)->action_override != RPZ_NO_OVERRIDE_ACTION) { 2610 client_action = (*r_out)->action_override; 2611 } 2612 if(client_action == RPZ_PASSTHRU_ACTION) { 2613 if(*r_out && (*r_out)->log) 2614 log_rpz_apply( 2615 (node?"clientip":"qname"), 2616 ((*z_out)?(*z_out)->name:NULL), 2617 (node?&node->node:NULL), 2618 client_action, qinfo, repinfo, NULL, 2619 (*r_out)->log_name); 2620 *passthru = 1; 2621 ret = 0; 2622 goto done; 2623 } 2624 if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION && 2625 client_action != RPZ_PASSTHRU_ACTION)) { 2626 if(client_action == RPZ_PASSTHRU_ACTION 2627 || client_action == RPZ_INVALID_ACTION 2628 || (client_action == RPZ_TCP_ONLY_ACTION 2629 && !rpz_is_udp_query(repinfo))) { 2630 ret = 0; 2631 goto done; 2632 } 2633 stats->rpz_action[client_action]++; 2634 if(client_action == RPZ_LOCAL_DATA_ACTION) { 2635 rpz_apply_clientip_localdata_action(node, env, qinfo, 2636 edns, repinfo, buf, temp, *a_out); 2637 ret = 1; 2638 } else if(client_action == RPZ_CNAME_OVERRIDE_ACTION) { 2639 if(!rpz_apply_cname_override_action(*r_out, qinfo, 2640 temp)) { 2641 ret = 0; 2642 goto done; 2643 } 2644 ret = 0; 2645 } else { 2646 local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns, 2647 repinfo, buf, temp, 0 /* no local data used */, 2648 rpz_action_to_localzone_type(client_action)); 2649 if(*r_out && (*r_out)->signal_nxdomain_ra && 2650 LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 2651 == LDNS_RCODE_NXDOMAIN) 2652 LDNS_RA_CLR(sldns_buffer_begin(buf)); 2653 ret = 1; 2654 } 2655 if(*r_out && (*r_out)->log) 2656 log_rpz_apply( 2657 (node?"clientip":"qname"), 2658 ((*z_out)?(*z_out)->name:NULL), 2659 (node?&node->node:NULL), 2660 client_action, qinfo, repinfo, NULL, 2661 (*r_out)->log_name); 2662 goto done; 2663 } 2664 ret = -1; 2665 done: 2666 if(node != NULL) { 2667 lock_rw_unlock(&node->lock); 2668 } 2669 return ret; 2670 } 2671 2672 int 2673 rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env, 2674 struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, 2675 struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, 2676 size_t taglen, struct ub_server_stats* stats, int* passthru) 2677 { 2678 struct rpz* r = NULL; 2679 struct auth_zone* a = NULL; 2680 struct local_zone* z = NULL; 2681 int ret; 2682 enum localzone_type lzt; 2683 2684 int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo, 2685 edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r, 2686 passthru); 2687 if(clientip_trigger >= 0) { 2688 if(a) { 2689 lock_rw_unlock(&a->lock); 2690 } 2691 if(z) { 2692 lock_rw_unlock(&z->lock); 2693 } 2694 return clientip_trigger; 2695 } 2696 2697 if(z == NULL) { 2698 if(a) { 2699 lock_rw_unlock(&a->lock); 2700 } 2701 return 0; 2702 } 2703 2704 log_assert(r); 2705 2706 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2707 lzt = z->type; 2708 } else { 2709 lzt = rpz_action_to_localzone_type(r->action_override); 2710 } 2711 if(r->action_override == RPZ_PASSTHRU_ACTION || 2712 lzt == local_zone_always_transparent /* RPZ_PASSTHRU_ACTION */) { 2713 *passthru = 1; 2714 } 2715 2716 if(verbosity >= VERB_ALGO) { 2717 char nm[255+1], zn[255+1]; 2718 dname_str(qinfo->qname, nm); 2719 dname_str(z->name, zn); 2720 if(strcmp(zn, nm) != 0) 2721 verbose(VERB_ALGO, "rpz: qname trigger %s on %s with action=%s", 2722 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2723 else 2724 verbose(VERB_ALGO, "rpz: qname trigger %s with action=%s", 2725 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2726 } 2727 2728 ret = rpz_synthesize_qname_localdata(env, r, z, lzt, qinfo, edns, buf, temp, 2729 repinfo, stats); 2730 2731 lock_rw_unlock(&z->lock); 2732 lock_rw_unlock(&a->lock); 2733 2734 return ret; 2735 } 2736 2737 void rpz_enable(struct rpz* r) 2738 { 2739 if(!r) 2740 return; 2741 r->disabled = 0; 2742 } 2743 2744 void rpz_disable(struct rpz* r) 2745 { 2746 if(!r) 2747 return; 2748 r->disabled = 1; 2749 } 2750