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