updated Doxyfile
[strongswan.git] / src / charon / config / peer_cfg.c
1 /*
2 * Copyright (C) 2007-2008 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * $Id$
18 */
19
20 #include <string.h>
21
22 #include "peer_cfg.h"
23
24 #include <daemon.h>
25
26 #include <utils/mutex.h>
27 #include <utils/linked_list.h>
28 #include <utils/identification.h>
29
30 ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
31 "CERT_ALWAYS_SEND",
32 "CERT_SEND_IF_ASKED",
33 "CERT_NEVER_SEND",
34 );
35
36 ENUM(unique_policy_names, UNIQUE_NO, UNIQUE_KEEP,
37 "UNIQUE_NO",
38 "UNIQUE_REPLACE",
39 "UNIQUE_KEEP",
40 );
41
42 typedef struct private_peer_cfg_t private_peer_cfg_t;
43
44 /**
45 * Private data of an peer_cfg_t object
46 */
47 struct private_peer_cfg_t {
48
49 /**
50 * Public part
51 */
52 peer_cfg_t public;
53
54 /**
55 * Number of references hold by others to this peer_cfg
56 */
57 refcount_t refcount;
58
59 /**
60 * Name of the peer_cfg, used to query it
61 */
62 char *name;
63
64 /**
65 * IKE version to use for initiation
66 */
67 u_int ike_version;
68
69 /**
70 * IKE config associated to this peer config
71 */
72 ike_cfg_t *ike_cfg;
73
74 /**
75 * list of child configs associated to this peer config
76 */
77 linked_list_t *child_cfgs;
78
79 /**
80 * mutex to lock access to list of child_cfgs
81 */
82 mutex_t *mutex;
83
84 /**
85 * id to use to identify us
86 */
87 identification_t *my_id;
88
89 /**
90 * allowed id for other
91 */
92 identification_t *other_id;
93
94 /**
95 * should we send a certificate
96 */
97 cert_policy_t cert_policy;
98
99 /**
100 * uniqueness of an IKE_SA
101 */
102 unique_policy_t unique;
103
104 /**
105 * number of tries after giving up if peer does not respond
106 */
107 u_int32_t keyingtries;
108
109 /**
110 * enable support for MOBIKE
111 */
112 bool use_mobike;
113
114 /**
115 * Time before starting rekeying
116 */
117 u_int32_t rekey_time;
118
119 /**
120 * Time before starting reauthentication
121 */
122 u_int32_t reauth_time;
123
124 /**
125 * Time, which specifies the range of a random value substracted from above.
126 */
127 u_int32_t jitter_time;
128
129 /**
130 * Delay before deleting a rekeying/reauthenticating SA
131 */
132 u_int32_t over_time;
133
134 /**
135 * DPD check intervall
136 */
137 u_int32_t dpd;
138
139 /**
140 * virtual IP to use locally
141 */
142 host_t *virtual_ip;
143
144 /**
145 * pool to acquire configuration attributes from
146 */
147 char *pool;
148
149 /**
150 * required authorization constraints
151 */
152 auth_info_t *auth;
153
154 #ifdef ME
155 /**
156 * Is this a mediation connection?
157 */
158 bool mediation;
159
160 /**
161 * Name of the mediation connection to mediate through
162 */
163 peer_cfg_t *mediated_by;
164
165 /**
166 * ID of our peer at the mediation server (= leftid of the peer's conn with
167 * the mediation server)
168 */
169 identification_t *peer_id;
170 #endif /* ME */
171 };
172
173 /**
174 * Implementation of peer_cfg_t.get_name
175 */
176 static char *get_name(private_peer_cfg_t *this)
177 {
178 return this->name;
179 }
180
181 /**
182 * Implementation of peer_cfg_t.get_ike_version
183 */
184 static u_int get_ike_version(private_peer_cfg_t *this)
185 {
186 return this->ike_version;
187 }
188
189 /**
190 * Implementation of peer_cfg_t.get_ike_cfg
191 */
192 static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this)
193 {
194 return this->ike_cfg;
195 }
196
197 /**
198 * Implementation of peer_cfg_t.add_child_cfg.
199 */
200 static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
201 {
202 this->mutex->lock(this->mutex);
203 this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
204 this->mutex->unlock(this->mutex);
205 }
206
207 /**
208 * Implementation of peer_cfg_t.remove_child_cfg.
209 */
210 static void remove_child_cfg(private_peer_cfg_t *this, enumerator_t *enumerator)
211 {
212 this->mutex->lock(this->mutex);
213 this->child_cfgs->remove_at(this->child_cfgs, enumerator);
214 this->mutex->unlock(this->mutex);
215 }
216
217 /**
218 * Implementation of peer_cfg_t.create_child_cfg_enumerator.
219 */
220 static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
221 {
222 enumerator_t *enumerator;
223
224 this->mutex->lock(this->mutex);
225 enumerator = this->child_cfgs->create_enumerator(this->child_cfgs);
226 return enumerator_create_cleaner(enumerator,
227 (void*)this->mutex->unlock, this->mutex);
228 }
229
230 /**
231 * Check if child_cfg contains traffic selectors
232 */
233 static int contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts,
234 host_t *host)
235 {
236 linked_list_t *selected;
237 int prio;
238
239 if (child->equal_traffic_selectors(child, mine, ts, host))
240 {
241 return 2;
242 }
243 selected = child->get_traffic_selectors(child, mine, ts, host);
244 prio = selected->get_count(selected) ? 1 : 0;
245 selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy));
246 return prio;
247 }
248
249 /**
250 * Implementation of peer_cfg_t.select_child_cfg
251 */
252 static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
253 linked_list_t *my_ts,
254 linked_list_t *other_ts,
255 host_t *my_host, host_t *other_host)
256 {
257 child_cfg_t *current, *found = NULL;
258 enumerator_t *enumerator;
259 int best = 0;
260
261 DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts);
262 enumerator = create_child_cfg_enumerator(this);
263 while (enumerator->enumerate(enumerator, &current))
264 {
265 int prio = contains_ts(current, TRUE, my_ts, my_host) +
266 contains_ts(current, FALSE, other_ts, other_host);
267
268 if (prio)
269 {
270 DBG2(DBG_CFG, " candidate \"%s\" with prio %d",
271 current->get_name(current), prio);
272 if (prio > best)
273 {
274 best = prio;
275 DESTROY_IF(found);
276 found = current->get_ref(current);
277 }
278 }
279 }
280 enumerator->destroy(enumerator);
281 if (found)
282 {
283 DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d",
284 found->get_name(found), best);
285 }
286 return found;
287 }
288
289 /**
290 * Implementation of peer_cfg_t.get_my_id
291 */
292 static identification_t *get_my_id(private_peer_cfg_t *this)
293 {
294 return this->my_id;
295 }
296
297 /**
298 * Implementation of peer_cfg_t.get_other_id
299 */
300 static identification_t *get_other_id(private_peer_cfg_t *this)
301 {
302 return this->other_id;
303 }
304
305 /**
306 * Implementation of peer_cfg_t.get_cert_policy.
307 */
308 static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
309 {
310 return this->cert_policy;
311 }
312
313 /**
314 * Implementation of peer_cfg_t.get_unique_policy.
315 */
316 static unique_policy_t get_unique_policy(private_peer_cfg_t *this)
317 {
318 return this->unique;
319 }
320
321 /**
322 * Implementation of peer_cfg_t.get_keyingtries.
323 */
324 static u_int32_t get_keyingtries(private_peer_cfg_t *this)
325 {
326 return this->keyingtries;
327 }
328
329 /**
330 * Implementation of peer_cfg_t.get_rekey_time.
331 */
332 static u_int32_t get_rekey_time(private_peer_cfg_t *this)
333 {
334 if (this->rekey_time == 0)
335 {
336 return 0;
337 }
338 if (this->jitter_time == 0)
339 {
340 return this->rekey_time;
341 }
342 return this->rekey_time - (random() % this->jitter_time);
343 }
344
345 /**
346 * Implementation of peer_cfg_t.get_reauth_time.
347 */
348 static u_int32_t get_reauth_time(private_peer_cfg_t *this)
349 {
350 if (this->reauth_time == 0)
351 {
352 return 0;
353 }
354 if (this->jitter_time == 0)
355 {
356 return this->reauth_time;
357 }
358 return this->reauth_time - (random() % this->jitter_time);
359 }
360
361 /**
362 * Implementation of peer_cfg_t.get_over_time.
363 */
364 static u_int32_t get_over_time(private_peer_cfg_t *this)
365 {
366 return this->over_time;
367 }
368
369 /**
370 * Implementation of peer_cfg_t.use_mobike.
371 */
372 static bool use_mobike(private_peer_cfg_t *this)
373 {
374 return this->use_mobike;
375 }
376
377 /**
378 * Implements peer_cfg_t.get_dpd
379 */
380 static u_int32_t get_dpd(private_peer_cfg_t *this)
381 {
382 return this->dpd;
383 }
384
385 /**
386 * Implementation of peer_cfg_t.get_virtual_ip.
387 */
388 static host_t* get_virtual_ip(private_peer_cfg_t *this)
389 {
390 return this->virtual_ip;
391 }
392
393 /**
394 * Implementation of peer_cfg_t.get_pool.
395 */
396 static char* get_pool(private_peer_cfg_t *this)
397 {
398 return this->pool;
399 }
400
401 /**
402 * Implementation of peer_cfg_t.get_auth.
403 */
404 static auth_info_t* get_auth(private_peer_cfg_t *this)
405 {
406 return this->auth;
407 }
408
409 #ifdef ME
410 /**
411 * Implementation of peer_cfg_t.is_mediation.
412 */
413 static bool is_mediation(private_peer_cfg_t *this)
414 {
415 return this->mediation;
416 }
417
418 /**
419 * Implementation of peer_cfg_t.get_mediated_by.
420 */
421 static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this)
422 {
423 return this->mediated_by;
424 }
425
426 /**
427 * Implementation of peer_cfg_t.get_peer_id.
428 */
429 static identification_t* get_peer_id(private_peer_cfg_t *this)
430 {
431 return this->peer_id;
432 }
433 #endif /* ME */
434
435 /**
436 * Implementation of peer_cfg_t.equals.
437 */
438 static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
439 {
440 if (this == other)
441 {
442 return TRUE;
443 }
444 if (this->public.equals != other->public.equals)
445 {
446 return FALSE;
447 }
448
449 return (
450 this->ike_version == other->ike_version &&
451 this->my_id->equals(this->my_id, other->my_id) &&
452 this->other_id->equals(this->other_id, other->other_id) &&
453 this->cert_policy == other->cert_policy &&
454 this->unique == other->unique &&
455 this->keyingtries == other->keyingtries &&
456 this->use_mobike == other->use_mobike &&
457 this->rekey_time == other->rekey_time &&
458 this->reauth_time == other->reauth_time &&
459 this->jitter_time == other->jitter_time &&
460 this->over_time == other->over_time &&
461 this->dpd == other->dpd &&
462 (this->virtual_ip == other->virtual_ip ||
463 (this->virtual_ip && other->virtual_ip &&
464 this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
465 (this->pool == other->pool ||
466 (this->pool && other->pool && streq(this->pool, other->pool))) &&
467 this->auth->equals(this->auth, other->auth)
468 #ifdef ME
469 && this->mediation == other->mediation &&
470 this->mediated_by == other->mediated_by &&
471 (this->peer_id == other->peer_id ||
472 (this->peer_id && other->peer_id &&
473 this->peer_id->equals(this->peer_id, other->peer_id)))
474 #endif /* ME */
475 );
476 }
477
478 /**
479 * Implements peer_cfg_t.get_ref.
480 */
481 static peer_cfg_t* get_ref(private_peer_cfg_t *this)
482 {
483 ref_get(&this->refcount);
484 return &this->public;
485 }
486
487 /**
488 * Implements peer_cfg_t.destroy.
489 */
490 static void destroy(private_peer_cfg_t *this)
491 {
492 if (ref_put(&this->refcount))
493 {
494 this->ike_cfg->destroy(this->ike_cfg);
495 this->child_cfgs->destroy_offset(this->child_cfgs, offsetof(child_cfg_t, destroy));
496 this->my_id->destroy(this->my_id);
497 this->other_id->destroy(this->other_id);
498 DESTROY_IF(this->virtual_ip);
499 this->auth->destroy(this->auth);
500 #ifdef ME
501 DESTROY_IF(this->mediated_by);
502 DESTROY_IF(this->peer_id);
503 #endif /* ME */
504 this->mutex->destroy(this->mutex);
505 free(this->name);
506 free(this->pool);
507 free(this);
508 }
509 }
510
511 /*
512 * Described in header-file
513 */
514 peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
515 identification_t *my_id, identification_t *other_id,
516 cert_policy_t cert_policy, unique_policy_t unique,
517 u_int32_t keyingtries, u_int32_t rekey_time,
518 u_int32_t reauth_time, u_int32_t jitter_time,
519 u_int32_t over_time, bool mobike, u_int32_t dpd,
520 host_t *virtual_ip, char *pool,
521 bool mediation, peer_cfg_t *mediated_by,
522 identification_t *peer_id)
523 {
524 private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
525
526 /* public functions */
527 this->public.get_name = (char* (*) (peer_cfg_t *))get_name;
528 this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;
529 this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
530 this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
531 this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
532 this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
533 this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
534 this->public.get_my_id = (identification_t* (*)(peer_cfg_t*))get_my_id;
535 this->public.get_other_id = (identification_t* (*)(peer_cfg_t *))get_other_id;
536 this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
537 this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy;
538 this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
539 this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
540 this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
541 this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
542 this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
543 this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd;
544 this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip;
545 this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool;
546 this->public.get_auth = (auth_info_t*(*)(peer_cfg_t*))get_auth;
547 this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
548 this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref;
549 this->public.destroy = (void(*)(peer_cfg_t *))destroy;
550 #ifdef ME
551 this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation;
552 this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by;
553 this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id;
554 #endif /* ME */
555
556 /* apply init values */
557 this->name = strdup(name);
558 this->ike_version = ike_version;
559 this->ike_cfg = ike_cfg;
560 this->child_cfgs = linked_list_create();
561 this->mutex = mutex_create(MUTEX_DEFAULT);
562 this->my_id = my_id;
563 this->other_id = other_id;
564 this->cert_policy = cert_policy;
565 this->unique = unique;
566 this->keyingtries = keyingtries;
567 this->rekey_time = rekey_time;
568 this->reauth_time = reauth_time;
569 if (rekey_time && jitter_time > rekey_time)
570 {
571 jitter_time = rekey_time;
572 }
573 if (reauth_time && jitter_time > reauth_time)
574 {
575 jitter_time = reauth_time;
576 }
577 this->jitter_time = jitter_time;
578 this->over_time = over_time;
579 this->use_mobike = mobike;
580 this->dpd = dpd;
581 this->virtual_ip = virtual_ip;
582 this->pool = pool ? strdup(pool) : NULL;
583 this->auth = auth_info_create();
584 this->refcount = 1;
585 #ifdef ME
586 this->mediation = mediation;
587 this->mediated_by = mediated_by;
588 this->peer_id = peer_id;
589 #else /* ME */
590 DESTROY_IF(mediated_by);
591 DESTROY_IF(peer_id);
592 #endif /* ME */
593
594 return &this->public;
595 }