1/* 2 * ipsecmod/ipsecmod-whitelist.h - White listed domains for the ipsecmod to 3 * operate on. 4 * 5 * Copyright (c) 2017, NLnet Labs. All rights reserved. 6 * 7 * This software is open source. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * 16 * Redistributions in binary form must reproduce the above copyright notice, 17 * this list of conditions and the following disclaimer in the documentation 18 * and/or other materials provided with the distribution. 19 * 20 * Neither the name of the NLNET LABS nor the names of its contributors may 21 * be used to endorse or promote products derived from this software without 22 * specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 30 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36/** 37 * \file 38 * 39 * Keep track of the white listed domains for ipsecmod. 40 */ 41 42#include "config.h" 43 44#ifdef USE_IPSECMOD 45#include "ipsecmod/ipsecmod.h" 46#include "ipsecmod/ipsecmod-whitelist.h" 47#include "util/regional.h" 48#include "util/log.h" 49#include "util/config_file.h" 50#include "util/rbtree.h" 51#include "util/data/dname.h" 52#include "util/storage/dnstree.h" 53#include "sldns/str2wire.h" 54 55/** Apply ipsecmod-whitelist string. */ 56static int 57whitelist_str_cfg(rbtree_type* whitelist, const char* name) 58{ 59 struct name_tree_node* n; 60 size_t len; 61 uint8_t* nm = sldns_str2wire_dname(name, &len); 62 if(!nm) { 63 log_err("ipsecmod: could not parse %s for whitelist.", name); 64 return 0; 65 } 66 n = (struct name_tree_node*)calloc(1, sizeof(*n)); 67 if(!n) { 68 log_err("ipsecmod: out of memory while creating whitelist."); 69 free(nm); 70 return 0; 71 } 72 n->node.key = n; 73 n->name = nm; 74 n->len = len; 75 n->labs = dname_count_labels(nm); 76 n->dclass = LDNS_RR_CLASS_IN; 77 if(!name_tree_insert(whitelist, n, nm, len, n->labs, n->dclass)) { 78 /* duplicate element ignored, idempotent */ 79 free(n->name); 80 free(n); 81 } 82 return 1; 83} 84 85/** Read ipsecmod-whitelist config. */ 86static int 87read_whitelist(rbtree_type* whitelist, struct config_file* cfg) 88{ 89 struct config_strlist* p; 90 for(p = cfg->ipsecmod_whitelist; p; p = p->next) { 91 log_assert(p->str); 92 if(!whitelist_str_cfg(whitelist, p->str)) 93 return 0; 94 } 95 return 1; 96} 97 98int 99ipsecmod_whitelist_apply_cfg(struct ipsecmod_env* ie, 100 struct config_file* cfg) 101{ 102 ie->whitelist = rbtree_create(name_tree_compare); 103 if(!read_whitelist(ie->whitelist, cfg)) 104 return 0; 105 name_tree_init_parents(ie->whitelist); 106 return 1; 107} 108 109/** Delete ipsecmod_env->whitelist element. */ 110static void 111whitelist_free(struct rbnode_type* n, void* ATTR_UNUSED(d)) 112{ 113 if(n) { 114 free(((struct name_tree_node*)n)->name); 115 free(n); 116 } 117} 118 119/** Get memory usage of ipsecmod_env->whitelist element. */ 120static void 121whitelist_get_mem(struct rbnode_type* n, void* arg) 122{ 123 struct name_tree_node* node = (struct name_tree_node*)n; 124 size_t* size = (size_t*) arg; 125 if(node) { 126 *size += sizeof(node) + node->len; 127 } 128} 129 130void 131ipsecmod_whitelist_delete(rbtree_type* whitelist) 132{ 133 if(whitelist) { 134 traverse_postorder(whitelist, whitelist_free, NULL); 135 free(whitelist); 136 } 137} 138 139int 140ipsecmod_domain_is_whitelisted(struct ipsecmod_env* ie, uint8_t* dname, 141 size_t dname_len, uint16_t qclass) 142{ 143 if(!ie->whitelist) return 1; /* No whitelist, treat as whitelisted. */ 144 return name_tree_lookup(ie->whitelist, dname, dname_len, 145 dname_count_labels(dname), qclass) != NULL; 146} 147 148size_t 149ipsecmod_whitelist_get_mem(rbtree_type* whitelist) 150{ 151 size_t size = 0; 152 if(whitelist) { 153 traverse_postorder(whitelist, whitelist_get_mem, &size); 154 } 155 return size; 156} 157 158#endif /* USE_IPSECMOD */ 159