- dead end implementation
[strongswan.git] / Source / charon / config / sa_config.c
1 /**
2 * @file sa_config.c
3 *
4 * @brief Implementation of sa_config_t.
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
23 #include "sa_config.h"
24
25 #include <utils/linked_list.h>
26 #include <utils/allocator.h>
27 #include <utils/identification.h>
28 #include <utils/logger.h>
29
30 typedef struct private_sa_config_t private_sa_config_t;
31
32 /**
33 * Private data of an sa_config_t object
34 */
35 struct private_sa_config_t {
36
37 /**
38 * Public part
39 */
40 sa_config_t public;
41
42 /**
43 * id to use to identify us
44 */
45 identification_t *my_id;
46
47 /**
48 * allowed id for other
49 */
50 identification_t *other_id;
51
52 /**
53 * authentification method to use
54 */
55 auth_method_t auth_method;
56
57 /**
58 * Lifetime of IKE_SA in milliseconds.
59 */
60 u_int32_t ike_sa_lifetime;
61
62 /**
63 * list for all proposals
64 */
65 linked_list_t *proposals;
66
67 /**
68 * list for traffic selectors for initiator site
69 */
70 linked_list_t *ts_initiator;
71
72 /**
73 * list for traffic selectors for responder site
74 */
75 linked_list_t *ts_responder;
76
77 /**
78 * get_traffic_selectors for both
79 */
80 size_t (*get_traffic_selectors) (private_sa_config_t *,linked_list_t*,traffic_selector_t**[]);
81
82 /**
83 * select_traffic_selectors for both
84 */
85 size_t (*select_traffic_selectors) (private_sa_config_t *,linked_list_t*,traffic_selector_t*[],size_t,traffic_selector_t**[]);
86 };
87
88 /**
89 * Implementation of sa_config_t.get_my_id
90 */
91 static identification_t *get_my_id(private_sa_config_t *this)
92 {
93 return this->my_id;
94 }
95
96 /**
97 * Implementation of sa_config_t.get_other_id
98 */
99 static identification_t *get_other_id(private_sa_config_t *this)
100 {
101 return this->other_id;
102 }
103
104 /**
105 * Implementation of sa_config_t.get_auth_method.
106 */
107 static auth_method_t get_auth_method(private_sa_config_t *this)
108 {
109 return this->auth_method;
110 }
111
112 /**
113 * Implementation of sa_config_t.get_ike_sa_lifetime.
114 */
115 static u_int32_t get_ike_sa_lifetime (private_sa_config_t *this)
116 {
117 return this->ike_sa_lifetime;
118 }
119
120 /**
121 * Implementation of sa_config_t.get_traffic_selectors_initiator
122 */
123 static size_t get_traffic_selectors_initiator(private_sa_config_t *this, traffic_selector_t **traffic_selectors[])
124 {
125 return this->get_traffic_selectors(this, this->ts_initiator, traffic_selectors);
126 }
127
128 /**
129 * Implementation of sa_config_t.get_traffic_selectors_responder
130 */
131 static size_t get_traffic_selectors_responder(private_sa_config_t *this, traffic_selector_t **traffic_selectors[])
132 {
133 return this->get_traffic_selectors(this, this->ts_responder, traffic_selectors);
134 }
135
136 /**
137 * Implementation of private_sa_config_t.get_traffic_selectors
138 */
139 static size_t get_traffic_selectors(private_sa_config_t *this, linked_list_t *ts_list, traffic_selector_t **traffic_selectors[])
140 {
141 iterator_t *iterator;
142 traffic_selector_t *current_ts;
143 int counter = 0;
144 *traffic_selectors = allocator_alloc(sizeof(traffic_selector_t*) * ts_list->get_count(ts_list));
145
146 /* copy all ts from the list in an array */
147 iterator = ts_list->create_iterator(ts_list, TRUE);
148 while (iterator->has_next(iterator))
149 {
150 iterator->current(iterator, (void**)&current_ts);
151 *((*traffic_selectors) + counter) = current_ts->clone(current_ts);
152 counter++;
153 }
154 iterator->destroy(iterator);
155 return counter;
156 }
157
158 /**
159 * Implementation of private_sa_config_t.select_traffic_selectors_initiator
160 */
161 static size_t select_traffic_selectors_initiator(private_sa_config_t *this,traffic_selector_t *supplied[], size_t count, traffic_selector_t **selected[])
162 {
163 return this->select_traffic_selectors(this, this->ts_initiator, supplied, count, selected);
164 }
165
166 /**
167 * Implementation of private_sa_config_t.select_traffic_selectors_responder
168 */
169 static size_t select_traffic_selectors_responder(private_sa_config_t *this,traffic_selector_t *supplied[], size_t count, traffic_selector_t **selected[])
170 {
171 return this->select_traffic_selectors(this, this->ts_responder, supplied, count, selected);
172 }
173 /**
174 * Implementation of private_sa_config_t.select_traffic_selectors
175 */
176 static size_t select_traffic_selectors(private_sa_config_t *this, linked_list_t *ts_list, traffic_selector_t *supplied[], size_t count, traffic_selector_t **selected[])
177 {
178 iterator_t *iterator;
179 traffic_selector_t *current_ts;
180 int i, counter = 0;
181 *selected = allocator_alloc(sizeof(traffic_selector_t*) * ts_list->get_count(ts_list));
182
183 /* iterate over all stored proposals */
184 iterator = ts_list->create_iterator(ts_list, TRUE);
185 while (iterator->has_next(iterator))
186 {
187 iterator->current(iterator, (void**)&current_ts);
188 for (i = 0; i < count; i++)
189 {
190 traffic_selector_t *new_ts;
191 /* compare it */
192 new_ts = current_ts->get_subset(current_ts, supplied[i]);
193 /* match ? */
194 if (new_ts)
195 {
196 *((*selected) + counter) = new_ts;
197 counter++;
198 }
199 }
200 }
201 iterator->destroy(iterator);
202
203 /* free unused space */
204 *selected = allocator_realloc(*selected, sizeof(traffic_selector_t) * counter);
205 return counter;
206 }
207
208 /**
209 * Implementation of sa_config_t.get_proposal_iterator
210 */
211 static iterator_t *create_proposal_iterator(private_sa_config_t *this)
212 {
213 return this->proposals->create_iterator(this->proposals, TRUE);
214 }
215
216 /**
217 * Implementation of sa_config_t.select_proposal
218 */
219 static child_proposal_t *select_proposal(private_sa_config_t *this, linked_list_t *proposals)
220 {
221 iterator_t *stored_iter, *supplied_iter;
222 child_proposal_t *stored, *supplied, *selected;
223
224 stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
225 supplied_iter = proposals->create_iterator(proposals, TRUE);
226
227 /* compare all stored proposals with all supplied. Stored ones are preferred. */
228 while (stored_iter->has_next(stored_iter))
229 {
230 supplied_iter->reset(supplied_iter);
231 stored_iter->current(stored_iter, (void**)&stored);
232
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)
238 {
239 /* they match, return */
240 stored_iter->destroy(stored_iter);
241 supplied_iter->destroy(supplied_iter);
242 return selected;
243 }
244 }
245 }
246
247 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
248 stored_iter->destroy(stored_iter);
249 supplied_iter->destroy(supplied_iter);
250
251 return NULL;
252 }
253
254 /**
255 * Implementation of sa_config_t.add_traffic_selector_initiator
256 */
257 static void add_traffic_selector_initiator(private_sa_config_t *this, traffic_selector_t *traffic_selector)
258 {
259 /* clone ts, and add*/
260 this->ts_initiator->insert_last(this->ts_initiator, (void*)traffic_selector->clone(traffic_selector));
261 }
262
263 /**
264 * Implementation of sa_config_t.add_traffic_selector_responder
265 */
266 static void add_traffic_selector_responder(private_sa_config_t *this, traffic_selector_t *traffic_selector)
267 {
268 /* clone ts, and add*/
269 this->ts_responder->insert_last(this->ts_responder, (void*)traffic_selector->clone(traffic_selector));
270 }
271
272 /**
273 * Implementation of sa_config_t.add_proposal
274 */
275 static void add_proposal(private_sa_config_t *this, child_proposal_t *proposal)
276 {
277 this->proposals->insert_last(this->proposals, (void*)proposal);
278 }
279
280 /**
281 * Implements sa_config_t.destroy.
282 */
283 static status_t destroy(private_sa_config_t *this)
284 {
285 child_proposal_t *proposal;
286 traffic_selector_t *traffic_selector;
287
288
289 /* delete proposals */
290 while(this->proposals->get_count(this->proposals) > 0)
291 {
292 this->proposals->remove_last(this->proposals, (void**)&proposal);
293 proposal->destroy(proposal);
294 }
295 this->proposals->destroy(this->proposals);
296
297 /* delete traffic selectors */
298 while(this->ts_initiator->get_count(this->ts_initiator) > 0)
299 {
300 this->ts_initiator->remove_last(this->ts_initiator, (void**)&traffic_selector);
301 traffic_selector->destroy(traffic_selector);
302 }
303 this->ts_initiator->destroy(this->ts_initiator);
304
305 /* delete traffic selectors */
306 while(this->ts_responder->get_count(this->ts_responder) > 0)
307 {
308 this->ts_responder->remove_last(this->ts_responder, (void**)&traffic_selector);
309 traffic_selector->destroy(traffic_selector);
310 }
311 this->ts_responder->destroy(this->ts_responder);
312
313 /* delete ids */
314 this->my_id->destroy(this->my_id);
315 this->other_id->destroy(this->other_id);
316
317 allocator_free(this);
318 return SUCCESS;
319 }
320
321 /*
322 * Described in header-file
323 */
324 sa_config_t *sa_config_create(id_type_t my_id_type, char *my_id, id_type_t other_id_type, char *other_id, auth_method_t auth_method, u_int32_t ike_sa_lifetime)
325 {
326 private_sa_config_t *this = allocator_alloc_thing(private_sa_config_t);
327
328 /* public functions */
329 this->public.get_my_id = (identification_t*(*)(sa_config_t*))get_my_id;
330 this->public.get_other_id = (identification_t*(*)(sa_config_t*))get_other_id;
331 this->public.get_auth_method = (auth_method_t(*)(sa_config_t*))get_auth_method;
332 this->public.get_ike_sa_lifetime = (u_int32_t(*)(sa_config_t*))get_ike_sa_lifetime;
333 this->public.get_traffic_selectors_initiator = (size_t(*)(sa_config_t*,traffic_selector_t**[]))get_traffic_selectors_initiator;
334 this->public.select_traffic_selectors_initiator = (size_t(*)(sa_config_t*,traffic_selector_t*[],size_t,traffic_selector_t**[]))select_traffic_selectors_initiator;
335 this->public.get_traffic_selectors_responder = (size_t(*)(sa_config_t*,traffic_selector_t**[]))get_traffic_selectors_responder;
336 this->public.select_traffic_selectors_responder = (size_t(*)(sa_config_t*,traffic_selector_t*[],size_t,traffic_selector_t**[]))select_traffic_selectors_responder;
337 this->public.create_proposal_iterator = (iterator_t*(*)(sa_config_t*))create_proposal_iterator;
338 this->public.select_proposal = (child_proposal_t*(*)(sa_config_t*,linked_list_t*))select_proposal;
339 this->public.add_traffic_selector_initiator = (void(*)(sa_config_t*,traffic_selector_t*))add_traffic_selector_initiator;
340 this->public.add_traffic_selector_responder = (void(*)(sa_config_t*,traffic_selector_t*))add_traffic_selector_responder;
341 this->public.add_proposal = (void(*)(sa_config_t*,child_proposal_t*))add_proposal;
342 this->public.destroy = (void(*)(sa_config_t*))destroy;
343
344 /* apply init values */
345 this->my_id = identification_create_from_string(my_id_type, my_id);
346 if (this->my_id == NULL)
347 {
348 allocator_free(this);
349 return NULL;
350 }
351 this->other_id = identification_create_from_string(other_id_type, other_id);
352 if (this->my_id == NULL)
353 {
354 this->other_id->destroy(this->other_id);
355 allocator_free(this);
356 return NULL;
357 }
358
359 /* init private members*/
360 this->select_traffic_selectors = select_traffic_selectors;
361 this->get_traffic_selectors = get_traffic_selectors;
362 this->proposals = linked_list_create();
363 this->ts_initiator = linked_list_create();
364 this->ts_responder = linked_list_create();
365 this->auth_method = auth_method;
366 this->ike_sa_lifetime = ike_sa_lifetime;
367
368 return (&this->public);
369 }