diff options
Diffstat (limited to 'contrib/bind9/lib/dns/rpz.c')
-rw-r--r-- | contrib/bind9/lib/dns/rpz.c | 133 |
1 files changed, 79 insertions, 54 deletions
diff --git a/contrib/bind9/lib/dns/rpz.c b/contrib/bind9/lib/dns/rpz.c index e3f4989..7865859 100644 --- a/contrib/bind9/lib/dns/rpz.c +++ b/contrib/bind9/lib/dns/rpz.c @@ -118,9 +118,9 @@ struct dns_rpz_cidr { isc_mem_t *mctx; isc_boolean_t have_nsdname; /* zone has NSDNAME record */ dns_rpz_cidr_node_t *root; - dns_name_t ip_name; /* RPZ_IP_ZONE.LOCALHOST. */ - dns_name_t nsip_name; /* RPZ_NSIP_ZONE.LOCALHOST. */ - dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.LOCALHOST */ + dns_name_t ip_name; /* RPZ_IP_ZONE.origin. */ + dns_name_t nsip_name; /* RPZ_NSIP_ZONE.origin. */ + dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */ }; static isc_boolean_t have_rpz_zones = ISC_FALSE; @@ -183,7 +183,7 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) { str = "NODATA"; break; case DNS_RPZ_POLICY_RECORD: - str = "records"; + str = "Local-Data"; break; case DNS_RPZ_POLICY_CNAME: case DNS_RPZ_POLICY_WILDCNAME: @@ -255,6 +255,8 @@ dns_rpz_view_destroy(dns_view_t *view) { ISC_LIST_UNLINK(view->rpz_zones, zone, link); if (dns_name_dynamic(&zone->origin)) dns_name_free(&zone->origin, view->mctx); + if (dns_name_dynamic(&zone->passthru)) + dns_name_free(&zone->passthru, view->mctx); if (dns_name_dynamic(&zone->nsdname)) dns_name_free(&zone->nsdname, view->mctx); if (dns_name_dynamic(&zone->cname)) @@ -427,14 +429,16 @@ new_node(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *ip, } static void -badname(int level, dns_name_t *name, const char *comment) { +badname(int level, dns_name_t *name, const char *str1, const char *str2) { char printname[DNS_NAME_FORMATSIZE]; - if (isc_log_wouldlog(dns_lctx, level)) { + if (level < DNS_RPZ_DEBUG_QUIET + && isc_log_wouldlog(dns_lctx, level)) { dns_name_format(name, printname, sizeof(printname)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, level, - "invalid rpz \"%s\"%s", printname, comment); + "invalid rpz IP address \"%s\"%s%s", + printname, str1, str2); } } @@ -566,11 +570,11 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, dns_rpz_type_t type, dns_rpz_cidr_key_t *tgt_ip, dns_rpz_cidr_bits_t *tgt_prefix) { - isc_buffer_t buffer; - unsigned char data[DNS_NAME_MAXWIRE+1]; + isc_result_t result; dns_fixedname_t fname; - dns_name_t *name; - const char *cp, *end; + dns_name_t *ipname; + char ipstr[DNS_NAME_FORMATSIZE]; + const char *prefix_str, *cp, *end; char *cp2; int ip_labels; dns_rpz_cidr_bits_t bits; @@ -585,37 +589,43 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, ip_labels -= dns_name_countlabels(&cidr->ip_name); ip_labels--; if (ip_labels < 1) { - badname(level, src_name, ", too short"); + badname(level, src_name, "; too short", ""); return (ISC_R_FAILURE); } /* - * Get text for the IP address without RPZ_x_ZONE.rpz.LOCALHOST. + * Get text for the IP address */ dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); + ipname = dns_fixedname_name(&fname); dns_name_split(src_name, dns_name_countlabels(&cidr->ip_name), - name, NULL); - isc_buffer_init(&buffer, data, sizeof(data)); - dns_name_totext(name, ISC_TRUE, &buffer); - isc_buffer_putuint8(&buffer, '\0'); - cp = isc_buffer_base(&buffer); - - prefix = strtoul(cp, &cp2, 10); - if (prefix < 1U || prefix > 128U || *cp2 != '.') { - badname(level, src_name, ", bad prefix length"); + ipname, NULL); + dns_name_format(ipname, ipstr, sizeof(ipstr)); + end = &ipstr[strlen(ipstr)+1]; + prefix_str = ipstr; + + prefix = strtoul(prefix_str, &cp2, 10); + if (*cp2 != '.') { + badname(level, src_name, + "; invalid leading prefix length", ""); + return (ISC_R_FAILURE); + } + *cp2 = '\0'; + if (prefix < 1U || prefix > 128U) { + badname(level, src_name, + "; invalid prefix length of ", prefix_str); return (ISC_R_FAILURE); } cp = cp2+1; - end = isc_buffer_used(&buffer); if (ip_labels == 4 && !strchr(cp, 'z')) { /* * Convert an IPv4 address * from the form "prefix.w.z.y.x" */ if (prefix > 32U) { - badname(level, src_name, "; bad IPv4 prefix length"); + badname(level, src_name, + "; invalid IPv4 prefix length of ", prefix_str); return (ISC_R_FAILURE); } prefix += 96; @@ -627,7 +637,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, for (i = 0; i < 32; i += 8) { l = strtoul(cp, &cp2, 10); if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) { - badname(level, src_name, "; bad IPv4 address"); + if (*cp2 == '.') + *cp2 = '\0'; + badname(level, src_name, + "; invalid IPv4 octet ", cp); return (ISC_R_FAILURE); } tgt_ip->w[3] |= l << i; @@ -654,7 +667,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, l = strtoul(cp, &cp2, 16); if (l > 0xffffu || (*cp2 != '.' && *cp2 != '\0')) { - badname(level, src_name, ""); + if (*cp2 == '.') + *cp2 = '\0'; + badname(level, src_name, + "; invalid IPv6 word ", cp); return (ISC_R_FAILURE); } if ((i & 1) == 0) @@ -667,7 +683,7 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, } } if (cp != end) { - badname(level, src_name, ""); + badname(level, src_name, "", ""); return (ISC_R_FAILURE); } @@ -681,7 +697,8 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, i = bits % DNS_RPZ_CIDR_WORD_BITS; aword = tgt_ip->w[bits / DNS_RPZ_CIDR_WORD_BITS]; if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) { - badname(level, src_name, "; wrong prefix length"); + badname(level, src_name, + "; too small prefix length of ", prefix_str); return (ISC_R_FAILURE); } bits -= i; @@ -689,13 +706,13 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name, } /* - * Convert the IPv6 address back to a canonical policy domain name + * Convert the address back to a canonical policy domain name * to ensure that it is in canonical form. */ - if (ISC_R_SUCCESS != ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t)prefix, - type, NULL, name) || - !dns_name_equal(src_name, name)) { - badname(level, src_name, "; not canonical"); + result = ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t) prefix, + type, NULL, ipname); + if (result != ISC_R_SUCCESS || !dns_name_equal(src_name, ipname)) { + badname(level, src_name, "; not canonical", ""); return (ISC_R_FAILURE); } @@ -934,6 +951,7 @@ search(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip, */ void dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { + isc_result_t result; dns_rpz_cidr_key_t tgt_ip; dns_rpz_cidr_bits_t tgt_prefix; dns_rpz_type_t type; @@ -956,19 +974,22 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { case DNS_RPZ_TYPE_BAD: return; } - if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name, - type, &tgt_ip, &tgt_prefix)) + result = name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name, + type, &tgt_ip, &tgt_prefix); + if (result != ISC_R_SUCCESS) return; - if (ISC_R_EXISTS == search(cidr, &tgt_ip, tgt_prefix, type, - ISC_TRUE, NULL) && - isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) { + result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_TRUE, NULL); + if (result == ISC_R_EXISTS && + isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) + { char printname[DNS_NAME_FORMATSIZE]; dns_name_format(name, printname, sizeof(printname)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "duplicate rpz name \"%s\"", printname); + "rpz add failed; \"%s\" is a duplicate name", + printname); } } @@ -978,6 +999,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { */ void dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) { + isc_result_t result; dns_rpz_cidr_key_t tgt_ip; dns_rpz_cidr_bits_t tgt_prefix; dns_rpz_type_t type; @@ -1010,19 +1032,14 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) { /* * Do not get excited about the deletion of interior rbt nodes. */ - if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL3, name, - type, &tgt_ip, &tgt_prefix)) + result = name2ipkey(cidr, DNS_RPZ_DEBUG_QUIET, name, + type, &tgt_ip, &tgt_prefix); + if (result != ISC_R_SUCCESS) return; - if (ISC_R_SUCCESS != search(cidr, &tgt_ip, tgt_prefix, type, - ISC_FALSE, &tgt)) { - if (isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) { - char printname[DNS_NAME_FORMATSIZE]; - - dns_name_format(name, printname, sizeof(printname)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "missing rpz node \"%s\"", printname); - } + + result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_FALSE, &tgt); + if (result != ISC_R_SUCCESS) { + badname(DNS_RPZ_ERROR_LEVEL, name, "; missing rpz node", ""); return; } @@ -1135,7 +1152,9 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr, * Translate CNAME rdata to a QNAME response policy action. */ dns_rpz_policy_t -dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) { +dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, + dns_name_t *selfname) +{ dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_cname_t cname; isc_result_t result; @@ -1171,7 +1190,13 @@ dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) { } /* - * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. means "do not rewrite" + * CNAME PASSTHRU.origin means "do not rewrite. + */ + if (dns_name_equal(&cname.cname, &rpz->passthru)) + return (DNS_RPZ_POLICY_PASSTHRU); + + /* + * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU */ if (selfname != NULL && dns_name_equal(&cname.cname, selfname)) return (DNS_RPZ_POLICY_PASSTHRU); |