mirror of
https://github.com/isc-projects/bind9.git
synced 2026-03-10 10:11:39 -04:00
[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:
parent
3402ce550a
commit
dddf97d534
18 changed files with 280 additions and 73 deletions
5
CHANGES
5
CHANGES
|
|
@ -1,3 +1,8 @@
|
|||
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]
|
||||
|
||||
4761. [protocol] Add support for DOA. [RT #45612]
|
||||
|
||||
4759. [func] Add logging channel "trust-anchor-telementry" to
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ EXTERN isc_boolean_t ns_g_notcp INIT(ISC_FALSE);
|
|||
EXTERN isc_boolean_t ns_g_disable6 INIT(ISC_FALSE);
|
||||
EXTERN isc_boolean_t ns_g_disable4 INIT(ISC_FALSE);
|
||||
EXTERN unsigned int ns_g_tat_interval INIT(24*3600);
|
||||
EXTERN isc_boolean_t ns_g_fixedlocal INIT(ISC_FALSE);
|
||||
|
||||
|
||||
#ifdef HAVE_GEOIP
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: interfacemgr.c,v 1.101 2011/11/09 18:44:03 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <config.h>
|
||||
|
|
@ -949,11 +947,22 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
|||
}
|
||||
|
||||
if (adjusting == ISC_FALSE) {
|
||||
/*
|
||||
* If running with -T fixedlocal, then we only
|
||||
* want 127.0.0.1 and ::1 in the localhost ACL.
|
||||
*/
|
||||
if (ns_g_fixedlocal &&
|
||||
!isc_netaddr_isloopback(&interface.address))
|
||||
{
|
||||
goto listenon;
|
||||
}
|
||||
|
||||
result = setup_locals(mgr, &interface);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto ignore_interface;
|
||||
}
|
||||
|
||||
listenon:
|
||||
ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6;
|
||||
dolistenon = ISC_TRUE;
|
||||
for (le = ISC_LIST_HEAD(ll->elts);
|
||||
|
|
|
|||
|
|
@ -611,17 +611,25 @@ parse_command_line(int argc, char *argv[]) {
|
|||
dns_zone_mkey_month = atoi(p);
|
||||
if (dns_zone_mkey_month < dns_zone_mkey_day)
|
||||
ns_main_earlyfatal("bad mkeytimer");
|
||||
} else if (!strcmp(isc_commandline_argument, "notcp"))
|
||||
} else if (!strcmp(isc_commandline_argument, "notcp")) {
|
||||
ns_g_notcp = ISC_TRUE;
|
||||
else if (!strncmp(isc_commandline_argument, "tat=", 4))
|
||||
} else if (!strncmp(isc_commandline_argument,
|
||||
"tat=", 4))
|
||||
{
|
||||
ns_g_tat_interval =
|
||||
atoi(isc_commandline_argument + 4);
|
||||
else if (!strcmp(isc_commandline_argument,
|
||||
"keepstderr"))
|
||||
} else if (!strcmp(isc_commandline_argument,
|
||||
"keepstderr"))
|
||||
{
|
||||
ns_g_keepstderr = ISC_TRUE;
|
||||
else
|
||||
} else if (!strcmp(isc_commandline_argument,
|
||||
"fixedlocal"))
|
||||
{
|
||||
ns_g_fixedlocal = ISC_TRUE;
|
||||
} else {
|
||||
fprintf(stderr, "unknown -T flag '%s\n",
|
||||
isc_commandline_argument);
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
ns_g_udpdisp = parse_int(isc_commandline_argument,
|
||||
|
|
|
|||
|
|
@ -813,8 +813,11 @@ typedef struct {
|
|||
/* The signature's name if the request was signed. */
|
||||
dns_name_t *signer;
|
||||
|
||||
/* The address of the client if the request was received via TCP. */
|
||||
isc_netaddr_t *tcpaddr;
|
||||
/* The address of the client. */
|
||||
isc_netaddr_t *addr;
|
||||
|
||||
/* Whether the request was sent via TCP. */
|
||||
isc_boolean_t tcp;
|
||||
|
||||
/* The ssu table to check against. */
|
||||
dns_ssutable_t *table;
|
||||
|
|
@ -835,16 +838,17 @@ ssu_checkrule(void *data, dns_rdataset_t *rrset) {
|
|||
if (rrset->type == dns_rdatatype_rrsig ||
|
||||
rrset->type == dns_rdatatype_nsec)
|
||||
return (ISC_R_SUCCESS);
|
||||
result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer,
|
||||
ssuinfo->name, ssuinfo->tcpaddr,
|
||||
rrset->type, ssuinfo->key);
|
||||
result = dns_ssutable_checkrules2(ssuinfo->table, ssuinfo->signer,
|
||||
ssuinfo->name, ssuinfo->addr,
|
||||
ssuinfo->tcp, &ns_g_server->aclenv,
|
||||
rrset->type, ssuinfo->key);
|
||||
return (result == ISC_TRUE ? ISC_R_SUCCESS : ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
||||
dns_ssutable_t *ssutable, dns_name_t *signer,
|
||||
isc_netaddr_t *tcpaddr, dst_key_t *key)
|
||||
isc_netaddr_t *addr, isc_boolean_t tcp, dst_key_t *key)
|
||||
{
|
||||
isc_result_t result;
|
||||
ssu_check_t ssuinfo;
|
||||
|
|
@ -852,7 +856,8 @@ ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||
ssuinfo.name = name;
|
||||
ssuinfo.table = ssutable;
|
||||
ssuinfo.signer = signer;
|
||||
ssuinfo.tcpaddr = tcpaddr;
|
||||
ssuinfo.addr = addr;
|
||||
ssuinfo.tcp = tcp;
|
||||
ssuinfo.key = key;
|
||||
result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo);
|
||||
return (ISC_TF(result == ISC_R_SUCCESS));
|
||||
|
|
@ -2686,38 +2691,33 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
|
||||
if (ssutable != NULL) {
|
||||
isc_netaddr_t *tcpaddr, netaddr;
|
||||
isc_netaddr_t netaddr;
|
||||
dst_key_t *tsigkey = NULL;
|
||||
/*
|
||||
* If this is a TCP connection then pass the
|
||||
* address of the client through for tcp-self
|
||||
* and 6to4-self otherwise pass NULL. This
|
||||
* provides weak address based authentication.
|
||||
*/
|
||||
if (TCPCLIENT(client)) {
|
||||
isc_netaddr_fromsockaddr(&netaddr,
|
||||
&client->peeraddr);
|
||||
tcpaddr = &netaddr;
|
||||
} else
|
||||
tcpaddr = NULL;
|
||||
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
||||
|
||||
if (client->message->tsigkey != NULL)
|
||||
tsigkey = client->message->tsigkey->key;
|
||||
|
||||
if (rdata.type != dns_rdatatype_any) {
|
||||
if (!dns_ssutable_checkrules(ssutable,
|
||||
client->signer,
|
||||
name, tcpaddr,
|
||||
rdata.type,
|
||||
tsigkey))
|
||||
if (!dns_ssutable_checkrules2
|
||||
(ssutable, client->signer, name, &netaddr,
|
||||
ISC_TF(TCPCLIENT(client)),
|
||||
&ns_g_server->aclenv,
|
||||
rdata.type, tsigkey))
|
||||
{
|
||||
FAILC(DNS_R_REFUSED,
|
||||
"rejected by secure update");
|
||||
}
|
||||
} else {
|
||||
if (!ssu_checkall(db, ver, name, ssutable,
|
||||
client->signer, tcpaddr,
|
||||
client->signer,
|
||||
&netaddr,
|
||||
ISC_TF(TCPCLIENT(client)),
|
||||
tsigkey))
|
||||
{
|
||||
FAILC(DNS_R_REFUSED,
|
||||
"rejected by secure update");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
|
|||
|
||||
result = dns_ssutable_addrule(table, ISC_TRUE,
|
||||
ns_g_server->session_keyname,
|
||||
DNS_SSUMATCHTYPE_SUBDOMAIN,
|
||||
DNS_SSUMATCHTYPE_LOCAL,
|
||||
dns_zone_getorigin(zone),
|
||||
1, &any);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,12 @@
|
|||
#
|
||||
|
||||
rm -f */named.memstats
|
||||
rm -f */named.run
|
||||
rm -f */named.run */ans.run
|
||||
rm -f Kxxx.*
|
||||
rm -f dig.out.*
|
||||
rm -f jp.out.ns3.*
|
||||
rm -f ns*/named.lock
|
||||
rm -f ns1/*.jnl ns2/*.jnl ns3/*.jnl
|
||||
rm -f ns1/example.db ns1/unixtime.db ns1/update.db ns1/other.db ns1/keytests.db
|
||||
rm -f */*.jnl
|
||||
rm -f ns1/example.db ns1/unixtime.db ns1/yyyymmddvv.db ns1/update.db ns1/other.db ns1/keytests.db
|
||||
rm -f ns1/many.test.db
|
||||
rm -f ns1/md5.key ns1/sha1.key ns1/sha224.key ns1/sha256.key ns1/sha384.key
|
||||
|
|
@ -42,6 +41,7 @@ rm -f ns3/example.db
|
|||
rm -f ns3/many.test.bk
|
||||
rm -f ns3/nsec3param.test.db
|
||||
rm -f ns3/too-big.test.db
|
||||
rm -f ns5/local.db
|
||||
rm -f nsupdate.out*
|
||||
rm -f typelist.out.*
|
||||
rm -f ns1/sample.db
|
||||
|
|
|
|||
20
bin/tests/system/nsupdate/ns5/local.db.in
Normal file
20
bin/tests/system/nsupdate/ns5/local.db.in
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
; Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
$ORIGIN .
|
||||
$TTL 300 ; 5 minutes
|
||||
local.nil IN SOA ns5.local.nil. hostmaster.local.nil. (
|
||||
1 ; serial
|
||||
2000 ; refresh (2000 seconds)
|
||||
2000 ; retry (2000 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
local.nil. NS ns5.local.nil.
|
||||
ns5.local.nil. A 10.53.0.5
|
||||
|
||||
$ORIGIN local.nil.
|
||||
a A 10.10.10.10
|
||||
1
bin/tests/system/nsupdate/ns5/named.args
Normal file
1
bin/tests/system/nsupdate/ns5/named.args
Normal file
|
|
@ -0,0 +1 @@
|
|||
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T fixedlocal
|
||||
37
bin/tests/system/nsupdate/ns5/named.conf
Normal file
37
bin/tests/system/nsupdate/ns5/named.conf
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
controls { /* empty */ };
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.5;
|
||||
notify-source 10.53.0.5;
|
||||
transfer-source 10.53.0.5;
|
||||
port 5300;
|
||||
pid-file "named.pid";
|
||||
session-keyfile "session.key";
|
||||
listen-on { 10.53.0.5; };
|
||||
recursion no;
|
||||
notify yes;
|
||||
minimal-responses no;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "local.nil" {
|
||||
type master;
|
||||
file "local.db";
|
||||
update-policy local;
|
||||
};
|
||||
|
|
@ -66,3 +66,5 @@ $DDNSCONFGEN -q -r $RANDFILE -a hmac-sha512 -k sha512-key -z keytests.nil > ns1/
|
|||
|
||||
cp ns1/sample.db.in ns1/sample.db
|
||||
cp ns2/sample.db.in ns2/sample.db
|
||||
|
||||
cp -f ns5/local.db.in ns5/local.db
|
||||
|
|
|
|||
|
|
@ -475,6 +475,44 @@ then
|
|||
echo "I:failed"; status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo "I:check that 'update-policy local' works from localhost address ($n)"
|
||||
$NSUPDATE -p 5300 -k ns5/session.key > nsupdate.out.$n 2>&1 << END || ret=1
|
||||
server 10.53.0.5 5300
|
||||
local 127.0.0.1 5300
|
||||
update add fromlocal.local.nil. 600 A 1.2.3.4
|
||||
send
|
||||
END
|
||||
grep REFUSED nsupdate.out.$n > /dev/null 2>&1 && ret=1
|
||||
$DIG @10.53.0.5 -p 5300 \
|
||||
+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
|
||||
fromlocal.local.nil. > dig.out.ns5.$n || ret=1
|
||||
grep fromlocal dig.out.ns5.$n > /dev/null 2>&1 || ret=1
|
||||
if test $ret -ne 0
|
||||
then
|
||||
echo "I:failed"; status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo "I:check that 'update-policy local' fails from non-localhost address ($n)"
|
||||
$NSUPDATE -p 5300 -k ns5/session.key > nsupdate.out.$n 2>&1 << END && ret=1
|
||||
server 10.53.0.5 5300
|
||||
local 10.53.0.1 5300
|
||||
update add nonlocal.local.nil. 600 A 4.3.2.1
|
||||
send
|
||||
END
|
||||
grep REFUSED nsupdate.out.$n > /dev/null 2>&1 || ret=1
|
||||
$DIG @10.53.0.5 -p 5300 \
|
||||
+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
|
||||
nonlocal.local.nil. > dig.out.ns5.$n || ret=1
|
||||
grep nonlocal dig.out.ns5.$n > /dev/null 2>&1 && ret=1
|
||||
if test $ret -ne 0
|
||||
then
|
||||
echo "I:failed"; status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo "I:check that changes to the DNSKEY RRset TTL do not have side effects ($n)"
|
||||
|
|
|
|||
|
|
@ -12184,38 +12184,52 @@ example.com. NS ns2.example.net.
|
|||
is present, it is a configuration error for the
|
||||
<command>allow-update</command> statement to be
|
||||
present. The <command>update-policy</command> statement
|
||||
only examines the signer of a message; the source
|
||||
(except when set to <literal>local</literal>) only
|
||||
examines the signer of a message; the source
|
||||
address is not relevant.
|
||||
</para>
|
||||
<para>
|
||||
There is a pre-defined <command>update-policy</command>
|
||||
rule which can be switched on with the command
|
||||
A pre-defined <command>update-policy</command> rule can be
|
||||
switched on with the command
|
||||
<command>update-policy local;</command>.
|
||||
Switching on this rule in a zone causes
|
||||
<command>named</command> to generate a TSIG session
|
||||
key and place it in a file, and to allow that key
|
||||
to update the zone. (By default, the file is
|
||||
<filename>/var/run/named/session.key</filename>, the key
|
||||
name is "local-ddns" and the key algorithm is HMAC-SHA256,
|
||||
but these values are configurable with the
|
||||
<command>named</command> to generate a TSIG session key and
|
||||
place it in a file. That key will then be allowed to update
|
||||
the zone, if the update request is sent from localhost.
|
||||
By default, the session key is stored in the file
|
||||
<filename>/var/run/named/session.key</filename>; the key name
|
||||
is "local-ddns" and the key algorithm is HMAC-SHA256.
|
||||
These values are configurable with the
|
||||
<command>session-keyfile</command>,
|
||||
<command>session-keyname</command> and
|
||||
<command>session-keyalg</command> options, respectively).
|
||||
</para>
|
||||
<para>
|
||||
A client running on the local system, and with appropriate
|
||||
permissions, may read that file and use the key to sign update
|
||||
requests. The zone's update policy will be set to allow that
|
||||
key to change any record within the zone. Assuming the
|
||||
key name is "local-ddns", this policy is equivalent to:
|
||||
A client on the local system, if it is run with appropriate
|
||||
permissions, may read the session key from the key file and
|
||||
use the key to sign update requests. The zone's update
|
||||
policy will be set to allow that key to change any record
|
||||
within the zone. Assuming the key name is "local-ddns",
|
||||
this policy is:
|
||||
</para>
|
||||
|
||||
<programlisting>update-policy { grant local-ddns zonesub any; };
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
The command <command>nsupdate -l</command> sends update
|
||||
requests to localhost, and signs them using the session key.
|
||||
...with an additional restriction that only clients
|
||||
connecting from the local system will be permitted to send
|
||||
updates.
|
||||
</para>
|
||||
<para>
|
||||
Note that only one session key is generated; all zones
|
||||
configured to use <command>update-policy local</command>
|
||||
will accept the same key.
|
||||
</para>
|
||||
<para>
|
||||
The command <command>nsupdate -l</command> implements this
|
||||
feature, sending requests to localhost and signing them using
|
||||
the key retrieved from the session key file.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
|
|
|||
|
|
@ -134,6 +134,15 @@
|
|||
<filename>bind.keys</filename>. [RT #46155]
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Previously, <command>update-policy local;</command> accepted
|
||||
updates from any source so long as they were signed by the
|
||||
locally-generated session key. This has been further restricted;
|
||||
updates are now only accepted from locally configured addresses.
|
||||
[RT #45492]
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<command>dig +ednsopt</command> now accepts the names
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue