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