2000-11-13 22:22:53 -05:00
|
|
|
/*
|
2018-02-23 03:53:12 -05:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2000-11-13 22:22:53 -05:00
|
|
|
*
|
2021-06-03 02:37:05 -04:00
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
*
|
2016-06-27 00:56:38 -04:00
|
|
|
* 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
|
2020-09-14 19:20:40 -04:00
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 03:53:12 -05:00
|
|
|
*
|
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
|
* information regarding copyright ownership.
|
2000-11-13 22:22:53 -05:00
|
|
|
*/
|
|
|
|
|
|
2005-04-27 00:57:32 -04:00
|
|
|
/*! \file */
|
2000-11-13 22:22:53 -05:00
|
|
|
|
|
|
|
|
#include <isc/mem.h>
|
2021-10-04 11:14:53 -04:00
|
|
|
#include <isc/result.h>
|
2000-11-13 22:22:53 -05:00
|
|
|
#include <isc/util.h>
|
|
|
|
|
|
|
|
|
|
#include <dns/acl.h>
|
2017-09-08 16:39:09 -04:00
|
|
|
#include <dns/message.h>
|
2000-11-13 22:22:53 -05:00
|
|
|
|
2017-09-08 16:39:09 -04:00
|
|
|
#include <ns/server.h>
|
|
|
|
|
#include <ns/sortlist.h>
|
2000-11-13 22:22:53 -05:00
|
|
|
|
|
|
|
|
ns_sortlisttype_t
|
2020-02-12 07:59:18 -05:00
|
|
|
ns_sortlist_setup(dns_acl_t *acl, dns_aclenv_t *env, isc_netaddr_t *clientaddr,
|
2022-03-14 07:38:46 -04:00
|
|
|
void **argp) {
|
2020-02-13 15:48:23 -05:00
|
|
|
if (acl == NULL) {
|
2000-11-13 22:22:53 -05:00
|
|
|
goto dont_sort;
|
2020-02-13 15:48:23 -05:00
|
|
|
}
|
2000-11-13 22:22:53 -05:00
|
|
|
|
2022-03-14 07:38:46 -04:00
|
|
|
for (size_t i = 0; i < acl->length; i++) {
|
2000-11-13 22:22:53 -05:00
|
|
|
/*
|
|
|
|
|
* 'e' refers to the current 'top level statement'
|
|
|
|
|
* in the sortlist (see ARM).
|
|
|
|
|
*/
|
2020-02-13 17:44:37 -05:00
|
|
|
dns_aclelement_t *e = &acl->elements[i];
|
|
|
|
|
dns_aclelement_t *try_elt;
|
|
|
|
|
dns_aclelement_t *order_elt = NULL;
|
2022-03-14 07:38:46 -04:00
|
|
|
dns_aclelement_t *matched_elt = NULL;
|
2001-10-30 14:45:33 -05:00
|
|
|
|
|
|
|
|
if (e->type == dns_aclelementtype_nestedacl) {
|
2007-09-11 21:09:08 -04:00
|
|
|
dns_acl_t *inner = e->nestedacl;
|
2001-10-30 14:45:33 -05:00
|
|
|
|
2020-02-13 15:48:23 -05:00
|
|
|
if (inner->length == 0) {
|
2007-09-13 21:46:06 -04:00
|
|
|
try_elt = e;
|
2020-02-13 15:48:23 -05:00
|
|
|
} else if (inner->length > 2) {
|
2001-10-30 14:45:33 -05:00
|
|
|
goto dont_sort;
|
2020-02-13 15:48:23 -05:00
|
|
|
} else if (inner->elements[0].negative) {
|
2001-10-30 14:45:33 -05:00
|
|
|
goto dont_sort;
|
2020-02-13 15:48:23 -05:00
|
|
|
} else {
|
2007-09-13 21:46:06 -04:00
|
|
|
try_elt = &inner->elements[0];
|
2020-02-13 15:48:23 -05:00
|
|
|
if (inner->length == 2) {
|
2007-09-13 21:46:06 -04:00
|
|
|
order_elt = &inner->elements[1];
|
2020-02-13 15:48:23 -05:00
|
|
|
}
|
2007-09-13 21:46:06 -04:00
|
|
|
}
|
2001-10-30 14:45:33 -05:00
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* BIND 8 allows bare elements at the top level
|
|
|
|
|
* as an undocumented feature.
|
|
|
|
|
*/
|
|
|
|
|
try_elt = e;
|
2001-10-30 01:41:58 -05:00
|
|
|
}
|
|
|
|
|
|
2022-03-14 07:38:46 -04:00
|
|
|
if (!dns_aclelement_match(
|
|
|
|
|
clientaddr, NULL, try_elt, env,
|
|
|
|
|
(const dns_aclelement_t **)&matched_elt))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (order_elt == NULL) {
|
|
|
|
|
INSIST(matched_elt != NULL);
|
|
|
|
|
*argp = matched_elt;
|
|
|
|
|
return NS_SORTLISTTYPE_1ELEMENT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (order_elt->type == dns_aclelementtype_nestedacl) {
|
|
|
|
|
dns_acl_t *inner = NULL;
|
|
|
|
|
dns_acl_attach(order_elt->nestedacl, &inner);
|
|
|
|
|
*argp = inner;
|
|
|
|
|
return NS_SORTLISTTYPE_2ELEMENT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (order_elt->type == dns_aclelementtype_localhost) {
|
|
|
|
|
dns_acl_t *inner = NULL;
|
|
|
|
|
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
|
|
|
|
if (env->localhost != NULL) {
|
|
|
|
|
dns_acl_attach(env->localhost, &inner);
|
|
|
|
|
}
|
|
|
|
|
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
|
|
|
|
|
|
|
|
|
if (inner != NULL) {
|
|
|
|
|
*argp = inner;
|
|
|
|
|
return NS_SORTLISTTYPE_2ELEMENT;
|
2000-11-13 22:22:53 -05:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-14 07:38:46 -04:00
|
|
|
|
|
|
|
|
if (order_elt->type == dns_aclelementtype_localnets) {
|
|
|
|
|
dns_acl_t *inner = NULL;
|
|
|
|
|
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
|
|
|
|
if (env->localnets != NULL) {
|
|
|
|
|
dns_acl_attach(env->localnets, &inner);
|
|
|
|
|
}
|
|
|
|
|
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
|
|
|
|
if (inner != NULL) {
|
|
|
|
|
*argp = inner;
|
|
|
|
|
return NS_SORTLISTTYPE_2ELEMENT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* BIND 8 allows a bare IP prefix as
|
|
|
|
|
* the 2nd element of a 2-element
|
|
|
|
|
* sortlist statement.
|
|
|
|
|
*/
|
|
|
|
|
*argp = order_elt;
|
|
|
|
|
return NS_SORTLISTTYPE_1ELEMENT;
|
2000-11-13 22:22:53 -05:00
|
|
|
}
|
|
|
|
|
|
2020-02-12 07:59:18 -05:00
|
|
|
dont_sort:
|
2000-11-13 22:22:53 -05:00
|
|
|
*argp = NULL;
|
|
|
|
|
return NS_SORTLISTTYPE_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2020-02-13 17:44:37 -05:00
|
|
|
ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg) {
|
2020-02-12 07:59:18 -05:00
|
|
|
const dns_sortlist_arg_t *sla = (const dns_sortlist_arg_t *)arg;
|
2022-03-14 07:38:46 -04:00
|
|
|
dns_aclenv_t *env = sla->env;
|
2020-02-13 17:44:37 -05:00
|
|
|
const dns_acl_t *sortacl = sla->acl;
|
|
|
|
|
int match;
|
2000-11-13 22:22:53 -05:00
|
|
|
|
2018-04-26 23:57:41 -04:00
|
|
|
(void)dns_acl_match(addr, NULL, sortacl, env, &match, NULL);
|
|
|
|
|
if (match > 0) {
|
2000-11-13 22:22:53 -05:00
|
|
|
return match;
|
2018-04-26 23:57:41 -04:00
|
|
|
} else if (match < 0) {
|
2000-11-13 22:22:53 -05:00
|
|
|
return INT_MAX - (-match);
|
2018-04-26 23:57:41 -04:00
|
|
|
} else {
|
2000-11-13 22:22:53 -05:00
|
|
|
return INT_MAX / 2;
|
2018-04-26 23:57:41 -04:00
|
|
|
}
|
2000-11-13 22:22:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2020-02-13 17:44:37 -05:00
|
|
|
ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg) {
|
2020-02-12 07:59:18 -05:00
|
|
|
const dns_sortlist_arg_t *sla = (const dns_sortlist_arg_t *)arg;
|
2022-03-14 07:38:46 -04:00
|
|
|
dns_aclenv_t *env = sla->env;
|
2020-02-13 17:44:37 -05:00
|
|
|
const dns_aclelement_t *element = sla->element;
|
2017-09-08 16:39:09 -04:00
|
|
|
|
2018-04-26 23:57:41 -04:00
|
|
|
if (dns_aclelement_match(addr, NULL, element, env, NULL)) {
|
2000-11-13 22:22:53 -05:00
|
|
|
return 0;
|
|
|
|
|
}
|
2017-09-08 16:39:09 -04:00
|
|
|
|
|
|
|
|
return INT_MAX;
|
2000-11-13 22:22:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2017-09-08 16:39:09 -04:00
|
|
|
ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, dns_aclenv_t *env,
|
2020-02-13 17:44:37 -05:00
|
|
|
isc_netaddr_t *client_addr,
|
2022-03-14 07:38:46 -04:00
|
|
|
dns_addressorderfunc_t *orderp, void **argp) {
|
2000-11-15 15:35:13 -05:00
|
|
|
ns_sortlisttype_t sortlisttype;
|
|
|
|
|
|
2017-09-08 16:39:09 -04:00
|
|
|
sortlisttype = ns_sortlist_setup(sortlist_acl, env, client_addr, argp);
|
2000-11-15 15:35:13 -05:00
|
|
|
|
|
|
|
|
switch (sortlisttype) {
|
2000-11-13 22:22:53 -05:00
|
|
|
case NS_SORTLISTTYPE_1ELEMENT:
|
2000-11-15 15:35:13 -05:00
|
|
|
*orderp = ns_sortlist_addrorder1;
|
2000-11-13 22:22:53 -05:00
|
|
|
break;
|
|
|
|
|
case NS_SORTLISTTYPE_2ELEMENT:
|
2000-11-15 15:35:13 -05:00
|
|
|
*orderp = ns_sortlist_addrorder2;
|
2000-11-13 22:22:53 -05:00
|
|
|
break;
|
|
|
|
|
case NS_SORTLISTTYPE_NONE:
|
2000-11-15 15:35:13 -05:00
|
|
|
*orderp = NULL;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2022-10-14 11:07:07 -04:00
|
|
|
UNEXPECTED_ERROR(
|
|
|
|
|
"unexpected return from ns_sortlist_setup(): %d",
|
|
|
|
|
sortlisttype);
|
2000-11-13 22:22:53 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|