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. */ 56 static int 57 whitelist_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. */ 86 static int 87 read_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 98 int 99 ipsecmod_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. */ 110 static void 111 whitelist_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. */ 120 static void 121 whitelist_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 130 void 131 ipsecmod_whitelist_delete(rbtree_type* whitelist) 132 { 133 if(whitelist) { 134 traverse_postorder(whitelist, whitelist_free, NULL); 135 free(whitelist); 136 } 137 } 138 139 int 140 ipsecmod_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 148 size_t 149 ipsecmod_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