1b7579f77SDag-Erling Smørgrav /* 2b7579f77SDag-Erling Smørgrav * daemon/acl_list.h - client access control storage for the server. 3b7579f77SDag-Erling Smørgrav * 4b7579f77SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 5b7579f77SDag-Erling Smørgrav * 6b7579f77SDag-Erling Smørgrav * This software is open source. 7b7579f77SDag-Erling Smørgrav * 8b7579f77SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 9b7579f77SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 10b7579f77SDag-Erling Smørgrav * are met: 11b7579f77SDag-Erling Smørgrav * 12b7579f77SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 13b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 14b7579f77SDag-Erling Smørgrav * 15b7579f77SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 16b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 17b7579f77SDag-Erling Smørgrav * and/or other materials provided with the distribution. 18b7579f77SDag-Erling Smørgrav * 19b7579f77SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 20b7579f77SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 21b7579f77SDag-Erling Smørgrav * specific prior written permission. 22b7579f77SDag-Erling Smørgrav * 23b7579f77SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34b7579f77SDag-Erling Smørgrav */ 35b7579f77SDag-Erling Smørgrav 36b7579f77SDag-Erling Smørgrav /** 37b7579f77SDag-Erling Smørgrav * \file 38b7579f77SDag-Erling Smørgrav * 39b7579f77SDag-Erling Smørgrav * This file helps the server keep out queries from outside sources, that 40b7579f77SDag-Erling Smørgrav * should not be answered. 41b7579f77SDag-Erling Smørgrav */ 42b7579f77SDag-Erling Smørgrav #include "config.h" 43b7579f77SDag-Erling Smørgrav #include "daemon/acl_list.h" 44b7579f77SDag-Erling Smørgrav #include "util/regional.h" 45b7579f77SDag-Erling Smørgrav #include "util/log.h" 46b7579f77SDag-Erling Smørgrav #include "util/config_file.h" 47b7579f77SDag-Erling Smørgrav #include "util/net_help.h" 48b5663de9SDag-Erling Smørgrav #include "services/localzone.h" 49865f46b2SCy Schubert #include "services/listen_dnsport.h" 50b5663de9SDag-Erling Smørgrav #include "sldns/str2wire.h" 51b7579f77SDag-Erling Smørgrav 52b7579f77SDag-Erling Smørgrav struct acl_list* 53b7579f77SDag-Erling Smørgrav acl_list_create(void) 54b7579f77SDag-Erling Smørgrav { 55b7579f77SDag-Erling Smørgrav struct acl_list* acl = (struct acl_list*)calloc(1, 56b7579f77SDag-Erling Smørgrav sizeof(struct acl_list)); 57b7579f77SDag-Erling Smørgrav if(!acl) 58b7579f77SDag-Erling Smørgrav return NULL; 59b7579f77SDag-Erling Smørgrav acl->region = regional_create(); 60b7579f77SDag-Erling Smørgrav if(!acl->region) { 61b7579f77SDag-Erling Smørgrav acl_list_delete(acl); 62b7579f77SDag-Erling Smørgrav return NULL; 63b7579f77SDag-Erling Smørgrav } 64b7579f77SDag-Erling Smørgrav return acl; 65b7579f77SDag-Erling Smørgrav } 66b7579f77SDag-Erling Smørgrav 67b7579f77SDag-Erling Smørgrav void 68b7579f77SDag-Erling Smørgrav acl_list_delete(struct acl_list* acl) 69b7579f77SDag-Erling Smørgrav { 70b7579f77SDag-Erling Smørgrav if(!acl) 71b7579f77SDag-Erling Smørgrav return; 72b7579f77SDag-Erling Smørgrav regional_destroy(acl->region); 73b7579f77SDag-Erling Smørgrav free(acl); 74b7579f77SDag-Erling Smørgrav } 75b7579f77SDag-Erling Smørgrav 76b7579f77SDag-Erling Smørgrav /** insert new address into acl_list structure */ 77b5663de9SDag-Erling Smørgrav static struct acl_addr* 78b7579f77SDag-Erling Smørgrav acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr, 79b7579f77SDag-Erling Smørgrav socklen_t addrlen, int net, enum acl_access control, 80b7579f77SDag-Erling Smørgrav int complain_duplicates) 81b7579f77SDag-Erling Smørgrav { 82b5663de9SDag-Erling Smørgrav struct acl_addr* node = regional_alloc_zero(acl->region, 83b7579f77SDag-Erling Smørgrav sizeof(struct acl_addr)); 84b7579f77SDag-Erling Smørgrav if(!node) 85b5663de9SDag-Erling Smørgrav return NULL; 86b7579f77SDag-Erling Smørgrav node->control = control; 87b7579f77SDag-Erling Smørgrav if(!addr_tree_insert(&acl->tree, &node->node, addr, addrlen, net)) { 88b7579f77SDag-Erling Smørgrav if(complain_duplicates) 89b7579f77SDag-Erling Smørgrav verbose(VERB_QUERY, "duplicate acl address ignored."); 90b7579f77SDag-Erling Smørgrav } 91b5663de9SDag-Erling Smørgrav return node; 92b7579f77SDag-Erling Smørgrav } 93b7579f77SDag-Erling Smørgrav 94865f46b2SCy Schubert /** parse str to acl_access enum */ 95865f46b2SCy Schubert static int 96865f46b2SCy Schubert parse_acl_access(const char* str, enum acl_access* control) 97865f46b2SCy Schubert { 98865f46b2SCy Schubert if(strcmp(str, "allow") == 0) 99865f46b2SCy Schubert *control = acl_allow; 100865f46b2SCy Schubert else if(strcmp(str, "deny") == 0) 101865f46b2SCy Schubert *control = acl_deny; 102865f46b2SCy Schubert else if(strcmp(str, "refuse") == 0) 103865f46b2SCy Schubert *control = acl_refuse; 104865f46b2SCy Schubert else if(strcmp(str, "deny_non_local") == 0) 105865f46b2SCy Schubert *control = acl_deny_non_local; 106865f46b2SCy Schubert else if(strcmp(str, "refuse_non_local") == 0) 107865f46b2SCy Schubert *control = acl_refuse_non_local; 108865f46b2SCy Schubert else if(strcmp(str, "allow_snoop") == 0) 109865f46b2SCy Schubert *control = acl_allow_snoop; 110865f46b2SCy Schubert else if(strcmp(str, "allow_setrd") == 0) 111865f46b2SCy Schubert *control = acl_allow_setrd; 1128f76bb7dSCy Schubert else if (strcmp(str, "allow_cookie") == 0) 1138f76bb7dSCy Schubert *control = acl_allow_cookie; 114865f46b2SCy Schubert else { 115865f46b2SCy Schubert log_err("access control type %s unknown", str); 116865f46b2SCy Schubert return 0; 117865f46b2SCy Schubert } 118865f46b2SCy Schubert return 1; 119865f46b2SCy Schubert } 120865f46b2SCy Schubert 121b7579f77SDag-Erling Smørgrav /** apply acl_list string */ 122b7579f77SDag-Erling Smørgrav static int 123b7579f77SDag-Erling Smørgrav acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2, 124b7579f77SDag-Erling Smørgrav int complain_duplicates) 125b7579f77SDag-Erling Smørgrav { 126b7579f77SDag-Erling Smørgrav struct sockaddr_storage addr; 127b7579f77SDag-Erling Smørgrav int net; 128b7579f77SDag-Erling Smørgrav socklen_t addrlen; 129b7579f77SDag-Erling Smørgrav enum acl_access control; 130865f46b2SCy Schubert if(!parse_acl_access(s2, &control)) { 131b7579f77SDag-Erling Smørgrav return 0; 132b7579f77SDag-Erling Smørgrav } 133b7579f77SDag-Erling Smørgrav if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) { 134b7579f77SDag-Erling Smørgrav log_err("cannot parse access control: %s %s", str, s2); 135b7579f77SDag-Erling Smørgrav return 0; 136b7579f77SDag-Erling Smørgrav } 137b7579f77SDag-Erling Smørgrav if(!acl_list_insert(acl, &addr, addrlen, net, control, 138b7579f77SDag-Erling Smørgrav complain_duplicates)) { 139b7579f77SDag-Erling Smørgrav log_err("out of memory"); 140b7579f77SDag-Erling Smørgrav return 0; 141b7579f77SDag-Erling Smørgrav } 142b7579f77SDag-Erling Smørgrav return 1; 143b7579f77SDag-Erling Smørgrav } 144b7579f77SDag-Erling Smørgrav 145b5663de9SDag-Erling Smørgrav /** find or create node (NULL on parse or error) */ 146b5663de9SDag-Erling Smørgrav static struct acl_addr* 147865f46b2SCy Schubert acl_find_or_create_str2addr(struct acl_list* acl, const char* str, 148865f46b2SCy Schubert int is_interface, int port) 149b5663de9SDag-Erling Smørgrav { 150b5663de9SDag-Erling Smørgrav struct acl_addr* node; 151b5663de9SDag-Erling Smørgrav struct sockaddr_storage addr; 152b5663de9SDag-Erling Smørgrav socklen_t addrlen; 153865f46b2SCy Schubert int net = (str_is_ip6(str)?128:32); 154865f46b2SCy Schubert if(is_interface) { 155865f46b2SCy Schubert if(!extstrtoaddr(str, &addr, &addrlen, port)) { 156865f46b2SCy Schubert log_err("cannot parse interface: %s", str); 157865f46b2SCy Schubert return NULL; 158865f46b2SCy Schubert } 159865f46b2SCy Schubert } else { 160b5663de9SDag-Erling Smørgrav if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) { 161b5663de9SDag-Erling Smørgrav log_err("cannot parse netblock: %s", str); 162b5663de9SDag-Erling Smørgrav return NULL; 163b5663de9SDag-Erling Smørgrav } 164865f46b2SCy Schubert } 165b5663de9SDag-Erling Smørgrav /* find or create node */ 166b5663de9SDag-Erling Smørgrav if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr, 167865f46b2SCy Schubert addrlen, net)) && !is_interface) { 168b5663de9SDag-Erling Smørgrav /* create node, type 'allow' since otherwise tags are 169b5663de9SDag-Erling Smørgrav * pointless, can override with specific access-control: cfg */ 170b5663de9SDag-Erling Smørgrav if(!(node=(struct acl_addr*)acl_list_insert(acl, &addr, 171b5663de9SDag-Erling Smørgrav addrlen, net, acl_allow, 1))) { 172b5663de9SDag-Erling Smørgrav log_err("out of memory"); 173b5663de9SDag-Erling Smørgrav return NULL; 174b5663de9SDag-Erling Smørgrav } 175b5663de9SDag-Erling Smørgrav } 176b5663de9SDag-Erling Smørgrav return node; 177b5663de9SDag-Erling Smørgrav } 178b5663de9SDag-Erling Smørgrav 179865f46b2SCy Schubert /** find or create node (NULL on error) */ 180865f46b2SCy Schubert static struct acl_addr* 181865f46b2SCy Schubert acl_find_or_create(struct acl_list* acl, struct sockaddr_storage* addr, 182865f46b2SCy Schubert socklen_t addrlen, enum acl_access control) 183865f46b2SCy Schubert { 184865f46b2SCy Schubert struct acl_addr* node; 185865f46b2SCy Schubert int net = (addr_is_ip6(addr, addrlen)?128:32); 186865f46b2SCy Schubert /* find or create node */ 187865f46b2SCy Schubert if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, addr, 188865f46b2SCy Schubert addrlen, net))) { 189865f46b2SCy Schubert /* create node; 190865f46b2SCy Schubert * can override with specific access-control: cfg */ 191865f46b2SCy Schubert if(!(node=(struct acl_addr*)acl_list_insert(acl, addr, 192865f46b2SCy Schubert addrlen, net, control, 1))) { 193865f46b2SCy Schubert log_err("out of memory"); 194865f46b2SCy Schubert return NULL; 195865f46b2SCy Schubert } 196865f46b2SCy Schubert } 197865f46b2SCy Schubert return node; 198865f46b2SCy Schubert } 199865f46b2SCy Schubert 200865f46b2SCy Schubert /** apply acl_interface string */ 201865f46b2SCy Schubert static int 202865f46b2SCy Schubert acl_interface_str_cfg(struct acl_list* acl_interface, const char* iface, 203865f46b2SCy Schubert const char* s2, int port) 204865f46b2SCy Schubert { 205865f46b2SCy Schubert struct acl_addr* node; 206865f46b2SCy Schubert enum acl_access control; 207865f46b2SCy Schubert if(!parse_acl_access(s2, &control)) { 208865f46b2SCy Schubert return 0; 209865f46b2SCy Schubert } 210865f46b2SCy Schubert if(!(node=acl_find_or_create_str2addr(acl_interface, iface, 1, port))) { 211865f46b2SCy Schubert log_err("cannot update ACL on non-configured interface: %s %d", 212865f46b2SCy Schubert iface, port); 213865f46b2SCy Schubert return 0; 214865f46b2SCy Schubert } 215865f46b2SCy Schubert node->control = control; 216865f46b2SCy Schubert return 1; 217865f46b2SCy Schubert } 218865f46b2SCy Schubert 219865f46b2SCy Schubert struct acl_addr* 220865f46b2SCy Schubert acl_interface_insert(struct acl_list* acl_interface, 221865f46b2SCy Schubert struct sockaddr_storage* addr, socklen_t addrlen, 222865f46b2SCy Schubert enum acl_access control) 223865f46b2SCy Schubert { 224*be771a7bSCy Schubert struct acl_addr* node = acl_find_or_create(acl_interface, addr, addrlen, control); 225*be771a7bSCy Schubert node->is_interface = 1; 226*be771a7bSCy Schubert return node; 227865f46b2SCy Schubert } 228865f46b2SCy Schubert 229b5663de9SDag-Erling Smørgrav /** apply acl_tag string */ 230b5663de9SDag-Erling Smørgrav static int 231b5663de9SDag-Erling Smørgrav acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap, 232865f46b2SCy Schubert size_t bitmaplen, int is_interface, int port) 233b5663de9SDag-Erling Smørgrav { 234b5663de9SDag-Erling Smørgrav struct acl_addr* node; 235865f46b2SCy Schubert if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) { 236865f46b2SCy Schubert if(is_interface) 237865f46b2SCy Schubert log_err("non-configured interface: %s", str); 238b5663de9SDag-Erling Smørgrav return 0; 239865f46b2SCy Schubert } 240b5663de9SDag-Erling Smørgrav node->taglen = bitmaplen; 241b5663de9SDag-Erling Smørgrav node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen); 242b5663de9SDag-Erling Smørgrav if(!node->taglist) { 243b5663de9SDag-Erling Smørgrav log_err("out of memory"); 244b5663de9SDag-Erling Smørgrav return 0; 245b5663de9SDag-Erling Smørgrav } 246b5663de9SDag-Erling Smørgrav return 1; 247b5663de9SDag-Erling Smørgrav } 248b5663de9SDag-Erling Smørgrav 249bc892140SDag-Erling Smørgrav /** apply acl_view string */ 250bc892140SDag-Erling Smørgrav static int 251bc892140SDag-Erling Smørgrav acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2, 252865f46b2SCy Schubert struct views* vs, int is_interface, int port) 253bc892140SDag-Erling Smørgrav { 254bc892140SDag-Erling Smørgrav struct acl_addr* node; 255865f46b2SCy Schubert if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) { 256865f46b2SCy Schubert if(is_interface) 257865f46b2SCy Schubert log_err("non-configured interface: %s", str); 258bc892140SDag-Erling Smørgrav return 0; 259865f46b2SCy Schubert } 260bc892140SDag-Erling Smørgrav node->view = views_find_view(vs, str2, 0 /* get read lock*/); 261bc892140SDag-Erling Smørgrav if(!node->view) { 262bc892140SDag-Erling Smørgrav log_err("no view with name: %s", str2); 263bc892140SDag-Erling Smørgrav return 0; 264bc892140SDag-Erling Smørgrav } 265bc892140SDag-Erling Smørgrav lock_rw_unlock(&node->view->lock); 266bc892140SDag-Erling Smørgrav return 1; 267bc892140SDag-Erling Smørgrav } 268bc892140SDag-Erling Smørgrav 269b5663de9SDag-Erling Smørgrav /** apply acl_tag_action string */ 270b5663de9SDag-Erling Smørgrav static int 271b5663de9SDag-Erling Smørgrav acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg, 272865f46b2SCy Schubert const char* str, const char* tag, const char* action, 273865f46b2SCy Schubert int is_interface, int port) 274b5663de9SDag-Erling Smørgrav { 275b5663de9SDag-Erling Smørgrav struct acl_addr* node; 276b5663de9SDag-Erling Smørgrav int tagid; 277b5663de9SDag-Erling Smørgrav enum localzone_type t; 278865f46b2SCy Schubert if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) { 279865f46b2SCy Schubert if(is_interface) 280865f46b2SCy Schubert log_err("non-configured interface: %s", str); 281b5663de9SDag-Erling Smørgrav return 0; 282865f46b2SCy Schubert } 283b5663de9SDag-Erling Smørgrav /* allocate array if not yet */ 284b5663de9SDag-Erling Smørgrav if(!node->tag_actions) { 285b5663de9SDag-Erling Smørgrav node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region, 286b5663de9SDag-Erling Smørgrav sizeof(*node->tag_actions)*cfg->num_tags); 287b5663de9SDag-Erling Smørgrav if(!node->tag_actions) { 288b5663de9SDag-Erling Smørgrav log_err("out of memory"); 289b5663de9SDag-Erling Smørgrav return 0; 290b5663de9SDag-Erling Smørgrav } 291b5663de9SDag-Erling Smørgrav node->tag_actions_size = (size_t)cfg->num_tags; 292b5663de9SDag-Erling Smørgrav } 293b5663de9SDag-Erling Smørgrav /* parse tag */ 294b5663de9SDag-Erling Smørgrav if((tagid=find_tag_id(cfg, tag)) == -1) { 295b5663de9SDag-Erling Smørgrav log_err("cannot parse tag (define-tag it): %s %s", str, tag); 296b5663de9SDag-Erling Smørgrav return 0; 297b5663de9SDag-Erling Smørgrav } 298b5663de9SDag-Erling Smørgrav if((size_t)tagid >= node->tag_actions_size) { 299b5663de9SDag-Erling Smørgrav log_err("tagid too large for array %s %s", str, tag); 300b5663de9SDag-Erling Smørgrav return 0; 301b5663de9SDag-Erling Smørgrav } 302b5663de9SDag-Erling Smørgrav if(!local_zone_str2type(action, &t)) { 303b5663de9SDag-Erling Smørgrav log_err("cannot parse access control action type: %s %s %s", 304b5663de9SDag-Erling Smørgrav str, tag, action); 305b5663de9SDag-Erling Smørgrav return 0; 306b5663de9SDag-Erling Smørgrav } 307b5663de9SDag-Erling Smørgrav node->tag_actions[tagid] = (uint8_t)t; 308b5663de9SDag-Erling Smørgrav return 1; 309b5663de9SDag-Erling Smørgrav } 310b5663de9SDag-Erling Smørgrav 311b5663de9SDag-Erling Smørgrav /** check wire data parse */ 312b5663de9SDag-Erling Smørgrav static int 313bc892140SDag-Erling Smørgrav check_data(const char* data, const struct config_strlist* head) 314b5663de9SDag-Erling Smørgrav { 315b5663de9SDag-Erling Smørgrav char buf[65536]; 316b5663de9SDag-Erling Smørgrav uint8_t rr[LDNS_RR_BUF_SIZE]; 317b5663de9SDag-Erling Smørgrav size_t len = sizeof(rr); 318b5663de9SDag-Erling Smørgrav int res; 319bc892140SDag-Erling Smørgrav /* '.' is sufficient for validation, and it makes the call to 320bc892140SDag-Erling Smørgrav * sldns_wirerr_get_type() simpler below. */ 321bc892140SDag-Erling Smørgrav snprintf(buf, sizeof(buf), "%s %s", ".", data); 322b5663de9SDag-Erling Smørgrav res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL, 0, 323b5663de9SDag-Erling Smørgrav NULL, 0); 324bc892140SDag-Erling Smørgrav 325bc892140SDag-Erling Smørgrav /* Reject it if we would end up having CNAME and other data (including 326bc892140SDag-Erling Smørgrav * another CNAME) for the same tag. */ 327bc892140SDag-Erling Smørgrav if(res == 0 && head) { 328bc892140SDag-Erling Smørgrav const char* err_data = NULL; 329bc892140SDag-Erling Smørgrav 330bc892140SDag-Erling Smørgrav if(sldns_wirerr_get_type(rr, len, 1) == LDNS_RR_TYPE_CNAME) { 331bc892140SDag-Erling Smørgrav /* adding CNAME while other data already exists. */ 332bc892140SDag-Erling Smørgrav err_data = data; 333bc892140SDag-Erling Smørgrav } else { 334bc892140SDag-Erling Smørgrav snprintf(buf, sizeof(buf), "%s %s", ".", head->str); 335bc892140SDag-Erling Smørgrav len = sizeof(rr); 336bc892140SDag-Erling Smørgrav res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, 337bc892140SDag-Erling Smørgrav NULL, 0, NULL, 0); 338bc892140SDag-Erling Smørgrav if(res != 0) { 339bc892140SDag-Erling Smørgrav /* This should be impossible here as head->str 340bc892140SDag-Erling Smørgrav * has been validated, but we check it just in 341bc892140SDag-Erling Smørgrav * case. */ 342bc892140SDag-Erling Smørgrav return 0; 343bc892140SDag-Erling Smørgrav } 344bc892140SDag-Erling Smørgrav if(sldns_wirerr_get_type(rr, len, 1) == 345bc892140SDag-Erling Smørgrav LDNS_RR_TYPE_CNAME) /* already have CNAME */ 346bc892140SDag-Erling Smørgrav err_data = head->str; 347bc892140SDag-Erling Smørgrav } 348bc892140SDag-Erling Smørgrav if(err_data) { 349bc892140SDag-Erling Smørgrav log_err("redirect tag data '%s' must not coexist with " 350bc892140SDag-Erling Smørgrav "other data.", err_data); 351bc892140SDag-Erling Smørgrav return 0; 352bc892140SDag-Erling Smørgrav } 353bc892140SDag-Erling Smørgrav } 354b5663de9SDag-Erling Smørgrav if(res == 0) 355b5663de9SDag-Erling Smørgrav return 1; 356b5663de9SDag-Erling Smørgrav log_err("rr data [char %d] parse error %s", 35725039b37SCy Schubert (int)LDNS_WIREPARSE_OFFSET(res)-2, 358b5663de9SDag-Erling Smørgrav sldns_get_errorstr_parse(res)); 359b5663de9SDag-Erling Smørgrav return 0; 360b5663de9SDag-Erling Smørgrav } 361b5663de9SDag-Erling Smørgrav 362b5663de9SDag-Erling Smørgrav /** apply acl_tag_data string */ 363b5663de9SDag-Erling Smørgrav static int 364b5663de9SDag-Erling Smørgrav acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg, 365865f46b2SCy Schubert const char* str, const char* tag, const char* data, 366865f46b2SCy Schubert int is_interface, int port) 367b5663de9SDag-Erling Smørgrav { 368b5663de9SDag-Erling Smørgrav struct acl_addr* node; 369b5663de9SDag-Erling Smørgrav int tagid; 370b5663de9SDag-Erling Smørgrav char* dupdata; 371865f46b2SCy Schubert if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) { 372865f46b2SCy Schubert if(is_interface) 373865f46b2SCy Schubert log_err("non-configured interface: %s", str); 374b5663de9SDag-Erling Smørgrav return 0; 375865f46b2SCy Schubert } 376b5663de9SDag-Erling Smørgrav /* allocate array if not yet */ 377b5663de9SDag-Erling Smørgrav if(!node->tag_datas) { 378b5663de9SDag-Erling Smørgrav node->tag_datas = (struct config_strlist**)regional_alloc_zero( 379b5663de9SDag-Erling Smørgrav acl->region, sizeof(*node->tag_datas)*cfg->num_tags); 380b5663de9SDag-Erling Smørgrav if(!node->tag_datas) { 381b5663de9SDag-Erling Smørgrav log_err("out of memory"); 382b5663de9SDag-Erling Smørgrav return 0; 383b5663de9SDag-Erling Smørgrav } 384b5663de9SDag-Erling Smørgrav node->tag_datas_size = (size_t)cfg->num_tags; 385b5663de9SDag-Erling Smørgrav } 386b5663de9SDag-Erling Smørgrav /* parse tag */ 387b5663de9SDag-Erling Smørgrav if((tagid=find_tag_id(cfg, tag)) == -1) { 388b5663de9SDag-Erling Smørgrav log_err("cannot parse tag (define-tag it): %s %s", str, tag); 389b5663de9SDag-Erling Smørgrav return 0; 390b5663de9SDag-Erling Smørgrav } 391b5663de9SDag-Erling Smørgrav if((size_t)tagid >= node->tag_datas_size) { 392b5663de9SDag-Erling Smørgrav log_err("tagid too large for array %s %s", str, tag); 393b5663de9SDag-Erling Smørgrav return 0; 394b5663de9SDag-Erling Smørgrav } 395b5663de9SDag-Erling Smørgrav 396b5663de9SDag-Erling Smørgrav /* check data? */ 397bc892140SDag-Erling Smørgrav if(!check_data(data, node->tag_datas[tagid])) { 398b5663de9SDag-Erling Smørgrav log_err("cannot parse access-control-tag data: %s %s '%s'", 399b5663de9SDag-Erling Smørgrav str, tag, data); 400b5663de9SDag-Erling Smørgrav return 0; 401b5663de9SDag-Erling Smørgrav } 402b5663de9SDag-Erling Smørgrav 403b5663de9SDag-Erling Smørgrav dupdata = regional_strdup(acl->region, data); 404b5663de9SDag-Erling Smørgrav if(!dupdata) { 405b5663de9SDag-Erling Smørgrav log_err("out of memory"); 406b5663de9SDag-Erling Smørgrav return 0; 407b5663de9SDag-Erling Smørgrav } 408b5663de9SDag-Erling Smørgrav if(!cfg_region_strlist_insert(acl->region, 409b5663de9SDag-Erling Smørgrav &(node->tag_datas[tagid]), dupdata)) { 410b5663de9SDag-Erling Smørgrav log_err("out of memory"); 411b5663de9SDag-Erling Smørgrav return 0; 412b5663de9SDag-Erling Smørgrav } 413b5663de9SDag-Erling Smørgrav return 1; 414b5663de9SDag-Erling Smørgrav } 415b5663de9SDag-Erling Smørgrav 416b7579f77SDag-Erling Smørgrav /** read acl_list config */ 417b7579f77SDag-Erling Smørgrav static int 418865f46b2SCy Schubert read_acl_list(struct acl_list* acl, struct config_str2list* acls) 419b7579f77SDag-Erling Smørgrav { 420b7579f77SDag-Erling Smørgrav struct config_str2list* p; 421865f46b2SCy Schubert for(p = acls; p; p = p->next) { 422b7579f77SDag-Erling Smørgrav log_assert(p->str && p->str2); 423b7579f77SDag-Erling Smørgrav if(!acl_list_str_cfg(acl, p->str, p->str2, 1)) 424b7579f77SDag-Erling Smørgrav return 0; 425b7579f77SDag-Erling Smørgrav } 426b7579f77SDag-Erling Smørgrav return 1; 427b7579f77SDag-Erling Smørgrav } 428b7579f77SDag-Erling Smørgrav 429865f46b2SCy Schubert /** read acl view config */ 430b5663de9SDag-Erling Smørgrav static int 431865f46b2SCy Schubert read_acl_view(struct acl_list* acl, struct config_str2list** acl_view, 432865f46b2SCy Schubert struct views* v) 433b5663de9SDag-Erling Smørgrav { 434865f46b2SCy Schubert struct config_str2list* np, *p = *acl_view; 435865f46b2SCy Schubert *acl_view = NULL; 436b5663de9SDag-Erling Smørgrav while(p) { 437b5663de9SDag-Erling Smørgrav log_assert(p->str && p->str2); 438865f46b2SCy Schubert if(!acl_list_view_cfg(acl, p->str, p->str2, v, 0, 0)) { 439865f46b2SCy Schubert config_deldblstrlist(p); 440b5663de9SDag-Erling Smørgrav return 0; 441b5663de9SDag-Erling Smørgrav } 442b5663de9SDag-Erling Smørgrav /* free the items as we go to free up memory */ 443b5663de9SDag-Erling Smørgrav np = p->next; 444b5663de9SDag-Erling Smørgrav free(p->str); 445b5663de9SDag-Erling Smørgrav free(p->str2); 446b5663de9SDag-Erling Smørgrav free(p); 447b5663de9SDag-Erling Smørgrav p = np; 448b5663de9SDag-Erling Smørgrav } 449b5663de9SDag-Erling Smørgrav return 1; 450b5663de9SDag-Erling Smørgrav } 451b5663de9SDag-Erling Smørgrav 452865f46b2SCy Schubert /** read acl tags config */ 453bc892140SDag-Erling Smørgrav static int 454865f46b2SCy Schubert read_acl_tags(struct acl_list* acl, struct config_strbytelist** acl_tags) 455bc892140SDag-Erling Smørgrav { 456865f46b2SCy Schubert struct config_strbytelist* np, *p = *acl_tags; 457865f46b2SCy Schubert *acl_tags = NULL; 458bc892140SDag-Erling Smørgrav while(p) { 459bc892140SDag-Erling Smørgrav log_assert(p->str && p->str2); 460865f46b2SCy Schubert if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len, 0, 0)) { 461865f46b2SCy Schubert config_del_strbytelist(p); 462bc892140SDag-Erling Smørgrav return 0; 463bc892140SDag-Erling Smørgrav } 464bc892140SDag-Erling Smørgrav /* free the items as we go to free up memory */ 465bc892140SDag-Erling Smørgrav np = p->next; 466bc892140SDag-Erling Smørgrav free(p->str); 467bc892140SDag-Erling Smørgrav free(p->str2); 468bc892140SDag-Erling Smørgrav free(p); 469bc892140SDag-Erling Smørgrav p = np; 470bc892140SDag-Erling Smørgrav } 471bc892140SDag-Erling Smørgrav return 1; 472bc892140SDag-Erling Smørgrav } 473bc892140SDag-Erling Smørgrav 474b5663de9SDag-Erling Smørgrav /** read acl tag actions config */ 475b5663de9SDag-Erling Smørgrav static int 476865f46b2SCy Schubert read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg, 477865f46b2SCy Schubert struct config_str3list** acl_tag_actions) 478b5663de9SDag-Erling Smørgrav { 479b5663de9SDag-Erling Smørgrav struct config_str3list* p, *np; 480865f46b2SCy Schubert p = *acl_tag_actions; 481865f46b2SCy Schubert *acl_tag_actions = NULL; 482b5663de9SDag-Erling Smørgrav while(p) { 483b5663de9SDag-Erling Smørgrav log_assert(p->str && p->str2 && p->str3); 484b5663de9SDag-Erling Smørgrav if(!acl_list_tag_action_cfg(acl, cfg, p->str, p->str2, 485865f46b2SCy Schubert p->str3, 0, 0)) { 486b5663de9SDag-Erling Smørgrav config_deltrplstrlist(p); 487b5663de9SDag-Erling Smørgrav return 0; 488b5663de9SDag-Erling Smørgrav } 489b5663de9SDag-Erling Smørgrav /* free the items as we go to free up memory */ 490b5663de9SDag-Erling Smørgrav np = p->next; 491b5663de9SDag-Erling Smørgrav free(p->str); 492b5663de9SDag-Erling Smørgrav free(p->str2); 493b5663de9SDag-Erling Smørgrav free(p->str3); 494b5663de9SDag-Erling Smørgrav free(p); 495b5663de9SDag-Erling Smørgrav p = np; 496b5663de9SDag-Erling Smørgrav } 497b5663de9SDag-Erling Smørgrav return 1; 498b5663de9SDag-Erling Smørgrav } 499b5663de9SDag-Erling Smørgrav 500b5663de9SDag-Erling Smørgrav /** read acl tag datas config */ 501b5663de9SDag-Erling Smørgrav static int 502865f46b2SCy Schubert read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg, 503865f46b2SCy Schubert struct config_str3list** acl_tag_datas) 504b5663de9SDag-Erling Smørgrav { 505b5663de9SDag-Erling Smørgrav struct config_str3list* p, *np; 506865f46b2SCy Schubert p = *acl_tag_datas; 507865f46b2SCy Schubert *acl_tag_datas = NULL; 508b5663de9SDag-Erling Smørgrav while(p) { 509b5663de9SDag-Erling Smørgrav log_assert(p->str && p->str2 && p->str3); 510865f46b2SCy Schubert if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3, 511865f46b2SCy Schubert 0, 0)) { 512b5663de9SDag-Erling Smørgrav config_deltrplstrlist(p); 513b5663de9SDag-Erling Smørgrav return 0; 514b5663de9SDag-Erling Smørgrav } 515b5663de9SDag-Erling Smørgrav /* free the items as we go to free up memory */ 516b5663de9SDag-Erling Smørgrav np = p->next; 517b5663de9SDag-Erling Smørgrav free(p->str); 518b5663de9SDag-Erling Smørgrav free(p->str2); 519b5663de9SDag-Erling Smørgrav free(p->str3); 520b5663de9SDag-Erling Smørgrav free(p); 521b5663de9SDag-Erling Smørgrav p = np; 522b5663de9SDag-Erling Smørgrav } 523b5663de9SDag-Erling Smørgrav return 1; 524b5663de9SDag-Erling Smørgrav } 525b5663de9SDag-Erling Smørgrav 526b7579f77SDag-Erling Smørgrav int 527bc892140SDag-Erling Smørgrav acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg, 528bc892140SDag-Erling Smørgrav struct views* v) 529b7579f77SDag-Erling Smørgrav { 530b7579f77SDag-Erling Smørgrav regional_free_all(acl->region); 531b7579f77SDag-Erling Smørgrav addr_tree_init(&acl->tree); 532865f46b2SCy Schubert if(!read_acl_list(acl, cfg->acls)) 533b7579f77SDag-Erling Smørgrav return 0; 534865f46b2SCy Schubert if(!read_acl_view(acl, &cfg->acl_view, v)) 535bc892140SDag-Erling Smørgrav return 0; 536865f46b2SCy Schubert if(!read_acl_tags(acl, &cfg->acl_tags)) 537b5663de9SDag-Erling Smørgrav return 0; 538865f46b2SCy Schubert if(!read_acl_tag_actions(acl, cfg, &cfg->acl_tag_actions)) 539b5663de9SDag-Erling Smørgrav return 0; 540865f46b2SCy Schubert if(!read_acl_tag_datas(acl, cfg, &cfg->acl_tag_datas)) 541b5663de9SDag-Erling Smørgrav return 0; 542b7579f77SDag-Erling Smørgrav /* insert defaults, with '0' to ignore them if they are duplicates */ 543865f46b2SCy Schubert /* the 'refuse' defaults for /0 are now done per interface instead */ 544b7579f77SDag-Erling Smørgrav if(!acl_list_str_cfg(acl, "127.0.0.0/8", "allow", 0)) 545b7579f77SDag-Erling Smørgrav return 0; 546b7579f77SDag-Erling Smørgrav if(cfg->do_ip6) { 547b7579f77SDag-Erling Smørgrav if(!acl_list_str_cfg(acl, "::1", "allow", 0)) 548b7579f77SDag-Erling Smørgrav return 0; 549b7579f77SDag-Erling Smørgrav if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0)) 550b7579f77SDag-Erling Smørgrav return 0; 551b7579f77SDag-Erling Smørgrav } 552b7579f77SDag-Erling Smørgrav addr_tree_init_parents(&acl->tree); 553b7579f77SDag-Erling Smørgrav return 1; 554b7579f77SDag-Erling Smørgrav } 555b7579f77SDag-Erling Smørgrav 556865f46b2SCy Schubert void 557865f46b2SCy Schubert acl_interface_init(struct acl_list* acl_interface) 558865f46b2SCy Schubert { 559865f46b2SCy Schubert regional_free_all(acl_interface->region); 560865f46b2SCy Schubert /* We want comparison in the tree to include only address and port. 561865f46b2SCy Schubert * We don't care about comparing node->net. All addresses in the 562865f46b2SCy Schubert * acl_interface->tree should have either 32 (ipv4) or 128 (ipv6). 563865f46b2SCy Schubert * Initialise with the appropriate compare function but keep treating 564865f46b2SCy Schubert * it as an addr_tree. */ 565865f46b2SCy Schubert addr_tree_addrport_init(&acl_interface->tree); 566865f46b2SCy Schubert } 567865f46b2SCy Schubert 568865f46b2SCy Schubert static int 569865f46b2SCy Schubert read_acl_interface_action(struct acl_list* acl_interface, 570865f46b2SCy Schubert struct config_str2list* acls, int port) 571865f46b2SCy Schubert { 572865f46b2SCy Schubert struct config_str2list* p; 573865f46b2SCy Schubert for(p = acls; p; p = p->next) { 574865f46b2SCy Schubert char** resif = NULL; 575865f46b2SCy Schubert int num_resif = 0; 576865f46b2SCy Schubert int i; 577865f46b2SCy Schubert log_assert(p->str && p->str2); 578865f46b2SCy Schubert if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) 579865f46b2SCy Schubert return 0; 580865f46b2SCy Schubert for(i = 0; i<num_resif; i++) { 581865f46b2SCy Schubert if(!acl_interface_str_cfg(acl_interface, resif[i], p->str2, port)){ 582865f46b2SCy Schubert config_del_strarray(resif, num_resif); 583865f46b2SCy Schubert return 0; 584865f46b2SCy Schubert } 585865f46b2SCy Schubert } 586865f46b2SCy Schubert config_del_strarray(resif, num_resif); 587865f46b2SCy Schubert } 588865f46b2SCy Schubert return 1; 589865f46b2SCy Schubert } 590865f46b2SCy Schubert 591865f46b2SCy Schubert /** read acl view config for interface */ 592865f46b2SCy Schubert static int 593865f46b2SCy Schubert read_acl_interface_view(struct acl_list* acl_interface, 594865f46b2SCy Schubert struct config_str2list** acl_view, 595865f46b2SCy Schubert struct views* v, int port) 596865f46b2SCy Schubert { 597865f46b2SCy Schubert struct config_str2list* np, *p = *acl_view; 598865f46b2SCy Schubert *acl_view = NULL; 599865f46b2SCy Schubert while(p) { 600865f46b2SCy Schubert char** resif = NULL; 601865f46b2SCy Schubert int num_resif = 0; 602865f46b2SCy Schubert int i; 603865f46b2SCy Schubert log_assert(p->str && p->str2); 604865f46b2SCy Schubert if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) { 605865f46b2SCy Schubert config_deldblstrlist(p); 606865f46b2SCy Schubert return 0; 607865f46b2SCy Schubert } 608865f46b2SCy Schubert for(i = 0; i<num_resif; i++) { 609865f46b2SCy Schubert if(!acl_list_view_cfg(acl_interface, resif[i], p->str2, 610865f46b2SCy Schubert v, 1, port)) { 611865f46b2SCy Schubert config_del_strarray(resif, num_resif); 612865f46b2SCy Schubert config_deldblstrlist(p); 613865f46b2SCy Schubert return 0; 614865f46b2SCy Schubert } 615865f46b2SCy Schubert } 616865f46b2SCy Schubert config_del_strarray(resif, num_resif); 617865f46b2SCy Schubert /* free the items as we go to free up memory */ 618865f46b2SCy Schubert np = p->next; 619865f46b2SCy Schubert free(p->str); 620865f46b2SCy Schubert free(p->str2); 621865f46b2SCy Schubert free(p); 622865f46b2SCy Schubert p = np; 623865f46b2SCy Schubert } 624865f46b2SCy Schubert return 1; 625865f46b2SCy Schubert } 626865f46b2SCy Schubert 627865f46b2SCy Schubert /** read acl tags config for interface */ 628865f46b2SCy Schubert static int 629865f46b2SCy Schubert read_acl_interface_tags(struct acl_list* acl_interface, 630865f46b2SCy Schubert struct config_strbytelist** acl_tags, int port) 631865f46b2SCy Schubert { 632865f46b2SCy Schubert struct config_strbytelist* np, *p = *acl_tags; 633865f46b2SCy Schubert *acl_tags = NULL; 634865f46b2SCy Schubert while(p) { 635865f46b2SCy Schubert char** resif = NULL; 636865f46b2SCy Schubert int num_resif = 0; 637865f46b2SCy Schubert int i; 638865f46b2SCy Schubert log_assert(p->str && p->str2); 639865f46b2SCy Schubert if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) { 640865f46b2SCy Schubert config_del_strbytelist(p); 641865f46b2SCy Schubert return 0; 642865f46b2SCy Schubert } 643865f46b2SCy Schubert for(i = 0; i<num_resif; i++) { 644865f46b2SCy Schubert if(!acl_list_tags_cfg(acl_interface, resif[i], p->str2, 645865f46b2SCy Schubert p->str2len, 1, port)) { 646865f46b2SCy Schubert config_del_strbytelist(p); 647865f46b2SCy Schubert config_del_strarray(resif, num_resif); 648865f46b2SCy Schubert return 0; 649865f46b2SCy Schubert } 650865f46b2SCy Schubert } 651865f46b2SCy Schubert config_del_strarray(resif, num_resif); 652865f46b2SCy Schubert /* free the items as we go to free up memory */ 653865f46b2SCy Schubert np = p->next; 654865f46b2SCy Schubert free(p->str); 655865f46b2SCy Schubert free(p->str2); 656865f46b2SCy Schubert free(p); 657865f46b2SCy Schubert p = np; 658865f46b2SCy Schubert } 659865f46b2SCy Schubert return 1; 660865f46b2SCy Schubert } 661865f46b2SCy Schubert 662865f46b2SCy Schubert /** read acl tag actions config for interface*/ 663865f46b2SCy Schubert static int 664865f46b2SCy Schubert read_acl_interface_tag_actions(struct acl_list* acl_interface, 665865f46b2SCy Schubert struct config_file* cfg, 666865f46b2SCy Schubert struct config_str3list** acl_tag_actions, int port) 667865f46b2SCy Schubert { 668865f46b2SCy Schubert struct config_str3list* p, *np; 669865f46b2SCy Schubert p = *acl_tag_actions; 670865f46b2SCy Schubert *acl_tag_actions = NULL; 671865f46b2SCy Schubert while(p) { 672865f46b2SCy Schubert char** resif = NULL; 673865f46b2SCy Schubert int num_resif = 0; 674865f46b2SCy Schubert int i; 675865f46b2SCy Schubert log_assert(p->str && p->str2 && p->str3); 676865f46b2SCy Schubert if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) { 677865f46b2SCy Schubert config_deltrplstrlist(p); 678865f46b2SCy Schubert return 0; 679865f46b2SCy Schubert } 680865f46b2SCy Schubert for(i = 0; i<num_resif; i++) { 681865f46b2SCy Schubert if(!acl_list_tag_action_cfg(acl_interface, cfg, 682865f46b2SCy Schubert resif[i], p->str2, p->str3, 1, port)) { 683865f46b2SCy Schubert config_deltrplstrlist(p); 684865f46b2SCy Schubert config_del_strarray(resif, num_resif); 685865f46b2SCy Schubert return 0; 686865f46b2SCy Schubert } 687865f46b2SCy Schubert } 688865f46b2SCy Schubert config_del_strarray(resif, num_resif); 689865f46b2SCy Schubert /* free the items as we go to free up memory */ 690865f46b2SCy Schubert np = p->next; 691865f46b2SCy Schubert free(p->str); 692865f46b2SCy Schubert free(p->str2); 693865f46b2SCy Schubert free(p->str3); 694865f46b2SCy Schubert free(p); 695865f46b2SCy Schubert p = np; 696865f46b2SCy Schubert } 697865f46b2SCy Schubert return 1; 698865f46b2SCy Schubert } 699865f46b2SCy Schubert 700865f46b2SCy Schubert /** read acl tag datas config for interface */ 701865f46b2SCy Schubert static int 702865f46b2SCy Schubert read_acl_interface_tag_datas(struct acl_list* acl_interface, 703865f46b2SCy Schubert struct config_file* cfg, 704865f46b2SCy Schubert struct config_str3list** acl_tag_datas, int port) 705865f46b2SCy Schubert { 706865f46b2SCy Schubert struct config_str3list* p, *np; 707865f46b2SCy Schubert p = *acl_tag_datas; 708865f46b2SCy Schubert *acl_tag_datas = NULL; 709865f46b2SCy Schubert while(p) { 710865f46b2SCy Schubert char** resif = NULL; 711865f46b2SCy Schubert int num_resif = 0; 712865f46b2SCy Schubert int i; 713865f46b2SCy Schubert log_assert(p->str && p->str2 && p->str3); 714865f46b2SCy Schubert if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) { 715865f46b2SCy Schubert config_deltrplstrlist(p); 716865f46b2SCy Schubert return 0; 717865f46b2SCy Schubert } 718865f46b2SCy Schubert for(i = 0; i<num_resif; i++) { 719865f46b2SCy Schubert if(!acl_list_tag_data_cfg(acl_interface, cfg, 720865f46b2SCy Schubert resif[i], p->str2, p->str3, 1, port)) { 721865f46b2SCy Schubert config_deltrplstrlist(p); 722865f46b2SCy Schubert config_del_strarray(resif, num_resif); 723865f46b2SCy Schubert return 0; 724865f46b2SCy Schubert } 725865f46b2SCy Schubert } 726865f46b2SCy Schubert config_del_strarray(resif, num_resif); 727865f46b2SCy Schubert /* free the items as we go to free up memory */ 728865f46b2SCy Schubert np = p->next; 729865f46b2SCy Schubert free(p->str); 730865f46b2SCy Schubert free(p->str2); 731865f46b2SCy Schubert free(p->str3); 732865f46b2SCy Schubert free(p); 733865f46b2SCy Schubert p = np; 734865f46b2SCy Schubert } 735865f46b2SCy Schubert return 1; 736865f46b2SCy Schubert } 737865f46b2SCy Schubert 738865f46b2SCy Schubert int 739865f46b2SCy Schubert acl_interface_apply_cfg(struct acl_list* acl_interface, struct config_file* cfg, 740865f46b2SCy Schubert struct views* v) 741865f46b2SCy Schubert { 742865f46b2SCy Schubert if(!read_acl_interface_action(acl_interface, cfg->interface_actions, 743865f46b2SCy Schubert cfg->port)) 744865f46b2SCy Schubert return 0; 745865f46b2SCy Schubert if(!read_acl_interface_view(acl_interface, &cfg->interface_view, v, 746865f46b2SCy Schubert cfg->port)) 747865f46b2SCy Schubert return 0; 748865f46b2SCy Schubert if(!read_acl_interface_tags(acl_interface, &cfg->interface_tags, 749865f46b2SCy Schubert cfg->port)) 750865f46b2SCy Schubert return 0; 751865f46b2SCy Schubert if(!read_acl_interface_tag_actions(acl_interface, cfg, 752865f46b2SCy Schubert &cfg->interface_tag_actions, cfg->port)) 753865f46b2SCy Schubert return 0; 754865f46b2SCy Schubert if(!read_acl_interface_tag_datas(acl_interface, cfg, 755865f46b2SCy Schubert &cfg->interface_tag_datas, cfg->port)) 756865f46b2SCy Schubert return 0; 757865f46b2SCy Schubert addr_tree_init_parents(&acl_interface->tree); 758865f46b2SCy Schubert return 1; 759865f46b2SCy Schubert } 760865f46b2SCy Schubert 761b7579f77SDag-Erling Smørgrav enum acl_access 762b5663de9SDag-Erling Smørgrav acl_get_control(struct acl_addr* acl) 763b5663de9SDag-Erling Smørgrav { 764b5663de9SDag-Erling Smørgrav if(acl) return acl->control; 765b5663de9SDag-Erling Smørgrav return acl_deny; 766b5663de9SDag-Erling Smørgrav } 767b5663de9SDag-Erling Smørgrav 768b5663de9SDag-Erling Smørgrav struct acl_addr* 769b5663de9SDag-Erling Smørgrav acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr, 770b7579f77SDag-Erling Smørgrav socklen_t addrlen) 771b7579f77SDag-Erling Smørgrav { 772b5663de9SDag-Erling Smørgrav return (struct acl_addr*)addr_tree_lookup(&acl->tree, 773b7579f77SDag-Erling Smørgrav addr, addrlen); 774b7579f77SDag-Erling Smørgrav } 775b7579f77SDag-Erling Smørgrav 776b7579f77SDag-Erling Smørgrav size_t 777b7579f77SDag-Erling Smørgrav acl_list_get_mem(struct acl_list* acl) 778b7579f77SDag-Erling Smørgrav { 779b7579f77SDag-Erling Smørgrav if(!acl) return 0; 780b7579f77SDag-Erling Smørgrav return sizeof(*acl) + regional_get_mem(acl->region); 781b7579f77SDag-Erling Smørgrav } 782a39a5a69SCy Schubert 783a39a5a69SCy Schubert const char* acl_access_to_str(enum acl_access acl) 784a39a5a69SCy Schubert { 785a39a5a69SCy Schubert switch(acl) { 786a39a5a69SCy Schubert case acl_deny: return "deny"; 787a39a5a69SCy Schubert case acl_refuse: return "refuse"; 788a39a5a69SCy Schubert case acl_deny_non_local: return "deny_non_local"; 789a39a5a69SCy Schubert case acl_refuse_non_local: return "refuse_non_local"; 790a39a5a69SCy Schubert case acl_allow: return "allow"; 791a39a5a69SCy Schubert case acl_allow_snoop: return "allow_snoop"; 792a39a5a69SCy Schubert case acl_allow_setrd: return "allow_setrd"; 793a39a5a69SCy Schubert default: break; 794a39a5a69SCy Schubert } 795a39a5a69SCy Schubert return "unknown"; 796a39a5a69SCy Schubert } 797a39a5a69SCy Schubert 798a39a5a69SCy Schubert void 799a39a5a69SCy Schubert log_acl_action(const char* action, struct sockaddr_storage* addr, 800a39a5a69SCy Schubert socklen_t addrlen, enum acl_access acl, struct acl_addr* acladdr) 801a39a5a69SCy Schubert { 802a39a5a69SCy Schubert char a[128], n[128]; 803a39a5a69SCy Schubert uint16_t port; 804a39a5a69SCy Schubert addr_to_str(addr, addrlen, a, sizeof(a)); 805a39a5a69SCy Schubert port = ntohs(((struct sockaddr_in*)addr)->sin_port); 806a39a5a69SCy Schubert if(acladdr) { 807a39a5a69SCy Schubert addr_to_str(&acladdr->node.addr, acladdr->node.addrlen, 808a39a5a69SCy Schubert n, sizeof(n)); 809a39a5a69SCy Schubert verbose(VERB_ALGO, "%s query from %s port %d because of " 810*be771a7bSCy Schubert "%s/%d %s%s", action, a, (int)port, n, 811*be771a7bSCy Schubert acladdr->node.net, 812*be771a7bSCy Schubert acladdr->is_interface?"(ACL on interface IP) ":"", 813a39a5a69SCy Schubert acl_access_to_str(acl)); 814a39a5a69SCy Schubert } else { 815a39a5a69SCy Schubert verbose(VERB_ALGO, "%s query from %s port %d", action, a, 816a39a5a69SCy Schubert (int)port); 817a39a5a69SCy Schubert } 818a39a5a69SCy Schubert } 819*be771a7bSCy Schubert 820*be771a7bSCy Schubert void acl_list_swap_tree(struct acl_list* acl, struct acl_list* data) 821*be771a7bSCy Schubert { 822*be771a7bSCy Schubert /* swap tree and region */ 823*be771a7bSCy Schubert rbtree_type oldtree = acl->tree; 824*be771a7bSCy Schubert struct regional* oldregion = acl->region; 825*be771a7bSCy Schubert acl->tree = data->tree; 826*be771a7bSCy Schubert acl->region = data->region; 827*be771a7bSCy Schubert data->tree = oldtree; 828*be771a7bSCy Schubert data->region = oldregion; 829*be771a7bSCy Schubert } 830