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->client_addr, repinfo->client_addrlen, ip, sizeof(ip)); 1396 port = ntohs(((struct sockaddr_in*)&repinfo->client_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.client_addr, 1399 ms->mesh_info->reply_list->query_reply.client_addrlen, 1400 ip, sizeof(ip)); 1401 port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.client_addr)->sin_port); 1402 } else { 1403 ip[0]=0; 1404 port = 0; 1405 } 1406 snprintf(portstr, sizeof(portstr), "@%u", (unsigned)port); 1407 snprintf(txt, sizeof(txt), "rpz: applied %s%s%s%s%s%s %s %s%s", 1408 (log_name?"[":""), (log_name?log_name:""), (log_name?"] ":""), 1409 (strcmp(trigger,"qname")==0?"":trigger), 1410 (strcmp(trigger,"qname")==0?"":" "), 1411 dnamestr, rpz_action_to_string(a), 1412 (ip[0]?ip:""), (ip[0]?portstr:"")); 1413 log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); 1414 } 1415 1416 static struct clientip_synthesized_rr* 1417 rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set, 1418 struct sockaddr_storage* addr, socklen_t addrlen, char* triggername) 1419 { 1420 struct clientip_synthesized_rr* raddr = NULL; 1421 enum rpz_action action = RPZ_INVALID_ACTION; 1422 1423 lock_rw_rdlock(&set->lock); 1424 1425 raddr = (struct clientip_synthesized_rr*)addr_tree_lookup(&set->entries, 1426 addr, addrlen); 1427 if(raddr != NULL) { 1428 lock_rw_rdlock(&raddr->lock); 1429 action = raddr->action; 1430 if(verbosity >= VERB_ALGO) { 1431 char ip[256], net[256]; 1432 addr_to_str(addr, addrlen, ip, sizeof(ip)); 1433 addr_to_str(&raddr->node.addr, raddr->node.addrlen, 1434 net, sizeof(net)); 1435 verbose(VERB_ALGO, "rpz: trigger %s %s/%d on %s action=%s", 1436 triggername, net, raddr->node.net, ip, rpz_action_to_string(action)); 1437 } 1438 } 1439 lock_rw_unlock(&set->lock); 1440 1441 return raddr; 1442 } 1443 1444 static inline 1445 struct clientip_synthesized_rr* 1446 rpz_resolve_client_action_and_zone(struct auth_zones* az, struct query_info* qinfo, 1447 struct comm_reply* repinfo, uint8_t* taglist, size_t taglen, 1448 struct ub_server_stats* stats, 1449 /* output parameters */ 1450 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out) 1451 { 1452 struct clientip_synthesized_rr* node = NULL; 1453 struct auth_zone* a = NULL; 1454 struct rpz* r = NULL; 1455 struct local_zone* z = NULL; 1456 1457 lock_rw_rdlock(&az->rpz_lock); 1458 1459 for(a = az->rpz_first; a; a = a->rpz_az_next) { 1460 lock_rw_rdlock(&a->lock); 1461 r = a->rpz; 1462 if(r->disabled) { 1463 lock_rw_unlock(&a->lock); 1464 continue; 1465 } 1466 if(r->taglist && !taglist_intersect(r->taglist, 1467 r->taglistlen, taglist, taglen)) { 1468 lock_rw_unlock(&a->lock); 1469 continue; 1470 } 1471 z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len, 1472 qinfo->qclass, 0, 0, 0); 1473 node = rpz_ipbased_trigger_lookup(r->client_set, 1474 &repinfo->client_addr, repinfo->client_addrlen, 1475 "clientip"); 1476 if((z || node) && r->action_override == RPZ_DISABLED_ACTION) { 1477 if(r->log) 1478 log_rpz_apply((node?"clientip":"qname"), 1479 (z?z->name:NULL), 1480 (node?&node->node:NULL), 1481 r->action_override, 1482 qinfo, repinfo, NULL, r->log_name); 1483 stats->rpz_action[r->action_override]++; 1484 if(z != NULL) { 1485 lock_rw_unlock(&z->lock); 1486 z = NULL; 1487 } 1488 if(node != NULL) { 1489 lock_rw_unlock(&node->lock); 1490 node = NULL; 1491 } 1492 } 1493 if(z || node) { 1494 break; 1495 } 1496 /* not found in this auth_zone */ 1497 lock_rw_unlock(&a->lock); 1498 } 1499 1500 lock_rw_unlock(&az->rpz_lock); 1501 1502 *r_out = r; 1503 *a_out = a; 1504 *z_out = z; 1505 1506 return node; 1507 } 1508 1509 static inline int 1510 rpz_is_udp_query(struct comm_reply* repinfo) { 1511 return repinfo != NULL 1512 ? (repinfo->c != NULL 1513 ? repinfo->c->type == comm_udp 1514 : 0) 1515 : 0; 1516 } 1517 1518 /** encode answer consisting of 1 rrset */ 1519 static int 1520 rpz_local_encode(struct module_env* env, struct query_info* qinfo, 1521 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1522 struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, 1523 int rcode, struct ub_packed_rrset_key* soa_rrset) 1524 { 1525 struct reply_info rep; 1526 uint16_t udpsize; 1527 struct ub_packed_rrset_key* rrsetlist[3]; 1528 1529 memset(&rep, 0, sizeof(rep)); 1530 rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode); 1531 rep.qdcount = 1; 1532 rep.rrset_count = ansec; 1533 rep.rrsets = rrsetlist; 1534 if(ansec > 0) { 1535 rep.an_numrrsets = 1; 1536 rep.rrsets[0] = rrset; 1537 rep.ttl = ((struct packed_rrset_data*)rrset->entry.data)->rr_ttl[0]; 1538 } 1539 if(soa_rrset != NULL) { 1540 rep.ar_numrrsets = 1; 1541 rep.rrsets[rep.rrset_count] = soa_rrset; 1542 rep.rrset_count ++; 1543 if(rep.ttl < ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]) { 1544 rep.ttl = ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]; 1545 } 1546 } 1547 1548 udpsize = edns->udp_size; 1549 edns->edns_version = EDNS_ADVERTISED_VERSION; 1550 edns->udp_size = EDNS_ADVERTISED_SIZE; 1551 edns->ext_rcode = 0; 1552 edns->bits &= EDNS_DO; 1553 if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, 1554 repinfo, temp, env->now_tv) || 1555 !reply_info_answer_encode(qinfo, &rep, 1556 *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), 1557 buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) { 1558 error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, 1559 *(uint16_t*)sldns_buffer_begin(buf), 1560 sldns_buffer_read_u16_at(buf, 2), edns); 1561 } 1562 1563 return 1; 1564 } 1565 1566 static struct local_rrset* 1567 rpz_find_synthesized_rrset(uint16_t qtype, 1568 struct clientip_synthesized_rr* data) 1569 { 1570 struct local_rrset* cursor = data->data; 1571 while( cursor != NULL) { 1572 struct packed_rrset_key* packed_rrset = &cursor->rrset->rk; 1573 if(htons(qtype) == packed_rrset->type) { 1574 return cursor; 1575 } 1576 cursor = cursor->next; 1577 } 1578 return NULL; 1579 } 1580 1581 /** allocate SOA record ubrrsetkey in region */ 1582 static struct ub_packed_rrset_key* 1583 make_soa_ubrrset(struct auth_zone* auth_zone, struct auth_rrset* soa, 1584 struct regional* temp) 1585 { 1586 struct ub_packed_rrset_key csoa; 1587 if(!soa) 1588 return NULL; 1589 memset(&csoa, 0, sizeof(csoa)); 1590 csoa.entry.key = &csoa; 1591 csoa.rk.rrset_class = htons(LDNS_RR_CLASS_IN); 1592 csoa.rk.type = htons(LDNS_RR_TYPE_SOA); 1593 csoa.rk.flags |= PACKED_RRSET_FIXEDTTL 1594 | PACKED_RRSET_RPZ; 1595 csoa.rk.dname = auth_zone->name; 1596 csoa.rk.dname_len = auth_zone->namelen; 1597 csoa.entry.hash = rrset_key_hash(&csoa.rk); 1598 csoa.entry.data = soa->data; 1599 return respip_copy_rrset(&csoa, temp); 1600 } 1601 1602 static void 1603 rpz_apply_clientip_localdata_action(struct clientip_synthesized_rr* raddr, 1604 struct module_env* env, struct query_info* qinfo, 1605 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1606 struct regional* temp, struct auth_zone* auth_zone) 1607 { 1608 struct local_rrset* rrset; 1609 enum rpz_action action = RPZ_INVALID_ACTION; 1610 struct ub_packed_rrset_key* rp = NULL; 1611 struct ub_packed_rrset_key* rsoa = NULL; 1612 int rcode = LDNS_RCODE_NOERROR|BIT_AA; 1613 int rrset_count = 1; 1614 1615 /* prepare synthesized answer for client */ 1616 action = raddr->action; 1617 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL ) { 1618 verbose(VERB_ALGO, "rpz: bug: local-data action but no local data"); 1619 return; 1620 } 1621 1622 /* check query type / rr type */ 1623 rrset = rpz_find_synthesized_rrset(qinfo->qtype, raddr); 1624 if(rrset == NULL) { 1625 verbose(VERB_ALGO, "rpz: unable to find local-data for query"); 1626 rrset_count = 0; 1627 goto nodata; 1628 } 1629 1630 rp = respip_copy_rrset(rrset->rrset, temp); 1631 if(!rp) { 1632 verbose(VERB_ALGO, "rpz: local data action: out of memory"); 1633 return; 1634 } 1635 1636 rp->rk.flags |= PACKED_RRSET_FIXEDTTL | PACKED_RRSET_RPZ; 1637 rp->rk.dname = qinfo->qname; 1638 rp->rk.dname_len = qinfo->qname_len; 1639 rp->entry.hash = rrset_key_hash(&rp->rk); 1640 nodata: 1641 if(auth_zone) { 1642 struct auth_rrset* soa = NULL; 1643 soa = auth_zone_get_soa_rrset(auth_zone); 1644 if(soa) { 1645 rsoa = make_soa_ubrrset(auth_zone, soa, temp); 1646 if(!rsoa) { 1647 verbose(VERB_ALGO, "rpz: local data action soa: out of memory"); 1648 return; 1649 } 1650 } 1651 } 1652 1653 rpz_local_encode(env, qinfo, edns, repinfo, buf, temp, rp, 1654 rrset_count, rcode, rsoa); 1655 } 1656 1657 /** add additional section SOA record to the reply. 1658 * Since this gets fed into the normal iterator answer creation, it 1659 * gets minimal-responses applied to it, that can remove the additional SOA 1660 * again. */ 1661 static int 1662 rpz_add_soa(struct reply_info* rep, struct module_qstate* ms, 1663 struct auth_zone* az) 1664 { 1665 struct auth_rrset* soa = NULL; 1666 struct ub_packed_rrset_key* rsoa = NULL; 1667 struct ub_packed_rrset_key** prevrrsets; 1668 if(!az) return 1; 1669 soa = auth_zone_get_soa_rrset(az); 1670 if(!soa) return 1; 1671 if(!rep) return 0; 1672 rsoa = make_soa_ubrrset(az, soa, ms->region); 1673 if(!rsoa) return 0; 1674 prevrrsets = rep->rrsets; 1675 rep->rrsets = regional_alloc_zero(ms->region, 1676 sizeof(*rep->rrsets)*(rep->rrset_count+1)); 1677 if(!rep->rrsets) 1678 return 0; 1679 if(prevrrsets && rep->rrset_count > 0) 1680 memcpy(rep->rrsets, prevrrsets, rep->rrset_count*sizeof(*rep->rrsets)); 1681 rep->rrset_count++; 1682 rep->ar_numrrsets++; 1683 rep->rrsets[rep->rrset_count-1] = rsoa; 1684 return 1; 1685 } 1686 1687 static inline struct dns_msg* 1688 rpz_dns_msg_new(struct regional* region) 1689 { 1690 struct dns_msg* msg = 1691 (struct dns_msg*)regional_alloc(region, 1692 sizeof(struct dns_msg)); 1693 if(msg == NULL) { return NULL; } 1694 memset(msg, 0, sizeof(struct dns_msg)); 1695 1696 return msg; 1697 } 1698 1699 static inline struct dns_msg* 1700 rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 1701 struct query_info* qinfo, struct auth_zone* az) 1702 { 1703 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1704 if(msg == NULL) { return msg; } 1705 msg->qinfo = *qinfo; 1706 msg->rep = construct_reply_info_base(ms->region, 1707 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 1708 1, /* qd */ 1709 0, /* ttl */ 1710 0, /* prettl */ 1711 0, /* expttl */ 1712 0, /* an */ 1713 0, /* ns */ 1714 0, /* ar */ 1715 0, /* total */ 1716 sec_status_insecure); 1717 if(msg->rep) 1718 msg->rep->authoritative = 1; 1719 if(!rpz_add_soa(msg->rep, ms, az)) 1720 return NULL; 1721 return msg; 1722 } 1723 1724 static inline struct dns_msg* 1725 rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms, 1726 struct query_info* qinfo, struct auth_zone* az) 1727 { 1728 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1729 uint16_t flags; 1730 if(msg == NULL) { return msg; } 1731 msg->qinfo = *qinfo; 1732 flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA; 1733 if(r->signal_nxdomain_ra) 1734 flags &= ~BIT_RA; 1735 msg->rep = construct_reply_info_base(ms->region, 1736 flags, 1737 1, /* qd */ 1738 0, /* ttl */ 1739 0, /* prettl */ 1740 0, /* expttl */ 1741 0, /* an */ 1742 0, /* ns */ 1743 0, /* ar */ 1744 0, /* total */ 1745 sec_status_insecure); 1746 if(msg->rep) 1747 msg->rep->authoritative = 1; 1748 if(!rpz_add_soa(msg->rep, ms, az)) 1749 return NULL; 1750 return msg; 1751 } 1752 1753 static inline struct dns_msg* 1754 rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 1755 struct query_info* qi, struct local_rrset* rrset, struct auth_zone* az) 1756 { 1757 struct dns_msg* msg = NULL; 1758 struct reply_info* new_reply_info; 1759 struct ub_packed_rrset_key* rp; 1760 1761 1762 msg = rpz_dns_msg_new(ms->region); 1763 if(msg == NULL) { return NULL; } 1764 1765 new_reply_info = construct_reply_info_base(ms->region, 1766 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 1767 1, /* qd */ 1768 0, /* ttl */ 1769 0, /* prettl */ 1770 0, /* expttl */ 1771 1, /* an */ 1772 0, /* ns */ 1773 0, /* ar */ 1774 1, /* total */ 1775 sec_status_insecure); 1776 if(new_reply_info == NULL) { 1777 log_err("out of memory"); 1778 return NULL; 1779 } 1780 new_reply_info->authoritative = 1; 1781 rp = respip_copy_rrset(rrset->rrset, ms->region); 1782 if(rp == NULL) { 1783 log_err("out of memory"); 1784 return NULL; 1785 } 1786 rp->rk.dname = qi->qname; 1787 rp->rk.dname_len = qi->qname_len; 1788 /* this rrset is from the rpz data, or synthesized. 1789 * It is not actually from the network, so we flag it with this 1790 * flags as a fake RRset. If later the cache is used to look up 1791 * rrsets, then the fake ones are not returned (if you look without 1792 * the flag). For like CNAME lookups from the iterator or A, AAAA 1793 * lookups for nameserver targets, it would use the without flag 1794 * actual data. So that the actual network data and fake data 1795 * are kept track of separately. */ 1796 rp->rk.flags |= PACKED_RRSET_RPZ; 1797 new_reply_info->rrsets[0] = rp; 1798 msg->rep = new_reply_info; 1799 if(!rpz_add_soa(msg->rep, ms, az)) 1800 return NULL; 1801 return msg; 1802 } 1803 1804 static inline struct dns_msg* 1805 rpz_synthesize_nsip_localdata(struct rpz* r, struct module_qstate* ms, 1806 struct clientip_synthesized_rr* data, struct auth_zone* az) 1807 { 1808 struct query_info* qi = &ms->qinfo; 1809 struct local_rrset* rrset; 1810 1811 rrset = rpz_find_synthesized_rrset(qi->qtype, data); 1812 if(rrset == NULL) { 1813 verbose(VERB_ALGO, "rpz: nsip: no matching local data found"); 1814 return NULL; 1815 } 1816 1817 return rpz_synthesize_localdata_from_rrset(r, ms, &ms->qinfo, rrset, az); 1818 } 1819 1820 /* copy'n'paste from localzone.c */ 1821 static struct local_rrset* 1822 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok) 1823 { 1824 struct local_rrset* p; 1825 type = htons(type); 1826 for(p = data->rrsets; p; p = p->next) { 1827 if(p->rrset->rk.type == type) 1828 return p; 1829 if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) 1830 return p; 1831 } 1832 return NULL; 1833 } 1834 1835 /* based on localzone.c:local_data_answer() */ 1836 static inline struct dns_msg* 1837 rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms, 1838 struct local_zone* z, struct matched_delegation_point const* match, 1839 struct auth_zone* az) 1840 { 1841 struct local_data key; 1842 struct local_data* ld; 1843 struct local_rrset* rrset; 1844 1845 if(match->dname == NULL) { return NULL; } 1846 1847 key.node.key = &key; 1848 key.name = match->dname; 1849 key.namelen = match->dname_len; 1850 key.namelabs = dname_count_labels(match->dname); 1851 1852 rpz_log_dname("nsdname local data", key.name, key.namelen); 1853 1854 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1855 if(ld == NULL) { 1856 verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found"); 1857 return NULL; 1858 } 1859 1860 rrset = local_data_find_type(ld, ms->qinfo.qtype, 1); 1861 if(rrset == NULL) { 1862 verbose(VERB_ALGO, "rpz: nsdname: no matching local data found"); 1863 return NULL; 1864 } 1865 1866 return rpz_synthesize_localdata_from_rrset(r, ms, &ms->qinfo, rrset, az); 1867 } 1868 1869 /* like local_data_answer for qname triggers after a cname */ 1870 static struct dns_msg* 1871 rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms, 1872 struct query_info* qinfo, struct local_zone* z, struct auth_zone* az) 1873 { 1874 struct local_data key; 1875 struct local_data* ld; 1876 struct local_rrset* rrset; 1877 key.node.key = &key; 1878 key.name = qinfo->qname; 1879 key.namelen = qinfo->qname_len; 1880 key.namelabs = dname_count_labels(qinfo->qname); 1881 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1882 if(ld == NULL) { 1883 verbose(VERB_ALGO, "rpz: qname after cname: name not found"); 1884 return NULL; 1885 } 1886 rrset = local_data_find_type(ld, qinfo->qtype, 1); 1887 if(rrset == NULL) { 1888 verbose(VERB_ALGO, "rpz: qname after cname: type not found"); 1889 return NULL; 1890 } 1891 return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az); 1892 } 1893 1894 static int 1895 rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r, 1896 struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo, 1897 struct edns_data* edns, sldns_buffer* buf, struct regional* temp, 1898 struct comm_reply* repinfo, struct ub_server_stats* stats) 1899 { 1900 struct local_data* ld = NULL; 1901 int ret = 0; 1902 if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { 1903 qinfo->local_alias = regional_alloc_zero(temp, sizeof(struct local_rrset)); 1904 if(qinfo->local_alias == NULL) { 1905 return 0; /* out of memory */ 1906 } 1907 qinfo->local_alias->rrset = regional_alloc_init(temp, r->cname_override, 1908 sizeof(*r->cname_override)); 1909 if(qinfo->local_alias->rrset == NULL) { 1910 return 0; /* out of memory */ 1911 } 1912 qinfo->local_alias->rrset->rk.dname = qinfo->qname; 1913 qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; 1914 if(r->log) { 1915 log_rpz_apply("qname", z->name, NULL, RPZ_CNAME_OVERRIDE_ACTION, 1916 qinfo, repinfo, NULL, r->log_name); 1917 } 1918 stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++; 1919 return 0; 1920 } 1921 1922 if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo, 1923 edns, repinfo, buf, temp, dname_count_labels(qinfo->qname), 1924 &ld, lzt, -1, NULL, 0, NULL, 0)) { 1925 if(r->log) { 1926 log_rpz_apply("qname", z->name, NULL, 1927 localzone_type_to_rpz_action(lzt), qinfo, 1928 repinfo, NULL, r->log_name); 1929 } 1930 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 1931 return !qinfo->local_alias; 1932 } 1933 1934 ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, 1935 0 /* no local data used */, lzt); 1936 if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 1937 == LDNS_RCODE_NXDOMAIN) 1938 LDNS_RA_CLR(sldns_buffer_begin(buf)); 1939 if(r->log) { 1940 log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt), 1941 qinfo, repinfo, NULL, r->log_name); 1942 } 1943 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 1944 return ret; 1945 } 1946 1947 static struct clientip_synthesized_rr* 1948 rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is) 1949 { 1950 struct delegpt_addr* cursor; 1951 struct clientip_synthesized_rr* action = NULL; 1952 if(is->dp == NULL) { return NULL; } 1953 for(cursor = is->dp->target_list; 1954 cursor != NULL; 1955 cursor = cursor->next_target) { 1956 if(cursor->bogus) { continue; } 1957 action = rpz_ipbased_trigger_lookup(rpz->ns_set, &cursor->addr, 1958 cursor->addrlen, "nsip"); 1959 if(action != NULL) { return action; } 1960 } 1961 return NULL; 1962 } 1963 1964 static struct dns_msg* 1965 rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r, 1966 struct clientip_synthesized_rr* raddr, struct auth_zone* az) 1967 { 1968 enum rpz_action action = raddr->action; 1969 struct dns_msg* ret = NULL; 1970 1971 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 1972 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 1973 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 1974 action = r->action_override; 1975 } 1976 1977 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) { 1978 verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data"); 1979 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 1980 goto done; 1981 } 1982 1983 switch(action) { 1984 case RPZ_NXDOMAIN_ACTION: 1985 ret = rpz_synthesize_nxdomain(r, ms, &ms->qinfo, az); 1986 break; 1987 case RPZ_NODATA_ACTION: 1988 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 1989 break; 1990 case RPZ_TCP_ONLY_ACTION: 1991 /* basically a passthru here but the tcp-only will be 1992 * honored before the query gets sent. */ 1993 ms->respip_action_info->action = respip_truncate; 1994 ret = NULL; 1995 break; 1996 case RPZ_DROP_ACTION: 1997 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 1998 ms->is_drop = 1; 1999 break; 2000 case RPZ_LOCAL_DATA_ACTION: 2001 ret = rpz_synthesize_nsip_localdata(r, ms, raddr, az); 2002 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); } 2003 break; 2004 case RPZ_PASSTHRU_ACTION: 2005 ret = NULL; 2006 ms->rpz_passthru = 1; 2007 break; 2008 default: 2009 verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'", 2010 rpz_action_to_string(action)); 2011 ret = NULL; 2012 } 2013 2014 done: 2015 if(r->log) 2016 log_rpz_apply("nsip", NULL, &raddr->node, 2017 action, &ms->qinfo, NULL, ms, r->log_name); 2018 if(ms->env->worker) 2019 ms->env->worker->stats.rpz_action[action]++; 2020 lock_rw_unlock(&raddr->lock); 2021 return ret; 2022 } 2023 2024 static struct dns_msg* 2025 rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r, 2026 struct local_zone* z, struct matched_delegation_point const* match, 2027 struct auth_zone* az) 2028 { 2029 struct dns_msg* ret = NULL; 2030 enum rpz_action action = localzone_type_to_rpz_action(z->type); 2031 2032 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 2033 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 2034 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 2035 action = r->action_override; 2036 } 2037 2038 switch(action) { 2039 case RPZ_NXDOMAIN_ACTION: 2040 ret = rpz_synthesize_nxdomain(r, ms, &ms->qinfo, az); 2041 break; 2042 case RPZ_NODATA_ACTION: 2043 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2044 break; 2045 case RPZ_TCP_ONLY_ACTION: 2046 /* basically a passthru here but the tcp-only will be 2047 * honored before the query gets sent. */ 2048 ms->respip_action_info->action = respip_truncate; 2049 ret = NULL; 2050 break; 2051 case RPZ_DROP_ACTION: 2052 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2053 ms->is_drop = 1; 2054 break; 2055 case RPZ_LOCAL_DATA_ACTION: 2056 ret = rpz_synthesize_nsdname_localdata(r, ms, z, match, az); 2057 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); } 2058 break; 2059 case RPZ_PASSTHRU_ACTION: 2060 ret = NULL; 2061 ms->rpz_passthru = 1; 2062 break; 2063 default: 2064 verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'", 2065 rpz_action_to_string(action)); 2066 ret = NULL; 2067 } 2068 2069 if(r->log) 2070 log_rpz_apply("nsdname", match->dname, NULL, 2071 action, &ms->qinfo, NULL, ms, r->log_name); 2072 if(ms->env->worker) 2073 ms->env->worker->stats.rpz_action[action]++; 2074 lock_rw_unlock(&z->lock); 2075 return ret; 2076 } 2077 2078 static struct local_zone* 2079 rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones, 2080 uint16_t qclass, 2081 /* output parameter */ 2082 struct matched_delegation_point* match) 2083 { 2084 struct delegpt_ns* nameserver; 2085 struct local_zone* z = NULL; 2086 2087 /* the rpz specs match the nameserver names (NS records), not the 2088 * name of the delegation point itself, to the nsdname triggers */ 2089 for(nameserver = dp->nslist; 2090 nameserver != NULL; 2091 nameserver = nameserver->next) { 2092 z = rpz_find_zone(zones, nameserver->name, nameserver->namelen, 2093 qclass, 0, 0, 0); 2094 if(z != NULL) { 2095 match->dname = nameserver->name; 2096 match->dname_len = nameserver->namelen; 2097 if(verbosity >= VERB_ALGO) { 2098 char nm[255+1], zn[255+1]; 2099 dname_str(match->dname, nm); 2100 dname_str(z->name, zn); 2101 if(strcmp(nm, zn) != 0) 2102 verbose(VERB_ALGO, "rpz: trigger nsdname %s on %s action=%s", 2103 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2104 else 2105 verbose(VERB_ALGO, "rpz: trigger nsdname %s action=%s", 2106 nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2107 } 2108 break; 2109 } 2110 } 2111 2112 return z; 2113 } 2114 2115 struct dns_msg* 2116 rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate* is) 2117 { 2118 struct auth_zones* az; 2119 struct auth_zone* a; 2120 struct clientip_synthesized_rr* raddr = NULL; 2121 struct rpz* r = NULL; 2122 struct local_zone* z = NULL; 2123 struct matched_delegation_point match = {0}; 2124 2125 if(ms->rpz_passthru) { 2126 verbose(VERB_ALGO, "query is rpz_passthru, no further processing"); 2127 return NULL; 2128 } 2129 2130 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2131 2132 az = ms->env->auth_zones; 2133 2134 verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL); 2135 2136 lock_rw_rdlock(&az->rpz_lock); 2137 2138 /* precedence of RPZ works, loosely, like this: 2139 * CNAMEs in order of the CNAME chain. rpzs in the order they are 2140 * configured. In an RPZ: first client-IP addr, then QNAME, then 2141 * response IP, then NSDNAME, then NSIP. Longest match first. Smallest 2142 * one from a set. */ 2143 /* we use the precedence rules for the topics and triggers that 2144 * are pertinent at this stage of the resolve processing */ 2145 for(a = az->rpz_first; a != NULL; a = a->rpz_az_next) { 2146 lock_rw_rdlock(&a->lock); 2147 r = a->rpz; 2148 if(r->disabled) { 2149 lock_rw_unlock(&a->lock); 2150 continue; 2151 } 2152 2153 /* the nsdname has precedence over the nsip triggers */ 2154 z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones, 2155 ms->qinfo.qclass, &match); 2156 if(z != NULL) { 2157 lock_rw_unlock(&a->lock); 2158 break; 2159 } 2160 2161 raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is); 2162 if(raddr != NULL) { 2163 lock_rw_unlock(&a->lock); 2164 break; 2165 } 2166 lock_rw_unlock(&a->lock); 2167 } 2168 2169 lock_rw_unlock(&az->rpz_lock); 2170 2171 if(raddr == NULL && z == NULL) 2172 return NULL; 2173 2174 if(raddr != NULL) { 2175 if(z) { 2176 lock_rw_unlock(&z->lock); 2177 } 2178 return rpz_apply_nsip_trigger(ms, r, raddr, a); 2179 } 2180 return rpz_apply_nsdname_trigger(ms, r, z, &match, a); 2181 } 2182 2183 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms, 2184 struct iter_qstate* is) 2185 { 2186 struct auth_zones* az; 2187 struct auth_zone* a = NULL; 2188 struct rpz* r = NULL; 2189 struct local_zone* z = NULL; 2190 enum localzone_type lzt; 2191 struct dns_msg* ret = NULL; 2192 2193 if(ms->rpz_passthru) { 2194 verbose(VERB_ALGO, "query is rpz_passthru, no further processing"); 2195 return NULL; 2196 } 2197 2198 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2199 az = ms->env->auth_zones; 2200 2201 lock_rw_rdlock(&az->rpz_lock); 2202 2203 for(a = az->rpz_first; a; a = a->rpz_az_next) { 2204 lock_rw_rdlock(&a->lock); 2205 r = a->rpz; 2206 if(r->disabled) { 2207 lock_rw_unlock(&a->lock); 2208 continue; 2209 } 2210 z = rpz_find_zone(r->local_zones, is->qchase.qname, 2211 is->qchase.qname_len, is->qchase.qclass, 0, 0, 0); 2212 if(z && r->action_override == RPZ_DISABLED_ACTION) { 2213 if(r->log) 2214 log_rpz_apply("qname", z->name, NULL, 2215 r->action_override, 2216 &ms->qinfo, NULL, ms, r->log_name); 2217 if(ms->env->worker) 2218 ms->env->worker->stats.rpz_action[r->action_override]++; 2219 lock_rw_unlock(&z->lock); 2220 z = NULL; 2221 } 2222 if(z) { 2223 break; 2224 } 2225 /* not found in this auth_zone */ 2226 lock_rw_unlock(&a->lock); 2227 } 2228 lock_rw_unlock(&az->rpz_lock); 2229 2230 if(z == NULL) 2231 return NULL; 2232 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2233 lzt = z->type; 2234 } else { 2235 lzt = rpz_action_to_localzone_type(r->action_override); 2236 } 2237 2238 if(verbosity >= VERB_ALGO) { 2239 char nm[255+1], zn[255+1]; 2240 dname_str(is->qchase.qname, nm); 2241 dname_str(z->name, zn); 2242 if(strcmp(zn, nm) != 0) 2243 verbose(VERB_ALGO, "rpz: qname trigger after cname %s on %s, with action=%s", 2244 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2245 else 2246 verbose(VERB_ALGO, "rpz: qname trigger after cname %s, with action=%s", 2247 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2248 } 2249 switch(localzone_type_to_rpz_action(lzt)) { 2250 case RPZ_NXDOMAIN_ACTION: 2251 ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a); 2252 break; 2253 case RPZ_NODATA_ACTION: 2254 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2255 break; 2256 case RPZ_TCP_ONLY_ACTION: 2257 /* basically a passthru here but the tcp-only will be 2258 * honored before the query gets sent. */ 2259 ms->respip_action_info->action = respip_truncate; 2260 ret = NULL; 2261 break; 2262 case RPZ_DROP_ACTION: 2263 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2264 ms->is_drop = 1; 2265 break; 2266 case RPZ_LOCAL_DATA_ACTION: 2267 ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a); 2268 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); } 2269 break; 2270 case RPZ_PASSTHRU_ACTION: 2271 ret = NULL; 2272 ms->rpz_passthru = 1; 2273 break; 2274 default: 2275 verbose(VERB_ALGO, "rpz: qname trigger after cname: bug: unhandled or invalid action: '%s'", 2276 rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2277 ret = NULL; 2278 } 2279 lock_rw_unlock(&z->lock); 2280 lock_rw_unlock(&a->lock); 2281 return ret; 2282 } 2283 2284 static int 2285 rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env, 2286 struct query_info* qinfo, struct edns_data* edns, struct comm_reply* repinfo, 2287 uint8_t* taglist, size_t taglen, struct ub_server_stats* stats, 2288 sldns_buffer* buf, struct regional* temp, 2289 /* output parameters */ 2290 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out, 2291 int* passthru) 2292 { 2293 int ret = 0; 2294 enum rpz_action client_action; 2295 struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone( 2296 az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out); 2297 2298 client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action); 2299 if(client_action == RPZ_PASSTHRU_ACTION) { 2300 *passthru = 1; 2301 } 2302 if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION && 2303 client_action != RPZ_PASSTHRU_ACTION)) { 2304 if(client_action == RPZ_PASSTHRU_ACTION 2305 || client_action == RPZ_INVALID_ACTION 2306 || (client_action == RPZ_TCP_ONLY_ACTION 2307 && !rpz_is_udp_query(repinfo))) { 2308 ret = 0; 2309 goto done; 2310 } 2311 stats->rpz_action[client_action]++; 2312 if(client_action == RPZ_LOCAL_DATA_ACTION) { 2313 rpz_apply_clientip_localdata_action(node, env, qinfo, 2314 edns, repinfo, buf, temp, *a_out); 2315 } else { 2316 if(*r_out && (*r_out)->log) 2317 log_rpz_apply( 2318 (node?"clientip":"qname"), 2319 ((*z_out)?(*z_out)->name:NULL), 2320 (node?&node->node:NULL), 2321 client_action, qinfo, repinfo, NULL, 2322 (*r_out)->log_name); 2323 local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns, 2324 repinfo, buf, temp, 0 /* no local data used */, 2325 rpz_action_to_localzone_type(client_action)); 2326 if(*r_out && (*r_out)->signal_nxdomain_ra && 2327 LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 2328 == LDNS_RCODE_NXDOMAIN) 2329 LDNS_RA_CLR(sldns_buffer_begin(buf)); 2330 } 2331 ret = 1; 2332 goto done; 2333 } 2334 ret = -1; 2335 done: 2336 if(node != NULL) { 2337 lock_rw_unlock(&node->lock); 2338 } 2339 return ret; 2340 } 2341 2342 int 2343 rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env, 2344 struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, 2345 struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, 2346 size_t taglen, struct ub_server_stats* stats, int* passthru) 2347 { 2348 struct rpz* r = NULL; 2349 struct auth_zone* a = NULL; 2350 struct local_zone* z = NULL; 2351 int ret; 2352 enum localzone_type lzt; 2353 2354 int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo, 2355 edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r, 2356 passthru); 2357 if(clientip_trigger >= 0) { 2358 if(a) { 2359 lock_rw_unlock(&a->lock); 2360 } 2361 if(z) { 2362 lock_rw_unlock(&z->lock); 2363 } 2364 return clientip_trigger; 2365 } 2366 2367 if(z == NULL) { 2368 if(a) { 2369 lock_rw_unlock(&a->lock); 2370 } 2371 return 0; 2372 } 2373 2374 log_assert(r); 2375 2376 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2377 lzt = z->type; 2378 } else { 2379 lzt = rpz_action_to_localzone_type(r->action_override); 2380 } 2381 if(r->action_override == RPZ_PASSTHRU_ACTION || 2382 lzt == local_zone_always_transparent /* RPZ_PASSTHRU_ACTION */) { 2383 *passthru = 1; 2384 } 2385 2386 if(verbosity >= VERB_ALGO) { 2387 char nm[255+1], zn[255+1]; 2388 dname_str(qinfo->qname, nm); 2389 dname_str(z->name, zn); 2390 if(strcmp(zn, nm) != 0) 2391 verbose(VERB_ALGO, "rpz: qname trigger %s on %s with action=%s", 2392 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2393 else 2394 verbose(VERB_ALGO, "rpz: qname trigger %s with action=%s", 2395 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2396 } 2397 2398 ret = rpz_synthesize_qname_localdata(env, r, z, lzt, qinfo, edns, buf, temp, 2399 repinfo, stats); 2400 2401 lock_rw_unlock(&z->lock); 2402 lock_rw_unlock(&a->lock); 2403 2404 return ret; 2405 } 2406 2407 void rpz_enable(struct rpz* r) 2408 { 2409 if(!r) 2410 return; 2411 r->disabled = 0; 2412 } 2413 2414 void rpz_disable(struct rpz* r) 2415 { 2416 if(!r) 2417 return; 2418 r->disabled = 1; 2419 } 2420