1 /* $NetBSD: rpz.c,v 1.16 2025/01/26 16:25:25 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <inttypes.h> 19 #include <stdbool.h> 20 #include <stdint.h> 21 #include <stdlib.h> 22 23 #include <isc/async.h> 24 #include <isc/buffer.h> 25 #include <isc/loop.h> 26 #include <isc/magic.h> 27 #include <isc/mem.h> 28 #include <isc/net.h> 29 #include <isc/netaddr.h> 30 #include <isc/refcount.h> 31 #include <isc/result.h> 32 #include <isc/rwlock.h> 33 #include <isc/string.h> 34 #include <isc/util.h> 35 #include <isc/work.h> 36 37 #include <dns/db.h> 38 #include <dns/dbiterator.h> 39 #include <dns/dnsrps.h> 40 #include <dns/fixedname.h> 41 #include <dns/log.h> 42 #include <dns/qp.h> 43 #include <dns/rdata.h> 44 #include <dns/rdataset.h> 45 #include <dns/rdatasetiter.h> 46 #include <dns/rdatastruct.h> 47 #include <dns/rpz.h> 48 #include <dns/view.h> 49 50 #define DNS_RPZ_ZONE_MAGIC ISC_MAGIC('r', 'p', 'z', ' ') 51 #define DNS_RPZ_ZONES_MAGIC ISC_MAGIC('r', 'p', 'z', 's') 52 53 #define DNS_RPZ_ZONE_VALID(rpz) ISC_MAGIC_VALID(rpz, DNS_RPZ_ZONE_MAGIC) 54 #define DNS_RPZ_ZONES_VALID(rpzs) ISC_MAGIC_VALID(rpzs, DNS_RPZ_ZONES_MAGIC) 55 56 /* 57 * Parallel radix trees for databases of response policy IP addresses 58 * 59 * The radix or patricia trees are somewhat specialized to handle response 60 * policy addresses by representing the two sets of IP addresses and name 61 * server IP addresses in a single tree. One set of IP addresses is 62 * for rpz-ip policies or policies triggered by addresses in A or 63 * AAAA records in responses. 64 * The second set is for rpz-nsip policies or policies triggered by addresses 65 * in A or AAAA records for NS records that are authorities for responses. 66 * 67 * Each leaf indicates that an IP address is listed in the IP address or the 68 * name server IP address policy sub-zone (or both) of the corresponding 69 * response policy zone. The policy data such as a CNAME or an A record 70 * is kept in the policy zone. After an IP address has been found in a radix 71 * tree, the node in the policy zone's database is found by converting 72 * the IP address to a domain name in a canonical form. 73 * 74 * 75 * The response policy zone canonical form of an IPv6 address is one of: 76 * prefix.W.W.W.W.W.W.W.W 77 * prefix.WORDS.zz 78 * prefix.WORDS.zz.WORDS 79 * prefix.zz.WORDS 80 * where 81 * prefix is the prefix length of the IPv6 address between 1 and 128 82 * W is a number between 0 and 65535 83 * WORDS is one or more numbers W separated with "." 84 * zz corresponds to :: in the standard IPv6 text representation 85 * 86 * The canonical form of IPv4 addresses is: 87 * prefix.B.B.B.B 88 * where 89 * prefix is the prefix length of the address between 1 and 32 90 * B is a number between 0 and 255 91 * 92 * Names for IPv4 addresses are distinguished from IPv6 addresses by having 93 * 5 labels all of which are numbers, and a prefix between 1 and 32. 94 */ 95 96 /* 97 * Nodes hashtable calculation parameters 98 */ 99 #define DNS_RPZ_HTSIZE_MAX 24 100 #define DNS_RPZ_HTSIZE_DIV 3 101 102 static isc_result_t 103 dns__rpz_shuttingdown(dns_rpz_zones_t *rpzs); 104 static void 105 dns__rpz_timer_cb(void *); 106 static void 107 dns__rpz_timer_start(dns_rpz_zone_t *rpz); 108 109 /* 110 * Use a private definition of IPv6 addresses because s6_addr32 is not 111 * always defined and our IPv6 addresses are in non-standard byte order 112 */ 113 typedef uint32_t dns_rpz_cidr_word_t; 114 #define DNS_RPZ_CIDR_WORD_BITS ((int)sizeof(dns_rpz_cidr_word_t) * 8) 115 #define DNS_RPZ_CIDR_KEY_BITS ((int)sizeof(dns_rpz_cidr_key_t) * 8) 116 #define DNS_RPZ_CIDR_WORDS (128 / DNS_RPZ_CIDR_WORD_BITS) 117 typedef struct { 118 dns_rpz_cidr_word_t w[DNS_RPZ_CIDR_WORDS]; 119 } dns_rpz_cidr_key_t; 120 121 #define ADDR_V4MAPPED 0xffff 122 #define KEY_IS_IPV4(prefix, ip) \ 123 ((prefix) >= 96 && (ip)->w[0] == 0 && (ip)->w[1] == 0 && \ 124 (ip)->w[2] == ADDR_V4MAPPED) 125 126 #define DNS_RPZ_WORD_MASK(b) \ 127 ((b) == 0 ? (dns_rpz_cidr_word_t)(-1) \ 128 : ((dns_rpz_cidr_word_t)(-1) \ 129 << (DNS_RPZ_CIDR_WORD_BITS - (b)))) 130 131 /* 132 * Get bit #n from the array of words of an IP address. 133 */ 134 #define DNS_RPZ_IP_BIT(ip, n) \ 135 (1 & ((ip)->w[(n) / DNS_RPZ_CIDR_WORD_BITS] >> \ 136 (DNS_RPZ_CIDR_WORD_BITS - 1 - ((n) % DNS_RPZ_CIDR_WORD_BITS)))) 137 138 /* 139 * A triplet of arrays of bits flagging the existence of 140 * client-IP, IP, and NSIP policy triggers. 141 */ 142 typedef struct dns_rpz_addr_zbits dns_rpz_addr_zbits_t; 143 struct dns_rpz_addr_zbits { 144 dns_rpz_zbits_t client_ip; 145 dns_rpz_zbits_t ip; 146 dns_rpz_zbits_t nsip; 147 }; 148 149 /* 150 * A CIDR or radix tree node. 151 */ 152 struct dns_rpz_cidr_node { 153 dns_rpz_cidr_node_t *parent; 154 dns_rpz_cidr_node_t *child[2]; 155 dns_rpz_cidr_key_t ip; 156 dns_rpz_prefix_t prefix; 157 dns_rpz_addr_zbits_t set; 158 dns_rpz_addr_zbits_t sum; 159 }; 160 161 /* 162 * A pair of arrays of bits flagging the existence of 163 * QNAME and NSDNAME policy triggers. 164 */ 165 typedef struct dns_rpz_nm_zbits dns_rpz_nm_zbits_t; 166 struct dns_rpz_nm_zbits { 167 dns_rpz_zbits_t qname; 168 dns_rpz_zbits_t ns; 169 }; 170 171 /* 172 * The data for a name in the summary database. This has two pairs of bits 173 * for policy zones: one pair is for the exact name of the node, such as 174 * example.com, and the other pair is for a wildcard child such as 175 * *.example.com. 176 */ 177 typedef struct nmdata nmdata_t; 178 struct nmdata { 179 dns_name_t name; 180 isc_mem_t *mctx; 181 isc_refcount_t references; 182 dns_rpz_nm_zbits_t set; 183 dns_rpz_nm_zbits_t wild; 184 }; 185 186 #ifdef DNS_RPZ_TRACE 187 #define nmdata_ref(ptr) nmdata__ref(ptr, __func__, __FILE__, __LINE__) 188 #define nmdata_unref(ptr) nmdata__unref(ptr, __func__, __FILE__, __LINE__) 189 #define nmdata_attach(ptr, ptrp) \ 190 nmdata__attach(ptr, ptrp, __func__, __FILE__, __LINE__) 191 #define nmdata_detach(ptrp) nmdata__detach(ptrp, __func__, __FILE__, __LINE__) 192 ISC_REFCOUNT_TRACE_DECL(nmdata); 193 #else 194 ISC_REFCOUNT_DECL(nmdata); 195 #endif 196 197 static isc_result_t 198 rpz_add(dns_rpz_zone_t *rpz, const dns_name_t *src_name); 199 static void 200 rpz_del(dns_rpz_zone_t *rpz, const dns_name_t *src_name); 201 202 static nmdata_t * 203 new_nmdata(isc_mem_t *mctx, const dns_name_t *name, const nmdata_t *data); 204 205 /* QP trie methods */ 206 static void 207 qp_attach(void *uctx, void *pval, uint32_t ival); 208 static void 209 qp_detach(void *uctx, void *pval, uint32_t ival); 210 static size_t 211 qp_makekey(dns_qpkey_t key, void *uctx, void *pval, uint32_t ival); 212 static void 213 qp_triename(void *uctx, char *buf, size_t size); 214 215 static dns_qpmethods_t qpmethods = { 216 qp_attach, 217 qp_detach, 218 qp_makekey, 219 qp_triename, 220 }; 221 222 const char * 223 dns_rpz_type2str(dns_rpz_type_t type) { 224 switch (type) { 225 case DNS_RPZ_TYPE_CLIENT_IP: 226 return "CLIENT-IP"; 227 case DNS_RPZ_TYPE_QNAME: 228 return "QNAME"; 229 case DNS_RPZ_TYPE_IP: 230 return "IP"; 231 case DNS_RPZ_TYPE_NSIP: 232 return "NSIP"; 233 case DNS_RPZ_TYPE_NSDNAME: 234 return "NSDNAME"; 235 case DNS_RPZ_TYPE_BAD: 236 break; 237 } 238 FATAL_ERROR("impossible rpz type %d", type); 239 return "impossible"; 240 } 241 242 dns_rpz_policy_t 243 dns_rpz_str2policy(const char *str) { 244 static struct { 245 const char *str; 246 dns_rpz_policy_t policy; 247 } tbl[] = { 248 { "given", DNS_RPZ_POLICY_GIVEN }, 249 { "disabled", DNS_RPZ_POLICY_DISABLED }, 250 { "passthru", DNS_RPZ_POLICY_PASSTHRU }, 251 { "drop", DNS_RPZ_POLICY_DROP }, 252 { "tcp-only", DNS_RPZ_POLICY_TCP_ONLY }, 253 { "nxdomain", DNS_RPZ_POLICY_NXDOMAIN }, 254 { "nodata", DNS_RPZ_POLICY_NODATA }, 255 { "cname", DNS_RPZ_POLICY_CNAME }, 256 { "no-op", DNS_RPZ_POLICY_PASSTHRU }, /* old passthru */ 257 }; 258 unsigned int n; 259 260 if (str == NULL) { 261 return DNS_RPZ_POLICY_ERROR; 262 } 263 for (n = 0; n < sizeof(tbl) / sizeof(tbl[0]); ++n) { 264 if (!strcasecmp(tbl[n].str, str)) { 265 return tbl[n].policy; 266 } 267 } 268 return DNS_RPZ_POLICY_ERROR; 269 } 270 271 const char * 272 dns_rpz_policy2str(dns_rpz_policy_t policy) { 273 const char *str = NULL; 274 275 switch (policy) { 276 case DNS_RPZ_POLICY_PASSTHRU: 277 str = "PASSTHRU"; 278 break; 279 case DNS_RPZ_POLICY_DROP: 280 str = "DROP"; 281 break; 282 case DNS_RPZ_POLICY_TCP_ONLY: 283 str = "TCP-ONLY"; 284 break; 285 case DNS_RPZ_POLICY_NXDOMAIN: 286 str = "NXDOMAIN"; 287 break; 288 case DNS_RPZ_POLICY_NODATA: 289 str = "NODATA"; 290 break; 291 case DNS_RPZ_POLICY_RECORD: 292 str = "Local-Data"; 293 break; 294 case DNS_RPZ_POLICY_CNAME: 295 case DNS_RPZ_POLICY_WILDCNAME: 296 str = "CNAME"; 297 break; 298 case DNS_RPZ_POLICY_MISS: 299 str = "MISS"; 300 break; 301 case DNS_RPZ_POLICY_DNS64: 302 str = "DNS64"; 303 break; 304 case DNS_RPZ_POLICY_ERROR: 305 str = "ERROR"; 306 break; 307 default: 308 UNREACHABLE(); 309 } 310 return str; 311 } 312 313 uint16_t 314 dns_rpz_str2ede(const char *str) { 315 static struct { 316 const char *str; 317 uint16_t ede; 318 } tbl[] = { 319 { "none", 0 }, 320 { "forged", DNS_EDE_FORGEDANSWER }, 321 { "blocked", DNS_EDE_BLOCKED }, 322 { "censored", DNS_EDE_CENSORED }, 323 { "filtered", DNS_EDE_FILTERED }, 324 { "prohibited", DNS_EDE_PROHIBITED }, 325 }; 326 unsigned int n; 327 328 if (str == NULL) { 329 return UINT16_MAX; 330 } 331 for (n = 0; n < sizeof(tbl) / sizeof(tbl[0]); ++n) { 332 if (!strcasecmp(tbl[n].str, str)) { 333 return tbl[n].ede; 334 } 335 } 336 return UINT16_MAX; 337 } 338 339 /* 340 * Return the bit number of the highest set bit in 'zbit'. 341 * (for example, 0x01 returns 0, 0xFF returns 7, etc.) 342 */ 343 static int 344 zbit_to_num(dns_rpz_zbits_t zbit) { 345 dns_rpz_num_t rpz_num; 346 347 REQUIRE(zbit != 0); 348 rpz_num = 0; 349 if ((zbit & 0xffffffff00000000ULL) != 0) { 350 zbit >>= 32; 351 rpz_num += 32; 352 } 353 if ((zbit & 0xffff0000) != 0) { 354 zbit >>= 16; 355 rpz_num += 16; 356 } 357 if ((zbit & 0xff00) != 0) { 358 zbit >>= 8; 359 rpz_num += 8; 360 } 361 if ((zbit & 0xf0) != 0) { 362 zbit >>= 4; 363 rpz_num += 4; 364 } 365 if ((zbit & 0xc) != 0) { 366 zbit >>= 2; 367 rpz_num += 2; 368 } 369 if ((zbit & 2) != 0) { 370 ++rpz_num; 371 } 372 return rpz_num; 373 } 374 375 /* 376 * Make a set of bit masks given one or more bits and their type. 377 */ 378 static void 379 make_addr_set(dns_rpz_addr_zbits_t *tgt_set, dns_rpz_zbits_t zbits, 380 dns_rpz_type_t type) { 381 switch (type) { 382 case DNS_RPZ_TYPE_CLIENT_IP: 383 tgt_set->client_ip = zbits; 384 tgt_set->ip = 0; 385 tgt_set->nsip = 0; 386 break; 387 case DNS_RPZ_TYPE_IP: 388 tgt_set->client_ip = 0; 389 tgt_set->ip = zbits; 390 tgt_set->nsip = 0; 391 break; 392 case DNS_RPZ_TYPE_NSIP: 393 tgt_set->client_ip = 0; 394 tgt_set->ip = 0; 395 tgt_set->nsip = zbits; 396 break; 397 default: 398 UNREACHABLE(); 399 } 400 } 401 402 static void 403 make_nm_set(dns_rpz_nm_zbits_t *tgt_set, dns_rpz_num_t rpz_num, 404 dns_rpz_type_t type) { 405 switch (type) { 406 case DNS_RPZ_TYPE_QNAME: 407 tgt_set->qname = DNS_RPZ_ZBIT(rpz_num); 408 tgt_set->ns = 0; 409 break; 410 case DNS_RPZ_TYPE_NSDNAME: 411 tgt_set->qname = 0; 412 tgt_set->ns = DNS_RPZ_ZBIT(rpz_num); 413 break; 414 default: 415 UNREACHABLE(); 416 } 417 } 418 419 /* 420 * Mark a node and all of its parents as having client-IP, IP, or NSIP data 421 */ 422 static void 423 set_sum_pair(dns_rpz_cidr_node_t *cnode) { 424 dns_rpz_addr_zbits_t sum; 425 426 do { 427 dns_rpz_cidr_node_t *child = cnode->child[0]; 428 sum = cnode->set; 429 430 if (child != NULL) { 431 sum.client_ip |= child->sum.client_ip; 432 sum.ip |= child->sum.ip; 433 sum.nsip |= child->sum.nsip; 434 } 435 436 child = cnode->child[1]; 437 if (child != NULL) { 438 sum.client_ip |= child->sum.client_ip; 439 sum.ip |= child->sum.ip; 440 sum.nsip |= child->sum.nsip; 441 } 442 443 if (cnode->sum.client_ip == sum.client_ip && 444 cnode->sum.ip == sum.ip && cnode->sum.nsip == sum.nsip) 445 { 446 break; 447 } 448 cnode->sum = sum; 449 cnode = cnode->parent; 450 } while (cnode != NULL); 451 } 452 453 /* Caller must hold rpzs->maint_lock */ 454 static void 455 fix_qname_skip_recurse(dns_rpz_zones_t *rpzs) { 456 dns_rpz_zbits_t mask; 457 458 /* 459 * qname_wait_recurse and qname_skip_recurse are used to 460 * implement the "qname-wait-recurse" config option. 461 * 462 * When "qname-wait-recurse" is yes, no processing happens without 463 * recursion. In this case, qname_wait_recurse is true, and 464 * qname_skip_recurse (a bit field indicating which policy zones 465 * can be processed without recursion) is set to all 0's by 466 * fix_qname_skip_recurse(). 467 * 468 * When "qname-wait-recurse" is no, qname_skip_recurse may be 469 * set to a non-zero value by fix_qname_skip_recurse(). The mask 470 * has to have bits set for the policy zones for which 471 * processing may continue without recursion, and bits cleared 472 * for the rest. 473 * 474 * (1) The ARM says: 475 * 476 * The "qname-wait-recurse no" option overrides that default 477 * behavior when recursion cannot change a non-error 478 * response. The option does not affect QNAME or client-IP 479 * triggers in policy zones listed after other zones 480 * containing IP, NSIP and NSDNAME triggers, because those may 481 * depend on the A, AAAA, and NS records that would be found 482 * during recursive resolution. 483 * 484 * Let's consider the following: 485 * 486 * zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 | 487 * rpzs->have.nsdname | 488 * rpzs->have.nsipv4 | rpzs->have.nsipv6); 489 * 490 * zbits_req now contains bits set for zones which require 491 * recursion. 492 * 493 * But going by the description in the ARM, if the first policy 494 * zone requires recursion, then all zones after that (higher 495 * order bits) have to wait as well. If the Nth zone requires 496 * recursion, then (N+1)th zone onwards all need to wait. 497 * 498 * So mapping this, examples: 499 * 500 * zbits_req = 0b000 mask = 0xffffffff (no zones have to wait for 501 * recursion) 502 * zbits_req = 0b001 mask = 0x00000000 (all zones have to wait) 503 * zbits_req = 0b010 mask = 0x00000001 (the first zone doesn't have to 504 * wait, second zone onwards need 505 * to wait) 506 * zbits_req = 0b011 mask = 0x00000000 (all zones have to wait) 507 * zbits_req = 0b100 mask = 0x00000011 (the 1st and 2nd zones don't 508 * have to wait, third zone 509 * onwards need to wait) 510 * 511 * More generally, we have to count the number of trailing 0 512 * bits in zbits_req and only these can be processed without 513 * recursion. All the rest need to wait. 514 * 515 * (2) The ARM says that "qname-wait-recurse no" option 516 * overrides the default behavior when recursion cannot change a 517 * non-error response. So, in the order of listing of policy 518 * zones, within the first policy zone where recursion may be 519 * required, we should first allow CLIENT-IP and QNAME policy 520 * records to be attempted without recursion. 521 */ 522 523 /* 524 * Get a mask covering all policy zones that are not subordinate to 525 * other policy zones containing triggers that require that the 526 * qname be resolved before they can be checked. 527 */ 528 rpzs->have.client_ip = rpzs->have.client_ipv4 | rpzs->have.client_ipv6; 529 rpzs->have.ip = rpzs->have.ipv4 | rpzs->have.ipv6; 530 rpzs->have.nsip = rpzs->have.nsipv4 | rpzs->have.nsipv6; 531 532 if (rpzs->p.qname_wait_recurse) { 533 mask = 0; 534 } else { 535 dns_rpz_zbits_t zbits_req; 536 dns_rpz_zbits_t zbits_notreq; 537 dns_rpz_zbits_t mask2; 538 dns_rpz_zbits_t req_mask; 539 540 /* 541 * Get the masks of zones with policies that 542 * do/don't require recursion 543 */ 544 545 zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 | 546 rpzs->have.nsdname | rpzs->have.nsipv4 | 547 rpzs->have.nsipv6); 548 zbits_notreq = (rpzs->have.client_ip | rpzs->have.qname); 549 550 if (zbits_req == 0) { 551 mask = DNS_RPZ_ALL_ZBITS; 552 goto set; 553 } 554 555 /* 556 * req_mask is a mask covering used bits in 557 * zbits_req. (For instance, 0b1 => 0b1, 0b101 => 0b111, 558 * 0b11010101 => 0b11111111). 559 */ 560 req_mask = zbits_req; 561 req_mask |= req_mask >> 1; 562 req_mask |= req_mask >> 2; 563 req_mask |= req_mask >> 4; 564 req_mask |= req_mask >> 8; 565 req_mask |= req_mask >> 16; 566 req_mask |= req_mask >> 32; 567 568 /* 569 * There's no point in skipping recursion for a later 570 * zone if it is required in a previous zone. 571 */ 572 if ((zbits_notreq & req_mask) == 0) { 573 mask = 0; 574 goto set; 575 } 576 577 /* 578 * This bit arithmetic creates a mask of zones in which 579 * it is okay to skip recursion. After the first zone 580 * that has to wait for recursion, all the others have 581 * to wait as well, so we want to create a mask in which 582 * all the trailing zeroes in zbits_req are are 1, and 583 * more significant bits are 0. (For instance, 584 * 0x0700 => 0x00ff, 0x0007 => 0x0000) 585 */ 586 mask = ~(zbits_req | ((~zbits_req) + 1)); 587 588 /* 589 * As mentioned in (2) above, the zone corresponding to 590 * the least significant zero could have its CLIENT-IP 591 * and QNAME policies checked before recursion, if it 592 * has any of those policies. So if it does, we 593 * can set its 0 to 1. 594 * 595 * Locate the least significant 0 bit in the mask (for 596 * instance, 0xff => 0x100)... 597 */ 598 mask2 = (mask << 1) & ~mask; 599 600 /* 601 * Also set the bit for zone 0, because if it's in 602 * zbits_notreq then it's definitely okay to attempt to 603 * skip recursion for zone 0... 604 */ 605 mask2 |= 1; 606 607 /* Clear any bits *not* in zbits_notreq... */ 608 mask2 &= zbits_notreq; 609 610 /* And merge the result into the skip-recursion mask */ 611 mask |= mask2; 612 } 613 614 set: 615 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, 616 DNS_RPZ_DEBUG_QUIET, 617 "computed RPZ qname_skip_recurse mask=0x%" PRIx64, 618 (uint64_t)mask); 619 rpzs->have.qname_skip_recurse = mask; 620 } 621 622 static void 623 adj_trigger_cnt(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 624 const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, 625 bool inc) { 626 dns_rpz_trigger_counter_t *cnt = NULL; 627 dns_rpz_zbits_t *have = NULL; 628 629 switch (rpz_type) { 630 case DNS_RPZ_TYPE_CLIENT_IP: 631 REQUIRE(tgt_ip != NULL); 632 if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { 633 cnt = &rpz->rpzs->triggers[rpz->num].client_ipv4; 634 have = &rpz->rpzs->have.client_ipv4; 635 } else { 636 cnt = &rpz->rpzs->triggers[rpz->num].client_ipv6; 637 have = &rpz->rpzs->have.client_ipv6; 638 } 639 break; 640 case DNS_RPZ_TYPE_QNAME: 641 cnt = &rpz->rpzs->triggers[rpz->num].qname; 642 have = &rpz->rpzs->have.qname; 643 break; 644 case DNS_RPZ_TYPE_IP: 645 REQUIRE(tgt_ip != NULL); 646 if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { 647 cnt = &rpz->rpzs->triggers[rpz->num].ipv4; 648 have = &rpz->rpzs->have.ipv4; 649 } else { 650 cnt = &rpz->rpzs->triggers[rpz->num].ipv6; 651 have = &rpz->rpzs->have.ipv6; 652 } 653 break; 654 case DNS_RPZ_TYPE_NSDNAME: 655 cnt = &rpz->rpzs->triggers[rpz->num].nsdname; 656 have = &rpz->rpzs->have.nsdname; 657 break; 658 case DNS_RPZ_TYPE_NSIP: 659 REQUIRE(tgt_ip != NULL); 660 if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { 661 cnt = &rpz->rpzs->triggers[rpz->num].nsipv4; 662 have = &rpz->rpzs->have.nsipv4; 663 } else { 664 cnt = &rpz->rpzs->triggers[rpz->num].nsipv6; 665 have = &rpz->rpzs->have.nsipv6; 666 } 667 break; 668 default: 669 UNREACHABLE(); 670 } 671 672 if (inc) { 673 if (++*cnt == 1U) { 674 *have |= DNS_RPZ_ZBIT(rpz->num); 675 fix_qname_skip_recurse(rpz->rpzs); 676 } 677 } else { 678 REQUIRE(*cnt != 0U); 679 if (--*cnt == 0U) { 680 *have &= ~DNS_RPZ_ZBIT(rpz->num); 681 fix_qname_skip_recurse(rpz->rpzs); 682 } 683 } 684 } 685 686 static dns_rpz_cidr_node_t * 687 new_node(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *ip, 688 dns_rpz_prefix_t prefix, const dns_rpz_cidr_node_t *child) { 689 dns_rpz_cidr_node_t *node = NULL; 690 int i, words, wlen; 691 692 node = isc_mem_get(rpzs->mctx, sizeof(*node)); 693 *node = (dns_rpz_cidr_node_t){ 694 .prefix = prefix, 695 }; 696 697 if (child != NULL) { 698 node->sum = child->sum; 699 } 700 701 words = prefix / DNS_RPZ_CIDR_WORD_BITS; 702 wlen = prefix % DNS_RPZ_CIDR_WORD_BITS; 703 i = 0; 704 while (i < words) { 705 node->ip.w[i] = ip->w[i]; 706 ++i; 707 } 708 if (wlen != 0) { 709 node->ip.w[i] = ip->w[i] & DNS_RPZ_WORD_MASK(wlen); 710 ++i; 711 } 712 while (i < DNS_RPZ_CIDR_WORDS) { 713 node->ip.w[i++] = 0; 714 } 715 716 return node; 717 } 718 719 static void 720 badname(int level, const dns_name_t *name, const char *str1, const char *str2) { 721 /* 722 * bin/tests/system/rpz/tests.sh looks for "invalid rpz". 723 */ 724 if (level < DNS_RPZ_DEBUG_QUIET && isc_log_wouldlog(dns_lctx, level)) { 725 char namebuf[DNS_NAME_FORMATSIZE]; 726 dns_name_format(name, namebuf, sizeof(namebuf)); 727 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 728 DNS_LOGMODULE_RBTDB, level, 729 "invalid rpz IP address \"%s\"%s%s", namebuf, 730 str1, str2); 731 } 732 } 733 734 /* 735 * Convert an IP address from radix tree binary (host byte order) to 736 * to its canonical response policy domain name without the origin of the 737 * policy zone. 738 * 739 * Generate a name for an IPv6 address that fits RFC 5952, except that our 740 * reversed format requires that when the length of the consecutive 16-bit 741 * 0 fields are equal (e.g., 1.0.0.1.0.0.db8.2001 corresponding to 742 * 2001:db8:0:0:1:0:0:1), we shorted the last instead of the first 743 * (e.g., 1.0.0.1.zz.db8.2001 corresponding to 2001:db8::1:0:0:1). 744 */ 745 static isc_result_t 746 ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, 747 const dns_name_t *base_name, dns_name_t *ip_name) { 748 #ifndef INET6_ADDRSTRLEN 749 #define INET6_ADDRSTRLEN 46 750 #endif /* ifndef INET6_ADDRSTRLEN */ 751 char str[1 + 8 + 1 + INET6_ADDRSTRLEN + 1]; 752 isc_buffer_t buffer; 753 isc_result_t result; 754 int len; 755 756 if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { 757 len = snprintf(str, sizeof(str), "%u.%u.%u.%u.%u", 758 tgt_prefix - 96U, tgt_ip->w[3] & 0xffU, 759 (tgt_ip->w[3] >> 8) & 0xffU, 760 (tgt_ip->w[3] >> 16) & 0xffU, 761 (tgt_ip->w[3] >> 24) & 0xffU); 762 if (len < 0 || (size_t)len >= sizeof(str)) { 763 return ISC_R_FAILURE; 764 } 765 } else { 766 int w[DNS_RPZ_CIDR_WORDS * 2]; 767 int best_first, best_len, cur_first, cur_len; 768 769 len = snprintf(str, sizeof(str), "%d", tgt_prefix); 770 if (len < 0 || (size_t)len >= sizeof(str)) { 771 return ISC_R_FAILURE; 772 } 773 774 for (int n = 0; n < DNS_RPZ_CIDR_WORDS; n++) { 775 w[n * 2 + 1] = 776 ((tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - n] >> 16) & 777 0xffff); 778 w[n * 2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - n] & 779 0xffff; 780 } 781 /* 782 * Find the start and length of the first longest sequence 783 * of zeros in the address. 784 */ 785 best_first = -1; 786 best_len = 0; 787 cur_first = -1; 788 cur_len = 0; 789 for (int n = 0; n <= 7; ++n) { 790 if (w[n] != 0) { 791 cur_len = 0; 792 cur_first = -1; 793 } else { 794 ++cur_len; 795 if (cur_first < 0) { 796 cur_first = n; 797 } else if (cur_len >= best_len) { 798 best_first = cur_first; 799 best_len = cur_len; 800 } 801 } 802 } 803 804 for (int n = 0; n <= 7; ++n) { 805 int i; 806 807 INSIST(len > 0 && (size_t)len < sizeof(str)); 808 if (n == best_first) { 809 i = snprintf(str + len, sizeof(str) - len, 810 ".zz"); 811 n += best_len - 1; 812 } else { 813 i = snprintf(str + len, sizeof(str) - len, 814 ".%x", w[n]); 815 } 816 if (i < 0 || (size_t)i >= (size_t)(sizeof(str) - len)) { 817 return ISC_R_FAILURE; 818 } 819 len += i; 820 } 821 } 822 823 isc_buffer_init(&buffer, str, sizeof(str)); 824 isc_buffer_add(&buffer, len); 825 result = dns_name_fromtext(ip_name, &buffer, base_name, 0, NULL); 826 return result; 827 } 828 829 /* 830 * Determine the type of a name in a response policy zone. 831 */ 832 static dns_rpz_type_t 833 type_from_name(const dns_rpz_zones_t *rpzs, dns_rpz_zone_t *rpz, 834 const dns_name_t *name) { 835 if (dns_name_issubdomain(name, &rpz->ip)) { 836 return DNS_RPZ_TYPE_IP; 837 } 838 839 if (dns_name_issubdomain(name, &rpz->client_ip)) { 840 return DNS_RPZ_TYPE_CLIENT_IP; 841 } 842 843 if ((rpzs->p.nsip_on & DNS_RPZ_ZBIT(rpz->num)) != 0 && 844 dns_name_issubdomain(name, &rpz->nsip)) 845 { 846 return DNS_RPZ_TYPE_NSIP; 847 } 848 849 if ((rpzs->p.nsdname_on & DNS_RPZ_ZBIT(rpz->num)) != 0 && 850 dns_name_issubdomain(name, &rpz->nsdname)) 851 { 852 return DNS_RPZ_TYPE_NSDNAME; 853 } 854 855 return DNS_RPZ_TYPE_QNAME; 856 } 857 858 /* 859 * Convert an IP address from canonical response policy domain name form 860 * to radix tree binary (host byte order) for adding or deleting IP or NSIP 861 * data. 862 */ 863 static isc_result_t 864 name2ipkey(int log_level, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 865 const dns_name_t *src_name, dns_rpz_cidr_key_t *tgt_ip, 866 dns_rpz_prefix_t *tgt_prefix, dns_rpz_addr_zbits_t *new_set) { 867 char ip_str[DNS_NAME_FORMATSIZE]; 868 dns_offsets_t ip_name_offsets; 869 dns_fixedname_t ip_name2f; 870 dns_name_t ip_name; 871 const char *prefix_str = NULL, *cp = NULL, *end = NULL; 872 char *cp2; 873 int ip_labels; 874 dns_rpz_prefix_t prefix; 875 unsigned long prefix_num, l; 876 isc_result_t result; 877 int i; 878 879 REQUIRE(rpz != NULL); 880 REQUIRE(rpz->rpzs != NULL && rpz->num < rpz->rpzs->p.num_zones); 881 882 make_addr_set(new_set, DNS_RPZ_ZBIT(rpz->num), rpz_type); 883 884 ip_labels = dns_name_countlabels(src_name); 885 if (rpz_type == DNS_RPZ_TYPE_QNAME) { 886 ip_labels -= dns_name_countlabels(&rpz->origin); 887 } else { 888 ip_labels -= dns_name_countlabels(&rpz->nsdname); 889 } 890 if (ip_labels < 2) { 891 badname(log_level, src_name, "; too short", ""); 892 return ISC_R_FAILURE; 893 } 894 dns_name_init(&ip_name, ip_name_offsets); 895 dns_name_getlabelsequence(src_name, 0, ip_labels, &ip_name); 896 897 /* 898 * Get text for the IP address 899 */ 900 dns_name_format(&ip_name, ip_str, sizeof(ip_str)); 901 end = &ip_str[strlen(ip_str) + 1]; 902 prefix_str = ip_str; 903 904 prefix_num = strtoul(prefix_str, &cp2, 10); 905 if (*cp2 != '.') { 906 badname(log_level, src_name, "; invalid leading prefix length", 907 ""); 908 return ISC_R_FAILURE; 909 } 910 /* 911 * Patch in trailing nul character to print just the length 912 * label (for various cases below). 913 */ 914 *cp2 = '\0'; 915 if (prefix_num < 1U || prefix_num > 128U) { 916 badname(log_level, src_name, "; invalid prefix length of ", 917 prefix_str); 918 return ISC_R_FAILURE; 919 } 920 cp = cp2 + 1; 921 922 if (--ip_labels == 4 && !strchr(cp, 'z')) { 923 /* 924 * Convert an IPv4 address 925 * from the form "prefix.z.y.x.w" 926 */ 927 if (prefix_num > 32U) { 928 badname(log_level, src_name, 929 "; invalid IPv4 prefix length of ", prefix_str); 930 return ISC_R_FAILURE; 931 } 932 prefix_num += 96; 933 *tgt_prefix = (dns_rpz_prefix_t)prefix_num; 934 tgt_ip->w[0] = 0; 935 tgt_ip->w[1] = 0; 936 tgt_ip->w[2] = ADDR_V4MAPPED; 937 tgt_ip->w[3] = 0; 938 for (i = 0; i < 32; i += 8) { 939 l = strtoul(cp, &cp2, 10); 940 if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) { 941 if (*cp2 == '.') { 942 *cp2 = '\0'; 943 } 944 badname(log_level, src_name, 945 "; invalid IPv4 octet ", cp); 946 return ISC_R_FAILURE; 947 } 948 tgt_ip->w[3] |= l << i; 949 cp = cp2 + 1; 950 } 951 } else { 952 /* 953 * Convert a text IPv6 address. 954 */ 955 *tgt_prefix = (dns_rpz_prefix_t)prefix_num; 956 for (i = 0; ip_labels > 0 && i < DNS_RPZ_CIDR_WORDS * 2; 957 ip_labels--) 958 { 959 if (cp[0] == 'z' && cp[1] == 'z' && 960 (cp[2] == '.' || cp[2] == '\0') && i <= 6) 961 { 962 do { 963 if ((i & 1) == 0) { 964 tgt_ip->w[3 - i / 2] = 0; 965 } 966 ++i; 967 } while (ip_labels + i <= 8); 968 cp += 3; 969 } else { 970 l = strtoul(cp, &cp2, 16); 971 if (l > 0xffffu || 972 (*cp2 != '.' && *cp2 != '\0')) 973 { 974 if (*cp2 == '.') { 975 *cp2 = '\0'; 976 } 977 badname(log_level, src_name, 978 "; invalid IPv6 word ", cp); 979 return ISC_R_FAILURE; 980 } 981 if ((i & 1) == 0) { 982 tgt_ip->w[3 - i / 2] = l; 983 } else { 984 tgt_ip->w[3 - i / 2] |= l << 16; 985 } 986 i++; 987 cp = cp2 + 1; 988 } 989 } 990 } 991 if (cp != end) { 992 badname(log_level, src_name, "", ""); 993 return ISC_R_FAILURE; 994 } 995 996 /* 997 * Check for 1s after the prefix length. 998 */ 999 prefix = (dns_rpz_prefix_t)prefix_num; 1000 while (prefix < DNS_RPZ_CIDR_KEY_BITS) { 1001 dns_rpz_cidr_word_t aword; 1002 1003 i = prefix % DNS_RPZ_CIDR_WORD_BITS; 1004 aword = tgt_ip->w[prefix / DNS_RPZ_CIDR_WORD_BITS]; 1005 if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) { 1006 badname(log_level, src_name, 1007 "; too small prefix length of ", prefix_str); 1008 return ISC_R_FAILURE; 1009 } 1010 prefix -= i; 1011 prefix += DNS_RPZ_CIDR_WORD_BITS; 1012 } 1013 1014 /* 1015 * Complain about bad names but be generous and accept them. 1016 */ 1017 if (log_level < DNS_RPZ_DEBUG_QUIET && 1018 isc_log_wouldlog(dns_lctx, log_level)) 1019 { 1020 /* 1021 * Convert the address back to a canonical domain name 1022 * to ensure that the original name is in canonical form. 1023 */ 1024 dns_name_t *ip_name2 = dns_fixedname_initname(&ip_name2f); 1025 result = ip2name(tgt_ip, (dns_rpz_prefix_t)prefix_num, NULL, 1026 ip_name2); 1027 if (result != ISC_R_SUCCESS || 1028 !dns_name_equal(&ip_name, ip_name2)) 1029 { 1030 char ip2_str[DNS_NAME_FORMATSIZE]; 1031 dns_name_format(ip_name2, ip2_str, sizeof(ip2_str)); 1032 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 1033 DNS_LOGMODULE_RBTDB, log_level, 1034 "rpz IP address \"%s\"" 1035 " is not the canonical \"%s\"", 1036 ip_str, ip2_str); 1037 } 1038 } 1039 1040 return ISC_R_SUCCESS; 1041 } 1042 1043 /* 1044 * Get trigger name and data bits for adding or deleting summary NSDNAME 1045 * or QNAME data. 1046 */ 1047 static void 1048 name2data(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 1049 const dns_name_t *src_name, dns_name_t *trig_name, 1050 nmdata_t *new_data) { 1051 dns_offsets_t tmp_name_offsets; 1052 dns_name_t tmp_name; 1053 unsigned int prefix_len, n; 1054 1055 REQUIRE(rpz != NULL); 1056 REQUIRE(rpz->rpzs != NULL && rpz->num < rpz->rpzs->p.num_zones); 1057 1058 /* 1059 * Handle wildcards by putting only the parent into the 1060 * summary database. The database only causes a check of the 1061 * real policy zone where wildcards will be handled. 1062 */ 1063 if (dns_name_iswildcard(src_name)) { 1064 prefix_len = 1; 1065 memset(&new_data->set, 0, sizeof(new_data->set)); 1066 make_nm_set(&new_data->wild, rpz->num, rpz_type); 1067 } else { 1068 prefix_len = 0; 1069 make_nm_set(&new_data->set, rpz->num, rpz_type); 1070 memset(&new_data->wild, 0, sizeof(new_data->wild)); 1071 } 1072 1073 dns_name_init(&tmp_name, tmp_name_offsets); 1074 n = dns_name_countlabels(src_name); 1075 n -= prefix_len; 1076 if (rpz_type == DNS_RPZ_TYPE_QNAME) { 1077 n -= dns_name_countlabels(&rpz->origin); 1078 } else { 1079 n -= dns_name_countlabels(&rpz->nsdname); 1080 } 1081 dns_name_getlabelsequence(src_name, prefix_len, n, &tmp_name); 1082 (void)dns_name_concatenate(&tmp_name, dns_rootname, trig_name, NULL); 1083 } 1084 1085 #ifndef HAVE_BUILTIN_CLZ 1086 /** 1087 * \brief Count Leading Zeros: Find the location of the left-most set 1088 * bit. 1089 */ 1090 static unsigned int 1091 clz(dns_rpz_cidr_word_t w) { 1092 unsigned int bit; 1093 1094 bit = DNS_RPZ_CIDR_WORD_BITS - 1; 1095 1096 if ((w & 0xffff0000) != 0) { 1097 w >>= 16; 1098 bit -= 16; 1099 } 1100 1101 if ((w & 0xff00) != 0) { 1102 w >>= 8; 1103 bit -= 8; 1104 } 1105 1106 if ((w & 0xf0) != 0) { 1107 w >>= 4; 1108 bit -= 4; 1109 } 1110 1111 if ((w & 0xc) != 0) { 1112 w >>= 2; 1113 bit -= 2; 1114 } 1115 1116 if ((w & 2) != 0) { 1117 --bit; 1118 } 1119 1120 return bit; 1121 } 1122 #endif /* ifndef HAVE_BUILTIN_CLZ */ 1123 1124 /* 1125 * Find the first differing bit in two keys (IP addresses). 1126 */ 1127 static int 1128 diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_prefix_t prefix1, 1129 const dns_rpz_cidr_key_t *key2, dns_rpz_prefix_t prefix2) { 1130 dns_rpz_cidr_word_t delta; 1131 dns_rpz_prefix_t maxbit, bit; 1132 int i; 1133 1134 bit = 0; 1135 maxbit = ISC_MIN(prefix1, prefix2); 1136 1137 /* 1138 * find the first differing words 1139 */ 1140 for (i = 0; bit < maxbit; i++, bit += DNS_RPZ_CIDR_WORD_BITS) { 1141 delta = key1->w[i] ^ key2->w[i]; 1142 if (delta != 0) { 1143 #ifdef HAVE_BUILTIN_CLZ 1144 bit += __builtin_clz(delta); 1145 #else /* ifdef HAVE_BUILTIN_CLZ */ 1146 bit += clz(delta); 1147 #endif /* ifdef HAVE_BUILTIN_CLZ */ 1148 break; 1149 } 1150 } 1151 return ISC_MIN(bit, maxbit); 1152 } 1153 1154 /* 1155 * Given a hit while searching the radix trees, 1156 * clear all bits for higher numbered zones. 1157 */ 1158 static dns_rpz_zbits_t 1159 trim_zbits(dns_rpz_zbits_t zbits, dns_rpz_zbits_t found) { 1160 dns_rpz_zbits_t x; 1161 1162 /* 1163 * Isolate the first or smallest numbered hit bit. 1164 * Make a mask of that bit and all smaller numbered bits. 1165 */ 1166 x = zbits & found; 1167 x &= (~x + 1); 1168 x = (x << 1) - 1; 1169 zbits &= x; 1170 return zbits; 1171 } 1172 1173 /* 1174 * Search a radix tree for an IP address for ordinary lookup 1175 * or for a CIDR block adding or deleting an entry 1176 * 1177 * Return ISC_R_SUCCESS, DNS_R_PARTIALMATCH, ISC_R_NOTFOUND, 1178 * and *found=longest match node 1179 * or with create==true, ISC_R_EXISTS 1180 */ 1181 static isc_result_t 1182 search(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *tgt_ip, 1183 dns_rpz_prefix_t tgt_prefix, const dns_rpz_addr_zbits_t *tgt_set, 1184 bool create, dns_rpz_cidr_node_t **found) { 1185 dns_rpz_cidr_node_t *cur = rpzs->cidr; 1186 dns_rpz_cidr_node_t *parent = NULL, *child = NULL; 1187 dns_rpz_cidr_node_t *new_parent = NULL, *sibling = NULL; 1188 dns_rpz_addr_zbits_t set = *tgt_set; 1189 int cur_num = 0, child_num; 1190 isc_result_t find_result = ISC_R_NOTFOUND; 1191 1192 *found = NULL; 1193 for (;;) { 1194 dns_rpz_prefix_t dbit; 1195 if (cur == NULL) { 1196 /* 1197 * No child so we cannot go down. 1198 * Quit with whatever we already found 1199 * or add the target as a child of the current parent. 1200 */ 1201 if (!create) { 1202 return find_result; 1203 } 1204 child = new_node(rpzs, tgt_ip, tgt_prefix, NULL); 1205 if (parent == NULL) { 1206 rpzs->cidr = child; 1207 } else { 1208 parent->child[cur_num] = child; 1209 } 1210 child->parent = parent; 1211 child->set.client_ip |= tgt_set->client_ip; 1212 child->set.ip |= tgt_set->ip; 1213 child->set.nsip |= tgt_set->nsip; 1214 set_sum_pair(child); 1215 *found = child; 1216 return ISC_R_SUCCESS; 1217 } 1218 1219 if ((cur->sum.client_ip & set.client_ip) == 0 && 1220 (cur->sum.ip & set.ip) == 0 && 1221 (cur->sum.nsip & set.nsip) == 0) 1222 { 1223 /* 1224 * This node has no relevant data 1225 * and is in none of the target trees. 1226 * Pretend it does not exist if we are not adding. 1227 * 1228 * If we are adding, continue down to eventually add 1229 * a node and mark/put this node in the correct tree. 1230 */ 1231 if (!create) { 1232 return find_result; 1233 } 1234 } 1235 1236 dbit = diff_keys(tgt_ip, tgt_prefix, &cur->ip, cur->prefix); 1237 /* 1238 * dbit <= tgt_prefix and dbit <= cur->prefix always. 1239 * We are finished searching if we matched all of the target. 1240 */ 1241 if (dbit == tgt_prefix) { 1242 if (tgt_prefix == cur->prefix) { 1243 /* 1244 * The node's key matches the target exactly. 1245 */ 1246 if ((cur->set.client_ip & set.client_ip) != 0 || 1247 (cur->set.ip & set.ip) != 0 || 1248 (cur->set.nsip & set.nsip) != 0) 1249 { 1250 /* 1251 * It is the answer if it has data. 1252 */ 1253 *found = cur; 1254 if (create) { 1255 find_result = ISC_R_EXISTS; 1256 } else { 1257 find_result = ISC_R_SUCCESS; 1258 } 1259 } else if (create) { 1260 /* 1261 * The node lacked relevant data, 1262 * but will have it now. 1263 */ 1264 cur->set.client_ip |= 1265 tgt_set->client_ip; 1266 cur->set.ip |= tgt_set->ip; 1267 cur->set.nsip |= tgt_set->nsip; 1268 set_sum_pair(cur); 1269 *found = cur; 1270 find_result = ISC_R_SUCCESS; 1271 } 1272 return find_result; 1273 } 1274 1275 /* 1276 * We know tgt_prefix < cur->prefix which means that 1277 * the target is shorter than the current node. 1278 * Add the target as the current node's parent. 1279 */ 1280 if (!create) { 1281 return find_result; 1282 } 1283 1284 new_parent = new_node(rpzs, tgt_ip, tgt_prefix, cur); 1285 new_parent->parent = parent; 1286 if (parent == NULL) { 1287 rpzs->cidr = new_parent; 1288 } else { 1289 parent->child[cur_num] = new_parent; 1290 } 1291 child_num = DNS_RPZ_IP_BIT(&cur->ip, tgt_prefix); 1292 new_parent->child[child_num] = cur; 1293 cur->parent = new_parent; 1294 new_parent->set = *tgt_set; 1295 set_sum_pair(new_parent); 1296 *found = new_parent; 1297 return ISC_R_SUCCESS; 1298 } 1299 1300 if (dbit == cur->prefix) { 1301 if ((cur->set.client_ip & set.client_ip) != 0 || 1302 (cur->set.ip & set.ip) != 0 || 1303 (cur->set.nsip & set.nsip) != 0) 1304 { 1305 /* 1306 * We have a partial match between of all of the 1307 * current node but only part of the target. 1308 * Continue searching for other hits in the 1309 * same or lower numbered trees. 1310 */ 1311 find_result = DNS_R_PARTIALMATCH; 1312 *found = cur; 1313 set.client_ip = trim_zbits(set.client_ip, 1314 cur->set.client_ip); 1315 set.ip = trim_zbits(set.ip, cur->set.ip); 1316 set.nsip = trim_zbits(set.nsip, cur->set.nsip); 1317 } 1318 parent = cur; 1319 cur_num = DNS_RPZ_IP_BIT(tgt_ip, dbit); 1320 cur = cur->child[cur_num]; 1321 continue; 1322 } 1323 1324 /* 1325 * dbit < tgt_prefix and dbit < cur->prefix, 1326 * so we failed to match both the target and the current node. 1327 * Insert a fork of a parent above the current node and 1328 * add the target as a sibling of the current node 1329 */ 1330 if (!create) { 1331 return find_result; 1332 } 1333 1334 sibling = new_node(rpzs, tgt_ip, tgt_prefix, NULL); 1335 new_parent = new_node(rpzs, tgt_ip, dbit, cur); 1336 new_parent->parent = parent; 1337 if (parent == NULL) { 1338 rpzs->cidr = new_parent; 1339 } else { 1340 parent->child[cur_num] = new_parent; 1341 } 1342 child_num = DNS_RPZ_IP_BIT(tgt_ip, dbit); 1343 new_parent->child[child_num] = sibling; 1344 new_parent->child[1 - child_num] = cur; 1345 cur->parent = new_parent; 1346 sibling->parent = new_parent; 1347 sibling->set = *tgt_set; 1348 set_sum_pair(sibling); 1349 *found = sibling; 1350 return ISC_R_SUCCESS; 1351 } 1352 } 1353 1354 /* 1355 * Add an IP address to the radix tree. 1356 */ 1357 static isc_result_t 1358 add_cidr(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 1359 const dns_name_t *src_name) { 1360 dns_rpz_cidr_key_t tgt_ip; 1361 dns_rpz_prefix_t tgt_prefix; 1362 dns_rpz_addr_zbits_t set; 1363 dns_rpz_cidr_node_t *found = NULL; 1364 isc_result_t result; 1365 1366 result = name2ipkey(DNS_RPZ_ERROR_LEVEL, rpz, rpz_type, src_name, 1367 &tgt_ip, &tgt_prefix, &set); 1368 /* 1369 * Log complaints about bad owner names but let the zone load. 1370 */ 1371 if (result != ISC_R_SUCCESS) { 1372 return ISC_R_SUCCESS; 1373 } 1374 1375 RWLOCK(&rpz->rpzs->search_lock, isc_rwlocktype_write); 1376 result = search(rpz->rpzs, &tgt_ip, tgt_prefix, &set, true, &found); 1377 if (result != ISC_R_SUCCESS) { 1378 char namebuf[DNS_NAME_FORMATSIZE]; 1379 1380 /* 1381 * Do not worry if the radix tree already exists, 1382 * because diff_apply() likes to add nodes before deleting. 1383 */ 1384 if (result == ISC_R_EXISTS) { 1385 result = ISC_R_SUCCESS; 1386 goto done; 1387 } 1388 1389 /* 1390 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". 1391 */ 1392 dns_name_format(src_name, namebuf, sizeof(namebuf)); 1393 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 1394 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 1395 "rpz add_cidr(%s) failed: %s", namebuf, 1396 isc_result_totext(result)); 1397 goto done; 1398 } 1399 1400 adj_trigger_cnt(rpz, rpz_type, &tgt_ip, tgt_prefix, true); 1401 done: 1402 RWUNLOCK(&rpz->rpzs->search_lock, isc_rwlocktype_write); 1403 return result; 1404 } 1405 1406 static nmdata_t * 1407 new_nmdata(isc_mem_t *mctx, const dns_name_t *name, const nmdata_t *data) { 1408 nmdata_t *newdata = isc_mem_get(mctx, sizeof(*newdata)); 1409 *newdata = (nmdata_t){ 1410 .set = data->set, 1411 .wild = data->wild, 1412 .name = DNS_NAME_INITEMPTY, 1413 .references = ISC_REFCOUNT_INITIALIZER(1), 1414 }; 1415 dns_name_dupwithoffsets(name, mctx, &newdata->name); 1416 isc_mem_attach(mctx, &newdata->mctx); 1417 1418 #ifdef DNS_RPZ_TRACE 1419 fprintf(stderr, "new_nmdata:%s:%s:%d:%p->references = 1\n", __func__, 1420 __FILE__, __LINE__ + 1, name); 1421 #endif 1422 1423 return newdata; 1424 } 1425 1426 static isc_result_t 1427 add_nm(dns_rpz_zones_t *rpzs, dns_name_t *trig_name, const nmdata_t *new_data) { 1428 isc_result_t result; 1429 nmdata_t *data = NULL; 1430 dns_qp_t *qp = NULL; 1431 1432 dns_qpmulti_write(rpzs->table, &qp); 1433 result = dns_qp_getname(qp, trig_name, (void **)&data, NULL); 1434 if (result != ISC_R_SUCCESS) { 1435 INSIST(data == NULL); 1436 data = new_nmdata(rpzs->mctx, trig_name, new_data); 1437 result = dns_qp_insert(qp, data, 0); 1438 nmdata_detach(&data); 1439 goto done; 1440 } 1441 1442 /* 1443 * Do not count bits that are already present 1444 */ 1445 if ((data->set.qname & new_data->set.qname) != 0 || 1446 (data->set.ns & new_data->set.ns) != 0 || 1447 (data->wild.qname & new_data->wild.qname) != 0 || 1448 (data->wild.ns & new_data->wild.ns) != 0) 1449 { 1450 result = ISC_R_EXISTS; 1451 } 1452 1453 /* copy in the bits from the new data */ 1454 data->set.qname |= new_data->set.qname; 1455 data->set.ns |= new_data->set.ns; 1456 data->wild.qname |= new_data->wild.qname; 1457 data->wild.ns |= new_data->wild.ns; 1458 1459 done: 1460 dns_qp_compact(qp, DNS_QPGC_MAYBE); 1461 dns_qpmulti_commit(rpzs->table, &qp); 1462 1463 return result; 1464 } 1465 1466 static isc_result_t 1467 add_name(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 1468 const dns_name_t *src_name) { 1469 nmdata_t new_data; 1470 dns_fixedname_t trig_namef; 1471 dns_name_t *trig_name = NULL; 1472 isc_result_t result; 1473 1474 /* 1475 * We need a summary database of names even with 1 policy zone, 1476 * because wildcard triggers are handled differently. 1477 */ 1478 1479 trig_name = dns_fixedname_initname(&trig_namef); 1480 name2data(rpz, rpz_type, src_name, trig_name, &new_data); 1481 1482 result = add_nm(rpz->rpzs, trig_name, &new_data); 1483 1484 /* 1485 * Do not worry if the node already exists, 1486 * because diff_apply() likes to add nodes before deleting. 1487 */ 1488 if (result == ISC_R_EXISTS) { 1489 return ISC_R_SUCCESS; 1490 } 1491 if (result == ISC_R_SUCCESS) { 1492 RWLOCK(&rpz->rpzs->search_lock, isc_rwlocktype_write); 1493 adj_trigger_cnt(rpz, rpz_type, NULL, 0, true); 1494 RWUNLOCK(&rpz->rpzs->search_lock, isc_rwlocktype_write); 1495 } 1496 return result; 1497 } 1498 1499 /* 1500 * Get ready for a new set of policy zones for a view. 1501 */ 1502 isc_result_t 1503 dns_rpz_new_zones(dns_view_t *view, isc_loopmgr_t *loopmgr, char *rps_cstr, 1504 size_t rps_cstr_size, dns_rpz_zones_t **rpzsp) { 1505 dns_rpz_zones_t *rpzs = NULL; 1506 isc_mem_t *mctx = NULL; 1507 #ifdef USE_DNSRPS 1508 isc_result_t result = ISC_R_SUCCESS; 1509 #endif 1510 1511 REQUIRE(rpzsp != NULL && *rpzsp == NULL); 1512 REQUIRE(view != NULL); 1513 1514 mctx = view->mctx; 1515 1516 rpzs = isc_mem_get(mctx, sizeof(*rpzs)); 1517 *rpzs = (dns_rpz_zones_t){ 1518 .rps_cstr = rps_cstr, 1519 .rps_cstr_size = rps_cstr_size, 1520 .loopmgr = loopmgr, 1521 .magic = DNS_RPZ_ZONES_MAGIC, 1522 }; 1523 1524 isc_rwlock_init(&rpzs->search_lock); 1525 isc_mutex_init(&rpzs->maint_lock); 1526 isc_refcount_init(&rpzs->references, 1); 1527 1528 #ifdef USE_DNSRPS 1529 if (rps_cstr != NULL) { 1530 result = dns_dnsrps_view_init(rpzs, rps_cstr); 1531 if (result != ISC_R_SUCCESS) { 1532 goto cleanup; 1533 } 1534 } 1535 #else /* ifdef USE_DNSRPS */ 1536 INSIST(!rpzs->p.dnsrps_enabled); 1537 #endif /* ifdef USE_DNSRPS */ 1538 if (!rpzs->p.dnsrps_enabled) { 1539 dns_qpmulti_create(mctx, &qpmethods, view, &rpzs->table); 1540 } 1541 1542 isc_mem_attach(mctx, &rpzs->mctx); 1543 1544 *rpzsp = rpzs; 1545 return ISC_R_SUCCESS; 1546 1547 #ifdef USE_DNSRPS 1548 /* Only if DNSRPS is in use can this function fail */ 1549 cleanup: 1550 isc_refcount_decrementz(&rpzs->references); 1551 isc_refcount_destroy(&rpzs->references); 1552 isc_mutex_destroy(&rpzs->maint_lock); 1553 isc_rwlock_destroy(&rpzs->search_lock); 1554 isc_mem_put(mctx, rpzs, sizeof(*rpzs)); 1555 1556 return result; 1557 #endif /* ifdef USE_DNSRPS */ 1558 } 1559 1560 isc_result_t 1561 dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) { 1562 isc_result_t result; 1563 dns_rpz_zone_t *rpz = NULL; 1564 1565 REQUIRE(DNS_RPZ_ZONES_VALID(rpzs)); 1566 REQUIRE(rpzp != NULL && *rpzp == NULL); 1567 1568 if (rpzs->p.num_zones >= DNS_RPZ_MAX_ZONES) { 1569 return ISC_R_NOSPACE; 1570 } 1571 1572 result = dns__rpz_shuttingdown(rpzs); 1573 if (result != ISC_R_SUCCESS) { 1574 return result; 1575 } 1576 1577 rpz = isc_mem_get(rpzs->mctx, sizeof(*rpz)); 1578 *rpz = (dns_rpz_zone_t){ 1579 .addsoa = true, 1580 .magic = DNS_RPZ_ZONE_MAGIC, 1581 .rpzs = rpzs, 1582 }; 1583 1584 /* 1585 * This will never be used, but costs us nothing and 1586 * simplifies update_from_db(). 1587 */ 1588 1589 isc_ht_init(&rpz->nodes, rpzs->mctx, 1, ISC_HT_CASE_SENSITIVE); 1590 1591 dns_name_init(&rpz->origin, NULL); 1592 dns_name_init(&rpz->client_ip, NULL); 1593 dns_name_init(&rpz->ip, NULL); 1594 dns_name_init(&rpz->nsdname, NULL); 1595 dns_name_init(&rpz->nsip, NULL); 1596 dns_name_init(&rpz->passthru, NULL); 1597 dns_name_init(&rpz->drop, NULL); 1598 dns_name_init(&rpz->tcp_only, NULL); 1599 dns_name_init(&rpz->cname, NULL); 1600 1601 isc_time_settoepoch(&rpz->lastupdated); 1602 1603 rpz->num = rpzs->p.num_zones++; 1604 rpzs->zones[rpz->num] = rpz; 1605 1606 *rpzp = rpz; 1607 1608 return ISC_R_SUCCESS; 1609 } 1610 1611 isc_result_t 1612 dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) { 1613 dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)fn_arg; 1614 isc_result_t result = ISC_R_SUCCESS; 1615 1616 REQUIRE(DNS_DB_VALID(db)); 1617 REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); 1618 1619 LOCK(&rpz->rpzs->maint_lock); 1620 1621 if (rpz->rpzs->shuttingdown) { 1622 result = ISC_R_SHUTTINGDOWN; 1623 goto unlock; 1624 } 1625 1626 /* New zone came as AXFR */ 1627 if (rpz->db != NULL && rpz->db != db) { 1628 /* We need to clean up the old DB */ 1629 if (rpz->dbversion != NULL) { 1630 dns_db_closeversion(rpz->db, &rpz->dbversion, false); 1631 } 1632 dns_db_updatenotify_unregister(rpz->db, 1633 dns_rpz_dbupdate_callback, rpz); 1634 dns_db_detach(&rpz->db); 1635 } 1636 1637 if (rpz->db == NULL) { 1638 RUNTIME_CHECK(rpz->dbversion == NULL); 1639 dns_db_attach(db, &rpz->db); 1640 } 1641 1642 if (!rpz->updatepending && !rpz->updaterunning) { 1643 rpz->updatepending = true; 1644 1645 dns_db_currentversion(rpz->db, &rpz->dbversion); 1646 dns__rpz_timer_start(rpz); 1647 } else { 1648 char dname[DNS_NAME_FORMATSIZE]; 1649 rpz->updatepending = true; 1650 1651 dns_name_format(&rpz->origin, dname, DNS_NAME_FORMATSIZE); 1652 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1653 DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), 1654 "rpz: %s: update already queued or running", 1655 dname); 1656 if (rpz->dbversion != NULL) { 1657 dns_db_closeversion(rpz->db, &rpz->dbversion, false); 1658 } 1659 dns_db_currentversion(rpz->db, &rpz->dbversion); 1660 } 1661 1662 unlock: 1663 UNLOCK(&rpz->rpzs->maint_lock); 1664 1665 return result; 1666 } 1667 1668 void 1669 dns_rpz_dbupdate_unregister(dns_db_t *db, dns_rpz_zone_t *rpz) { 1670 REQUIRE(DNS_DB_VALID(db)); 1671 REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); 1672 1673 dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback, rpz); 1674 } 1675 1676 void 1677 dns_rpz_dbupdate_register(dns_db_t *db, dns_rpz_zone_t *rpz) { 1678 REQUIRE(DNS_DB_VALID(db)); 1679 REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); 1680 1681 dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback, rpz); 1682 } 1683 static void 1684 dns__rpz_timer_start(dns_rpz_zone_t *rpz) { 1685 uint64_t tdiff; 1686 isc_interval_t interval; 1687 isc_time_t now; 1688 1689 REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); 1690 1691 now = isc_time_now(); 1692 tdiff = isc_time_microdiff(&now, &rpz->lastupdated) / 1000000; 1693 if (tdiff < rpz->min_update_interval) { 1694 uint64_t defer = rpz->min_update_interval - tdiff; 1695 char dname[DNS_NAME_FORMATSIZE]; 1696 1697 dns_name_format(&rpz->origin, dname, DNS_NAME_FORMATSIZE); 1698 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1699 DNS_LOGMODULE_MASTER, ISC_LOG_INFO, 1700 "rpz: %s: new zone version came " 1701 "too soon, deferring update for " 1702 "%" PRIu64 " seconds", 1703 dname, defer); 1704 isc_interval_set(&interval, (unsigned int)defer, 0); 1705 } else { 1706 isc_interval_set(&interval, 0, 0); 1707 } 1708 1709 rpz->loop = isc_loop(); 1710 1711 isc_timer_create(rpz->loop, dns__rpz_timer_cb, rpz, &rpz->updatetimer); 1712 isc_timer_start(rpz->updatetimer, isc_timertype_once, &interval); 1713 } 1714 1715 static void 1716 dns__rpz_timer_stop(void *arg) { 1717 dns_rpz_zone_t *rpz = arg; 1718 REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); 1719 1720 isc_timer_stop(rpz->updatetimer); 1721 isc_timer_destroy(&rpz->updatetimer); 1722 rpz->loop = NULL; 1723 1724 dns_rpz_zones_unref(rpz->rpzs); 1725 } 1726 1727 static void 1728 update_rpz_done_cb(void *data) { 1729 dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)data; 1730 char dname[DNS_NAME_FORMATSIZE]; 1731 1732 REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); 1733 1734 LOCK(&rpz->rpzs->maint_lock); 1735 rpz->updaterunning = false; 1736 1737 dns_name_format(&rpz->origin, dname, DNS_NAME_FORMATSIZE); 1738 1739 if (rpz->updatepending && !rpz->rpzs->shuttingdown) { 1740 /* Restart the timer */ 1741 dns__rpz_timer_start(rpz); 1742 } 1743 1744 dns_db_closeversion(rpz->updb, &rpz->updbversion, false); 1745 dns_db_detach(&rpz->updb); 1746 1747 UNLOCK(&rpz->rpzs->maint_lock); 1748 1749 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, 1750 ISC_LOG_INFO, "rpz: %s: reload done: %s", dname, 1751 isc_result_totext(rpz->updateresult)); 1752 1753 dns_rpz_zones_unref(rpz->rpzs); 1754 } 1755 1756 static isc_result_t 1757 update_nodes(dns_rpz_zone_t *rpz, isc_ht_t *newnodes) { 1758 isc_result_t result; 1759 dns_dbiterator_t *updbit = NULL; 1760 dns_name_t *name = NULL; 1761 dns_fixedname_t fixname; 1762 char domain[DNS_NAME_FORMATSIZE]; 1763 1764 dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE); 1765 1766 name = dns_fixedname_initname(&fixname); 1767 1768 result = dns_db_createiterator(rpz->updb, DNS_DB_NONSEC3, &updbit); 1769 if (result != ISC_R_SUCCESS) { 1770 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1771 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1772 "rpz: %s: failed to create DB iterator - %s", 1773 domain, isc_result_totext(result)); 1774 return result; 1775 } 1776 1777 result = dns_dbiterator_first(updbit); 1778 if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) { 1779 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1780 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1781 "rpz: %s: failed to get db iterator - %s", domain, 1782 isc_result_totext(result)); 1783 goto cleanup; 1784 } 1785 1786 while (result == ISC_R_SUCCESS) { 1787 char namebuf[DNS_NAME_FORMATSIZE]; 1788 dns_rdatasetiter_t *rdsiter = NULL; 1789 dns_dbnode_t *node = NULL; 1790 1791 result = dns__rpz_shuttingdown(rpz->rpzs); 1792 if (result != ISC_R_SUCCESS) { 1793 goto cleanup; 1794 } 1795 1796 result = dns_dbiterator_current(updbit, &node, name); 1797 if (result != ISC_R_SUCCESS) { 1798 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1799 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1800 "rpz: %s: failed to get dbiterator - %s", 1801 domain, isc_result_totext(result)); 1802 goto cleanup; 1803 } 1804 1805 result = dns_dbiterator_pause(updbit); 1806 RUNTIME_CHECK(result == ISC_R_SUCCESS); 1807 1808 result = dns_db_allrdatasets(rpz->updb, node, rpz->updbversion, 1809 0, 0, &rdsiter); 1810 if (result != ISC_R_SUCCESS) { 1811 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1812 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1813 "rpz: %s: failed to fetch " 1814 "rrdatasets - %s", 1815 domain, isc_result_totext(result)); 1816 dns_db_detachnode(rpz->updb, &node); 1817 goto cleanup; 1818 } 1819 1820 result = dns_rdatasetiter_first(rdsiter); 1821 1822 dns_rdatasetiter_destroy(&rdsiter); 1823 dns_db_detachnode(rpz->updb, &node); 1824 1825 if (result != ISC_R_SUCCESS) { /* skip empty non-terminal */ 1826 if (result != ISC_R_NOMORE) { 1827 isc_log_write( 1828 dns_lctx, DNS_LOGCATEGORY_GENERAL, 1829 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1830 "rpz: %s: error %s while creating " 1831 "rdatasetiter", 1832 domain, isc_result_totext(result)); 1833 } 1834 goto next; 1835 } 1836 1837 dns_name_downcase(name, name, NULL); 1838 1839 /* Add entry to the new nodes table */ 1840 result = isc_ht_add(newnodes, name->ndata, name->length, rpz); 1841 if (result != ISC_R_SUCCESS) { 1842 dns_name_format(name, namebuf, sizeof(namebuf)); 1843 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1844 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1845 "rpz: %s, adding node %s to HT error %s", 1846 domain, namebuf, 1847 isc_result_totext(result)); 1848 goto next; 1849 } 1850 1851 /* Does the entry exist in the old nodes table? */ 1852 result = isc_ht_find(rpz->nodes, name->ndata, name->length, 1853 NULL); 1854 if (result == ISC_R_SUCCESS) { /* found */ 1855 isc_ht_delete(rpz->nodes, name->ndata, name->length); 1856 goto next; 1857 } 1858 1859 /* 1860 * Only the single rpz updates are serialized, so we need to 1861 * lock here because we can be processing more updates to 1862 * different rpz zones at the same time 1863 */ 1864 LOCK(&rpz->rpzs->maint_lock); 1865 result = rpz_add(rpz, name); 1866 UNLOCK(&rpz->rpzs->maint_lock); 1867 1868 if (result != ISC_R_SUCCESS) { 1869 dns_name_format(name, namebuf, sizeof(namebuf)); 1870 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1871 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1872 "rpz: %s: adding node %s " 1873 "to RPZ error %s", 1874 domain, namebuf, 1875 isc_result_totext(result)); 1876 } else if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 1877 dns_name_format(name, namebuf, sizeof(namebuf)); 1878 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1879 DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), 1880 "rpz: %s: adding node %s", domain, 1881 namebuf); 1882 } 1883 1884 next: 1885 result = dns_dbiterator_next(updbit); 1886 } 1887 INSIST(result != ISC_R_SUCCESS); 1888 if (result == ISC_R_NOMORE) { 1889 result = ISC_R_SUCCESS; 1890 } 1891 1892 cleanup: 1893 dns_dbiterator_destroy(&updbit); 1894 1895 return result; 1896 } 1897 1898 static isc_result_t 1899 cleanup_nodes(dns_rpz_zone_t *rpz) { 1900 isc_result_t result; 1901 isc_ht_iter_t *iter = NULL; 1902 dns_name_t *name = NULL; 1903 dns_fixedname_t fixname; 1904 1905 name = dns_fixedname_initname(&fixname); 1906 1907 isc_ht_iter_create(rpz->nodes, &iter); 1908 1909 for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS; 1910 result = isc_ht_iter_delcurrent_next(iter)) 1911 { 1912 isc_region_t region; 1913 unsigned char *key = NULL; 1914 size_t keysize; 1915 1916 result = dns__rpz_shuttingdown(rpz->rpzs); 1917 if (result != ISC_R_SUCCESS) { 1918 break; 1919 } 1920 1921 isc_ht_iter_currentkey(iter, &key, &keysize); 1922 region.base = key; 1923 region.length = (unsigned int)keysize; 1924 dns_name_fromregion(name, ®ion); 1925 1926 LOCK(&rpz->rpzs->maint_lock); 1927 rpz_del(rpz, name); 1928 UNLOCK(&rpz->rpzs->maint_lock); 1929 } 1930 INSIST(result != ISC_R_SUCCESS); 1931 if (result == ISC_R_NOMORE) { 1932 result = ISC_R_SUCCESS; 1933 } 1934 1935 isc_ht_iter_destroy(&iter); 1936 1937 return result; 1938 } 1939 1940 static isc_result_t 1941 dns__rpz_shuttingdown(dns_rpz_zones_t *rpzs) { 1942 bool shuttingdown = false; 1943 1944 LOCK(&rpzs->maint_lock); 1945 shuttingdown = rpzs->shuttingdown; 1946 UNLOCK(&rpzs->maint_lock); 1947 1948 if (shuttingdown) { 1949 return ISC_R_SHUTTINGDOWN; 1950 } 1951 1952 return ISC_R_SUCCESS; 1953 } 1954 1955 static void 1956 update_rpz_cb(void *data) { 1957 dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)data; 1958 isc_result_t result = ISC_R_SUCCESS; 1959 isc_ht_t *newnodes = NULL; 1960 1961 REQUIRE(rpz->nodes != NULL); 1962 1963 result = dns__rpz_shuttingdown(rpz->rpzs); 1964 if (result != ISC_R_SUCCESS) { 1965 goto shuttingdown; 1966 } 1967 1968 isc_ht_init(&newnodes, rpz->rpzs->mctx, 1, ISC_HT_CASE_SENSITIVE); 1969 1970 result = update_nodes(rpz, newnodes); 1971 if (result != ISC_R_SUCCESS) { 1972 goto cleanup; 1973 } 1974 1975 result = cleanup_nodes(rpz); 1976 if (result != ISC_R_SUCCESS) { 1977 goto cleanup; 1978 } 1979 1980 /* Finalize the update */ 1981 ISC_SWAP(rpz->nodes, newnodes); 1982 1983 cleanup: 1984 isc_ht_destroy(&newnodes); 1985 1986 shuttingdown: 1987 rpz->updateresult = result; 1988 } 1989 1990 static void 1991 dns__rpz_timer_cb(void *arg) { 1992 char domain[DNS_NAME_FORMATSIZE]; 1993 dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)arg; 1994 1995 REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); 1996 REQUIRE(DNS_DB_VALID(rpz->db)); 1997 REQUIRE(rpz->updb == NULL); 1998 REQUIRE(rpz->updbversion == NULL); 1999 2000 LOCK(&rpz->rpzs->maint_lock); 2001 2002 if (rpz->rpzs->shuttingdown) { 2003 goto unlock; 2004 } 2005 2006 rpz->updatepending = false; 2007 rpz->updaterunning = true; 2008 rpz->updateresult = ISC_R_UNSET; 2009 2010 dns_db_attach(rpz->db, &rpz->updb); 2011 INSIST(rpz->dbversion != NULL); 2012 rpz->updbversion = rpz->dbversion; 2013 rpz->dbversion = NULL; 2014 2015 dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE); 2016 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, 2017 ISC_LOG_INFO, "rpz: %s: reload start", domain); 2018 2019 dns_rpz_zones_ref(rpz->rpzs); 2020 isc_work_enqueue(rpz->loop, update_rpz_cb, update_rpz_done_cb, rpz); 2021 2022 isc_timer_destroy(&rpz->updatetimer); 2023 rpz->loop = NULL; 2024 2025 rpz->lastupdated = isc_time_now(); 2026 unlock: 2027 UNLOCK(&rpz->rpzs->maint_lock); 2028 } 2029 2030 /* 2031 * Free the radix tree of a response policy database. 2032 */ 2033 static void 2034 cidr_free(dns_rpz_zones_t *rpzs) { 2035 dns_rpz_cidr_node_t *cur = NULL, *child = NULL, *parent = NULL; 2036 2037 cur = rpzs->cidr; 2038 while (cur != NULL) { 2039 /* Depth first. */ 2040 child = cur->child[0]; 2041 if (child != NULL) { 2042 cur = child; 2043 continue; 2044 } 2045 child = cur->child[1]; 2046 if (child != NULL) { 2047 cur = child; 2048 continue; 2049 } 2050 2051 /* Delete this leaf and go up. */ 2052 parent = cur->parent; 2053 if (parent == NULL) { 2054 rpzs->cidr = NULL; 2055 } else { 2056 parent->child[parent->child[1] == cur] = NULL; 2057 } 2058 isc_mem_put(rpzs->mctx, cur, sizeof(*cur)); 2059 cur = parent; 2060 } 2061 } 2062 2063 static void 2064 dns__rpz_shutdown(dns_rpz_zone_t *rpz) { 2065 /* maint_lock must be locked */ 2066 if (rpz->updatetimer != NULL) { 2067 /* Don't wait for timer to trigger for shutdown */ 2068 INSIST(rpz->loop != NULL); 2069 2070 dns_rpz_zones_ref(rpz->rpzs); 2071 isc_async_run(rpz->loop, dns__rpz_timer_stop, rpz); 2072 } 2073 } 2074 2075 static void 2076 dns_rpz_zone_destroy(dns_rpz_zone_t **rpzp) { 2077 dns_rpz_zone_t *rpz = NULL; 2078 dns_rpz_zones_t *rpzs; 2079 2080 rpz = *rpzp; 2081 *rpzp = NULL; 2082 2083 rpzs = rpz->rpzs; 2084 rpz->rpzs = NULL; 2085 2086 if (dns_name_dynamic(&rpz->origin)) { 2087 dns_name_free(&rpz->origin, rpzs->mctx); 2088 } 2089 if (dns_name_dynamic(&rpz->client_ip)) { 2090 dns_name_free(&rpz->client_ip, rpzs->mctx); 2091 } 2092 if (dns_name_dynamic(&rpz->ip)) { 2093 dns_name_free(&rpz->ip, rpzs->mctx); 2094 } 2095 if (dns_name_dynamic(&rpz->nsdname)) { 2096 dns_name_free(&rpz->nsdname, rpzs->mctx); 2097 } 2098 if (dns_name_dynamic(&rpz->nsip)) { 2099 dns_name_free(&rpz->nsip, rpzs->mctx); 2100 } 2101 if (dns_name_dynamic(&rpz->passthru)) { 2102 dns_name_free(&rpz->passthru, rpzs->mctx); 2103 } 2104 if (dns_name_dynamic(&rpz->drop)) { 2105 dns_name_free(&rpz->drop, rpzs->mctx); 2106 } 2107 if (dns_name_dynamic(&rpz->tcp_only)) { 2108 dns_name_free(&rpz->tcp_only, rpzs->mctx); 2109 } 2110 if (dns_name_dynamic(&rpz->cname)) { 2111 dns_name_free(&rpz->cname, rpzs->mctx); 2112 } 2113 if (rpz->db != NULL) { 2114 if (rpz->dbversion != NULL) { 2115 dns_db_closeversion(rpz->db, &rpz->dbversion, false); 2116 } 2117 dns_db_updatenotify_unregister(rpz->db, 2118 dns_rpz_dbupdate_callback, rpz); 2119 dns_db_detach(&rpz->db); 2120 } 2121 INSIST(!rpz->updaterunning); 2122 2123 isc_ht_destroy(&rpz->nodes); 2124 2125 isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz)); 2126 } 2127 2128 static void 2129 dns__rpz_zones_destroy(dns_rpz_zones_t *rpzs) { 2130 REQUIRE(rpzs->shuttingdown); 2131 2132 for (dns_rpz_num_t rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; ++rpz_num) 2133 { 2134 if (rpzs->zones[rpz_num] == NULL) { 2135 continue; 2136 } 2137 2138 dns_rpz_zone_destroy(&rpzs->zones[rpz_num]); 2139 } 2140 2141 if (rpzs->rps_cstr_size != 0) { 2142 #ifdef USE_DNSRPS 2143 librpz->client_detach(&rpzs->rps_client); 2144 #endif /* ifdef USE_DNSRPS */ 2145 isc_mem_put(rpzs->mctx, rpzs->rps_cstr, rpzs->rps_cstr_size); 2146 } 2147 2148 cidr_free(rpzs); 2149 if (rpzs->table != NULL) { 2150 dns_qpmulti_destroy(&rpzs->table); 2151 } 2152 2153 isc_mutex_destroy(&rpzs->maint_lock); 2154 isc_rwlock_destroy(&rpzs->search_lock); 2155 isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs)); 2156 } 2157 2158 void 2159 dns_rpz_zones_shutdown(dns_rpz_zones_t *rpzs) { 2160 REQUIRE(DNS_RPZ_ZONES_VALID(rpzs)); 2161 /* 2162 * Forget the last of the view's rpz machinery when shutting down. 2163 */ 2164 2165 LOCK(&rpzs->maint_lock); 2166 if (rpzs->shuttingdown) { 2167 UNLOCK(&rpzs->maint_lock); 2168 return; 2169 } 2170 2171 rpzs->shuttingdown = true; 2172 2173 for (dns_rpz_num_t rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; ++rpz_num) 2174 { 2175 if (rpzs->zones[rpz_num] == NULL) { 2176 continue; 2177 } 2178 2179 dns__rpz_shutdown(rpzs->zones[rpz_num]); 2180 } 2181 UNLOCK(&rpzs->maint_lock); 2182 } 2183 2184 #ifdef DNS_RPZ_TRACE 2185 ISC_REFCOUNT_TRACE_IMPL(dns_rpz_zones, dns__rpz_zones_destroy); 2186 #else 2187 ISC_REFCOUNT_IMPL(dns_rpz_zones, dns__rpz_zones_destroy); 2188 #endif 2189 2190 /* 2191 * Add an IP address to the radix tree or a name to the summary database. 2192 */ 2193 static isc_result_t 2194 rpz_add(dns_rpz_zone_t *rpz, const dns_name_t *src_name) { 2195 dns_rpz_type_t rpz_type; 2196 isc_result_t result = ISC_R_FAILURE; 2197 dns_rpz_zones_t *rpzs = NULL; 2198 dns_rpz_num_t rpz_num; 2199 2200 REQUIRE(rpz != NULL); 2201 2202 rpzs = rpz->rpzs; 2203 rpz_num = rpz->num; 2204 2205 REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); 2206 2207 rpz_type = type_from_name(rpzs, rpz, src_name); 2208 switch (rpz_type) { 2209 case DNS_RPZ_TYPE_QNAME: 2210 case DNS_RPZ_TYPE_NSDNAME: 2211 result = add_name(rpz, rpz_type, src_name); 2212 break; 2213 case DNS_RPZ_TYPE_CLIENT_IP: 2214 case DNS_RPZ_TYPE_IP: 2215 case DNS_RPZ_TYPE_NSIP: 2216 result = add_cidr(rpz, rpz_type, src_name); 2217 break; 2218 case DNS_RPZ_TYPE_BAD: 2219 break; 2220 } 2221 2222 return result; 2223 } 2224 2225 /* 2226 * Remove an IP address from the radix tree. 2227 */ 2228 static void 2229 del_cidr(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 2230 const dns_name_t *src_name) { 2231 isc_result_t result; 2232 dns_rpz_cidr_key_t tgt_ip; 2233 dns_rpz_prefix_t tgt_prefix; 2234 dns_rpz_addr_zbits_t tgt_set; 2235 dns_rpz_cidr_node_t *tgt = NULL, *parent = NULL, *child = NULL; 2236 2237 /* 2238 * Do not worry about invalid rpz IP address names. If we 2239 * are here, then something relevant was added and so was 2240 * valid. 2241 */ 2242 result = name2ipkey(DNS_RPZ_DEBUG_QUIET, rpz, rpz_type, src_name, 2243 &tgt_ip, &tgt_prefix, &tgt_set); 2244 if (result != ISC_R_SUCCESS) { 2245 return; 2246 } 2247 2248 RWLOCK(&rpz->rpzs->search_lock, isc_rwlocktype_write); 2249 result = search(rpz->rpzs, &tgt_ip, tgt_prefix, &tgt_set, false, &tgt); 2250 if (result != ISC_R_SUCCESS) { 2251 goto done; 2252 } 2253 2254 /* 2255 * Mark the node and its parents to reflect the deleted IP address. 2256 */ 2257 tgt_set.client_ip &= tgt->set.client_ip; 2258 tgt_set.ip &= tgt->set.ip; 2259 tgt_set.nsip &= tgt->set.nsip; 2260 tgt->set.client_ip &= ~tgt_set.client_ip; 2261 tgt->set.ip &= ~tgt_set.ip; 2262 tgt->set.nsip &= ~tgt_set.nsip; 2263 set_sum_pair(tgt); 2264 2265 adj_trigger_cnt(rpz, rpz_type, &tgt_ip, tgt_prefix, false); 2266 2267 /* 2268 * We might need to delete 2 nodes. 2269 */ 2270 do { 2271 /* 2272 * The node is now useless if it has no data of its own 2273 * and 0 or 1 children. We are finished if it is not 2274 * useless. 2275 */ 2276 if ((child = tgt->child[0]) != NULL) { 2277 if (tgt->child[1] != NULL) { 2278 break; 2279 } 2280 } else { 2281 child = tgt->child[1]; 2282 } 2283 if (tgt->set.client_ip != 0 || tgt->set.ip != 0 || 2284 tgt->set.nsip != 0) 2285 { 2286 break; 2287 } 2288 2289 /* 2290 * Replace the pointer to this node in the parent with 2291 * the remaining child or NULL. 2292 */ 2293 parent = tgt->parent; 2294 if (parent == NULL) { 2295 rpz->rpzs->cidr = child; 2296 } else { 2297 parent->child[parent->child[1] == tgt] = child; 2298 } 2299 2300 /* 2301 * If the child exists fix up its parent pointer. 2302 */ 2303 if (child != NULL) { 2304 child->parent = parent; 2305 } 2306 isc_mem_put(rpz->rpzs->mctx, tgt, sizeof(*tgt)); 2307 2308 tgt = parent; 2309 } while (tgt != NULL); 2310 2311 done: 2312 RWUNLOCK(&rpz->rpzs->search_lock, isc_rwlocktype_write); 2313 } 2314 2315 static void 2316 del_name(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 2317 const dns_name_t *src_name) { 2318 isc_result_t result; 2319 char namebuf[DNS_NAME_FORMATSIZE]; 2320 dns_fixedname_t trig_namef; 2321 dns_name_t *trig_name = NULL; 2322 dns_rpz_zones_t *rpzs = rpz->rpzs; 2323 nmdata_t *data = NULL; 2324 nmdata_t del_data; 2325 dns_qp_t *qp = NULL; 2326 bool exists; 2327 2328 dns_qpmulti_write(rpzs->table, &qp); 2329 2330 /* 2331 * We need a summary database of names even with 1 policy zone, 2332 * because wildcard triggers are handled differently. 2333 */ 2334 2335 trig_name = dns_fixedname_initname(&trig_namef); 2336 name2data(rpz, rpz_type, src_name, trig_name, &del_data); 2337 2338 result = dns_qp_getname(qp, trig_name, (void **)&data, NULL); 2339 if (result != ISC_R_SUCCESS) { 2340 return; 2341 } 2342 2343 INSIST(data != NULL); 2344 2345 del_data.set.qname &= data->set.qname; 2346 del_data.set.ns &= data->set.ns; 2347 del_data.wild.qname &= data->wild.qname; 2348 del_data.wild.ns &= data->wild.ns; 2349 2350 exists = (del_data.set.qname != 0 || del_data.set.ns != 0 || 2351 del_data.wild.qname != 0 || del_data.wild.ns != 0); 2352 2353 data->set.qname &= ~del_data.set.qname; 2354 data->set.ns &= ~del_data.set.ns; 2355 data->wild.qname &= ~del_data.wild.qname; 2356 data->wild.ns &= ~del_data.wild.ns; 2357 2358 if (data->set.qname == 0 && data->set.ns == 0 && 2359 data->wild.qname == 0 && data->wild.ns == 0) 2360 { 2361 result = dns_qp_deletename(qp, trig_name, NULL, NULL); 2362 if (result != ISC_R_SUCCESS) { 2363 /* 2364 * bin/tests/system/rpz/tests.sh looks for 2365 * "rpz.*failed". 2366 */ 2367 dns_name_format(src_name, namebuf, sizeof(namebuf)); 2368 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 2369 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 2370 "rpz del_name(%s) node delete " 2371 "failed: %s", 2372 namebuf, isc_result_totext(result)); 2373 } 2374 } 2375 2376 if (exists) { 2377 RWLOCK(&rpz->rpzs->search_lock, isc_rwlocktype_write); 2378 adj_trigger_cnt(rpz, rpz_type, NULL, 0, false); 2379 RWUNLOCK(&rpz->rpzs->search_lock, isc_rwlocktype_write); 2380 } 2381 2382 dns_qp_compact(qp, DNS_QPGC_MAYBE); 2383 dns_qpmulti_commit(rpzs->table, &qp); 2384 } 2385 2386 /* 2387 * Remove an IP address from the radix tree or a name from the summary database. 2388 */ 2389 static void 2390 rpz_del(dns_rpz_zone_t *rpz, const dns_name_t *src_name) { 2391 dns_rpz_type_t rpz_type; 2392 dns_rpz_zones_t *rpzs = NULL; 2393 dns_rpz_num_t rpz_num; 2394 2395 REQUIRE(rpz != NULL); 2396 2397 rpzs = rpz->rpzs; 2398 rpz_num = rpz->num; 2399 2400 REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); 2401 2402 rpz_type = type_from_name(rpzs, rpz, src_name); 2403 switch (rpz_type) { 2404 case DNS_RPZ_TYPE_QNAME: 2405 case DNS_RPZ_TYPE_NSDNAME: 2406 del_name(rpz, rpz_type, src_name); 2407 break; 2408 case DNS_RPZ_TYPE_CLIENT_IP: 2409 case DNS_RPZ_TYPE_IP: 2410 case DNS_RPZ_TYPE_NSIP: 2411 del_cidr(rpz, rpz_type, src_name); 2412 break; 2413 case DNS_RPZ_TYPE_BAD: 2414 break; 2415 } 2416 } 2417 2418 /* 2419 * Search the summary radix tree to get a relative owner name in a 2420 * policy zone relevant to a triggering IP address. 2421 * rpz_type and zbits limit the search for IP address netaddr 2422 * return the policy zone's number or DNS_RPZ_INVALID_NUM 2423 * ip_name is the relative owner name found and 2424 * *prefixp is its prefix length. 2425 */ 2426 dns_rpz_num_t 2427 dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, 2428 dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr, 2429 dns_name_t *ip_name, dns_rpz_prefix_t *prefixp) { 2430 dns_rpz_cidr_key_t tgt_ip; 2431 dns_rpz_addr_zbits_t tgt_set; 2432 dns_rpz_cidr_node_t *found = NULL; 2433 isc_result_t result; 2434 dns_rpz_num_t rpz_num = 0; 2435 dns_rpz_have_t have; 2436 int i; 2437 2438 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2439 have = rpzs->have; 2440 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2441 2442 /* 2443 * Convert IP address to CIDR tree key. 2444 */ 2445 if (netaddr->family == AF_INET) { 2446 tgt_ip.w[0] = 0; 2447 tgt_ip.w[1] = 0; 2448 tgt_ip.w[2] = ADDR_V4MAPPED; 2449 tgt_ip.w[3] = ntohl(netaddr->type.in.s_addr); 2450 switch (rpz_type) { 2451 case DNS_RPZ_TYPE_CLIENT_IP: 2452 zbits &= have.client_ipv4; 2453 break; 2454 case DNS_RPZ_TYPE_IP: 2455 zbits &= have.ipv4; 2456 break; 2457 case DNS_RPZ_TYPE_NSIP: 2458 zbits &= have.nsipv4; 2459 break; 2460 default: 2461 UNREACHABLE(); 2462 break; 2463 } 2464 } else if (netaddr->family == AF_INET6) { 2465 dns_rpz_cidr_key_t src_ip6; 2466 2467 /* 2468 * Given the int aligned struct in_addr member of netaddr->type 2469 * one could cast netaddr->type.in6 to dns_rpz_cidr_key_t *, 2470 * but some people object. 2471 */ 2472 memmove(src_ip6.w, &netaddr->type.in6, sizeof(src_ip6.w)); 2473 for (i = 0; i < 4; i++) { 2474 tgt_ip.w[i] = ntohl(src_ip6.w[i]); 2475 } 2476 switch (rpz_type) { 2477 case DNS_RPZ_TYPE_CLIENT_IP: 2478 zbits &= have.client_ipv6; 2479 break; 2480 case DNS_RPZ_TYPE_IP: 2481 zbits &= have.ipv6; 2482 break; 2483 case DNS_RPZ_TYPE_NSIP: 2484 zbits &= have.nsipv6; 2485 break; 2486 default: 2487 UNREACHABLE(); 2488 break; 2489 } 2490 } else { 2491 return DNS_RPZ_INVALID_NUM; 2492 } 2493 2494 if (zbits == 0) { 2495 return DNS_RPZ_INVALID_NUM; 2496 } 2497 make_addr_set(&tgt_set, zbits, rpz_type); 2498 2499 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2500 result = search(rpzs, &tgt_ip, 128, &tgt_set, false, &found); 2501 if (result == ISC_R_NOTFOUND) { 2502 /* 2503 * There are no eligible zones for this IP address. 2504 */ 2505 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2506 return DNS_RPZ_INVALID_NUM; 2507 } 2508 2509 /* 2510 * Construct the trigger name for the longest matching trigger 2511 * in the first eligible zone with a match. 2512 */ 2513 *prefixp = found->prefix; 2514 switch (rpz_type) { 2515 case DNS_RPZ_TYPE_CLIENT_IP: 2516 rpz_num = zbit_to_num(found->set.client_ip & tgt_set.client_ip); 2517 break; 2518 case DNS_RPZ_TYPE_IP: 2519 rpz_num = zbit_to_num(found->set.ip & tgt_set.ip); 2520 break; 2521 case DNS_RPZ_TYPE_NSIP: 2522 rpz_num = zbit_to_num(found->set.nsip & tgt_set.nsip); 2523 break; 2524 default: 2525 UNREACHABLE(); 2526 } 2527 result = ip2name(&found->ip, found->prefix, dns_rootname, ip_name); 2528 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2529 if (result != ISC_R_SUCCESS) { 2530 /* 2531 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". 2532 */ 2533 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 2534 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 2535 "rpz ip2name() failed: %s", 2536 isc_result_totext(result)); 2537 return DNS_RPZ_INVALID_NUM; 2538 } 2539 return rpz_num; 2540 } 2541 2542 /* 2543 * Search the summary radix tree for policy zones with triggers matching 2544 * a name. 2545 */ 2546 dns_rpz_zbits_t 2547 dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, 2548 dns_rpz_zbits_t zbits, dns_name_t *trig_name) { 2549 isc_result_t result; 2550 char namebuf[DNS_NAME_FORMATSIZE]; 2551 nmdata_t *data = NULL; 2552 dns_rpz_zbits_t found_zbits = 0; 2553 dns_qpchain_t chain; 2554 dns_qpread_t qpr; 2555 int i; 2556 2557 if (zbits == 0) { 2558 return 0; 2559 } 2560 2561 dns_qpmulti_query(rpzs->table, &qpr); 2562 dns_qpchain_init(&qpr, &chain); 2563 2564 result = dns_qp_lookup(&qpr, trig_name, NULL, NULL, &chain, 2565 (void **)&data, NULL); 2566 switch (result) { 2567 case ISC_R_SUCCESS: 2568 INSIST(data != NULL); 2569 if (rpz_type == DNS_RPZ_TYPE_QNAME) { 2570 found_zbits = data->set.qname; 2571 } else { 2572 found_zbits = data->set.ns; 2573 } 2574 FALLTHROUGH; 2575 2576 case DNS_R_PARTIALMATCH: 2577 i = dns_qpchain_length(&chain); 2578 while (i-- > 0) { 2579 dns_qpchain_node(&chain, i, NULL, (void **)&data, NULL); 2580 INSIST(data != NULL); 2581 if (rpz_type == DNS_RPZ_TYPE_QNAME) { 2582 found_zbits |= data->wild.qname; 2583 } else { 2584 found_zbits |= data->wild.ns; 2585 } 2586 } 2587 break; 2588 2589 case ISC_R_NOTFOUND: 2590 break; 2591 2592 default: 2593 /* 2594 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". 2595 */ 2596 dns_name_format(trig_name, namebuf, sizeof(namebuf)); 2597 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 2598 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 2599 "dns_rpz_find_name(%s) failed: %s", namebuf, 2600 isc_result_totext(result)); 2601 break; 2602 } 2603 2604 dns_qpread_destroy(rpzs->table, &qpr); 2605 return zbits & found_zbits; 2606 } 2607 2608 /* 2609 * Translate CNAME rdata to a QNAME response policy action. 2610 */ 2611 dns_rpz_policy_t 2612 dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, 2613 dns_name_t *selfname) { 2614 dns_rdata_t rdata = DNS_RDATA_INIT; 2615 dns_rdata_cname_t cname; 2616 isc_result_t result; 2617 2618 result = dns_rdataset_first(rdataset); 2619 INSIST(result == ISC_R_SUCCESS); 2620 dns_rdataset_current(rdataset, &rdata); 2621 result = dns_rdata_tostruct(&rdata, &cname, NULL); 2622 INSIST(result == ISC_R_SUCCESS); 2623 dns_rdata_reset(&rdata); 2624 2625 /* 2626 * CNAME . means NXDOMAIN 2627 */ 2628 if (dns_name_equal(&cname.cname, dns_rootname)) { 2629 return DNS_RPZ_POLICY_NXDOMAIN; 2630 } 2631 2632 if (dns_name_iswildcard(&cname.cname)) { 2633 /* 2634 * CNAME *. means NODATA 2635 */ 2636 if (dns_name_countlabels(&cname.cname) == 2) { 2637 return DNS_RPZ_POLICY_NODATA; 2638 } 2639 2640 /* 2641 * A qname of www.evil.com and a policy of 2642 * *.evil.com CNAME *.garden.net 2643 * gives a result of 2644 * evil.com CNAME evil.com.garden.net 2645 */ 2646 if (dns_name_countlabels(&cname.cname) > 2) { 2647 return DNS_RPZ_POLICY_WILDCNAME; 2648 } 2649 } 2650 2651 /* 2652 * CNAME rpz-tcp-only. means "send truncated UDP responses." 2653 */ 2654 if (dns_name_equal(&cname.cname, &rpz->tcp_only)) { 2655 return DNS_RPZ_POLICY_TCP_ONLY; 2656 } 2657 2658 /* 2659 * CNAME rpz-drop. means "do not respond." 2660 */ 2661 if (dns_name_equal(&cname.cname, &rpz->drop)) { 2662 return DNS_RPZ_POLICY_DROP; 2663 } 2664 2665 /* 2666 * CNAME rpz-passthru. means "do not rewrite." 2667 */ 2668 if (dns_name_equal(&cname.cname, &rpz->passthru)) { 2669 return DNS_RPZ_POLICY_PASSTHRU; 2670 } 2671 2672 /* 2673 * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU 2674 */ 2675 if (selfname != NULL && dns_name_equal(&cname.cname, selfname)) { 2676 return DNS_RPZ_POLICY_PASSTHRU; 2677 } 2678 2679 /* 2680 * Any other rdata gives a response consisting of the rdata. 2681 */ 2682 return DNS_RPZ_POLICY_RECORD; 2683 } 2684 2685 static void 2686 destroy_nmdata(nmdata_t *data) { 2687 dns_name_free(&data->name, data->mctx); 2688 isc_mem_putanddetach(&data->mctx, data, sizeof(nmdata_t)); 2689 } 2690 2691 #ifdef DNS_RPZ_TRACE 2692 ISC_REFCOUNT_TRACE_IMPL(nmdata, destroy_nmdata); 2693 #else 2694 ISC_REFCOUNT_IMPL(nmdata, destroy_nmdata); 2695 #endif 2696 2697 static void 2698 qp_attach(void *uctx ISC_ATTR_UNUSED, void *pval, 2699 uint32_t ival ISC_ATTR_UNUSED) { 2700 nmdata_t *data = pval; 2701 nmdata_ref(data); 2702 } 2703 2704 static void 2705 qp_detach(void *uctx ISC_ATTR_UNUSED, void *pval, 2706 uint32_t ival ISC_ATTR_UNUSED) { 2707 nmdata_t *data = pval; 2708 nmdata_detach(&data); 2709 } 2710 2711 static size_t 2712 qp_makekey(dns_qpkey_t key, void *uctx ISC_ATTR_UNUSED, void *pval, 2713 uint32_t ival ISC_ATTR_UNUSED) { 2714 nmdata_t *data = pval; 2715 return dns_qpkey_fromname(key, &data->name); 2716 } 2717 2718 static void 2719 qp_triename(void *uctx, char *buf, size_t size) { 2720 dns_view_t *view = uctx; 2721 snprintf(buf, size, "view %s RPZs", view->name); 2722 } 2723