1250079Scarl/* 2250079Scarl * ipsecmod/ipsecmod-whitelist.h - White listed domains for the ipsecmod to 3250079Scarl * operate on. 4250079Scarl * 5250079Scarl * Copyright (c) 2017, NLnet Labs. All rights reserved. 6250079Scarl * 7250079Scarl * This software is open source. 8250079Scarl * 9250079Scarl * Redistribution and use in source and binary forms, with or without 10250079Scarl * modification, are permitted provided that the following conditions 11250079Scarl * are met: 12250079Scarl * 13250079Scarl * Redistributions of source code must retain the above copyright notice, 14250079Scarl * this list of conditions and the following disclaimer. 15250079Scarl * 16250079Scarl * Redistributions in binary form must reproduce the above copyright notice, 17250079Scarl * this list of conditions and the following disclaimer in the documentation 18250079Scarl * and/or other materials provided with the distribution. 19250079Scarl * 20250079Scarl * Neither the name of the NLNET LABS nor the names of its contributors may 21250079Scarl * be used to endorse or promote products derived from this software without 22250079Scarl * specific prior written permission. 23250079Scarl * 24250079Scarl * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25250079Scarl * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26250079Scarl * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27250079Scarl * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28250079Scarl * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29250079Scarl * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 30250079Scarl * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31250079Scarl * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32250079Scarl * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33250079Scarl * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34250079Scarl * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35250079Scarl */ 36250079Scarl/** 37250079Scarl * \file 38250079Scarl * 39250079Scarl * Keep track of the white listed domains for ipsecmod. 40250079Scarl */ 41250079Scarl 42250079Scarl#include "config.h" 43250079Scarl 44250079Scarl#ifdef USE_IPSECMOD 45250079Scarl#include "ipsecmod/ipsecmod.h" 46250079Scarl#include "ipsecmod/ipsecmod-whitelist.h" 47250079Scarl#include "util/regional.h" 48250079Scarl#include "util/log.h" 49250079Scarl#include "util/config_file.h" 50250079Scarl#include "util/rbtree.h" 51250079Scarl#include "util/data/dname.h" 52250079Scarl#include "util/storage/dnstree.h" 53250079Scarl#include "sldns/str2wire.h" 54250079Scarl 55250079Scarl/** Apply ipsecmod-whitelist string. */ 56250079Scarlstatic int 57250079Scarlwhitelist_str_cfg(rbtree_type* whitelist, const char* name) 58250079Scarl{ 59250079Scarl struct name_tree_node* n; 60250079Scarl size_t len; 61250079Scarl uint8_t* nm = sldns_str2wire_dname(name, &len); 62250079Scarl if(!nm) { 63250079Scarl log_err("ipsecmod: could not parse %s for whitelist.", name); 64250079Scarl return 0; 65250079Scarl } 66250079Scarl n = (struct name_tree_node*)calloc(1, sizeof(*n)); 67250079Scarl if(!n) { 68250079Scarl log_err("ipsecmod: out of memory while creating whitelist."); 69250079Scarl free(nm); 70250079Scarl return 0; 71250079Scarl } 72250079Scarl n->node.key = n; 73250079Scarl n->name = nm; 74250079Scarl n->len = len; 75250079Scarl n->labs = dname_count_labels(nm); 76250079Scarl n->dclass = LDNS_RR_CLASS_IN; 77250079Scarl if(!name_tree_insert(whitelist, n, nm, len, n->labs, n->dclass)) { 78250079Scarl /* duplicate element ignored, idempotent */ 79250079Scarl free(n->name); 80250079Scarl free(n); 81250079Scarl } 82250079Scarl return 1; 83250079Scarl} 84250079Scarl 85250079Scarl/** Read ipsecmod-whitelist config. */ 86250079Scarlstatic int 87250079Scarlread_whitelist(rbtree_type* whitelist, struct config_file* cfg) 88250079Scarl{ 89250079Scarl struct config_strlist* p; 90250079Scarl for(p = cfg->ipsecmod_whitelist; p; p = p->next) { 91250079Scarl log_assert(p->str); 92250079Scarl if(!whitelist_str_cfg(whitelist, p->str)) 93250079Scarl return 0; 94250079Scarl } 95250079Scarl return 1; 96250079Scarl} 97250079Scarl 98250079Scarlint 99250079Scarlipsecmod_whitelist_apply_cfg(struct ipsecmod_env* ie, 100250079Scarl struct config_file* cfg) 101250079Scarl{ 102250079Scarl ie->whitelist = rbtree_create(name_tree_compare); 103250079Scarl if(!read_whitelist(ie->whitelist, cfg)) 104250079Scarl return 0; 105250079Scarl name_tree_init_parents(ie->whitelist); 106250079Scarl return 1; 107255281Scarl} 108250079Scarl 109250079Scarl/** Delete ipsecmod_env->whitelist element. */ 110250079Scarlstatic void 111250079Scarlwhitelist_free(struct rbnode_type* n, void* ATTR_UNUSED(d)) 112250079Scarl{ 113250079Scarl if(n) { 114250079Scarl free(((struct name_tree_node*)n)->name); 115250079Scarl free(n); 116250079Scarl } 117250079Scarl} 118250079Scarl 119250079Scarl/** Get memory usage of ipsecmod_env->whitelist element. */ 120250079Scarlstatic void 121250079Scarlwhitelist_get_mem(struct rbnode_type* n, void* arg) 122250079Scarl{ 123250079Scarl struct name_tree_node* node = (struct name_tree_node*)n; 124250079Scarl size_t* size = (size_t*) arg; 125250079Scarl if(node) { 126250079Scarl *size += sizeof(node) + node->len; 127250079Scarl } 128250079Scarl} 129250079Scarl 130250079Scarlvoid 131250079Scarlipsecmod_whitelist_delete(rbtree_type* whitelist) 132250079Scarl{ 133250079Scarl if(whitelist) { 134250079Scarl traverse_postorder(whitelist, whitelist_free, NULL); 135250079Scarl free(whitelist); 136250079Scarl } 137250079Scarl} 138250079Scarl 139250079Scarlint 140250079Scarlipsecmod_domain_is_whitelisted(struct ipsecmod_env* ie, uint8_t* dname, 141250079Scarl size_t dname_len, uint16_t qclass) 142250079Scarl{ 143250079Scarl if(!ie->whitelist) return 1; /* No whitelist, treat as whitelisted. */ 144250079Scarl return name_tree_lookup(ie->whitelist, dname, dname_len, 145250079Scarl dname_count_labels(dname), qclass) != NULL; 146250079Scarl} 147250079Scarl 148250079Scarlsize_t 149250079Scarlipsecmod_whitelist_get_mem(rbtree_type* whitelist) 150250079Scarl{ 151250079Scarl size_t size = 0; 152250079Scarl if(whitelist) { 153250079Scarl traverse_postorder(whitelist, whitelist_get_mem, &size); 154250079Scarl } 155250079Scarl return size; 156250079Scarl} 157250079Scarl 158250079Scarl#endif /* USE_IPSECMOD */ 159250079Scarl