]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/charon/config/policies/local_policy_store.c
adapt evaltest to changed debug output
[thirdparty/strongswan.git] / src / charon / config / policies / local_policy_store.c
CommitLineData
13e4a62f
MW
1/**
2 * @file local_policy_store.c
60356f33 3 *
13e4a62f 4 * @brief Implementation of local_policy_store_t.
60356f33 5 *
13e4a62f
MW
6 */
7
8/*
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
5238c9af
MW
23#include <string.h>
24
13e4a62f
MW
25#include "local_policy_store.h"
26
60356f33 27#include <daemon.h>
13e4a62f 28#include <utils/linked_list.h>
13e4a62f
MW
29
30
31typedef struct private_local_policy_store_t private_local_policy_store_t;
32
33/**
34 * Private data of an local_policy_store_t object
35 */
36struct private_local_policy_store_t {
37
38 /**
39 * Public part
40 */
41 local_policy_store_t public;
42
43 /**
44 * list of policy_t's
45 */
46 linked_list_t *policies;
47
9fe14f4b
MW
48 /**
49 * Mutex to exclusivly access list
50 */
51 pthread_mutex_t mutex;
13e4a62f
MW
52};
53
54/**
55 * Implementation of policy_store_t.add_policy.
56 */
57static void add_policy(private_local_policy_store_t *this, policy_t *policy)
58{
9fe14f4b 59 pthread_mutex_lock(&(this->mutex));
13e4a62f 60 this->policies->insert_last(this->policies, (void*)policy);
9fe14f4b 61 pthread_mutex_unlock(&(this->mutex));
13e4a62f
MW
62}
63
13e4a62f 64/**
8dfbe71b 65 * Check if a policy contains traffic selectors
13e4a62f 66 */
8dfbe71b
MW
67static bool contains_traffic_selectors(policy_t *policy, bool mine,
68 linked_list_t *ts, host_t *host)
69{
70 linked_list_t *selected;
71 bool contains = FALSE;
8dfbe71b
MW
72
73 if (mine)
74 {
75 selected = policy->select_my_traffic_selectors(policy, ts, host);
76 }
77 else
78 {
79 selected = policy->select_other_traffic_selectors(policy, ts, host);
80 }
81 if (selected->get_count(selected))
82 {
83 contains = TRUE;
84 }
55bbff11 85 selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy));
8dfbe71b
MW
86 return contains;
87}
88
89/**
90 * Implementation of policy_store_t.get_policy.
91 */
92static policy_t *get_policy(private_local_policy_store_t *this,
93 identification_t *my_id, identification_t *other_id,
94 linked_list_t *my_ts, linked_list_t *other_ts,
f27f6296 95 host_t *my_host, host_t *other_host)
13e4a62f 96{
9fe14f4b 97 typedef enum {
c361cc8c 98 PRIO_UNDEFINED = 0x00,
0cde6c41
MW
99 PRIO_TS_MISMATCH = 0x01,
100 PRIO_ID_ANY = 0x02,
c361cc8c 101 PRIO_ID_MATCH = PRIO_ID_ANY + MAX_WILDCARDS,
9fe14f4b
MW
102 } prio_t;
103
104 prio_t best_prio = PRIO_UNDEFINED;
105
13e4a62f 106 iterator_t *iterator;
9fe14f4b
MW
107 policy_t *candidate;
108 policy_t *found = NULL;
0cde6c41 109 traffic_selector_t *ts;
13e4a62f 110
0cde6c41
MW
111 DBG1(DBG_CFG, "searching policy for '%D'...'%D'", my_id, other_id);
112 iterator = my_ts->create_iterator(my_ts, TRUE);
113 while (iterator->iterate(iterator, (void**)&ts))
114 {
115 DBG1(DBG_CFG, " local TS: %R", ts);
116 }
117 iterator->destroy(iterator);
118 iterator = other_ts->create_iterator(other_ts, TRUE);
119 while (iterator->iterate(iterator, (void**)&ts))
120 {
121 DBG1(DBG_CFG, " remote TS: %R", ts);
122 }
123 iterator->destroy(iterator);
9fe14f4b
MW
124
125 pthread_mutex_lock(&(this->mutex));
13e4a62f 126 iterator = this->policies->create_iterator(this->policies, TRUE);
c361cc8c 127
9fe14f4b 128 /* determine closest matching policy */
191a26a6 129 while (iterator->iterate(iterator, (void**)&candidate))
13e4a62f 130 {
9fe14f4b
MW
131 identification_t *candidate_my_id;
132 identification_t *candidate_other_id;
c361cc8c 133 int wildcards;
9fe14f4b
MW
134
135 candidate_my_id = candidate->get_my_id(candidate);
136 candidate_other_id = candidate->get_other_id(candidate);
137
c361cc8c
AS
138 /* my_id is either %any or if set must match exactly */
139 if (candidate_my_id->matches(candidate_my_id, my_id, &wildcards))
13e4a62f 140 {
9fe14f4b
MW
141 prio_t prio = PRIO_UNDEFINED;
142
c361cc8c 143 /* wildcard match for other_id */
02b3101b 144 if (!other_id->matches(other_id, candidate_other_id, &wildcards))
9fe14f4b 145 {
02b3101b 146 continue;
9fe14f4b 147 }
02b3101b 148 prio = PRIO_ID_MATCH - wildcards;
8dfbe71b
MW
149
150 /* only accept if traffic selectors match */
151 if (!contains_traffic_selectors(candidate, TRUE, my_ts, my_host) ||
152 !contains_traffic_selectors(candidate, FALSE, other_ts, other_host))
153 {
b83806d8 154 DBG2(DBG_CFG, "candidate '%s' inacceptable due traffic "
60356f33 155 "selector mismatch", candidate->get_name(candidate));
0cde6c41 156 prio = PRIO_TS_MISMATCH;
8dfbe71b 157 }
9fe14f4b 158
1f916061 159 DBG2(DBG_CFG, "candidate policy '%s': '%D'...'%D' (prio=%d)",
60356f33
MW
160 candidate->get_name(candidate),
161 candidate_my_id, candidate_other_id, prio);
9fe14f4b
MW
162
163 if (prio > best_prio)
164 {
165 found = candidate;
166 best_prio = prio;
167 }
13e4a62f
MW
168 }
169 }
170 iterator->destroy(iterator);
171
13e4a62f
MW
172 if (found)
173 {
1f916061 174 DBG1(DBG_CFG, "found matching policy '%s': '%D'...'%D' (prio=%d)",
db7ef624
MW
175 found->get_name(found), found->get_my_id(found),
176 found->get_other_id(found), best_prio);
8dfbe71b
MW
177 /* give out a new reference to it */
178 found->get_ref(found);
9fe14f4b
MW
179 }
180 pthread_mutex_unlock(&(this->mutex));
181 return found;
182}
183
184/**
185 * Implementation of policy_store_t.get_policy_by_name.
186 */
187static policy_t *get_policy_by_name(private_local_policy_store_t *this, char *name)
188{
189 iterator_t *iterator;
190 policy_t *current, *found = NULL;
191
b83806d8 192 DBG2(DBG_CFG, "looking for policy '%s'", name);
9fe14f4b
MW
193
194 pthread_mutex_lock(&(this->mutex));
195 iterator = this->policies->create_iterator(this->policies, TRUE);
191a26a6 196 while (iterator->iterate(iterator, (void **)&current))
9fe14f4b 197 {
9fe14f4b
MW
198 if (strcmp(current->get_name(current), name) == 0)
199 {
8dfbe71b 200 found = current;
9fe14f4b 201 }
13e4a62f 202 }
9fe14f4b
MW
203 iterator->destroy(iterator);
204 pthread_mutex_unlock(&(this->mutex));
205
8dfbe71b
MW
206 /* give out a new reference */
207 found->get_ref(found);
13e4a62f
MW
208 return found;
209}
210
9fe14f4b
MW
211/**
212 * Implementation of policy_store_t.delete_policy.
213 */
214static status_t delete_policy(private_local_policy_store_t *this, char *name)
215{
216 iterator_t *iterator;
217 policy_t *current;
218 bool found = FALSE;
219
220 pthread_mutex_lock(&(this->mutex));
221 iterator = this->policies->create_iterator(this->policies, TRUE);
191a26a6 222 while (iterator->iterate(iterator, (void **)&current))
9fe14f4b 223 {
9fe14f4b
MW
224 if (strcmp(current->get_name(current), name) == 0)
225 {
226 /* remove policy from list, and destroy it */
227 iterator->remove(iterator);
228 current->destroy(current);
229 found = TRUE;
230 /* we do not break here, as there may be multipe policies */
231 }
232 }
233 iterator->destroy(iterator);
234 pthread_mutex_unlock(&(this->mutex));
235 if (found)
236 {
237 return SUCCESS;
238 }
239 return NOT_FOUND;
240}
241
60356f33
MW
242/**
243 * Implementation of policy_store_t.create_iterator.
244 */
245static iterator_t* create_iterator(private_local_policy_store_t *this)
246{
247 return this->policies->create_iterator_locked(this->policies,
248 &this->mutex);
249}
250
13e4a62f
MW
251/**
252 * Implementation of policy_store_t.destroy.
253 */
254static void destroy(private_local_policy_store_t *this)
255{
9fe14f4b 256 pthread_mutex_lock(&(this->mutex));
55bbff11 257 this->policies->destroy_offset(this->policies, offsetof(policy_t, destroy));
9fe14f4b 258 pthread_mutex_unlock(&(this->mutex));
13e4a62f
MW
259 free(this);
260}
261
262/**
263 * Described in header.
264 */
f768bdc3 265local_policy_store_t *local_policy_store_create(void)
13e4a62f
MW
266{
267 private_local_policy_store_t *this = malloc_thing(private_local_policy_store_t);
268
29137c0c
AS
269 this->public.policy_store.add_policy = (void (*) (policy_store_t*,policy_t*))add_policy;
270 this->public.policy_store.get_policy = (policy_t* (*) (policy_store_t*,identification_t*,identification_t*,
f27f6296 271 linked_list_t*,linked_list_t*,host_t*,host_t*))get_policy;
29137c0c
AS
272 this->public.policy_store.get_policy_by_name = (policy_t* (*) (policy_store_t*,char*))get_policy_by_name;
273 this->public.policy_store.delete_policy = (status_t (*) (policy_store_t*,char*))delete_policy;
274 this->public.policy_store.create_iterator = (iterator_t* (*) (policy_store_t*))create_iterator;
275 this->public.policy_store.destroy = (void (*) (policy_store_t*))destroy;
13e4a62f
MW
276
277 /* private variables */
278 this->policies = linked_list_create();
9fe14f4b 279 pthread_mutex_init(&(this->mutex), NULL);
13e4a62f
MW
280
281 return (&this->public);
282}