]> git.ipfire.org Git - thirdparty/strongswan.git/blame - programs/charon/charon/config/policies/policy.c
- import of strongswan-2.7.0
[thirdparty/strongswan.git] / programs / charon / charon / config / policies / policy.c
CommitLineData
d45ec1de 1/**
16b9a73c 2 * @file policy.c
d45ec1de 3 *
16b9a73c 4 * @brief Implementation of policy_t.
d45ec1de
MW
5 *
6 */
7
8/*
9 * Copyright (C) 2005 Jan Hutter, 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
16b9a73c 23#include "policy.h"
d45ec1de
MW
24
25#include <utils/linked_list.h>
ca060d4c 26#include <utils/identification.h>
7fa8decb 27#include <utils/logger.h>
d45ec1de 28
16b9a73c 29typedef struct private_policy_t private_policy_t;
d45ec1de
MW
30
31/**
16b9a73c 32 * Private data of an policy_t object
d45ec1de 33 */
16b9a73c 34struct private_policy_t {
d45ec1de
MW
35
36 /**
37 * Public part
38 */
16b9a73c 39 policy_t public;
d45ec1de
MW
40
41 /**
42 * id to use to identify us
43 */
44 identification_t *my_id;
45
46 /**
47 * allowed id for other
48 */
49 identification_t *other_id;
50
d45ec1de
MW
51 /**
52 * list for all proposals
53 */
54 linked_list_t *proposals;
55
56 /**
a527a426 57 * list for traffic selectors for my site
d45ec1de 58 */
a527a426 59 linked_list_t *my_ts;
257fa503
MW
60
61 /**
a527a426 62 * list for traffic selectors for others site
257fa503 63 */
a527a426 64 linked_list_t *other_ts;
257fa503
MW
65
66 /**
67 * select_traffic_selectors for both
68 */
16b9a73c 69 linked_list_t *(*select_traffic_selectors) (private_policy_t *,linked_list_t*,linked_list_t*);
d45ec1de
MW
70};
71
ca060d4c 72/**
16b9a73c 73 * Implementation of policy_t.get_my_id
ca060d4c 74 */
16b9a73c 75static identification_t *get_my_id(private_policy_t *this)
d45ec1de
MW
76{
77 return this->my_id;
78}
79
ca060d4c 80/**
16b9a73c 81 * Implementation of policy_t.get_other_id
ca060d4c 82 */
16b9a73c 83static identification_t *get_other_id(private_policy_t *this)
d45ec1de
MW
84{
85 return this->other_id;
86}
87
87a217f9
MW
88/**
89 * Implementation of policy_t.update_my_id
90 */
91static void update_my_id(private_policy_t *this, identification_t *my_id)
92{
93 this->my_id->destroy(this->my_id);
94 this->my_id = my_id;
95}
96
97/**
98 * Implementation of policy_t.update_other_id
99 */
100static void update_other_id(private_policy_t *this, identification_t *other_id)
101{
102 this->other_id->destroy(this->other_id);
103 this->other_id = other_id;
104}
105
106/**
107 * Helper function which does the work for policy_t.update_my_ts and update_other_ts
108 */
109static void update_ts(linked_list_t* list, host_t *new_host)
110{
111 traffic_selector_t *ts;
112 iterator_t *iterator;
113
114 iterator = list->create_iterator(list, TRUE);
115 while (iterator->has_next(iterator))
116 {
117 iterator->current(iterator, (void**)&ts);
118 ts->update_address_range(ts, new_host);
119 }
120 iterator->destroy(iterator);
121}
122
123/**
124 * Implementation of policy_t.update_my_id
125 */
126static void update_my_ts(private_policy_t *this, host_t *my_host)
127{
128 update_ts(this->my_ts, my_host);
129}
130
131/**
132 * Implementation of policy_t.update_other_ts
133 */
134static void update_other_ts(private_policy_t *this, host_t *my_host)
135{
136 update_ts(this->other_ts, my_host);
137}
138
ca060d4c 139/**
16b9a73c 140 * Implementation of policy_t.get_my_traffic_selectors
ca060d4c 141 */
16b9a73c 142static linked_list_t *get_my_traffic_selectors(private_policy_t *this)
257fa503 143{
a527a426 144 return this->my_ts;
257fa503
MW
145}
146
147/**
16b9a73c 148 * Implementation of policy_t.get_other_traffic_selectors
257fa503 149 */
16b9a73c 150static linked_list_t *get_other_traffic_selectors(private_policy_t *this, traffic_selector_t **traffic_selectors[])
257fa503 151{
a527a426 152 return this->other_ts;
d45ec1de
MW
153}
154
ca060d4c 155/**
16b9a73c 156 * Implementation of private_policy_t.select_my_traffic_selectors
ca060d4c 157 */
16b9a73c 158static linked_list_t *select_my_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
257fa503 159{
a527a426 160 return this->select_traffic_selectors(this, this->my_ts, supplied);
257fa503
MW
161}
162
163/**
16b9a73c 164 * Implementation of private_policy_t.select_other_traffic_selectors
257fa503 165 */
16b9a73c 166static linked_list_t *select_other_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
257fa503 167{
a527a426 168 return this->select_traffic_selectors(this, this->other_ts, supplied);
257fa503
MW
169}
170/**
16b9a73c 171 * Implementation of private_policy_t.select_traffic_selectors
257fa503 172 */
16b9a73c 173static linked_list_t *select_traffic_selectors(private_policy_t *this, linked_list_t *stored, linked_list_t *supplied)
d45ec1de 174{
a527a426
MW
175 iterator_t *supplied_iter, *stored_iter;
176 traffic_selector_t *supplied_ts, *stored_ts, *selected_ts;
177 linked_list_t *selected = linked_list_create();
178
d45ec1de 179
a527a426
MW
180 stored_iter = stored->create_iterator(stored, TRUE);
181 supplied_iter = supplied->create_iterator(supplied, TRUE);
182
183 /* iterate over all stored selectors */
184 while (stored_iter->has_next(stored_iter))
d45ec1de 185 {
a527a426
MW
186 stored_iter->current(stored_iter, (void**)&stored_ts);
187
188 supplied_iter->reset(supplied_iter);
189 /* iterate over all supplied traffic selectors */
190 while (supplied_iter->has_next(supplied_iter))
d45ec1de 191 {
a527a426
MW
192 supplied_iter->current(supplied_iter, (void**)&supplied_ts);
193
194 selected_ts = stored_ts->get_subset(stored_ts, supplied_ts);
195 if (selected_ts)
d45ec1de 196 {
a527a426
MW
197 /* got a match, add to list */
198 selected->insert_last(selected, (void*)selected_ts);
d45ec1de
MW
199 }
200 }
201 }
a527a426
MW
202 stored_iter->destroy(stored_iter);
203 supplied_iter->destroy(supplied_iter);
d45ec1de 204
a527a426 205 return selected;
d45ec1de 206}
ca060d4c
MW
207
208/**
16b9a73c 209 * Implementation of policy_t.get_proposal_iterator
ca060d4c 210 */
16b9a73c 211static linked_list_t *get_proposals(private_policy_t *this)
d45ec1de 212{
c06dbbab 213 return this->proposals;
d45ec1de
MW
214}
215
ca060d4c 216/**
16b9a73c 217 * Implementation of policy_t.select_proposal
ca060d4c 218 */
16b9a73c 219static proposal_t *select_proposal(private_policy_t *this, linked_list_t *proposals)
d45ec1de 220{
384efc76 221 iterator_t *stored_iter, *supplied_iter;
ce461bbd 222 proposal_t *stored, *supplied, *selected;
7fa8decb 223
384efc76
MW
224 stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
225 supplied_iter = proposals->create_iterator(proposals, TRUE);
d45ec1de 226
384efc76
MW
227 /* compare all stored proposals with all supplied. Stored ones are preferred. */
228 while (stored_iter->has_next(stored_iter))
d45ec1de 229 {
384efc76
MW
230 supplied_iter->reset(supplied_iter);
231 stored_iter->current(stored_iter, (void**)&stored);
7fa8decb 232
384efc76
MW
233 while (supplied_iter->has_next(supplied_iter))
234 {
235 supplied_iter->current(supplied_iter, (void**)&supplied);
236 selected = stored->select(stored, supplied);
237 if (selected)
d45ec1de 238 {
384efc76
MW
239 /* they match, return */
240 stored_iter->destroy(stored_iter);
241 supplied_iter->destroy(supplied_iter);
242 return selected;
d45ec1de
MW
243 }
244 }
245 }
ccf783d2 246
384efc76
MW
247 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
248 stored_iter->destroy(stored_iter);
249 supplied_iter->destroy(supplied_iter);
ca060d4c 250
384efc76 251 return NULL;
d45ec1de 252}
ca060d4c
MW
253
254/**
16b9a73c 255 * Implementation of policy_t.add_my_traffic_selector
ca060d4c 256 */
16b9a73c 257static void add_my_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector)
d45ec1de 258{
a527a426 259 this->my_ts->insert_last(this->my_ts, (void*)traffic_selector);
257fa503
MW
260}
261
262/**
16b9a73c 263 * Implementation of policy_t.add_other_traffic_selector
257fa503 264 */
16b9a73c 265static void add_other_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector)
257fa503 266{
a527a426 267 this->other_ts->insert_last(this->other_ts, (void*)traffic_selector);
d45ec1de
MW
268}
269
ca060d4c 270/**
16b9a73c 271 * Implementation of policy_t.add_proposal
ca060d4c 272 */
16b9a73c 273static void add_proposal(private_policy_t *this, proposal_t *proposal)
d45ec1de 274{
384efc76 275 this->proposals->insert_last(this->proposals, (void*)proposal);
d45ec1de
MW
276}
277
278/**
16b9a73c 279 * Implements policy_t.destroy.
d45ec1de 280 */
16b9a73c 281static status_t destroy(private_policy_t *this)
d45ec1de 282{
ce461bbd 283 proposal_t *proposal;
d45ec1de
MW
284 traffic_selector_t *traffic_selector;
285
ca060d4c 286
d45ec1de 287 /* delete proposals */
dfa6e086 288 while(this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS)
d45ec1de 289 {
384efc76 290 proposal->destroy(proposal);
d45ec1de
MW
291 }
292 this->proposals->destroy(this->proposals);
293
294 /* delete traffic selectors */
a527a426 295 while(this->my_ts->remove_last(this->my_ts, (void**)&traffic_selector) == SUCCESS)
257fa503 296 {
257fa503
MW
297 traffic_selector->destroy(traffic_selector);
298 }
a527a426 299 this->my_ts->destroy(this->my_ts);
257fa503
MW
300
301 /* delete traffic selectors */
a527a426 302 while(this->other_ts->remove_last(this->other_ts, (void**)&traffic_selector) == SUCCESS)
d45ec1de 303 {
712db4bf 304 traffic_selector->destroy(traffic_selector);
d45ec1de 305 }
a527a426 306 this->other_ts->destroy(this->other_ts);
d45ec1de 307
ca060d4c
MW
308 /* delete ids */
309 this->my_id->destroy(this->my_id);
310 this->other_id->destroy(this->other_id);
311
5113680f 312 free(this);
d45ec1de
MW
313 return SUCCESS;
314}
315
87a217f9
MW
316/**
317 * Implements policy_t.clone.
318 */
319static policy_t *clone(private_policy_t *this)
320{
321 private_policy_t *clone = (private_policy_t*)policy_create(this->my_id->clone(this->my_id),
322 this->other_id->clone(this->other_id));
323 iterator_t *iterator;
324 proposal_t *proposal;
325 traffic_selector_t *ts;
326
327 /* clone all proposals */
328 iterator = this->proposals->create_iterator(this->proposals, TRUE);
329 while (iterator->has_next(iterator))
330 {
331 iterator->current(iterator, (void**)&proposal);
332 proposal = proposal->clone(proposal);
333 clone->proposals->insert_last(clone->proposals, (void*)proposal);
334 }
335 iterator->destroy(iterator);
336
337 /* clone all local traffic selectors */
338 iterator = this->my_ts->create_iterator(this->my_ts, TRUE);
339 while (iterator->has_next(iterator))
340 {
341 iterator->current(iterator, (void**)&ts);
342 ts = ts->clone(ts);
343 clone->my_ts->insert_last(clone->my_ts, (void*)ts);
344 }
345 iterator->destroy(iterator);
346
347 /* clone all remote traffic selectors */
348 iterator = this->other_ts->create_iterator(this->other_ts, TRUE);
349 while (iterator->has_next(iterator))
350 {
351 iterator->current(iterator, (void**)&ts);
352 ts = ts->clone(ts);
353 clone->other_ts->insert_last(clone->other_ts, (void*)ts);
354 }
355 iterator->destroy(iterator);
356
357 return &clone->public;
358}
359
d45ec1de
MW
360/*
361 * Described in header-file
362 */
16b9a73c 363policy_t *policy_create(identification_t *my_id, identification_t *other_id)
d45ec1de 364{
5113680f 365 private_policy_t *this = malloc_thing(private_policy_t);
d45ec1de
MW
366
367 /* public functions */
16b9a73c
MW
368 this->public.get_my_id = (identification_t*(*)(policy_t*))get_my_id;
369 this->public.get_other_id = (identification_t*(*)(policy_t*))get_other_id;
87a217f9
MW
370 this->public.update_my_id = (void(*)(policy_t*,identification_t*))update_my_id;
371 this->public.update_other_id = (void(*)(policy_t*,identification_t*))update_other_id;
372 this->public.update_my_ts = (void(*)(policy_t*,host_t*))update_my_ts;
373 this->public.update_other_ts = (void(*)(policy_t*,host_t*))update_other_ts;
16b9a73c
MW
374 this->public.get_my_traffic_selectors = (linked_list_t*(*)(policy_t*))get_my_traffic_selectors;
375 this->public.select_my_traffic_selectors = (linked_list_t*(*)(policy_t*,linked_list_t*))select_my_traffic_selectors;
376 this->public.get_other_traffic_selectors = (linked_list_t*(*)(policy_t*))get_other_traffic_selectors;
377 this->public.select_other_traffic_selectors = (linked_list_t*(*)(policy_t*,linked_list_t*))select_other_traffic_selectors;
378 this->public.get_proposals = (linked_list_t*(*)(policy_t*))get_proposals;
379 this->public.select_proposal = (proposal_t*(*)(policy_t*,linked_list_t*))select_proposal;
380 this->public.add_my_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_my_traffic_selector;
381 this->public.add_other_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_other_traffic_selector;
382 this->public.add_proposal = (void(*)(policy_t*,proposal_t*))add_proposal;
87a217f9 383 this->public.clone = (policy_t*(*)(policy_t*))clone;
16b9a73c 384 this->public.destroy = (void(*)(policy_t*))destroy;
ca060d4c
MW
385
386 /* apply init values */
16b9a73c
MW
387 this->my_id = my_id;
388 this->other_id = other_id;
ca060d4c
MW
389
390 /* init private members*/
257fa503 391 this->select_traffic_selectors = select_traffic_selectors;
d45ec1de 392 this->proposals = linked_list_create();
a527a426
MW
393 this->my_ts = linked_list_create();
394 this->other_ts = linked_list_create();
d45ec1de
MW
395
396 return (&this->public);
397}