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