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