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