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