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