[v9_10] further restrict update-policy local
4762. [func] "update-policy local" is now restricted to updates
from local addresses. (Previously, other addresses
were allowed so long as updates were signed by the
local session key.) [RT #45492]
This commit is contained in:
@@ -15,8 +15,6 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: ssu.h,v 1.28 2011/01/06 23:47:00 tbox Exp $ */
|
||||
|
||||
#ifndef DNS_SSU_H
|
||||
#define DNS_SSU_H 1
|
||||
|
||||
@@ -24,6 +22,7 @@
|
||||
|
||||
#include <isc/lang.h>
|
||||
|
||||
#include <dns/acl.h>
|
||||
#include <dns/types.h>
|
||||
#include <dst/dst.h>
|
||||
|
||||
@@ -42,8 +41,10 @@ ISC_LANG_BEGINDECLS
|
||||
#define DNS_SSUMATCHTYPE_TCPSELF 10
|
||||
#define DNS_SSUMATCHTYPE_6TO4SELF 11
|
||||
#define DNS_SSUMATCHTYPE_EXTERNAL 12
|
||||
#define DNS_SSUMATCHTYPE_DLZ 13
|
||||
#define DNS_SSUMATCHTYPE_MAX 12 /* max value */
|
||||
#define DNS_SSUMATCHTYPE_LOCAL 13
|
||||
#define DNS_SSUMATCHTYPE_MAX 13 /* max value */
|
||||
|
||||
#define DNS_SSUMATCHTYPE_DLZ 14 /* intentionally higher than _MAX */
|
||||
|
||||
isc_result_t
|
||||
dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table);
|
||||
@@ -132,7 +133,12 @@ dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant,
|
||||
|
||||
isc_boolean_t
|
||||
dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
dns_name_t *name, isc_netaddr_t *tcpaddr,
|
||||
dns_name_t *name, isc_netaddr_t *addr,
|
||||
dns_rdatatype_t type, const dst_key_t *key);
|
||||
isc_boolean_t
|
||||
dns_ssutable_checkrules2(dns_ssutable_t *table, dns_name_t *signer,
|
||||
dns_name_t *name, isc_netaddr_t *addr,
|
||||
isc_boolean_t tcp, const dns_aclenv_t *env,
|
||||
dns_rdatatype_t type, const dst_key_t *key);
|
||||
/*%<
|
||||
* Checks that the attempted update of (name, type) is allowed according
|
||||
@@ -140,11 +146,19 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
* no rules are matched, access is denied.
|
||||
*
|
||||
* Notes:
|
||||
* 'tcpaddr' should only be set if the request received
|
||||
* via TCP. This provides a weak assurance that the
|
||||
* request was not spoofed. 'tcpaddr' is to to validate
|
||||
* DNS_SSUMATCHTYPE_TCPSELF and DNS_SSUMATCHTYPE_6TO4SELF
|
||||
* rules.
|
||||
* In dns_ssutable_checkrules(), 'addr' should only be
|
||||
* set if the request received via TCP. This provides a
|
||||
* weak assurance that the request was not spoofed.
|
||||
* 'addr' is to to validate DNS_SSUMATCHTYPE_TCPSELF
|
||||
* and DNS_SSUMATCHTYPE_6TO4SELF rules.
|
||||
*
|
||||
* In dns_ssutable_checkrules2(), 'addr' can also be passed for
|
||||
* UDP requests and TCP is specified via the 'tcp' parameter.
|
||||
* In addition to DNS_SSUMATCHTYPE_TCPSELF and
|
||||
* tcp_ssumatchtype_6to4self rules, the address
|
||||
* also be used to check DNS_SSUMATCHTYPE_LOCAL rules.
|
||||
* If 'addr' is set then 'env' must also be set so that
|
||||
* requests from non-localhost addresses can be rejected.
|
||||
*
|
||||
* For DNS_SSUMATCHTYPE_TCPSELF the addresses are mapped to
|
||||
* the standard reverse names under IN-ADDR.ARPA and IP6.ARPA.
|
||||
@@ -160,8 +174,10 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
* Requires:
|
||||
*\li 'table' is a valid SSU table
|
||||
*\li 'signer' is NULL or a valid absolute name
|
||||
*\li 'tcpaddr' is NULL or a valid network address.
|
||||
*\li 'addr' is NULL or a valid network address.
|
||||
*\li 'aclenv' is NULL or a valid ACL environment.
|
||||
*\li 'name' is a valid absolute name
|
||||
*\li if 'addr' is not NULL, 'env' is not NULL.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -348,9 +348,20 @@ stf_from_address(dns_name_t *stfself, isc_netaddr_t *tcpaddr) {
|
||||
|
||||
isc_boolean_t
|
||||
dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
dns_name_t *name, isc_netaddr_t *tcpaddr,
|
||||
dns_rdatatype_t type,
|
||||
const dst_key_t *key)
|
||||
dns_name_t *name, isc_netaddr_t *addr,
|
||||
dns_rdatatype_t type, const dst_key_t *key)
|
||||
{
|
||||
return (dns_ssutable_checkrules2
|
||||
(table, signer, name, addr,
|
||||
addr == NULL ? ISC_FALSE : ISC_TRUE,
|
||||
NULL, type, key));
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_ssutable_checkrules2(dns_ssutable_t *table, dns_name_t *signer,
|
||||
dns_name_t *name, isc_netaddr_t *addr,
|
||||
isc_boolean_t tcp, const dns_aclenv_t *env,
|
||||
dns_rdatatype_t type, const dst_key_t *key)
|
||||
{
|
||||
dns_ssurule_t *rule;
|
||||
unsigned int i;
|
||||
@@ -359,12 +370,14 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
dns_name_t *tcpself;
|
||||
dns_name_t *stfself;
|
||||
isc_result_t result;
|
||||
int match;
|
||||
|
||||
REQUIRE(VALID_SSUTABLE(table));
|
||||
REQUIRE(signer == NULL || dns_name_isabsolute(signer));
|
||||
REQUIRE(dns_name_isabsolute(name));
|
||||
REQUIRE(addr == NULL || env != NULL);
|
||||
|
||||
if (signer == NULL && tcpaddr == NULL)
|
||||
if (signer == NULL && addr == NULL)
|
||||
return (ISC_FALSE);
|
||||
|
||||
for (rule = ISC_LIST_HEAD(table->rules);
|
||||
@@ -373,6 +386,7 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
{
|
||||
switch (rule->matchtype) {
|
||||
case DNS_SSUMATCHTYPE_NAME:
|
||||
case DNS_SSUMATCHTYPE_LOCAL:
|
||||
case DNS_SSUMATCHTYPE_SUBDOMAIN:
|
||||
case DNS_SSUMATCHTYPE_WILDCARD:
|
||||
case DNS_SSUMATCHTYPE_SELF:
|
||||
@@ -398,7 +412,7 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
break;
|
||||
case DNS_SSUMATCHTYPE_TCPSELF:
|
||||
case DNS_SSUMATCHTYPE_6TO4SELF:
|
||||
if (tcpaddr == NULL)
|
||||
if (!tcp || addr == NULL)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
@@ -412,6 +426,20 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
if (!dns_name_issubdomain(name, rule->name))
|
||||
continue;
|
||||
break;
|
||||
case DNS_SSUMATCHTYPE_LOCAL:
|
||||
if (addr == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (!dns_name_issubdomain(name, rule->name)) {
|
||||
|
||||
continue;
|
||||
}
|
||||
dns_acl_match(addr, NULL, env->localhost,
|
||||
NULL, &match, NULL);
|
||||
if (match == 0) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case DNS_SSUMATCHTYPE_WILDCARD:
|
||||
if (!dns_name_matcheswildcard(name, rule->name))
|
||||
continue;
|
||||
@@ -461,7 +489,7 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
case DNS_SSUMATCHTYPE_TCPSELF:
|
||||
dns_fixedname_init(&fixed);
|
||||
tcpself = dns_fixedname_name(&fixed);
|
||||
reverse_from_address(tcpself, tcpaddr);
|
||||
reverse_from_address(tcpself, addr);
|
||||
if (dns_name_iswildcard(rule->identity)) {
|
||||
if (!dns_name_matcheswildcard(tcpself,
|
||||
rule->identity))
|
||||
@@ -476,7 +504,7 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
case DNS_SSUMATCHTYPE_6TO4SELF:
|
||||
dns_fixedname_init(&fixed);
|
||||
stfself = dns_fixedname_name(&fixed);
|
||||
stf_from_address(stfself, tcpaddr);
|
||||
stf_from_address(stfself, addr);
|
||||
if (dns_name_iswildcard(rule->identity)) {
|
||||
if (!dns_name_matcheswildcard(stfself,
|
||||
rule->identity))
|
||||
@@ -490,13 +518,13 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
|
||||
break;
|
||||
case DNS_SSUMATCHTYPE_EXTERNAL:
|
||||
if (!dns_ssu_external_match(rule->identity, signer,
|
||||
name, tcpaddr, type, key,
|
||||
name, addr, type, key,
|
||||
table->mctx))
|
||||
continue;
|
||||
break;
|
||||
case DNS_SSUMATCHTYPE_DLZ:
|
||||
if (!dns_dlz_ssumatch(table->dlzdatabase, signer,
|
||||
name, tcpaddr, type, key))
|
||||
name, addr, type, key))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -181,6 +181,12 @@ isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen);
|
||||
* ISC_R_FAILURE extra bits.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
isc_netaddr_isloopback(const isc_netaddr_t *na);
|
||||
/*
|
||||
* Test whether the netaddr 'na' is a loopback IPv4 or IPv6 address (in
|
||||
* 127.0.0.0/8 or ::1).
|
||||
*/
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* ISC_NETADDR_H */
|
||||
|
||||
@@ -448,3 +448,16 @@ isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) {
|
||||
memmove(&t->type.in, (char *)&src->type.in6 + 12, 4);
|
||||
return;
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
isc_netaddr_isloopback(const isc_netaddr_t *na) {
|
||||
switch (na->family) {
|
||||
case AF_INET:
|
||||
return (ISC_TF((ntohl(na->type.in.s_addr) & 0xff000000U) ==
|
||||
0x7f000000U));
|
||||
case AF_INET6:
|
||||
return (IN6_IS_ADDR_LOOPBACK(&na->type.in6));
|
||||
default:
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user