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