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, /* norecttl */ 1973 0, /* an */ 1974 0, /* ns */ 1975 0, /* ar */ 1976 0, /* total */ 1977 sec_status_insecure, 1978 LDNS_EDE_NONE); 1979 if(msg->rep) 1980 msg->rep->authoritative = 1; 1981 if(!rpz_add_soa(msg->rep, ms, az)) 1982 return NULL; 1983 return msg; 1984 } 1985 1986 static inline struct dns_msg* 1987 rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms, 1988 struct query_info* qinfo, struct auth_zone* az) 1989 { 1990 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1991 uint16_t flags; 1992 if(msg == NULL) { return msg; } 1993 msg->qinfo = *qinfo; 1994 flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA; 1995 if(r->signal_nxdomain_ra) 1996 flags &= ~BIT_RA; 1997 msg->rep = construct_reply_info_base(ms->region, 1998 flags, 1999 1, /* qd */ 2000 0, /* ttl */ 2001 0, /* prettl */ 2002 0, /* expttl */ 2003 0, /* norecttl */ 2004 0, /* an */ 2005 0, /* ns */ 2006 0, /* ar */ 2007 0, /* total */ 2008 sec_status_insecure, 2009 LDNS_EDE_NONE); 2010 if(msg->rep) 2011 msg->rep->authoritative = 1; 2012 if(!rpz_add_soa(msg->rep, ms, az)) 2013 return NULL; 2014 return msg; 2015 } 2016 2017 static inline struct dns_msg* 2018 rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 2019 struct query_info* qi, struct local_rrset* rrset, struct auth_zone* az) 2020 { 2021 struct dns_msg* msg = NULL; 2022 struct reply_info* new_reply_info; 2023 struct ub_packed_rrset_key* rp; 2024 2025 2026 msg = rpz_dns_msg_new(ms->region); 2027 if(msg == NULL) { return NULL; } 2028 2029 msg->qinfo = *qi; 2030 new_reply_info = construct_reply_info_base(ms->region, 2031 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 2032 1, /* qd */ 2033 0, /* ttl */ 2034 0, /* prettl */ 2035 0, /* expttl */ 2036 0, /* norecttl */ 2037 1, /* an */ 2038 0, /* ns */ 2039 0, /* ar */ 2040 1, /* total */ 2041 sec_status_insecure, 2042 LDNS_EDE_NONE); 2043 if(new_reply_info == NULL) { 2044 log_err("out of memory"); 2045 return NULL; 2046 } 2047 new_reply_info->authoritative = 1; 2048 rp = respip_copy_rrset(rrset->rrset, ms->region); 2049 if(rp == NULL) { 2050 log_err("out of memory"); 2051 return NULL; 2052 } 2053 rp->rk.dname = qi->qname; 2054 rp->rk.dname_len = qi->qname_len; 2055 /* this rrset is from the rpz data, or synthesized. 2056 * It is not actually from the network, so we flag it with this 2057 * flags as a fake RRset. If later the cache is used to look up 2058 * rrsets, then the fake ones are not returned (if you look without 2059 * the flag). For like CNAME lookups from the iterator or A, AAAA 2060 * lookups for nameserver targets, it would use the without flag 2061 * actual data. So that the actual network data and fake data 2062 * are kept track of separately. */ 2063 rp->rk.flags |= PACKED_RRSET_RPZ; 2064 new_reply_info->rrsets[0] = rp; 2065 msg->rep = new_reply_info; 2066 if(!rpz_add_soa(msg->rep, ms, az)) 2067 return NULL; 2068 return msg; 2069 } 2070 2071 static inline struct dns_msg* 2072 rpz_synthesize_nsip_localdata(struct rpz* r, struct module_qstate* ms, 2073 struct query_info* qi, struct clientip_synthesized_rr* data, 2074 struct auth_zone* az) 2075 { 2076 struct local_rrset* rrset; 2077 2078 rrset = rpz_find_synthesized_rrset(qi->qtype, data, 1); 2079 if(rrset == NULL) { 2080 verbose(VERB_ALGO, "rpz: nsip: no matching local data found"); 2081 return NULL; 2082 } 2083 2084 return rpz_synthesize_localdata_from_rrset(r, ms, qi, rrset, az); 2085 } 2086 2087 /* copy'n'paste from localzone.c */ 2088 static struct local_rrset* 2089 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok) 2090 { 2091 struct local_rrset* p, *cname = NULL; 2092 type = htons(type); 2093 for(p = data->rrsets; p; p = p->next) { 2094 if(p->rrset->rk.type == type) 2095 return p; 2096 if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) 2097 cname = p; 2098 } 2099 if(alias_ok) 2100 return cname; 2101 return NULL; 2102 } 2103 2104 /* based on localzone.c:local_data_answer() */ 2105 static inline struct dns_msg* 2106 rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms, 2107 struct query_info* qi, struct local_zone* z, 2108 struct matched_delegation_point const* match, struct auth_zone* az) 2109 { 2110 struct local_data key; 2111 struct local_data* ld; 2112 struct local_rrset* rrset; 2113 2114 if(match->dname == NULL) { return NULL; } 2115 2116 key.node.key = &key; 2117 key.name = match->dname; 2118 key.namelen = match->dname_len; 2119 key.namelabs = dname_count_labels(match->dname); 2120 2121 rpz_log_dname("nsdname local data", key.name, key.namelen); 2122 2123 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 2124 if(ld == NULL) { 2125 verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found"); 2126 return NULL; 2127 } 2128 2129 rrset = local_data_find_type(ld, qi->qtype, 1); 2130 if(rrset == NULL) { 2131 verbose(VERB_ALGO, "rpz: nsdname: no matching local data found"); 2132 return NULL; 2133 } 2134 2135 return rpz_synthesize_localdata_from_rrset(r, ms, qi, rrset, az); 2136 } 2137 2138 /* like local_data_answer for qname triggers after a cname */ 2139 static struct dns_msg* 2140 rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms, 2141 struct query_info* qinfo, struct local_zone* z, struct auth_zone* az) 2142 { 2143 struct local_data key; 2144 struct local_data* ld; 2145 struct local_rrset* rrset; 2146 key.node.key = &key; 2147 key.name = qinfo->qname; 2148 key.namelen = qinfo->qname_len; 2149 key.namelabs = dname_count_labels(qinfo->qname); 2150 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 2151 if(ld == NULL) { 2152 verbose(VERB_ALGO, "rpz: qname: name not found"); 2153 return NULL; 2154 } 2155 rrset = local_data_find_type(ld, qinfo->qtype, 1); 2156 if(rrset == NULL) { 2157 verbose(VERB_ALGO, "rpz: qname: type not found"); 2158 return NULL; 2159 } 2160 return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az); 2161 } 2162 2163 /** Synthesize a CNAME message for RPZ action override */ 2164 static struct dns_msg* 2165 rpz_synthesize_cname_override_msg(struct rpz* r, struct module_qstate* ms, 2166 struct query_info* qinfo) 2167 { 2168 struct dns_msg* msg = NULL; 2169 struct reply_info* new_reply_info; 2170 struct ub_packed_rrset_key* rp; 2171 2172 msg = rpz_dns_msg_new(ms->region); 2173 if(msg == NULL) { return NULL; } 2174 2175 msg->qinfo = *qinfo; 2176 new_reply_info = construct_reply_info_base(ms->region, 2177 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 2178 1, /* qd */ 2179 0, /* ttl */ 2180 0, /* prettl */ 2181 0, /* expttl */ 2182 0, /* norecttl */ 2183 1, /* an */ 2184 0, /* ns */ 2185 0, /* ar */ 2186 1, /* total */ 2187 sec_status_insecure, 2188 LDNS_EDE_NONE); 2189 if(new_reply_info == NULL) { 2190 log_err("out of memory"); 2191 return NULL; 2192 } 2193 new_reply_info->authoritative = 1; 2194 2195 rp = respip_copy_rrset(r->cname_override, ms->region); 2196 if(rp == NULL) { 2197 log_err("out of memory"); 2198 return NULL; 2199 } 2200 rp->rk.dname = qinfo->qname; 2201 rp->rk.dname_len = qinfo->qname_len; 2202 /* this rrset is from the rpz data, or synthesized. 2203 * It is not actually from the network, so we flag it with this 2204 * flags as a fake RRset. If later the cache is used to look up 2205 * rrsets, then the fake ones are not returned (if you look without 2206 * the flag). For like CNAME lookups from the iterator or A, AAAA 2207 * lookups for nameserver targets, it would use the without flag 2208 * actual data. So that the actual network data and fake data 2209 * are kept track of separately. */ 2210 rp->rk.flags |= PACKED_RRSET_RPZ; 2211 new_reply_info->rrsets[0] = rp; 2212 2213 msg->rep = new_reply_info; 2214 return msg; 2215 } 2216 2217 static int 2218 rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r, 2219 struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo, 2220 struct edns_data* edns, sldns_buffer* buf, struct regional* temp, 2221 struct comm_reply* repinfo, struct ub_server_stats* stats) 2222 { 2223 struct local_data* ld = NULL; 2224 int ret = 0; 2225 if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { 2226 if(!rpz_apply_cname_override_action(r, qinfo, temp)) 2227 return 0; 2228 if(r->log) { 2229 log_rpz_apply("qname", z->name, NULL, RPZ_CNAME_OVERRIDE_ACTION, 2230 qinfo, repinfo, NULL, r->log_name); 2231 } 2232 stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++; 2233 return 0; 2234 } 2235 2236 if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo, 2237 edns, repinfo, buf, temp, dname_count_labels(qinfo->qname), 2238 &ld, lzt, -1, NULL, 0, NULL, 0)) { 2239 if(r->log) { 2240 log_rpz_apply("qname", z->name, NULL, 2241 localzone_type_to_rpz_action(lzt), qinfo, 2242 repinfo, NULL, r->log_name); 2243 } 2244 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 2245 return !qinfo->local_alias; 2246 } 2247 2248 ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, 2249 0 /* no local data used */, lzt); 2250 if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 2251 == LDNS_RCODE_NXDOMAIN) 2252 LDNS_RA_CLR(sldns_buffer_begin(buf)); 2253 if(r->log) { 2254 log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt), 2255 qinfo, repinfo, NULL, r->log_name); 2256 } 2257 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 2258 return ret; 2259 } 2260 2261 static struct clientip_synthesized_rr* 2262 rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is) 2263 { 2264 struct delegpt_addr* cursor; 2265 struct clientip_synthesized_rr* action = NULL; 2266 if(is->dp == NULL) { return NULL; } 2267 for(cursor = is->dp->target_list; 2268 cursor != NULL; 2269 cursor = cursor->next_target) { 2270 if(cursor->bogus) { continue; } 2271 action = rpz_ipbased_trigger_lookup(rpz->ns_set, &cursor->addr, 2272 cursor->addrlen, "nsip"); 2273 if(action != NULL) { return action; } 2274 } 2275 return NULL; 2276 } 2277 2278 static struct dns_msg* 2279 rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase, 2280 struct rpz* r, struct clientip_synthesized_rr* raddr, 2281 struct auth_zone* az) 2282 { 2283 enum rpz_action action = raddr->action; 2284 struct dns_msg* ret = NULL; 2285 2286 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 2287 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 2288 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 2289 action = r->action_override; 2290 } 2291 2292 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) { 2293 verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data"); 2294 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2295 ms->rpz_applied = 1; 2296 goto done; 2297 } 2298 2299 switch(action) { 2300 case RPZ_NXDOMAIN_ACTION: 2301 ret = rpz_synthesize_nxdomain(r, ms, qchase, az); 2302 ms->rpz_applied = 1; 2303 break; 2304 case RPZ_NODATA_ACTION: 2305 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2306 ms->rpz_applied = 1; 2307 break; 2308 case RPZ_TCP_ONLY_ACTION: 2309 /* basically a passthru here but the tcp-only will be 2310 * honored before the query gets sent. */ 2311 ms->tcp_required = 1; 2312 ret = NULL; 2313 break; 2314 case RPZ_DROP_ACTION: 2315 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2316 ms->rpz_applied = 1; 2317 ms->is_drop = 1; 2318 break; 2319 case RPZ_LOCAL_DATA_ACTION: 2320 ret = rpz_synthesize_nsip_localdata(r, ms, qchase, raddr, az); 2321 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); } 2322 ms->rpz_applied = 1; 2323 break; 2324 case RPZ_PASSTHRU_ACTION: 2325 ret = NULL; 2326 ms->rpz_passthru = 1; 2327 break; 2328 case RPZ_CNAME_OVERRIDE_ACTION: 2329 ret = rpz_synthesize_cname_override_msg(r, ms, qchase); 2330 ms->rpz_applied = 1; 2331 break; 2332 default: 2333 verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'", 2334 rpz_action_to_string(action)); 2335 ret = NULL; 2336 } 2337 2338 done: 2339 if(r->log) 2340 log_rpz_apply("nsip", NULL, &raddr->node, 2341 action, &ms->qinfo, NULL, ms, r->log_name); 2342 if(ms->env->worker) 2343 ms->env->worker->stats.rpz_action[action]++; 2344 lock_rw_unlock(&raddr->lock); 2345 return ret; 2346 } 2347 2348 static struct dns_msg* 2349 rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase, 2350 struct rpz* r, struct local_zone* z, 2351 struct matched_delegation_point const* match, struct auth_zone* az) 2352 { 2353 struct dns_msg* ret = NULL; 2354 enum rpz_action action = localzone_type_to_rpz_action(z->type); 2355 2356 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 2357 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 2358 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 2359 action = r->action_override; 2360 } 2361 2362 switch(action) { 2363 case RPZ_NXDOMAIN_ACTION: 2364 ret = rpz_synthesize_nxdomain(r, ms, qchase, az); 2365 ms->rpz_applied = 1; 2366 break; 2367 case RPZ_NODATA_ACTION: 2368 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2369 ms->rpz_applied = 1; 2370 break; 2371 case RPZ_TCP_ONLY_ACTION: 2372 /* basically a passthru here but the tcp-only will be 2373 * honored before the query gets sent. */ 2374 ms->tcp_required = 1; 2375 ret = NULL; 2376 break; 2377 case RPZ_DROP_ACTION: 2378 ret = rpz_synthesize_nodata(r, ms, qchase, az); 2379 ms->rpz_applied = 1; 2380 ms->is_drop = 1; 2381 break; 2382 case RPZ_LOCAL_DATA_ACTION: 2383 ret = rpz_synthesize_nsdname_localdata(r, ms, qchase, z, match, az); 2384 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); } 2385 ms->rpz_applied = 1; 2386 break; 2387 case RPZ_PASSTHRU_ACTION: 2388 ret = NULL; 2389 ms->rpz_passthru = 1; 2390 break; 2391 case RPZ_CNAME_OVERRIDE_ACTION: 2392 ret = rpz_synthesize_cname_override_msg(r, ms, qchase); 2393 ms->rpz_applied = 1; 2394 break; 2395 default: 2396 verbose(VERB_ALGO, "rpz: nsdname: bug: unhandled or invalid action: '%s'", 2397 rpz_action_to_string(action)); 2398 ret = NULL; 2399 } 2400 2401 if(r->log) 2402 log_rpz_apply("nsdname", match->dname, NULL, 2403 action, &ms->qinfo, NULL, ms, r->log_name); 2404 if(ms->env->worker) 2405 ms->env->worker->stats.rpz_action[action]++; 2406 lock_rw_unlock(&z->lock); 2407 return ret; 2408 } 2409 2410 static struct local_zone* 2411 rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones, 2412 uint16_t qclass, 2413 /* output parameter */ 2414 struct matched_delegation_point* match) 2415 { 2416 struct delegpt_ns* nameserver; 2417 struct local_zone* z = NULL; 2418 2419 /* the rpz specs match the nameserver names (NS records), not the 2420 * name of the delegation point itself, to the nsdname triggers */ 2421 for(nameserver = dp->nslist; 2422 nameserver != NULL; 2423 nameserver = nameserver->next) { 2424 z = rpz_find_zone(zones, nameserver->name, nameserver->namelen, 2425 qclass, 0, 0, 0); 2426 if(z != NULL) { 2427 match->dname = nameserver->name; 2428 match->dname_len = nameserver->namelen; 2429 if(verbosity >= VERB_ALGO) { 2430 char nm[255+1], zn[255+1]; 2431 dname_str(match->dname, nm); 2432 dname_str(z->name, zn); 2433 if(strcmp(nm, zn) != 0) 2434 verbose(VERB_ALGO, "rpz: trigger nsdname %s on %s action=%s", 2435 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2436 else 2437 verbose(VERB_ALGO, "rpz: trigger nsdname %s action=%s", 2438 nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2439 } 2440 break; 2441 } 2442 } 2443 2444 return z; 2445 } 2446 2447 struct dns_msg* 2448 rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate* is) 2449 { 2450 struct auth_zones* az; 2451 struct auth_zone* a; 2452 struct clientip_synthesized_rr* raddr = NULL; 2453 struct rpz* r = NULL; 2454 struct local_zone* z = NULL; 2455 struct matched_delegation_point match = {0}; 2456 2457 if(ms->rpz_passthru) { 2458 verbose(VERB_ALGO, "query is rpz_passthru, no further processing"); 2459 return NULL; 2460 } 2461 2462 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2463 2464 az = ms->env->auth_zones; 2465 lock_rw_rdlock(&az->rpz_lock); 2466 2467 verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL); 2468 2469 /* precedence of RPZ works, loosely, like this: 2470 * CNAMEs in order of the CNAME chain. rpzs in the order they are 2471 * configured. In an RPZ: first client-IP addr, then QNAME, then 2472 * response IP, then NSDNAME, then NSIP. Longest match first. Smallest 2473 * one from a set. */ 2474 /* we use the precedence rules for the topics and triggers that 2475 * are pertinent at this stage of the resolve processing */ 2476 for(a = az->rpz_first; a != NULL; a = a->rpz_az_next) { 2477 lock_rw_rdlock(&a->lock); 2478 r = a->rpz; 2479 if(r->disabled) { 2480 lock_rw_unlock(&a->lock); 2481 continue; 2482 } 2483 if(r->taglist && (!ms->client_info || 2484 !taglist_intersect(r->taglist, r->taglistlen, 2485 ms->client_info->taglist, 2486 ms->client_info->taglen))) { 2487 lock_rw_unlock(&a->lock); 2488 continue; 2489 } 2490 2491 /* the nsdname has precedence over the nsip triggers */ 2492 z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones, 2493 is->qchase.qclass, &match); 2494 if(z != NULL) { 2495 lock_rw_unlock(&a->lock); 2496 break; 2497 } 2498 2499 raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is); 2500 if(raddr != NULL) { 2501 lock_rw_unlock(&a->lock); 2502 break; 2503 } 2504 lock_rw_unlock(&a->lock); 2505 } 2506 2507 lock_rw_unlock(&az->rpz_lock); 2508 2509 if(raddr == NULL && z == NULL) 2510 return NULL; 2511 2512 if(raddr != NULL) { 2513 if(z) { 2514 lock_rw_unlock(&z->lock); 2515 } 2516 return rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a); 2517 } 2518 return rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a); 2519 } 2520 2521 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms, 2522 struct iter_qstate* is) 2523 { 2524 struct auth_zones* az; 2525 struct auth_zone* a = NULL; 2526 struct rpz* r = NULL; 2527 struct local_zone* z = NULL; 2528 enum localzone_type lzt; 2529 struct dns_msg* ret = NULL; 2530 2531 if(ms->rpz_passthru) { 2532 verbose(VERB_ALGO, "query is rpz_passthru, no further processing"); 2533 return NULL; 2534 } 2535 2536 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2537 az = ms->env->auth_zones; 2538 2539 lock_rw_rdlock(&az->rpz_lock); 2540 2541 for(a = az->rpz_first; a; a = a->rpz_az_next) { 2542 lock_rw_rdlock(&a->lock); 2543 r = a->rpz; 2544 if(r->disabled) { 2545 lock_rw_unlock(&a->lock); 2546 continue; 2547 } 2548 if(r->taglist && (!ms->client_info || 2549 !taglist_intersect(r->taglist, r->taglistlen, 2550 ms->client_info->taglist, 2551 ms->client_info->taglen))) { 2552 lock_rw_unlock(&a->lock); 2553 continue; 2554 } 2555 z = rpz_find_zone(r->local_zones, is->qchase.qname, 2556 is->qchase.qname_len, is->qchase.qclass, 0, 0, 0); 2557 if(z && r->action_override == RPZ_DISABLED_ACTION) { 2558 if(r->log) 2559 log_rpz_apply("qname", z->name, NULL, 2560 r->action_override, 2561 &ms->qinfo, NULL, ms, r->log_name); 2562 if(ms->env->worker) 2563 ms->env->worker->stats.rpz_action[r->action_override]++; 2564 lock_rw_unlock(&z->lock); 2565 z = NULL; 2566 } 2567 if(z) { 2568 break; 2569 } 2570 /* not found in this auth_zone */ 2571 lock_rw_unlock(&a->lock); 2572 } 2573 lock_rw_unlock(&az->rpz_lock); 2574 2575 if(z == NULL) 2576 return NULL; 2577 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2578 lzt = z->type; 2579 } else { 2580 lzt = rpz_action_to_localzone_type(r->action_override); 2581 } 2582 2583 if(verbosity >= VERB_ALGO) { 2584 char nm[255+1], zn[255+1]; 2585 dname_str(is->qchase.qname, nm); 2586 dname_str(z->name, zn); 2587 if(strcmp(zn, nm) != 0) 2588 verbose(VERB_ALGO, "rpz: qname trigger %s on %s, with action=%s", 2589 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2590 else 2591 verbose(VERB_ALGO, "rpz: qname trigger %s, with action=%s", 2592 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2593 } 2594 switch(localzone_type_to_rpz_action(lzt)) { 2595 case RPZ_NXDOMAIN_ACTION: 2596 ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a); 2597 ms->rpz_applied = 1; 2598 break; 2599 case RPZ_NODATA_ACTION: 2600 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2601 ms->rpz_applied = 1; 2602 break; 2603 case RPZ_TCP_ONLY_ACTION: 2604 /* basically a passthru here but the tcp-only will be 2605 * honored before the query gets sent. */ 2606 ms->tcp_required = 1; 2607 ret = NULL; 2608 break; 2609 case RPZ_DROP_ACTION: 2610 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2611 ms->rpz_applied = 1; 2612 ms->is_drop = 1; 2613 break; 2614 case RPZ_LOCAL_DATA_ACTION: 2615 ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a); 2616 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); } 2617 ms->rpz_applied = 1; 2618 break; 2619 case RPZ_PASSTHRU_ACTION: 2620 ret = NULL; 2621 ms->rpz_passthru = 1; 2622 break; 2623 default: 2624 verbose(VERB_ALGO, "rpz: qname trigger: bug: unhandled or invalid action: '%s'", 2625 rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2626 ret = NULL; 2627 } 2628 if(r->log) 2629 log_rpz_apply("qname", (z?z->name:NULL), NULL, 2630 localzone_type_to_rpz_action(lzt), 2631 &is->qchase, NULL, ms, r->log_name); 2632 lock_rw_unlock(&z->lock); 2633 lock_rw_unlock(&a->lock); 2634 return ret; 2635 } 2636 2637 static int 2638 rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env, 2639 struct query_info* qinfo, struct edns_data* edns, struct comm_reply* repinfo, 2640 uint8_t* taglist, size_t taglen, struct ub_server_stats* stats, 2641 sldns_buffer* buf, struct regional* temp, 2642 /* output parameters */ 2643 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out, 2644 int* passthru) 2645 { 2646 int ret = 0; 2647 enum rpz_action client_action; 2648 struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone( 2649 az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out); 2650 2651 client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action); 2652 if(node != NULL && *r_out && 2653 (*r_out)->action_override != RPZ_NO_OVERRIDE_ACTION) { 2654 client_action = (*r_out)->action_override; 2655 } 2656 if(client_action == RPZ_PASSTHRU_ACTION) { 2657 if(*r_out && (*r_out)->log) 2658 log_rpz_apply( 2659 (node?"clientip":"qname"), 2660 ((*z_out)?(*z_out)->name:NULL), 2661 (node?&node->node:NULL), 2662 client_action, qinfo, repinfo, NULL, 2663 (*r_out)->log_name); 2664 *passthru = 1; 2665 ret = 0; 2666 goto done; 2667 } 2668 if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION && 2669 client_action != RPZ_PASSTHRU_ACTION)) { 2670 if(client_action == RPZ_PASSTHRU_ACTION 2671 || client_action == RPZ_INVALID_ACTION 2672 || (client_action == RPZ_TCP_ONLY_ACTION 2673 && !rpz_is_udp_query(repinfo))) { 2674 ret = 0; 2675 goto done; 2676 } 2677 stats->rpz_action[client_action]++; 2678 if(client_action == RPZ_LOCAL_DATA_ACTION) { 2679 rpz_apply_clientip_localdata_action(node, env, qinfo, 2680 edns, repinfo, buf, temp, *a_out); 2681 ret = 1; 2682 } else if(client_action == RPZ_CNAME_OVERRIDE_ACTION) { 2683 if(!rpz_apply_cname_override_action(*r_out, qinfo, 2684 temp)) { 2685 ret = 0; 2686 goto done; 2687 } 2688 ret = 0; 2689 } else { 2690 local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns, 2691 repinfo, buf, temp, 0 /* no local data used */, 2692 rpz_action_to_localzone_type(client_action)); 2693 if(*r_out && (*r_out)->signal_nxdomain_ra && 2694 LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 2695 == LDNS_RCODE_NXDOMAIN) 2696 LDNS_RA_CLR(sldns_buffer_begin(buf)); 2697 ret = 1; 2698 } 2699 if(*r_out && (*r_out)->log) 2700 log_rpz_apply( 2701 (node?"clientip":"qname"), 2702 ((*z_out)?(*z_out)->name:NULL), 2703 (node?&node->node:NULL), 2704 client_action, qinfo, repinfo, NULL, 2705 (*r_out)->log_name); 2706 goto done; 2707 } 2708 ret = -1; 2709 done: 2710 if(node != NULL) { 2711 lock_rw_unlock(&node->lock); 2712 } 2713 return ret; 2714 } 2715 2716 int 2717 rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env, 2718 struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, 2719 struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, 2720 size_t taglen, struct ub_server_stats* stats, int* passthru) 2721 { 2722 struct rpz* r = NULL; 2723 struct auth_zone* a = NULL; 2724 struct local_zone* z = NULL; 2725 int ret; 2726 enum localzone_type lzt; 2727 2728 int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo, 2729 edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r, 2730 passthru); 2731 if(clientip_trigger >= 0) { 2732 if(a) { 2733 lock_rw_unlock(&a->lock); 2734 } 2735 if(z) { 2736 lock_rw_unlock(&z->lock); 2737 } 2738 return clientip_trigger; 2739 } 2740 2741 if(z == NULL) { 2742 if(a) { 2743 lock_rw_unlock(&a->lock); 2744 } 2745 return 0; 2746 } 2747 2748 log_assert(r); 2749 2750 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2751 lzt = z->type; 2752 } else { 2753 lzt = rpz_action_to_localzone_type(r->action_override); 2754 } 2755 if(r->action_override == RPZ_PASSTHRU_ACTION || 2756 lzt == local_zone_always_transparent /* RPZ_PASSTHRU_ACTION */) { 2757 *passthru = 1; 2758 } 2759 2760 if(verbosity >= VERB_ALGO) { 2761 char nm[255+1], zn[255+1]; 2762 dname_str(qinfo->qname, nm); 2763 dname_str(z->name, zn); 2764 if(strcmp(zn, nm) != 0) 2765 verbose(VERB_ALGO, "rpz: qname trigger %s on %s with action=%s", 2766 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2767 else 2768 verbose(VERB_ALGO, "rpz: qname trigger %s with action=%s", 2769 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2770 } 2771 2772 ret = rpz_synthesize_qname_localdata(env, r, z, lzt, qinfo, edns, buf, temp, 2773 repinfo, stats); 2774 2775 lock_rw_unlock(&z->lock); 2776 lock_rw_unlock(&a->lock); 2777 2778 return ret; 2779 } 2780 2781 void rpz_enable(struct rpz* r) 2782 { 2783 if(!r) 2784 return; 2785 r->disabled = 0; 2786 } 2787 2788 void rpz_disable(struct rpz* r) 2789 { 2790 if(!r) 2791 return; 2792 r->disabled = 1; 2793 } 2794