1933707f3Ssthen /* 2933707f3Ssthen * daemon/acl_list.h - client access control storage for the server. 3933707f3Ssthen * 4933707f3Ssthen * Copyright (c) 2007, NLnet Labs. All rights reserved. 5933707f3Ssthen * 6933707f3Ssthen * This software is open source. 7933707f3Ssthen * 8933707f3Ssthen * Redistribution and use in source and binary forms, with or without 9933707f3Ssthen * modification, are permitted provided that the following conditions 10933707f3Ssthen * are met: 11933707f3Ssthen * 12933707f3Ssthen * Redistributions of source code must retain the above copyright notice, 13933707f3Ssthen * this list of conditions and the following disclaimer. 14933707f3Ssthen * 15933707f3Ssthen * Redistributions in binary form must reproduce the above copyright notice, 16933707f3Ssthen * this list of conditions and the following disclaimer in the documentation 17933707f3Ssthen * and/or other materials provided with the distribution. 18933707f3Ssthen * 19933707f3Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 20933707f3Ssthen * be used to endorse or promote products derived from this software without 21933707f3Ssthen * specific prior written permission. 22933707f3Ssthen * 23933707f3Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 245d76a658Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 255d76a658Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 265d76a658Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 275d76a658Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 285d76a658Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 295d76a658Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 305d76a658Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 315d76a658Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 325d76a658Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 335d76a658Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34933707f3Ssthen */ 35933707f3Ssthen 36933707f3Ssthen /** 37933707f3Ssthen * \file 38933707f3Ssthen * 39933707f3Ssthen * This file keeps track of the list of clients that are allowed to 40933707f3Ssthen * access the server. 41933707f3Ssthen */ 42933707f3Ssthen 43933707f3Ssthen #ifndef DAEMON_ACL_LIST_H 44933707f3Ssthen #define DAEMON_ACL_LIST_H 45933707f3Ssthen #include "util/storage/dnstree.h" 4677079be7Ssthen #include "services/view.h" 47933707f3Ssthen struct config_file; 48933707f3Ssthen struct regional; 49933707f3Ssthen 50933707f3Ssthen /** 51933707f3Ssthen * Enumeration of access control options for an address range. 52933707f3Ssthen * Allow or deny access. 53933707f3Ssthen */ 54933707f3Ssthen enum acl_access { 55933707f3Ssthen /** disallow any access whatsoever, drop it */ 56933707f3Ssthen acl_deny = 0, 57933707f3Ssthen /** disallow access, send a polite 'REFUSED' reply */ 58933707f3Ssthen acl_refuse, 595d76a658Ssthen /** disallow any access to zones that aren't local, drop it */ 605d76a658Ssthen acl_deny_non_local, 615d76a658Ssthen /** disallow access to zones that aren't local, 'REFUSED' reply */ 625d76a658Ssthen acl_refuse_non_local, 63933707f3Ssthen /** allow full access for recursion (+RD) queries */ 64933707f3Ssthen acl_allow, 65933707f3Ssthen /** allow full access for all queries, recursion and cache snooping */ 6620237c55Ssthen acl_allow_snoop, 67*8b7325afSsthen /** allow full access for recursion queries and set RD flag regardless 68*8b7325afSsthen * of request */ 69*8b7325afSsthen acl_allow_setrd, 70*8b7325afSsthen /** allow full access for recursion (+RD) queries if valid cookie 71*8b7325afSsthen * present or stateful transport */ 72*8b7325afSsthen acl_allow_cookie 73933707f3Ssthen }; 74933707f3Ssthen 75933707f3Ssthen /** 76933707f3Ssthen * Access control storage structure 77933707f3Ssthen */ 78933707f3Ssthen struct acl_list { 79933707f3Ssthen /** regional for allocation */ 80933707f3Ssthen struct regional* region; 81933707f3Ssthen /** 82933707f3Ssthen * Tree of the addresses that are allowed/blocked. 83933707f3Ssthen * contents of type acl_addr. 84933707f3Ssthen */ 8577079be7Ssthen rbtree_type tree; 86933707f3Ssthen }; 87933707f3Ssthen 88933707f3Ssthen /** 89933707f3Ssthen * 90933707f3Ssthen * An address span with access control information 91933707f3Ssthen */ 92933707f3Ssthen struct acl_addr { 93933707f3Ssthen /** node in address tree */ 94933707f3Ssthen struct addr_tree_node node; 95933707f3Ssthen /** access control on this netblock */ 96933707f3Ssthen enum acl_access control; 9777079be7Ssthen /** tag bitlist */ 9877079be7Ssthen uint8_t* taglist; 9977079be7Ssthen /** length of the taglist (in bytes) */ 10077079be7Ssthen size_t taglen; 10177079be7Ssthen /** array per tagnumber of localzonetype(in one byte). NULL if none. */ 10277079be7Ssthen uint8_t* tag_actions; 10377079be7Ssthen /** size of the tag_actions_array */ 10477079be7Ssthen size_t tag_actions_size; 10577079be7Ssthen /** array per tagnumber, with per tag a list of rdata strings. 10677079be7Ssthen * NULL if none. strings are like 'A 127.0.0.1' 'AAAA ::1' */ 10777079be7Ssthen struct config_strlist** tag_datas; 10877079be7Ssthen /** size of the tag_datas array */ 10977079be7Ssthen size_t tag_datas_size; 11077079be7Ssthen /* view element, NULL if none */ 11177079be7Ssthen struct view* view; 112933707f3Ssthen }; 113933707f3Ssthen 114933707f3Ssthen /** 115933707f3Ssthen * Create acl structure 116933707f3Ssthen * @return new structure or NULL on error. 117933707f3Ssthen */ 118933707f3Ssthen struct acl_list* acl_list_create(void); 119933707f3Ssthen 120933707f3Ssthen /** 121933707f3Ssthen * Delete acl structure. 122933707f3Ssthen * @param acl: to delete. 123933707f3Ssthen */ 124933707f3Ssthen void acl_list_delete(struct acl_list* acl); 125933707f3Ssthen 126933707f3Ssthen /** 12745872187Ssthen * Insert interface in the acl_list. This should happen when the listening 12845872187Ssthen * interface is setup. 12945872187Ssthen * @param acl_interface: acl_list to insert to. 13045872187Ssthen * @param addr: interface IP. 13145872187Ssthen * @param addrlen: length of the interface IP. 13245872187Ssthen * @param control: acl_access. 13345872187Ssthen * @return new structure or NULL on error. 13445872187Ssthen */ 13545872187Ssthen struct acl_addr* 13645872187Ssthen acl_interface_insert(struct acl_list* acl_interface, 13745872187Ssthen struct sockaddr_storage* addr, socklen_t addrlen, 13845872187Ssthen enum acl_access control); 13945872187Ssthen 14045872187Ssthen /** 141933707f3Ssthen * Process access control config. 142933707f3Ssthen * @param acl: where to store. 143933707f3Ssthen * @param cfg: config options. 14477079be7Ssthen * @param v: views structure 145933707f3Ssthen * @return 0 on error. 146933707f3Ssthen */ 14777079be7Ssthen int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg, 14877079be7Ssthen struct views* v); 149933707f3Ssthen 15045872187Ssthen /** compare ACL interface "addr_tree" nodes (+port) */ 15145872187Ssthen int acl_interface_compare(const void* k1, const void* k2); 15245872187Ssthen 15345872187Ssthen /** 15445872187Ssthen * Initialise (also clean) the acl_interface struct. 15545872187Ssthen * @param acl_interface: where to store. 15645872187Ssthen */ 15745872187Ssthen void acl_interface_init(struct acl_list* acl_interface); 15845872187Ssthen 15945872187Ssthen /** 16045872187Ssthen * Process interface control config. 16145872187Ssthen * @param acl_interface: where to store. 16245872187Ssthen * @param cfg: config options. 16345872187Ssthen * @param v: views structure 16445872187Ssthen * @return 0 on error. 16545872187Ssthen */ 16645872187Ssthen int acl_interface_apply_cfg(struct acl_list* acl_interface, struct config_file* cfg, 16745872187Ssthen struct views* v); 16845872187Ssthen 169933707f3Ssthen /** 17077079be7Ssthen * Lookup access control status for acl structure. 17177079be7Ssthen * @param acl: structure for acl storage. 17277079be7Ssthen * @return: what to do with message from this address. 17377079be7Ssthen */ 17477079be7Ssthen enum acl_access acl_get_control(struct acl_addr* acl); 17577079be7Ssthen 17677079be7Ssthen /** 17777079be7Ssthen * Lookup address to see its acl structure 178933707f3Ssthen * @param acl: structure for address storage. 179933707f3Ssthen * @param addr: address to check 180933707f3Ssthen * @param addrlen: length of addr. 18177079be7Ssthen * @return: acl structure from this address. 182933707f3Ssthen */ 18377079be7Ssthen struct acl_addr* 18477079be7Ssthen acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr, 18577079be7Ssthen socklen_t addrlen); 186933707f3Ssthen 187933707f3Ssthen /** 188933707f3Ssthen * Get memory used by acl structure. 189933707f3Ssthen * @param acl: structure for address storage. 190933707f3Ssthen * @return bytes in use. 191933707f3Ssthen */ 192933707f3Ssthen size_t acl_list_get_mem(struct acl_list* acl); 193933707f3Ssthen 1940bdb4f62Ssthen /* 1950bdb4f62Ssthen * Get string for acl access specification 1960bdb4f62Ssthen * @param acl: access type value 1970bdb4f62Ssthen * @return string 1980bdb4f62Ssthen */ 1990bdb4f62Ssthen const char* acl_access_to_str(enum acl_access acl); 2000bdb4f62Ssthen 2010bdb4f62Ssthen /* log acl and addr for action */ 2020bdb4f62Ssthen void log_acl_action(const char* action, struct sockaddr_storage* addr, 2030bdb4f62Ssthen socklen_t addrlen, enum acl_access acl, struct acl_addr* acladdr); 2040bdb4f62Ssthen 205933707f3Ssthen #endif /* DAEMON_ACL_LIST_H */ 206