]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libcharon/sa/ike_sa.c
ike-sa: Add property for interface ID
[thirdparty/strongswan.git] / src / libcharon / sa / ike_sa.c
CommitLineData
7ba38761 1/*
dec3c184 2 * Copyright (C) 2006-2019 Tobias Brunner
d5cc1758 3 * Copyright (C) 2006 Daniel Roethlisberger
a44bb934 4 * Copyright (C) 2005-2009 Martin Willi
c71d53ba 5 * Copyright (C) 2005 Jan Hutter
208678e6 6 * HSR Hochschule fuer Technik Rapperswil
7ba38761
JH
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
1396815a 18
05db0f97
VR
19/*
20 * Copyright (c) 2014 Volker RĂ¼melin
21 *
22 * Permission is hereby granted, free of charge, to any person obtaining a copy
23 * of this software and associated documentation files (the "Software"), to deal
24 * in the Software without restriction, including without limitation the rights
25 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 * copies of the Software, and to permit persons to whom the Software is
27 * furnished to do so, subject to the following conditions:
28 *
29 * The above copyright notice and this permission notice shall be included in
30 * all copies or substantial portions of the Software.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
38 * THE SOFTWARE.
39 */
40
5113680f 41#include <string.h>
c60c7694 42#include <sys/stat.h>
db97fd82 43#include <errno.h>
e13389a7 44#include <time.h>
7ba38761 45
88878242
MW
46#include "ike_sa.h"
47
db7ef624 48#include <library.h>
c5f7146b 49#include <daemon.h>
893da041 50#include <collections/array.h>
c60c7694 51#include <utils/lexparser.h>
e0fe7651
MW
52#include <processing/jobs/retransmit_job.h>
53#include <processing/jobs/delete_ike_sa_job.h>
54#include <processing/jobs/send_dpd_job.h>
55#include <processing/jobs/send_keepalive_job.h>
56#include <processing/jobs/rekey_ike_sa_job.h>
60c82591 57#include <processing/jobs/retry_initiate_job.h>
b1f2f05c 58#include <sa/ikev2/tasks/ike_auth_lifetime.h>
f20e00fe 59#include <sa/ikev2/tasks/ike_reauth_complete.h>
71c70705 60#include <sa/ikev2/tasks/ike_redirect.h>
1b9c1ae0 61#include <credentials/sets/auth_cfg_wrapper.h>
7ba38761 62
dc04b7c7 63#ifdef ME
15a682f4 64#include <sa/ikev2/tasks/ike_me.h>
38951252 65#include <processing/jobs/initiate_mediation_job.h>
d5cc1758 66#endif
c60c7694 67
a985db3f 68ENUM(ike_sa_state_names, IKE_CREATED, IKE_DESTROYING,
60356f33
MW
69 "CREATED",
70 "CONNECTING",
71 "ESTABLISHED",
c610f424 72 "PASSIVE",
60356f33 73 "REKEYING",
bb389973 74 "REKEYED",
60356f33 75 "DELETING",
a985db3f 76 "DESTROYING",
60356f33 77);
7ba38761 78
aad398a7 79typedef struct private_ike_sa_t private_ike_sa_t;
7f56b494 80typedef struct attribute_entry_t attribute_entry_t;
aad398a7
JH
81
82/**
83 * Private data of an ike_sa_t object.
84 */
85struct private_ike_sa_t {
7daf5226 86
aad398a7 87 /**
3dd3c5f3 88 * Public members
2f89902d 89 */
3dd3c5f3 90 ike_sa_t public;
7daf5226 91
aad398a7 92 /**
a374d1ee 93 * Identifier for the current IKE_SA.
aad398a7
JH
94 */
95 ike_sa_id_t *ike_sa_id;
7daf5226 96
0b611540
TB
97 /**
98 * IKE version of this SA.
99 */
100 ike_version_t version;
101
c60c7694
MW
102 /**
103 * unique numerical ID for this IKE_SA.
104 */
b12c53ce 105 uint32_t unique_id;
7daf5226 106
aad398a7 107 /**
8dfbe71b 108 * Current state of the IKE_SA
aad398a7 109 */
7f56b494 110 ike_sa_state_t state;
7daf5226 111
a9428251 112 /**
e0fe7651 113 * IKE configuration used to set up this IKE_SA
a9428251 114 */
e0fe7651 115 ike_cfg_t *ike_cfg;
7daf5226 116
c60c7694
MW
117 /**
118 * Peer and authentication information to establish IKE_SA.
119 */
e0fe7651 120 peer_cfg_t *peer_cfg;
7daf5226 121
552cc11b 122 /**
893da041 123 * currently used authentication ruleset, local
552cc11b 124 */
a44bb934 125 auth_cfg_t *my_auth;
7daf5226 126
44ce7493 127 /**
893da041 128 * currently used authentication constraints, remote
44ce7493 129 */
893da041 130 auth_cfg_t *other_auth;
44ce7493
MW
131
132 /**
893da041 133 * Array of completed local authentication rounds (as auth_cfg_t)
44ce7493 134 */
893da041 135 array_t *my_auths;
44ce7493 136
552cc11b 137 /**
893da041 138 * Array of completed remote authentication rounds (as auth_cfg_t)
552cc11b 139 */
893da041 140 array_t *other_auths;
7daf5226 141
5dffdea1
MW
142 /**
143 * Selected IKE proposal
144 */
145 proposal_t *proposal;
7daf5226 146
c60c7694
MW
147 /**
148 * Juggles tasks to process messages
149 */
150 task_manager_t *task_manager;
7daf5226 151
8dfbe71b
MW
152 /**
153 * Address of local host
154 */
155 host_t *my_host;
7daf5226 156
8dfbe71b
MW
157 /**
158 * Address of remote host
159 */
160 host_t *other_host;
7daf5226 161
dc04b7c7 162#ifdef ME
22452f70
TB
163 /**
164 * Are we mediation server
165 */
166 bool is_mediation_server;
7daf5226 167
d5cc1758
TB
168 /**
169 * Server reflexive host
170 */
171 host_t *server_reflexive_host;
7daf5226 172
9c2a905d
TB
173 /**
174 * Connect ID
175 */
176 chunk_t connect_id;
dc04b7c7 177#endif /* ME */
7daf5226 178
8dfbe71b
MW
179 /**
180 * Identification used for us
181 */
182 identification_t *my_id;
7daf5226 183
a9428251 184 /**
8dfbe71b 185 * Identification used for other
a9428251 186 */
8dfbe71b 187 identification_t *other_id;
7daf5226 188
3b04350a
MW
189 /**
190 * set of extensions the peer supports
191 */
192 ike_extension_t extensions;
7daf5226 193
17d92e97
MW
194 /**
195 * set of condition flags currently enabled for this IKE_SA
196 */
197 ike_condition_t conditions;
7daf5226 198
aad398a7 199 /**
893da041 200 * Array containing the child sa's of the current IKE_SA.
aad398a7 201 */
893da041 202 array_t *child_sas;
7daf5226 203
bc997f65 204 /**
6a4ff35c 205 * keymat of this IKE_SA
bc997f65 206 */
6a4ff35c 207 keymat_t *keymat;
7daf5226 208
3dd3c5f3 209 /**
101d26ba 210 * Virtual IPs on local host
3dd3c5f3 211 */
893da041 212 array_t *my_vips;
7daf5226 213
c60c7694 214 /**
101d26ba 215 * Virtual IPs on remote host
c60c7694 216 */
893da041 217 array_t *other_vips;
7daf5226 218
31e5d441 219 /**
7f56b494 220 * List of configuration attributes (attribute_entry_t)
31e5d441 221 */
893da041 222 array_t *attributes;
7daf5226 223
17d92e97 224 /**
94bbc602 225 * list of peer's addresses, additional ones transmitted via MOBIKE
17d92e97 226 */
893da041 227 array_t *peer_addresses;
7daf5226 228
9d9a772e
MW
229 /**
230 * previously value of received DESTINATION_IP hash
231 */
232 chunk_t nat_detection_dest;
7daf5226 233
3dfecde4
AS
234 /**
235 * NAT keep alive interval
236 */
b12c53ce 237 uint32_t keepalive_interval;
7daf5226 238
efd7fa7b
TB
239 /**
240 * The schedueld keep alive job, if any
241 */
242 send_keepalive_job_t *keepalive_job;
243
60c82591
TB
244 /**
245 * interval for retries during initiation (e.g. if DNS resolution failed),
246 * 0 to disable (default)
247 */
b12c53ce 248 uint32_t retry_initiate_interval;
60c82591 249
77e42826
TB
250 /**
251 * TRUE if a retry_initiate_job has been queued
252 */
253 bool retry_initiate_queued;
254
1396815a 255 /**
fe04e93a 256 * Timestamps for this IKE_SA
1396815a 257 */
b12c53ce 258 uint32_t stats[STAT_MAX];
7daf5226 259
fdb9b2bd
MW
260 /**
261 * how many times we have retried so far (keyingtries)
262 */
b12c53ce 263 uint32_t keyingtry;
7daf5226 264
d487b4b7
AS
265 /**
266 * local host address to be used for IKE, set via MIGRATE kernel message
267 */
268 host_t *local_host;
7daf5226 269
d487b4b7
AS
270 /**
271 * remote host address to be used for IKE, set via MIGRATE kernel message
272 */
273 host_t *remote_host;
b24b73b7
MW
274
275 /**
276 * Flush auth configs once established?
277 */
278 bool flush_auth_cfg;
40bab9a1
TB
279
280 /**
281 * Maximum length of a single fragment, 0 for address-specific defaults
282 */
283 size_t fragment_size;
489d154e
TB
284
285 /**
286 * Whether to follow IKEv2 redirects
287 */
288 bool follow_redirects;
e4af6e6b
TB
289
290 /**
291 * Original gateway address from which we got redirected
292 */
293 host_t *redirected_from;
c6ebd033
TB
294
295 /**
296 * Timestamps of redirect attempts to handle loops
297 */
298 array_t *redirected_at;
dec3c184
TB
299
300 /**
301 * Inbound interface ID
302 */
303 uint32_t if_id_in;
304
305 /**
306 * Outbound interface ID
307 */
308 uint32_t if_id_out;
aad398a7
JH
309};
310
7f56b494
MW
311/**
312 * Entry to maintain install configuration attributes during IKE_SA lifetime
313 */
314struct attribute_entry_t {
315 /** handler used to install this attribute */
316 attribute_handler_t *handler;
317 /** attribute type */
318 configuration_attribute_type_t type;
319 /** attribute data */
320 chunk_t data;
321};
322
0b2abb8c 323/**
3dd3c5f3 324 * get the time of the latest traffic processed by the kernel
0b2abb8c 325 */
c60c7694 326static time_t get_use_time(private_ike_sa_t* this, bool inbound)
3a8f9f44 327{
6e10aead 328 enumerator_t *enumerator;
3dd3c5f3 329 child_sa_t *child_sa;
c3a78360 330 time_t use_time, current;
7daf5226 331
c60c7694
MW
332 if (inbound)
333 {
85ac2fa5 334 use_time = this->stats[STAT_INBOUND];
c60c7694
MW
335 }
336 else
337 {
85ac2fa5 338 use_time = this->stats[STAT_OUTBOUND];
c60c7694 339 }
893da041
MW
340
341 enumerator = array_create_enumerator(this->child_sas);
6e10aead
MW
342 while (enumerator->enumerate(enumerator, &child_sa))
343 {
d954a208 344 child_sa->get_usestats(child_sa, inbound, &current, NULL, NULL);
c3a78360 345 use_time = max(use_time, current);
6e10aead
MW
346 }
347 enumerator->destroy(enumerator);
7daf5226 348
6e10aead 349 return use_time;
a9428251
JH
350}
351
b12c53ce 352METHOD(ike_sa_t, get_unique_id, uint32_t,
8bced61b 353 private_ike_sa_t *this)
aad398a7 354{
c60c7694 355 return this->unique_id;
aad398a7
JH
356}
357
8bced61b
MW
358METHOD(ike_sa_t, get_name, char*,
359 private_ike_sa_t *this)
0fdc3c7f 360{
e0fe7651 361 if (this->peer_cfg)
c60c7694 362 {
e0fe7651 363 return this->peer_cfg->get_name(this->peer_cfg);
c60c7694
MW
364 }
365 return "(unnamed)";
0fdc3c7f
JH
366}
367
b12c53ce 368METHOD(ike_sa_t, get_statistic, uint32_t,
8bced61b 369 private_ike_sa_t *this, statistic_t kind)
a3ce4bc2 370{
85ac2fa5 371 if (kind < STAT_MAX)
a3ce4bc2 372 {
85ac2fa5 373 return this->stats[kind];
a3ce4bc2 374 }
ee614711 375 return 0;
a3ce4bc2
MW
376}
377
44ff1153 378METHOD(ike_sa_t, set_statistic, void,
b12c53ce 379 private_ike_sa_t *this, statistic_t kind, uint32_t value)
44ff1153
TB
380{
381 if (kind < STAT_MAX)
382 {
383 this->stats[kind] = value;
384 }
385}
386
8bced61b
MW
387METHOD(ike_sa_t, get_my_host, host_t*,
388 private_ike_sa_t *this)
8dfbe71b 389{
e0fe7651 390 return this->my_host;
8dfbe71b
MW
391}
392
8bced61b
MW
393METHOD(ike_sa_t, set_my_host, void,
394 private_ike_sa_t *this, host_t *me)
8dfbe71b 395{
e0fe7651
MW
396 DESTROY_IF(this->my_host);
397 this->my_host = me;
8dfbe71b
MW
398}
399
8bced61b
MW
400METHOD(ike_sa_t, get_other_host, host_t*,
401 private_ike_sa_t *this)
397f3448 402{
e0fe7651 403 return this->other_host;
c60c7694
MW
404}
405
8bced61b
MW
406METHOD(ike_sa_t, set_other_host, void,
407 private_ike_sa_t *this, host_t *other)
c60c7694 408{
e0fe7651
MW
409 DESTROY_IF(this->other_host);
410 this->other_host = other;
397f3448
MW
411}
412
e4af6e6b
TB
413METHOD(ike_sa_t, get_redirected_from, host_t*,
414 private_ike_sa_t *this)
415{
416 return this->redirected_from;
417}
418
8bced61b
MW
419METHOD(ike_sa_t, get_peer_cfg, peer_cfg_t*,
420 private_ike_sa_t *this)
8dfbe71b 421{
e0fe7651 422 return this->peer_cfg;
8dfbe71b
MW
423}
424
8bced61b
MW
425METHOD(ike_sa_t, set_peer_cfg, void,
426 private_ike_sa_t *this, peer_cfg_t *peer_cfg)
fe04e93a 427{
e0fe7651 428 peer_cfg->get_ref(peer_cfg);
dbd21695 429 DESTROY_IF(this->peer_cfg);
e0fe7651 430 this->peer_cfg = peer_cfg;
7daf5226 431
dec3c184 432 if (!this->ike_cfg)
e0fe7651
MW
433 {
434 this->ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
435 this->ike_cfg->get_ref(this->ike_cfg);
436 }
dec3c184
TB
437
438 this->if_id_in = peer_cfg->get_if_id(peer_cfg, TRUE);
439 this->if_id_out = peer_cfg->get_if_id(peer_cfg, FALSE);
440 allocate_unique_if_ids(&this->if_id_in, &this->if_id_out);
552cc11b
MW
441}
442
8bced61b
MW
443METHOD(ike_sa_t, get_auth_cfg, auth_cfg_t*,
444 private_ike_sa_t *this, bool local)
552cc11b 445{
a44bb934
MW
446 if (local)
447 {
448 return this->my_auth;
449 }
552cc11b
MW
450 return this->other_auth;
451}
452
8bced61b
MW
453METHOD(ike_sa_t, add_auth_cfg, void,
454 private_ike_sa_t *this, bool local, auth_cfg_t *cfg)
44ce7493
MW
455{
456 if (local)
457 {
893da041 458 array_insert(this->my_auths, ARRAY_TAIL, cfg);
44ce7493
MW
459 }
460 else
461 {
893da041 462 array_insert(this->other_auths, ARRAY_TAIL, cfg);
44ce7493
MW
463 }
464}
465
8bced61b
MW
466METHOD(ike_sa_t, create_auth_cfg_enumerator, enumerator_t*,
467 private_ike_sa_t *this, bool local)
44ce7493
MW
468{
469 if (local)
470 {
893da041 471 return array_create_enumerator(this->my_auths);
44ce7493 472 }
893da041 473 return array_create_enumerator(this->other_auths);
44ce7493
MW
474}
475
e41adf5f
TB
476/**
477 * Flush the stored authentication round information
478 */
479static void flush_auth_cfgs(private_ike_sa_t *this)
480{
481 auth_cfg_t *cfg;
482
483 this->my_auth->purge(this->my_auth, FALSE);
484 this->other_auth->purge(this->other_auth, FALSE);
485
486 while (array_remove(this->my_auths, ARRAY_TAIL, &cfg))
487 {
488 cfg->destroy(cfg);
489 }
490 while (array_remove(this->other_auths, ARRAY_TAIL, &cfg))
491 {
492 cfg->destroy(cfg);
493 }
494}
495
1b9c1ae0
TB
496METHOD(ike_sa_t, verify_peer_certificate, bool,
497 private_ike_sa_t *this)
498{
499 enumerator_t *e1, *e2, *certs;
500 auth_cfg_t *cfg, *cfg_done;
501 certificate_t *peer, *cert;
502 public_key_t *key;
503 auth_cfg_t *auth;
504 auth_cfg_wrapper_t *wrapper;
505 time_t not_before, not_after;
506 bool valid = TRUE, found;
507
508 if (this->state != IKE_ESTABLISHED)
509 {
510 DBG1(DBG_IKE, "unable to verify peer certificate in state %N",
511 ike_sa_state_names, this->state);
512 return FALSE;
513 }
514
e41adf5f
TB
515 if (!this->flush_auth_cfg &&
516 lib->settings->get_bool(lib->settings,
1b9c1ae0 517 "%s.flush_auth_cfg", FALSE, lib->ns))
e41adf5f 518 { /* we can do this check only once if auth configs are flushed */
1b9c1ae0
TB
519 DBG1(DBG_IKE, "unable to verify peer certificate as authentication "
520 "information has been flushed");
521 return FALSE;
522 }
e41adf5f
TB
523 this->public.set_condition(&this->public, COND_ONLINE_VALIDATION_SUSPENDED,
524 FALSE);
1b9c1ae0
TB
525
526 e1 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, FALSE);
527 e2 = array_create_enumerator(this->other_auths);
528 while (e1->enumerate(e1, &cfg))
529 {
530 if (!e2->enumerate(e2, &cfg_done))
531 { /* this should not happen as the authentication should never have
532 * succeeded */
533 valid = FALSE;
534 break;
535 }
536 if ((uintptr_t)cfg_done->get(cfg_done,
537 AUTH_RULE_AUTH_CLASS) != AUTH_CLASS_PUBKEY)
538 {
539 continue;
540 }
541 peer = cfg_done->get(cfg_done, AUTH_RULE_SUBJECT_CERT);
542 if (!peer)
543 {
544 DBG1(DBG_IKE, "no subject certificate found, skipping certificate "
545 "verification");
546 continue;
547 }
548 if (!peer->get_validity(peer, NULL, &not_before, &not_after))
549 {
1b9c1ae0
TB
550 DBG1(DBG_IKE, "peer certificate invalid (valid from %T to %T)",
551 &not_before, FALSE, &not_after, FALSE);
552 valid = FALSE;
553 break;
554 }
555 key = peer->get_public_key(peer);
556 if (!key)
557 {
558 DBG1(DBG_IKE, "unable to retrieve public key, skipping certificate "
559 "verification");
560 continue;
561 }
562 DBG1(DBG_IKE, "verifying peer certificate");
563 /* serve received certificates */
564 wrapper = auth_cfg_wrapper_create(cfg_done);
565 lib->credmgr->add_local_set(lib->credmgr, &wrapper->set, FALSE);
566 certs = lib->credmgr->create_trusted_enumerator(lib->credmgr,
567 key->get_type(key), peer->get_subject(peer), TRUE);
568 key->destroy(key);
569
570 found = FALSE;
571 while (certs->enumerate(certs, &cert, &auth))
572 {
573 if (peer->equals(peer, cert))
574 {
575 cfg_done->add(cfg_done, AUTH_RULE_CERT_VALIDATION_SUSPENDED,
576 FALSE);
577 cfg_done->merge(cfg_done, auth, FALSE);
578 valid = cfg_done->complies(cfg_done, cfg, TRUE);
579 found = TRUE;
580 break;
581 }
582 }
583 certs->destroy(certs);
584 lib->credmgr->remove_local_set(lib->credmgr, &wrapper->set);
585 wrapper->destroy(wrapper);
586 if (!found || !valid)
587 {
588 valid = FALSE;
589 break;
590 }
591 }
592 e1->destroy(e1);
593 e2->destroy(e2);
1b9c1ae0 594
e41adf5f 595 if (this->flush_auth_cfg)
44ce7493 596 {
e41adf5f
TB
597 this->flush_auth_cfg = FALSE;
598 flush_auth_cfgs(this);
44ce7493 599 }
e41adf5f 600 return valid;
44ce7493
MW
601}
602
8bced61b
MW
603METHOD(ike_sa_t, get_proposal, proposal_t*,
604 private_ike_sa_t *this)
5dffdea1
MW
605{
606 return this->proposal;
607}
608
8bced61b
MW
609METHOD(ike_sa_t, set_proposal, void,
610 private_ike_sa_t *this, proposal_t *proposal)
5dffdea1
MW
611{
612 DESTROY_IF(this->proposal);
613 this->proposal = proposal->clone(proposal);
614}
615
8bced61b 616METHOD(ike_sa_t, set_message_id, void,
b12c53ce 617 private_ike_sa_t *this, bool initiate, uint32_t mid)
b09ca747
MW
618{
619 if (initiate)
620 {
f1f09810 621 this->task_manager->reset(this->task_manager, mid, UINT_MAX);
b09ca747
MW
622 }
623 else
624 {
f1f09810 625 this->task_manager->reset(this->task_manager, UINT_MAX, mid);
b09ca747
MW
626 }
627}
628
347c403c
TB
629METHOD(ike_sa_t, get_message_id, uint32_t,
630 private_ike_sa_t *this, bool initiate)
631{
632 return this->task_manager->get_mid(this->task_manager, initiate);
633}
634
8bced61b 635METHOD(ike_sa_t, send_keepalive, void,
efd7fa7b 636 private_ike_sa_t *this, bool scheduled)
2b3100b5 637{
2b3100b5 638 time_t last_out, now, diff;
7daf5226 639
efd7fa7b
TB
640 if (scheduled)
641 {
642 this->keepalive_job = NULL;
643 }
34f7d3b7
TB
644 if (!this->keepalive_interval || this->state == IKE_PASSIVE)
645 { /* keepalives disabled either by configuration or for passive IKE_SAs */
646 return;
647 }
648 if (!(this->conditions & COND_NAT_HERE) || (this->conditions & COND_STALE))
649 { /* disable keepalives if we are not NATed anymore, or the SA is stale */
3d928c9f
MW
650 return;
651 }
7daf5226 652
2b3100b5 653 last_out = get_use_time(this, FALSE);
6180a558 654 now = time_monotonic(NULL);
7daf5226 655
2b3100b5 656 diff = now - last_out;
7daf5226 657
3dfecde4 658 if (diff >= this->keepalive_interval)
2b3100b5
MW
659 {
660 packet_t *packet;
661 chunk_t data;
7daf5226 662
2b3100b5
MW
663 packet = packet_create();
664 packet->set_source(packet, this->my_host->clone(this->my_host));
665 packet->set_destination(packet, this->other_host->clone(this->other_host));
666 data.ptr = malloc(1);
667 data.ptr[0] = 0xFF;
668 data.len = 1;
669 packet->set_data(packet, data);
f3fefb18 670 DBG1(DBG_IKE, "sending keep alive to %#H", this->other_host);
75f83163 671 charon->sender->send_no_marker(charon->sender, packet);
2b3100b5
MW
672 diff = 0;
673 }
efd7fa7b
TB
674 if (!this->keepalive_job)
675 {
676 this->keepalive_job = send_keepalive_job_create(this->ike_sa_id);
677 lib->scheduler->schedule_job(lib->scheduler, (job_t*)this->keepalive_job,
678 this->keepalive_interval - diff);
679 }
2b3100b5
MW
680}
681
8bced61b
MW
682METHOD(ike_sa_t, get_ike_cfg, ike_cfg_t*,
683 private_ike_sa_t *this)
8dfbe71b 684{
e0fe7651 685 return this->ike_cfg;
8dfbe71b 686}
5b97779f 687
8bced61b
MW
688METHOD(ike_sa_t, set_ike_cfg, void,
689 private_ike_sa_t *this, ike_cfg_t *ike_cfg)
fe04e93a 690{
054ee5e7 691 DESTROY_IF(this->ike_cfg);
e0fe7651
MW
692 ike_cfg->get_ref(ike_cfg);
693 this->ike_cfg = ike_cfg;
fe04e93a 694}
4a035181 695
8bced61b
MW
696METHOD(ike_sa_t, enable_extension, void,
697 private_ike_sa_t *this, ike_extension_t extension)
2b3100b5
MW
698{
699 this->extensions |= extension;
700}
701
8bced61b
MW
702METHOD(ike_sa_t, supports_extension, bool,
703 private_ike_sa_t *this, ike_extension_t extension)
2b3100b5
MW
704{
705 return (this->extensions & extension) != FALSE;
706}
707
8bced61b
MW
708METHOD(ike_sa_t, has_condition, bool,
709 private_ike_sa_t *this, ike_condition_t condition)
2b3100b5
MW
710{
711 return (this->conditions & condition) != FALSE;
712}
713
8bced61b
MW
714METHOD(ike_sa_t, set_condition, void,
715 private_ike_sa_t *this, ike_condition_t condition, bool enable)
2b3100b5
MW
716{
717 if (has_condition(this, condition) != enable)
718 {
719 if (enable)
720 {
fc2d1c42 721 this->conditions |= condition;
2b3100b5
MW
722 switch (condition)
723 {
2b3100b5
MW
724 case COND_NAT_HERE:
725 DBG1(DBG_IKE, "local host is behind NAT, sending keep alives");
726 this->conditions |= COND_NAT_ANY;
efd7fa7b 727 send_keepalive(this, FALSE);
2b3100b5
MW
728 break;
729 case COND_NAT_THERE:
730 DBG1(DBG_IKE, "remote host is behind NAT");
731 this->conditions |= COND_NAT_ANY;
732 break;
9dae1bed 733 case COND_NAT_FAKE:
f53b74c9 734 DBG1(DBG_IKE, "faking NAT situation to enforce UDP encapsulation");
9dae1bed
MW
735 this->conditions |= COND_NAT_ANY;
736 break;
2b3100b5
MW
737 default:
738 break;
739 }
2b3100b5
MW
740 }
741 else
742 {
fc2d1c42 743 this->conditions &= ~condition;
2b3100b5
MW
744 switch (condition)
745 {
fc2d1c42
MW
746 case COND_NAT_HERE:
747 case COND_NAT_THERE:
f9056115
TB
748 DBG1(DBG_IKE, "%s host is not behind NAT anymore",
749 condition == COND_NAT_HERE ? "local" : "remote");
750 /* fall-through */
751 case COND_NAT_FAKE:
fc2d1c42
MW
752 set_condition(this, COND_NAT_ANY,
753 has_condition(this, COND_NAT_HERE) ||
9dae1bed
MW
754 has_condition(this, COND_NAT_THERE) ||
755 has_condition(this, COND_NAT_FAKE));
fc2d1c42 756 break;
34f7d3b7 757 case COND_STALE:
efd7fa7b 758 send_keepalive(this, FALSE);
34f7d3b7 759 break;
2b3100b5
MW
760 default:
761 break;
762 }
2b3100b5
MW
763 }
764 }
765}
fe04e93a 766
8bced61b
MW
767METHOD(ike_sa_t, send_dpd, status_t,
768 private_ike_sa_t *this)
fdb9b2bd 769{
6554b5e4 770 job_t *job;
fdb9b2bd 771 time_t diff, delay;
bcf8cdd5 772 bool task_queued = FALSE;
7daf5226 773
916cdca8
MW
774 if (this->state == IKE_PASSIVE)
775 {
776 return INVALID_STATE;
777 }
f15c85a4
TB
778 if (this->version == IKEV1 && this->state == IKE_REKEYING)
779 { /* don't send DPDs for rekeyed IKEv1 SAs */
780 return SUCCESS;
781 }
96926b00 782 delay = this->peer_cfg->get_dpd(this->peer_cfg);
fdb9b2bd
MW
783 if (this->task_manager->busy(this->task_manager))
784 {
785 /* an exchange is in the air, no need to start a DPD check */
786 diff = 0;
787 }
788 else
789 {
790 /* check if there was any inbound traffic */
791 time_t last_in, now;
792 last_in = get_use_time(this, TRUE);
6180a558 793 now = time_monotonic(NULL);
fdb9b2bd 794 diff = now - last_in;
6c2d466b 795 if (!delay || diff >= delay)
fdb9b2bd 796 {
bcf8cdd5 797 /* too long ago, initiate dead peer detection */
fdb9b2bd 798 DBG1(DBG_IKE, "sending DPD request");
244d715d 799 this->task_manager->queue_dpd(this->task_manager);
bcf8cdd5 800 task_queued = TRUE;
244d715d 801 diff = 0;
fdb9b2bd
MW
802 }
803 }
804 /* recheck in "interval" seconds */
6c2d466b
MW
805 if (delay)
806 {
807 job = (job_t*)send_dpd_job_create(this->ike_sa_id);
808 lib->scheduler->schedule_job(lib->scheduler, job, delay - diff);
809 }
bcf8cdd5
TB
810 if (task_queued)
811 {
812 return this->task_manager->initiate(this->task_manager);
813 }
814 return SUCCESS;
fdb9b2bd
MW
815}
816
8bced61b
MW
817METHOD(ike_sa_t, get_state, ike_sa_state_t,
818 private_ike_sa_t *this)
fdb9b2bd
MW
819{
820 return this->state;
821}
822
8bced61b
MW
823METHOD(ike_sa_t, set_state, void,
824 private_ike_sa_t *this, ike_sa_state_t state)
fdb9b2bd 825{
edaba56e 826 bool trigger_dpd = FALSE, keepalives = FALSE;
85dd6a8d 827
98ba96f1 828 DBG2(DBG_IKE, "IKE_SA %s[%d] state change: %N => %N",
51c8f826 829 get_name(this), this->unique_id,
fdb9b2bd
MW
830 ike_sa_state_names, this->state,
831 ike_sa_state_names, state);
7daf5226 832
0f33e826 833 switch (state)
fdb9b2bd 834 {
0f33e826 835 case IKE_ESTABLISHED:
fdb9b2bd 836 {
405cc1d9
MW
837 if (this->state == IKE_CONNECTING ||
838 this->state == IKE_PASSIVE)
0f33e826
MW
839 {
840 job_t *job;
b12c53ce 841 uint32_t t;
7daf5226 842
ee614711 843 /* calculate rekey, reauth and lifetime */
6180a558 844 this->stats[STAT_ESTABLISHED] = time_monotonic(NULL);
7daf5226 845
ee614711
MW
846 /* schedule rekeying if we have a time which is smaller than
847 * an already scheduled rekeying */
d08269c7 848 t = this->peer_cfg->get_rekey_time(this->peer_cfg, TRUE);
484a06bc 849 if (t && (this->stats[STAT_REKEY] == 0 ||
85ac2fa5 850 (this->stats[STAT_REKEY] > t + this->stats[STAT_ESTABLISHED])))
0f33e826 851 {
85ac2fa5 852 this->stats[STAT_REKEY] = t + this->stats[STAT_ESTABLISHED];
ee614711 853 job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE);
bb381e26 854 lib->scheduler->schedule_job(lib->scheduler, job, t);
ee614711 855 DBG1(DBG_IKE, "scheduling rekeying in %ds", t);
0f33e826 856 }
d08269c7 857 t = this->peer_cfg->get_reauth_time(this->peer_cfg, TRUE);
484a06bc 858 if (t && (this->stats[STAT_REAUTH] == 0 ||
85ac2fa5 859 (this->stats[STAT_REAUTH] > t + this->stats[STAT_ESTABLISHED])))
ee614711 860 {
85ac2fa5 861 this->stats[STAT_REAUTH] = t + this->stats[STAT_ESTABLISHED];
ee614711 862 job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
bb381e26 863 lib->scheduler->schedule_job(lib->scheduler, job, t);
ee614711
MW
864 DBG1(DBG_IKE, "scheduling reauthentication in %ds", t);
865 }
866 t = this->peer_cfg->get_over_time(this->peer_cfg);
85ac2fa5 867 if (this->stats[STAT_REKEY] || this->stats[STAT_REAUTH])
0f33e826 868 {
85ac2fa5 869 if (this->stats[STAT_REAUTH] == 0)
ee614711 870 {
85ac2fa5 871 this->stats[STAT_DELETE] = this->stats[STAT_REKEY];
ee614711 872 }
85ac2fa5 873 else if (this->stats[STAT_REKEY] == 0)
ee614711 874 {
85ac2fa5 875 this->stats[STAT_DELETE] = this->stats[STAT_REAUTH];
ee614711
MW
876 }
877 else
878 {
85ac2fa5
MW
879 this->stats[STAT_DELETE] = min(this->stats[STAT_REKEY],
880 this->stats[STAT_REAUTH]);
ee614711 881 }
85ac2fa5
MW
882 this->stats[STAT_DELETE] += t;
883 t = this->stats[STAT_DELETE] - this->stats[STAT_ESTABLISHED];
0f33e826 884 job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
bb381e26 885 lib->scheduler->schedule_job(lib->scheduler, job, t);
ee614711 886 DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
0f33e826 887 }
85dd6a8d 888 trigger_dpd = this->peer_cfg->get_dpd(this->peer_cfg);
b76e96e2
MW
889 if (trigger_dpd)
890 {
891 /* Some peers delay the DELETE after rekeying an IKE_SA.
892 * If this delay is longer than our DPD delay, we would
893 * send a DPD request here. The IKE_SA is not ready to do
894 * so yet, so prevent that. */
895 this->stats[STAT_INBOUND] = this->stats[STAT_ESTABLISHED];
896 }
edaba56e
TE
897 if (this->state == IKE_PASSIVE)
898 {
899 keepalives = TRUE;
900 }
e4af6e6b
TB
901 DESTROY_IF(this->redirected_from);
902 this->redirected_from = NULL;
0f33e826
MW
903 }
904 break;
fdb9b2bd 905 }
0f33e826
MW
906 default:
907 break;
fdb9b2bd 908 }
a985db3f 909 charon->bus->ike_state_change(charon->bus, &this->public, state);
fdb9b2bd 910 this->state = state;
85dd6a8d
MW
911
912 if (trigger_dpd)
913 {
f98af1dd
MW
914 if (supports_extension(this, EXT_DPD))
915 {
916 send_dpd(this);
917 }
918 else
919 {
920 DBG1(DBG_IKE, "DPD not supported by peer, disabled");
921 }
85dd6a8d 922 }
edaba56e
TE
923 if (keepalives)
924 {
efd7fa7b 925 send_keepalive(this, FALSE);
edaba56e 926 }
fdb9b2bd
MW
927}
928
8bced61b 929METHOD(ike_sa_t, reset, void,
c3539961 930 private_ike_sa_t *this, bool new_spi)
fdb9b2bd 931{
c3539961
TB
932 /* reset the initiator SPI if requested */
933 if (new_spi)
934 {
935 charon->ike_sa_manager->new_initiator_spi(charon->ike_sa_manager,
936 &this->public);
937 }
938 /* the responder ID is reset, as peer may choose another one */
fdb9b2bd
MW
939 if (this->ike_sa_id->is_initiator(this->ike_sa_id))
940 {
941 this->ike_sa_id->set_responder_spi(this->ike_sa_id, 0);
942 }
7daf5226 943
fdb9b2bd 944 set_state(this, IKE_CREATED);
7daf5226 945
550d9085
MW
946 flush_auth_cfgs(this);
947
948 this->keymat->destroy(this->keymat);
4b64a1a1
TB
949 this->keymat = keymat_create(this->version,
950 this->ike_sa_id->is_initiator(this->ike_sa_id));
550d9085 951
b09ca747 952 this->task_manager->reset(this->task_manager, 0, 0);
d9fe0ec7 953 this->task_manager->queue_ike(this->task_manager);
fdb9b2bd
MW
954}
955
8bced61b
MW
956METHOD(ike_sa_t, get_keymat, keymat_t*,
957 private_ike_sa_t *this)
6a4ff35c
MW
958{
959 return this->keymat;
960}
961
101d26ba 962METHOD(ike_sa_t, add_virtual_ip, void,
8bced61b 963 private_ike_sa_t *this, bool local, host_t *ip)
c532d646
MW
964{
965 if (local)
966 {
b185cdd1
MW
967 char *iface;
968
8394ea2a
TB
969 if (charon->kernel->get_interface(charon->kernel, this->my_host,
970 &iface))
c532d646 971 {
b185cdd1 972 DBG1(DBG_IKE, "installing new virtual IP %H", ip);
8394ea2a
TB
973 if (charon->kernel->add_ip(charon->kernel, ip, -1,
974 iface) == SUCCESS)
b185cdd1 975 {
893da041 976 array_insert_create(&this->my_vips, ARRAY_TAIL, ip->clone(ip));
b185cdd1
MW
977 }
978 else
979 {
980 DBG1(DBG_IKE, "installing virtual IP %H failed", ip);
981 }
982 free(iface);
c532d646
MW
983 }
984 else
985 {
b185cdd1 986 DBG1(DBG_IKE, "looking up interface for virtual IP %H failed", ip);
c532d646
MW
987 }
988 }
989 else
990 {
893da041 991 array_insert_create(&this->other_vips, ARRAY_TAIL, ip->clone(ip));
c532d646
MW
992 }
993}
994
d2e8f20d
TB
995
996METHOD(ike_sa_t, clear_virtual_ips, void,
997 private_ike_sa_t *this, bool local)
998{
893da041 999 array_t *vips;
d2e8f20d
TB
1000 host_t *vip;
1001
893da041
MW
1002 vips = local ? this->my_vips : this->other_vips;
1003 if (!local && array_count(vips))
12fa1784
AS
1004 {
1005 charon->bus->assign_vips(charon->bus, &this->public, FALSE);
1006 }
893da041 1007 while (array_remove(vips, ARRAY_HEAD, &vip))
d2e8f20d
TB
1008 {
1009 if (local)
1010 {
8394ea2a 1011 charon->kernel->del_ip(charon->kernel, vip, -1, TRUE);
d2e8f20d
TB
1012 }
1013 vip->destroy(vip);
1014 }
1015}
1016
101d26ba 1017METHOD(ike_sa_t, create_virtual_ip_enumerator, enumerator_t*,
8bced61b 1018 private_ike_sa_t *this, bool local)
c532d646
MW
1019{
1020 if (local)
1021 {
893da041 1022 return array_create_enumerator(this->my_vips);
c532d646 1023 }
893da041 1024 return array_create_enumerator(this->other_vips);
c532d646
MW
1025}
1026
94bbc602 1027METHOD(ike_sa_t, add_peer_address, void,
8bced61b 1028 private_ike_sa_t *this, host_t *host)
c532d646 1029{
893da041 1030 array_insert_create(&this->peer_addresses, ARRAY_TAIL, host);
c532d646 1031}
7daf5226 1032
94bbc602 1033METHOD(ike_sa_t, create_peer_address_enumerator, enumerator_t*,
8bced61b 1034 private_ike_sa_t *this)
c532d646 1035{
893da041 1036 if (this->peer_addresses)
12715f19 1037 {
893da041 1038 return array_create_enumerator(this->peer_addresses);
12715f19
TB
1039 }
1040 /* in case we don't have MOBIKE */
1041 return enumerator_create_single(this->other_host, NULL);
572abc6c
TB
1042}
1043
94bbc602 1044METHOD(ike_sa_t, clear_peer_addresses, void,
572abc6c
TB
1045 private_ike_sa_t *this)
1046{
893da041
MW
1047 array_destroy_offset(this->peer_addresses, offsetof(host_t, destroy));
1048 this->peer_addresses = NULL;
c532d646 1049}
9d9a772e 1050
8bced61b
MW
1051METHOD(ike_sa_t, has_mapping_changed, bool,
1052 private_ike_sa_t *this, chunk_t hash)
9d9a772e
MW
1053{
1054 if (this->nat_detection_dest.ptr == NULL)
1055 {
1056 this->nat_detection_dest = chunk_clone(hash);
1057 return FALSE;
1058 }
1059 if (chunk_equals(hash, this->nat_detection_dest))
1060 {
1061 return FALSE;
1062 }
1063 free(this->nat_detection_dest.ptr);
1064 this->nat_detection_dest = chunk_clone(hash);
1065 return TRUE;
1066}
1067
277f02ce
TB
1068METHOD(ike_sa_t, float_ports, void,
1069 private_ike_sa_t *this)
1070{
85bfab62
TB
1071 /* even if the remote port is not 500 (e.g. because the response was natted)
1072 * we switch the remote port if we used port 500 */
1073 if (this->other_host->get_port(this->other_host) == IKEV2_UDP_PORT ||
1074 this->my_host->get_port(this->my_host) == IKEV2_UDP_PORT)
1075 {
1076 this->other_host->set_port(this->other_host, IKEV2_NATT_PORT);
1077 }
b223d517
TB
1078 if (this->my_host->get_port(this->my_host) ==
1079 charon->socket->get_port(charon->socket, FALSE))
277f02ce 1080 {
b223d517
TB
1081 this->my_host->set_port(this->my_host,
1082 charon->socket->get_port(charon->socket, TRUE));
277f02ce 1083 }
277f02ce
TB
1084}
1085
8bced61b 1086METHOD(ike_sa_t, update_hosts, void,
2082417d 1087 private_ike_sa_t *this, host_t *me, host_t *other, bool force)
0fdc3c7f 1088{
2b3100b5 1089 bool update = FALSE;
7daf5226 1090
2b3100b5 1091 if (me == NULL)
8dfbe71b 1092 {
2b3100b5 1093 me = this->my_host;
8dfbe71b 1094 }
2b3100b5 1095 if (other == NULL)
3dd3c5f3 1096 {
2b3100b5 1097 other = this->other_host;
3dd3c5f3 1098 }
7daf5226 1099
2b3100b5
MW
1100 /* apply hosts on first received message */
1101 if (this->my_host->is_anyaddr(this->my_host) ||
1102 this->other_host->is_anyaddr(this->other_host))
3dd3c5f3 1103 {
2b3100b5
MW
1104 set_my_host(this, me->clone(me));
1105 set_other_host(this, other->clone(other));
1106 update = TRUE;
3dd3c5f3
MW
1107 }
1108 else
1109 {
2b3100b5 1110 /* update our address in any case */
21dd4c4b 1111 if (force && !me->equals(me, this->my_host))
3dd3c5f3 1112 {
e1fe2781 1113 charon->bus->ike_update(charon->bus, &this->public, TRUE, me);
2b3100b5
MW
1114 set_my_host(this, me->clone(me));
1115 update = TRUE;
3dd3c5f3 1116 }
7daf5226 1117
472156ee
TB
1118 if (!other->equals(other, this->other_host) &&
1119 (force || has_condition(this, COND_NAT_THERE)))
3dd3c5f3 1120 {
472156ee
TB
1121 /* only update other's address if we are behind a static NAT,
1122 * which we assume is the case if we are not initiator */
1123 if (force ||
1124 (!has_condition(this, COND_NAT_HERE) ||
1125 !has_condition(this, COND_ORIGINAL_INITIATOR)))
2b3100b5 1126 {
e1fe2781 1127 charon->bus->ike_update(charon->bus, &this->public, FALSE, other);
2b3100b5
MW
1128 set_other_host(this, other->clone(other));
1129 update = TRUE;
1130 }
3dd3c5f3
MW
1131 }
1132 }
7daf5226 1133
2b3100b5
MW
1134 /* update all associated CHILD_SAs, if required */
1135 if (update)
3dd3c5f3 1136 {
e2630434 1137 enumerator_t *enumerator;
2b3100b5 1138 child_sa_t *child_sa;
893da041 1139 linked_list_t *vips;
7daf5226 1140
893da041
MW
1141 vips = linked_list_create_from_enumerator(
1142 array_create_enumerator(this->my_vips));
1143
1144 enumerator = array_create_enumerator(this->child_sas);
1145 while (enumerator->enumerate(enumerator, &child_sa))
2b3100b5 1146 {
38227d0e
MW
1147 charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
1148 charon->child_sa_manager->add(charon->child_sa_manager,
1149 child_sa, &this->public);
1150
893da041
MW
1151 if (child_sa->update(child_sa, this->my_host, this->other_host,
1152 vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
ea625fab
TB
1153 {
1154 this->public.rekey_child_sa(&this->public,
1155 child_sa->get_protocol(child_sa),
1156 child_sa->get_spi(child_sa, TRUE));
1157 }
38227d0e 1158
2b3100b5 1159 }
e2630434 1160 enumerator->destroy(enumerator);
893da041
MW
1161
1162 vips->destroy(vips);
3dd3c5f3 1163 }
8d77edde
MW
1164}
1165
5b15bd5f
MW
1166/**
1167 * Set configured DSCP value on packet
1168 */
1169static void set_dscp(private_ike_sa_t *this, packet_t *packet)
1170{
1171 ike_cfg_t *ike_cfg;
1172
1173 /* prefer IKE config on peer_cfg, as its selection is more accurate
1174 * then the initial IKE config */
1175 if (this->peer_cfg)
1176 {
1177 ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg);
1178 }
1179 else
1180 {
1181 ike_cfg = this->ike_cfg;
1182 }
1183 if (ike_cfg)
1184 {
1185 packet->set_dscp(packet, ike_cfg->get_dscp(ike_cfg));
1186 }
1187}
1188
8bced61b
MW
1189METHOD(ike_sa_t, generate_message, status_t,
1190 private_ike_sa_t *this, message_t *message, packet_t **packet)
8d77edde 1191{
47b8f6ef
MW
1192 status_t status;
1193
9ca5d028 1194 if (message->is_encoded(message))
5b15bd5f 1195 { /* already encoded in task, but set DSCP value */
9ca5d028 1196 *packet = message->get_packet(message);
5b15bd5f 1197 set_dscp(this, *packet);
9ca5d028
MW
1198 return SUCCESS;
1199 }
6180a558 1200 this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
c60c7694 1201 message->set_ike_sa_id(message, this->ike_sa_id);
47b8f6ef
MW
1202 charon->bus->message(charon->bus, message, FALSE, TRUE);
1203 status = message->generate(message, this->keymat, packet);
1204 if (status == SUCCESS)
c60c7694 1205 {
5b15bd5f 1206 set_dscp(this, *packet);
47b8f6ef 1207 charon->bus->message(charon->bus, message, FALSE, FALSE);
b9d9f188 1208 }
47b8f6ef 1209 return status;
3dd3c5f3
MW
1210}
1211
525cc46c
TB
1212CALLBACK(filter_fragments, bool,
1213 private_ike_sa_t *this, enumerator_t *orig, va_list args)
40bab9a1 1214{
525cc46c
TB
1215 packet_t *fragment, **packet;
1216
1217 VA_ARGS_VGET(args, packet);
1218
1219 if (orig->enumerate(orig, &fragment))
1220 {
1221 *packet = fragment->clone(fragment);
1222 set_dscp(this, *packet);
1223 return TRUE;
1224 }
1225 return FALSE;
40bab9a1
TB
1226}
1227
1228METHOD(ike_sa_t, generate_message_fragmented, status_t,
1229 private_ike_sa_t *this, message_t *message, enumerator_t **packets)
1230{
1231 enumerator_t *fragments;
1232 packet_t *packet;
1233 status_t status;
1234 bool use_frags = FALSE;
e35bb6e9 1235 bool pre_generated = FALSE;
40bab9a1 1236
1446fd8a 1237 if (this->ike_cfg)
40bab9a1
TB
1238 {
1239 switch (this->ike_cfg->fragmentation(this->ike_cfg))
1240 {
1241 case FRAGMENTATION_FORCE:
1242 use_frags = TRUE;
1243 break;
1244 case FRAGMENTATION_YES:
1245 use_frags = supports_extension(this, EXT_IKE_FRAGMENTATION);
05db0f97
VR
1246 if (use_frags && this->version == IKEV1 &&
1247 supports_extension(this, EXT_MS_WINDOWS))
1248 {
1249 /* It seems Windows 7 and 8 peers only accept proprietary
1250 * fragmented messages if they expect certificates. */
1251 use_frags = message->get_payload(message,
1252 PLV1_CERTIFICATE) != NULL;
1253 }
40bab9a1
TB
1254 break;
1255 default:
1256 break;
1257 }
1258 }
1259 if (!use_frags)
1260 {
1261 status = generate_message(this, message, &packet);
1262 if (status != SUCCESS)
1263 {
1264 return status;
1265 }
1266 *packets = enumerator_create_single(packet, NULL);
1267 return SUCCESS;
1268 }
1269
e35bb6e9 1270 pre_generated = message->is_encoded(message);
40bab9a1
TB
1271 this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
1272 message->set_ike_sa_id(message, this->ike_sa_id);
e35bb6e9
TB
1273 if (!pre_generated)
1274 {
1275 charon->bus->message(charon->bus, message, FALSE, TRUE);
1276 }
40bab9a1
TB
1277 status = message->fragment(message, this->keymat, this->fragment_size,
1278 &fragments);
1279 if (status == SUCCESS)
1280 {
e35bb6e9
TB
1281 if (!pre_generated)
1282 {
1283 charon->bus->message(charon->bus, message, FALSE, FALSE);
1284 }
525cc46c 1285 *packets = enumerator_create_filter(fragments, filter_fragments,
40bab9a1
TB
1286 this, NULL);
1287 }
1288 return status;
1289}
1290
8bced61b
MW
1291METHOD(ike_sa_t, set_kmaddress, void,
1292 private_ike_sa_t *this, host_t *local, host_t *remote)
d487b4b7
AS
1293{
1294 DESTROY_IF(this->local_host);
1295 DESTROY_IF(this->remote_host);
1296 this->local_host = local->clone(local);
1297 this->remote_host = remote->clone(remote);
1298}
1299
dc04b7c7 1300#ifdef ME
8bced61b
MW
1301METHOD(ike_sa_t, act_as_mediation_server, void,
1302 private_ike_sa_t *this)
22452f70
TB
1303{
1304 charon->mediation_manager->update_sa_id(charon->mediation_manager,
1305 this->other_id, this->ike_sa_id);
1306 this->is_mediation_server = TRUE;
1307}
1308
8bced61b
MW
1309METHOD(ike_sa_t, get_server_reflexive_host, host_t*,
1310 private_ike_sa_t *this)
d5cc1758
TB
1311{
1312 return this->server_reflexive_host;
1313}
1314
8bced61b
MW
1315METHOD(ike_sa_t, set_server_reflexive_host, void,
1316 private_ike_sa_t *this, host_t *host)
d5cc1758
TB
1317{
1318 DESTROY_IF(this->server_reflexive_host);
1319 this->server_reflexive_host = host;
1320}
1321
8bced61b
MW
1322METHOD(ike_sa_t, get_connect_id, chunk_t,
1323 private_ike_sa_t *this)
9c2a905d
TB
1324{
1325 return this->connect_id;
1326}
1327
8bced61b
MW
1328METHOD(ike_sa_t, respond, status_t,
1329 private_ike_sa_t *this, identification_t *peer_id, chunk_t connect_id)
d5cc1758 1330{
dc04b7c7
TB
1331 ike_me_t *task = ike_me_create(&this->public, TRUE);
1332 task->respond(task, peer_id, connect_id);
d5cc1758
TB
1333 this->task_manager->queue_task(this->task_manager, (task_t*)task);
1334 return this->task_manager->initiate(this->task_manager);
1335}
1336
8bced61b
MW
1337METHOD(ike_sa_t, callback, status_t,
1338 private_ike_sa_t *this, identification_t *peer_id)
d5cc1758 1339{
dc04b7c7 1340 ike_me_t *task = ike_me_create(&this->public, TRUE);
d5cc1758
TB
1341 task->callback(task, peer_id);
1342 this->task_manager->queue_task(this->task_manager, (task_t*)task);
1343 return this->task_manager->initiate(this->task_manager);
1344}
1345
8bced61b
MW
1346METHOD(ike_sa_t, relay, status_t,
1347 private_ike_sa_t *this, identification_t *requester, chunk_t connect_id,
1348 chunk_t connect_key, linked_list_t *endpoints, bool response)
d5cc1758 1349{
dc04b7c7
TB
1350 ike_me_t *task = ike_me_create(&this->public, TRUE);
1351 task->relay(task, requester, connect_id, connect_key, endpoints, response);
d5cc1758
TB
1352 this->task_manager->queue_task(this->task_manager, (task_t*)task);
1353 return this->task_manager->initiate(this->task_manager);
1354}
1355
8bced61b
MW
1356METHOD(ike_sa_t, initiate_mediation, status_t,
1357 private_ike_sa_t *this, peer_cfg_t *mediated_cfg)
d5cc1758 1358{
dc04b7c7 1359 ike_me_t *task = ike_me_create(&this->public, TRUE);
d5cc1758
TB
1360 task->connect(task, mediated_cfg->get_peer_id(mediated_cfg));
1361 this->task_manager->queue_task(this->task_manager, (task_t*)task);
1362 return this->task_manager->initiate(this->task_manager);
1363}
1364
8bced61b
MW
1365METHOD(ike_sa_t, initiate_mediated, status_t,
1366 private_ike_sa_t *this, host_t *me, host_t *other, chunk_t connect_id)
d5cc1758 1367{
471f9230
TB
1368 set_my_host(this, me->clone(me));
1369 set_other_host(this, other->clone(other));
4a6474c2 1370 chunk_free(&this->connect_id);
9c2a905d 1371 this->connect_id = chunk_clone(connect_id);
d5cc1758
TB
1372 return this->task_manager->initiate(this->task_manager);
1373}
dc04b7c7 1374#endif /* ME */
d5cc1758 1375
5a22a021
MW
1376/**
1377 * Resolve DNS host in configuration
1378 */
1379static void resolve_hosts(private_ike_sa_t *this)
1380{
1381 host_t *host;
0edce687 1382 int family = AF_UNSPEC;
bf92887a
TB
1383
1384 switch (charon->socket->supported_families(charon->socket))
1385 {
1386 case SOCKET_FAMILY_IPV4:
1387 family = AF_INET;
1388 break;
1389 case SOCKET_FAMILY_IPV6:
1390 family = AF_INET6;
1391 break;
1392 case SOCKET_FAMILY_BOTH:
1393 case SOCKET_FAMILY_NONE:
1394 break;
1395 }
7daf5226 1396
a11048ad
TB
1397 /* if an IP address is set locally, use the same family to resolve remote */
1398 if (family == AF_UNSPEC && !this->remote_host)
1399 {
1400 if (this->local_host)
1401 {
1402 family = this->local_host->get_family(this->local_host);
1403 }
1404 else
1405 {
1406 family = ike_cfg_get_family(this->ike_cfg, TRUE);
1407 }
1408 }
1409
d487b4b7
AS
1410 if (this->remote_host)
1411 {
1412 host = this->remote_host->clone(this->remote_host);
1413 host->set_port(host, IKEV2_UDP_PORT);
1414 }
1415 else
1416 {
0edce687 1417 host = this->ike_cfg->resolve_other(this->ike_cfg, family);
d487b4b7 1418 }
5a22a021
MW
1419 if (host)
1420 {
6f7a3b33
TB
1421 if (!host->is_anyaddr(host) ||
1422 this->other_host->is_anyaddr(this->other_host))
1423 { /* don't set to %any if we currently have an address, but the
1424 * address family might have changed */
1425 set_other_host(this, host);
1426 }
faebdeac 1427 else
2d14cb4d
TB
1428 { /* reuse the original port as some implementations might not like
1429 * initial IKE messages on other ports */
1430 this->other_host->set_port(this->other_host, host->get_port(host));
faebdeac
TB
1431 host->destroy(host);
1432 }
5a22a021 1433 }
7daf5226 1434
d487b4b7 1435 if (this->local_host)
e7991a2e 1436 {
d487b4b7 1437 host = this->local_host->clone(this->local_host);
b223d517 1438 host->set_port(host, charon->socket->get_port(charon->socket, FALSE));
d487b4b7
AS
1439 }
1440 else
1441 {
c6a8990b
MW
1442 /* use same address family as for other */
1443 if (!this->other_host->is_anyaddr(this->other_host))
1444 {
1445 family = this->other_host->get_family(this->other_host);
1446 }
0edce687 1447 host = this->ike_cfg->resolve_me(this->ike_cfg, family);
7daf5226 1448
d487b4b7
AS
1449 if (host && host->is_anyaddr(host) &&
1450 !this->other_host->is_anyaddr(this->other_host))
5353f22e 1451 {
d487b4b7 1452 host->destroy(host);
8394ea2a
TB
1453 host = charon->kernel->get_source_addr(charon->kernel,
1454 this->other_host, NULL);
d487b4b7
AS
1455 if (host)
1456 {
cc2eadde 1457 host->set_port(host, this->ike_cfg->get_my_port(this->ike_cfg));
d487b4b7 1458 }
9717826f
MW
1459 else
1460 { /* fallback to address family specific %any(6), if configured */
0edce687 1461 host = this->ike_cfg->resolve_me(this->ike_cfg, family);
9717826f 1462 }
5353f22e 1463 }
e7991a2e 1464 }
5a22a021
MW
1465 if (host)
1466 {
e7991a2e 1467 set_my_host(this, host);
5a22a021
MW
1468 }
1469}
1470
8bced61b 1471METHOD(ike_sa_t, initiate, status_t,
b12c53ce 1472 private_ike_sa_t *this, child_cfg_t *child_cfg, uint32_t reqid,
8bced61b 1473 traffic_selector_t *tsi, traffic_selector_t *tsr)
aad398a7 1474{
60c82591
TB
1475 bool defer_initiate = FALSE;
1476
c60c7694 1477 if (this->state == IKE_CREATED)
c0593835 1478 {
a994050e
MW
1479 if (this->my_host->is_anyaddr(this->my_host) ||
1480 this->other_host->is_anyaddr(this->other_host))
1481 {
1482 resolve_hosts(this);
1483 }
7daf5226 1484
d5cc1758 1485 if (this->other_host->is_anyaddr(this->other_host)
dc04b7c7 1486#ifdef ME
d5cc1758 1487 && !this->peer_cfg->get_mediated_by(this->peer_cfg)
dc04b7c7 1488#endif /* ME */
d5cc1758 1489 )
128ca073 1490 {
0edce687
MW
1491 char *addr;
1492
be8af56e 1493 addr = this->ike_cfg->get_other_addr(this->ike_cfg);
53d2164c 1494 if (!this->retry_initiate_interval)
60c82591 1495 {
53d2164c
TB
1496 DBG1(DBG_IKE, "unable to resolve %s, initiate aborted",
1497 addr);
60c82591
TB
1498 DESTROY_IF(child_cfg);
1499 charon->bus->alert(charon->bus, ALERT_PEER_ADDR_FAILED);
1500 return DESTROY_ME;
1501 }
1502 DBG1(DBG_IKE, "unable to resolve %s, retrying in %ds",
1503 addr, this->retry_initiate_interval);
1504 defer_initiate = TRUE;
128ca073 1505 }
7daf5226 1506
faf9569f 1507 set_condition(this, COND_ORIGINAL_INITIATOR, TRUE);
a60daa07 1508 this->task_manager->queue_ike(this->task_manager);
d5cc1758
TB
1509 }
1510
dc04b7c7 1511#ifdef ME
4a6474c2 1512 if (this->peer_cfg->is_mediation(this->peer_cfg))
f967db31
TB
1513 {
1514 if (this->state == IKE_ESTABLISHED)
1515 {
484a06bc
TB
1516 /* mediation connection is already established, retrigger state
1517 * change to notify bus listeners */
f967db31
TB
1518 DBG1(DBG_IKE, "mediation connection is already up");
1519 set_state(this, IKE_ESTABLISHED);
1520 }
c3f803c4 1521 DESTROY_IF(child_cfg);
d5cc1758
TB
1522 }
1523 else
dc04b7c7 1524#endif /* ME */
9c64f214 1525 if (child_cfg)
d5cc1758 1526 {
38951252 1527 /* normal IKE_SA with CHILD_SA */
fe43d9a2
MW
1528 this->task_manager->queue_child(this->task_manager, child_cfg, reqid,
1529 tsi, tsr);
4a6474c2
TB
1530#ifdef ME
1531 if (this->peer_cfg->get_mediated_by(this->peer_cfg))
1532 {
1533 /* mediated connection, initiate mediation process */
1534 job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id);
bb381e26 1535 lib->processor->queue_job(lib->processor, job);
4a6474c2
TB
1536 return SUCCESS;
1537 }
1538#endif /* ME */
c60c7694 1539 }
7daf5226 1540
60c82591
TB
1541 if (defer_initiate)
1542 {
77e42826
TB
1543 if (!this->retry_initiate_queued)
1544 {
1545 job_t *job = (job_t*)retry_initiate_job_create(this->ike_sa_id);
1546 lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
1547 this->retry_initiate_interval);
1548 this->retry_initiate_queued = TRUE;
1549 }
60c82591
TB
1550 return SUCCESS;
1551 }
77e42826 1552 this->retry_initiate_queued = FALSE;
c60c7694 1553 return this->task_manager->initiate(this->task_manager);
aad398a7
JH
1554}
1555
77e42826
TB
1556METHOD(ike_sa_t, retry_initiate, status_t,
1557 private_ike_sa_t *this)
1558{
1559 if (this->retry_initiate_queued)
1560 {
1561 this->retry_initiate_queued = FALSE;
1562 return initiate(this, NULL, 0, NULL, NULL);
1563 }
1564 return SUCCESS;
1565}
1566
8bced61b
MW
1567METHOD(ike_sa_t, process_message, status_t,
1568 private_ike_sa_t *this, message_t *message)
98f97433
MW
1569{
1570 status_t status;
7daf5226 1571
c610f424
MW
1572 if (this->state == IKE_PASSIVE)
1573 { /* do not handle messages in passive state */
1574 return FAILED;
1575 }
448e2e29 1576 if (message->get_major_version(message) != this->version)
98f97433 1577 {
448e2e29 1578 DBG1(DBG_IKE, "ignoring %N IKEv%u exchange on %N SA",
98f97433 1579 exchange_type_names, message->get_exchange_type(message),
448e2e29
MW
1580 message->get_major_version(message),
1581 ike_version_names, this->version);
1582 /* TODO-IKEv1: fall back to IKEv1 if we receive an IKEv1
1583 * INVALID_MAJOR_VERSION on an IKEv2 SA. */
1584 return FAILED;
98f97433 1585 }
68c6863b 1586 status = this->task_manager->process_message(this->task_manager, message);
b24b73b7 1587 if (this->flush_auth_cfg && this->state == IKE_ESTABLISHED)
98f97433 1588 {
e41adf5f
TB
1589 /* authentication completed but if the online validation is suspended we
1590 * need the auth cfgs until we did the delayed verification, we flush
1591 * them afterwards */
1592 if (!has_condition(this, COND_ONLINE_VALIDATION_SUSPENDED))
1593 {
1594 this->flush_auth_cfg = FALSE;
1595 flush_auth_cfgs(this);
1596 }
98f97433 1597 }
44ce7493 1598 return status;
98f97433 1599}
8dfbe71b 1600
8bced61b
MW
1601METHOD(ike_sa_t, get_id, ike_sa_id_t*,
1602 private_ike_sa_t *this)
0df63d6b 1603{
8dfbe71b 1604 return this->ike_sa_id;
0df63d6b
JH
1605}
1606
0b611540
TB
1607METHOD(ike_sa_t, get_version, ike_version_t,
1608 private_ike_sa_t *this)
1609{
1610 return this->version;
1611}
1612
8bced61b
MW
1613METHOD(ike_sa_t, get_my_id, identification_t*,
1614 private_ike_sa_t *this)
0fdc3c7f 1615{
8dfbe71b 1616 return this->my_id;
8d68033e
JH
1617}
1618
8bced61b
MW
1619METHOD(ike_sa_t, set_my_id, void,
1620 private_ike_sa_t *this, identification_t *me)
8d68033e 1621{
c0593835 1622 DESTROY_IF(this->my_id);
8dfbe71b 1623 this->my_id = me;
0fdc3c7f
JH
1624}
1625
8bced61b
MW
1626METHOD(ike_sa_t, get_other_id, identification_t*,
1627 private_ike_sa_t *this)
30b5b412 1628{
8dfbe71b 1629 return this->other_id;
3dd3c5f3 1630}
8dfbe71b 1631
8bced61b
MW
1632METHOD(ike_sa_t, get_other_eap_id, identification_t*,
1633 private_ike_sa_t *this)
045833c7
MW
1634{
1635 identification_t *id = NULL, *current;
1636 enumerator_t *enumerator;
1637 auth_cfg_t *cfg;
1638
893da041 1639 enumerator = array_create_enumerator(this->other_auths);
045833c7
MW
1640 while (enumerator->enumerate(enumerator, &cfg))
1641 {
1642 /* prefer EAP-Identity of last round */
1643 current = cfg->get(cfg, AUTH_RULE_EAP_IDENTITY);
1644 if (!current || current->get_type(current) == ID_ANY)
beab4a90
MW
1645 {
1646 current = cfg->get(cfg, AUTH_RULE_XAUTH_IDENTITY);
1647 }
1648 if (!current || current->get_type(current) == ID_ANY)
045833c7
MW
1649 {
1650 current = cfg->get(cfg, AUTH_RULE_IDENTITY);
1651 }
1652 if (current && current->get_type(current) != ID_ANY)
1653 {
1654 id = current;
1655 continue;
1656 }
1657 }
1658 enumerator->destroy(enumerator);
1659 if (id)
1660 {
1661 return id;
1662 }
1663 return this->other_id;
1664}
1665
8bced61b
MW
1666METHOD(ike_sa_t, set_other_id, void,
1667 private_ike_sa_t *this, identification_t *other)
3dd3c5f3 1668{
c0593835 1669 DESTROY_IF(this->other_id);
8dfbe71b 1670 this->other_id = other;
30b5b412
MW
1671}
1672
dec3c184
TB
1673METHOD(ike_sa_t, get_if_id, uint32_t,
1674 private_ike_sa_t *this, bool inbound)
1675{
1676 return inbound ? this->if_id_in : this->if_id_out;
1677}
1678
8bced61b
MW
1679METHOD(ike_sa_t, add_child_sa, void,
1680 private_ike_sa_t *this, child_sa_t *child_sa)
32b6500f 1681{
893da041 1682 array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa);
38227d0e
MW
1683 charon->child_sa_manager->add(charon->child_sa_manager,
1684 child_sa, &this->public);
32b6500f
MW
1685}
1686
8bced61b 1687METHOD(ike_sa_t, get_child_sa, child_sa_t*,
b12c53ce 1688 private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi, bool inbound)
695723d4 1689{
e2630434 1690 enumerator_t *enumerator;
695723d4 1691 child_sa_t *current, *found = NULL;
7daf5226 1692
893da041 1693 enumerator = array_create_enumerator(this->child_sas);
e2630434 1694 while (enumerator->enumerate(enumerator, (void**)&current))
c60c7694 1695 {
698d7749 1696 if (current->get_spi(current, inbound) == spi &&
191a26a6 1697 current->get_protocol(current) == protocol)
695723d4
MW
1698 {
1699 found = current;
1700 }
1701 }
e2630434 1702 enumerator->destroy(enumerator);
695723d4 1703 return found;
8d77edde
MW
1704}
1705
4bbce1ef 1706METHOD(ike_sa_t, get_child_count, int,
8bced61b 1707 private_ike_sa_t *this)
3183006d 1708{
893da041 1709 return array_count(this->child_sas);
4bbce1ef
TB
1710}
1711
38227d0e
MW
1712/**
1713 * Private data of a create_child_sa_enumerator()
1714 */
1715typedef struct {
1716 /** implements enumerator */
1717 enumerator_t public;
1718 /** inner array enumerator */
1719 enumerator_t *inner;
1720 /** current item */
1721 child_sa_t *current;
1722} child_enumerator_t;
1723
1724METHOD(enumerator_t, child_enumerate, bool,
95a63bf2 1725 child_enumerator_t *this, va_list args)
38227d0e 1726{
95a63bf2
TB
1727 child_sa_t **child_sa;
1728
1729 VA_ARGS_VGET(args, child_sa);
38227d0e
MW
1730 if (this->inner->enumerate(this->inner, &this->current))
1731 {
1732 *child_sa = this->current;
1733 return TRUE;
1734 }
1735 return FALSE;
1736}
1737
1738METHOD(enumerator_t, child_enumerator_destroy, void,
1739 child_enumerator_t *this)
1740{
1741 this->inner->destroy(this->inner);
1742 free(this);
1743}
1744
4bbce1ef
TB
1745METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*,
1746 private_ike_sa_t *this)
1747{
38227d0e
MW
1748 child_enumerator_t *enumerator;
1749
1750 INIT(enumerator,
1751 .public = {
95a63bf2
TB
1752 .enumerate = enumerator_enumerate_default,
1753 .venumerate = _child_enumerate,
38227d0e
MW
1754 .destroy = _child_enumerator_destroy,
1755 },
1756 .inner = array_create_enumerator(this->child_sas),
1757 );
1758 return &enumerator->public;
4bbce1ef
TB
1759}
1760
1761METHOD(ike_sa_t, remove_child_sa, void,
1762 private_ike_sa_t *this, enumerator_t *enumerator)
1763{
38227d0e
MW
1764 child_enumerator_t *ce = (child_enumerator_t*)enumerator;
1765
1766 charon->child_sa_manager->remove(charon->child_sa_manager, ce->current);
1767 array_remove_at(this->child_sas, ce->inner);
3183006d
MW
1768}
1769
8bced61b 1770METHOD(ike_sa_t, rekey_child_sa, status_t,
b12c53ce 1771 private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi)
8d77edde 1772{
916cdca8
MW
1773 if (this->state == IKE_PASSIVE)
1774 {
1775 return INVALID_STATE;
1776 }
463a73cc 1777 this->task_manager->queue_child_rekey(this->task_manager, protocol, spi);
394eb35b 1778 return this->task_manager->initiate(this->task_manager);
698d7749
MW
1779}
1780
8bced61b 1781METHOD(ike_sa_t, delete_child_sa, status_t,
b12c53ce 1782 private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi, bool expired)
698d7749 1783{
916cdca8
MW
1784 if (this->state == IKE_PASSIVE)
1785 {
1786 return INVALID_STATE;
1787 }
3a925f74
MW
1788 this->task_manager->queue_child_delete(this->task_manager,
1789 protocol, spi, expired);
394eb35b 1790 return this->task_manager->initiate(this->task_manager);
698d7749
MW
1791}
1792
8bced61b 1793METHOD(ike_sa_t, destroy_child_sa, status_t,
b12c53ce 1794 private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi)
698d7749 1795{
e2630434 1796 enumerator_t *enumerator;
698d7749
MW
1797 child_sa_t *child_sa;
1798 status_t status = NOT_FOUND;
7daf5226 1799
38227d0e 1800 enumerator = create_child_sa_enumerator(this);
e2630434 1801 while (enumerator->enumerate(enumerator, (void**)&child_sa))
698d7749
MW
1802 {
1803 if (child_sa->get_protocol(child_sa) == protocol &&
1804 child_sa->get_spi(child_sa, TRUE) == spi)
1805 {
38227d0e 1806 remove_child_sa(this, enumerator);
698d7749 1807 child_sa->destroy(child_sa);
698d7749
MW
1808 status = SUCCESS;
1809 break;
1810 }
8d77edde 1811 }
e2630434 1812 enumerator->destroy(enumerator);
698d7749 1813 return status;
8d77edde
MW
1814}
1815
8bced61b 1816METHOD(ike_sa_t, delete_, status_t,
a79d5103 1817 private_ike_sa_t *this, bool force)
6fe03b0a 1818{
a79d5103
TB
1819 status_t status = DESTROY_ME;
1820
6fe03b0a
MW
1821 switch (this->state)
1822 {
3a0b67bc 1823 case IKE_ESTABLISHED:
ebc6445d
TB
1824 case IKE_REKEYING:
1825 if (time_monotonic(NULL) >= this->stats[STAT_DELETE] &&
1826 !(this->version == IKEV1 && this->state == IKE_REKEYING))
1827 { /* IKE_SA hard lifetime hit, ignored for reauthenticated
1828 * IKEv1 SAs */
c45cf904
MW
1829 charon->bus->alert(charon->bus, ALERT_IKE_SA_EXPIRED);
1830 }
3ed148b3 1831 this->task_manager->queue_ike_delete(this->task_manager);
a79d5103
TB
1832 status = this->task_manager->initiate(this->task_manager);
1833 break;
98f97433 1834 case IKE_CREATED:
a985db3f 1835 DBG1(DBG_IKE, "deleting unestablished IKE_SA");
98f97433 1836 break;
c610f424
MW
1837 case IKE_PASSIVE:
1838 break;
6fe03b0a 1839 default:
a79d5103
TB
1840 DBG1(DBG_IKE, "destroying IKE_SA in state %N without notification",
1841 ike_sa_state_names, this->state);
1842 force = TRUE;
c60c7694 1843 break;
6fe03b0a 1844 }
a79d5103
TB
1845
1846 if (force)
1847 {
1848 status = DESTROY_ME;
1849
1850 if (this->version == IKEV2)
1851 { /* for IKEv1 we trigger this in the ISAKMP delete task */
1852 switch (this->state)
1853 {
1854 case IKE_ESTABLISHED:
1855 case IKE_REKEYING:
1856 case IKE_DELETING:
1857 charon->bus->ike_updown(charon->bus, &this->public, FALSE);
1858 default:
1859 break;
1860 }
1861 }
1862 }
1863 return status;
6fe03b0a
MW
1864}
1865
8bced61b
MW
1866METHOD(ike_sa_t, rekey, status_t,
1867 private_ike_sa_t *this)
fe04e93a 1868{
916cdca8
MW
1869 if (this->state == IKE_PASSIVE)
1870 {
1871 return INVALID_STATE;
1872 }
dab60d64 1873 this->task_manager->queue_ike_rekey(this->task_manager);
c60c7694 1874 return this->task_manager->initiate(this->task_manager);
fe04e93a
MW
1875}
1876
8bced61b
MW
1877METHOD(ike_sa_t, reauth, status_t,
1878 private_ike_sa_t *this)
6fe03b0a 1879{
916cdca8
MW
1880 if (this->state == IKE_PASSIVE)
1881 {
1882 return INVALID_STATE;
1883 }
34e402ef
TB
1884 if (this->state == IKE_CONNECTING)
1885 {
1886 DBG0(DBG_IKE, "reinitiating IKE_SA %s[%d]",
1887 get_name(this), this->unique_id);
c3539961 1888 reset(this, TRUE);
34e402ef
TB
1889 return this->task_manager->initiate(this->task_manager);
1890 }
ee614711
MW
1891 /* we can't reauthenticate as responder when we use EAP or virtual IPs.
1892 * If the peer does not support RFC4478, there is no way to keep the
1893 * IKE_SA up. */
faf9569f 1894 if (!has_condition(this, COND_ORIGINAL_INITIATOR))
ee614711
MW
1895 {
1896 DBG1(DBG_IKE, "initiator did not reauthenticate as requested");
893da041 1897 if (array_count(this->other_vips) != 0 ||
7e9e1f96 1898 has_condition(this, COND_XAUTH_AUTHENTICATED) ||
78abba42
TB
1899 has_condition(this, COND_EAP_AUTHENTICATED)
1900#ifdef ME
484a06bc 1901 /* as mediation server we too cannot reauth the IKE_SA */
78abba42
TB
1902 || this->is_mediation_server
1903#endif /* ME */
1904 )
ee614711 1905 {
e9fcf1c6 1906 time_t del, now;
7daf5226 1907
e9fcf1c6
MW
1908 del = this->stats[STAT_DELETE];
1909 now = time_monotonic(NULL);
fbaf5cd2
MW
1910 DBG1(DBG_IKE, "IKE_SA %s[%d] will timeout in %V",
1911 get_name(this), this->unique_id, &now, &del);
ee614711
MW
1912 return FAILED;
1913 }
1914 else
1915 {
fbaf5cd2
MW
1916 DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d] actively",
1917 get_name(this), this->unique_id);
ee614711
MW
1918 }
1919 }
fbaf5cd2
MW
1920 else
1921 {
1922 DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d]",
1923 get_name(this), this->unique_id);
1924 }
873b63b7 1925 set_condition(this, COND_REAUTHENTICATING, TRUE);
cedb412e 1926 this->task_manager->queue_ike_reauth(this->task_manager);
26424f03 1927 return this->task_manager->initiate(this->task_manager);
6fe03b0a 1928}
face844a 1929
68db844f
TB
1930/**
1931 * Check if tasks to create CHILD_SAs are queued in the given queue
1932 */
1933static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue)
1934{
1935 enumerator_t *enumerator;
1936 task_t *task;
1937 bool found = FALSE;
1938
1939 enumerator = this->task_manager->create_task_enumerator(this->task_manager,
1940 queue);
1941 while (enumerator->enumerate(enumerator, &task))
1942 {
1943 if (task->get_type(task) == TASK_CHILD_CREATE ||
1944 task->get_type(task) == TASK_QUICK_MODE)
1945 {
1946 found = TRUE;
1947 break;
1948 }
1949 }
1950 enumerator->destroy(enumerator);
1951 return found;
1952}
1953
f20e00fe
TB
1954/**
1955 * Reestablish CHILD_SAs and migrate queued tasks.
1956 *
1957 * If force is true all SAs are restarted, otherwise their close/dpd_action
1958 * is followed.
1959 */
1960static status_t reestablish_children(private_ike_sa_t *this, ike_sa_t *new,
1961 bool force)
1962{
1963 enumerator_t *enumerator;
1964 child_sa_t *child_sa;
1965 child_cfg_t *child_cfg;
1966 action_t action;
1967 status_t status = FAILED;
1968
1969 /* handle existing CHILD_SAs */
1970 enumerator = create_child_sa_enumerator(this);
1971 while (enumerator->enumerate(enumerator, (void**)&child_sa))
1972 {
a747ad73
TB
1973 switch (child_sa->get_state(child_sa))
1974 {
1975 case CHILD_REKEYED:
1976 case CHILD_DELETED:
1977 /* ignore CHILD_SAs in these states */
1978 continue;
1979 default:
1980 break;
1981 }
f20e00fe
TB
1982 if (force)
1983 {
a1620c16 1984 action = ACTION_RESTART;
f20e00fe
TB
1985 }
1986 else
1987 { /* only restart CHILD_SAs that are configured accordingly */
1988 if (this->state == IKE_DELETING)
1989 {
1990 action = child_sa->get_close_action(child_sa);
1991 }
1992 else
1993 {
1994 action = child_sa->get_dpd_action(child_sa);
1995 }
1996 }
1997 switch (action)
1998 {
1999 case ACTION_RESTART:
2000 child_cfg = child_sa->get_config(child_sa);
2001 DBG1(DBG_IKE, "restarting CHILD_SA %s",
2002 child_cfg->get_name(child_cfg));
2003 child_cfg->get_ref(child_cfg);
2004 status = new->initiate(new, child_cfg,
2005 child_sa->get_reqid(child_sa), NULL, NULL);
2006 break;
2007 default:
2008 continue;
2009 }
2010 if (status == DESTROY_ME)
2011 {
2012 break;
2013 }
2014 }
2015 enumerator->destroy(enumerator);
2016 /* adopt any active or queued CHILD-creating tasks */
2017 if (status != DESTROY_ME)
2018 {
5e97a5e6 2019 new->adopt_child_tasks(new, &this->public);
f20e00fe
TB
2020 if (new->get_state(new) == IKE_CREATED)
2021 {
2022 status = new->initiate(new, NULL, 0, NULL, NULL);
2023 }
2024 }
2025 return status;
2026}
2027
8bced61b
MW
2028METHOD(ike_sa_t, reestablish, status_t,
2029 private_ike_sa_t *this)
96926b00
MW
2030{
2031 ike_sa_t *new;
2032 host_t *host;
348af092 2033 action_t action;
e2630434 2034 enumerator_t *enumerator;
96926b00 2035 child_sa_t *child_sa;
cf76c429 2036 bool restart = FALSE;
96926b00 2037 status_t status = FAILED;
7daf5226 2038
873b63b7 2039 if (has_condition(this, COND_REAUTHENTICATING))
23470d84 2040 { /* only reauthenticate if we have children */
893da041 2041 if (array_count(this->child_sas) == 0
23470d84
TB
2042#ifdef ME
2043 /* allow reauth of mediation connections without CHILD_SAs */
2044 && !this->peer_cfg->is_mediation(this->peer_cfg)
2045#endif /* ME */
2046 )
348af092 2047 {
23470d84
TB
2048 DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA "
2049 "to recreate");
348af092
MW
2050 }
2051 else
2052 {
23470d84 2053 restart = TRUE;
348af092 2054 }
23470d84
TB
2055 }
2056 else
2057 { /* check if we have children to keep up at all */
893da041 2058 enumerator = array_create_enumerator(this->child_sas);
23470d84 2059 while (enumerator->enumerate(enumerator, (void**)&child_sa))
cadb5d16 2060 {
a747ad73
TB
2061 switch (child_sa->get_state(child_sa))
2062 {
2063 case CHILD_REKEYED:
2064 case CHILD_DELETED:
2065 /* ignore CHILD_SAs in these states */
2066 continue;
2067 default:
2068 break;
2069 }
23470d84
TB
2070 if (this->state == IKE_DELETING)
2071 {
2072 action = child_sa->get_close_action(child_sa);
2073 }
2074 else
2075 {
2076 action = child_sa->get_dpd_action(child_sa);
2077 }
2078 switch (action)
2079 {
2080 case ACTION_RESTART:
2081 restart = TRUE;
2082 break;
2083 case ACTION_ROUTE:
2084 charon->traps->install(charon->traps, this->peer_cfg,
24fa1bb0 2085 child_sa->get_config(child_sa));
23470d84
TB
2086 break;
2087 default:
2088 break;
2089 }
cadb5d16 2090 }
23470d84 2091 enumerator->destroy(enumerator);
68db844f 2092 /* check if we have tasks that recreate children */
07a9d5c9
TB
2093 if (!restart)
2094 {
2095 restart = is_child_queued(this, TASK_QUEUE_ACTIVE) ||
2096 is_child_queued(this, TASK_QUEUE_QUEUED);
2097 }
cadb5d16 2098#ifdef ME
23470d84
TB
2099 /* mediation connections have no children, keep them up anyway */
2100 if (this->peer_cfg->is_mediation(this->peer_cfg))
2101 {
2102 restart = TRUE;
2103 }
cadb5d16 2104#endif /* ME */
23470d84 2105 }
cf76c429 2106 if (!restart)
cadb5d16
MW
2107 {
2108 return FAILED;
2109 }
7daf5226 2110
cadb5d16 2111 /* check if we are able to reestablish this IKE_SA */
faf9569f 2112 if (!has_condition(this, COND_ORIGINAL_INITIATOR) &&
893da041 2113 (array_count(this->other_vips) != 0 ||
96926b00
MW
2114 has_condition(this, COND_EAP_AUTHENTICATED)
2115#ifdef ME
2116 || this->is_mediation_server
2117#endif /* ME */
2118 ))
2119 {
68447302 2120 DBG1(DBG_IKE, "unable to reestablish IKE_SA due to asymmetric setup");
96926b00
MW
2121 return FAILED;
2122 }
7daf5226 2123
0b611540
TB
2124 new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
2125 this->version, TRUE);
3d54ae94
MW
2126 if (!new)
2127 {
2128 return FAILED;
2129 }
96926b00
MW
2130 new->set_peer_cfg(new, this->peer_cfg);
2131 host = this->other_host;
2132 new->set_other_host(new, host->clone(host));
2133 host = this->my_host;
2134 new->set_my_host(new, host->clone(host));
614359a7 2135 charon->bus->ike_reestablish_pre(charon->bus, &this->public, new);
7505fb8d
TB
2136 if (!has_condition(this, COND_REAUTHENTICATING))
2137 { /* reauthenticate to the same addresses, but resolve hosts if
2138 * reestablishing (old addresses serve as fallback) */
2139 resolve_hosts((private_ike_sa_t*)new);
2140 }
96926b00 2141 /* if we already have a virtual IP, we reuse it */
893da041 2142 enumerator = array_create_enumerator(this->my_vips);
101d26ba 2143 while (enumerator->enumerate(enumerator, &host))
96926b00 2144 {
101d26ba 2145 new->add_virtual_ip(new, TRUE, host);
96926b00 2146 }
101d26ba 2147 enumerator->destroy(enumerator);
7daf5226 2148
96926b00 2149#ifdef ME
96926b00
MW
2150 if (this->peer_cfg->is_mediation(this->peer_cfg))
2151 {
a13c013b 2152 status = new->initiate(new, NULL, 0, NULL, NULL);
96926b00 2153 }
cadb5d16 2154 else
96926b00 2155#endif /* ME */
96926b00 2156 {
f20e00fe
TB
2157 status = reestablish_children(this, new,
2158 has_condition(this, COND_REAUTHENTICATING));
96926b00 2159 }
7daf5226 2160
cadb5d16 2161 if (status == DESTROY_ME)
96926b00 2162 {
614359a7
TB
2163 charon->bus->ike_reestablish_post(charon->bus, &this->public, new,
2164 FALSE);
cadb5d16 2165 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
04d6583e 2166 status = FAILED;
96926b00
MW
2167 }
2168 else
2169 {
614359a7
TB
2170 charon->bus->ike_reestablish_post(charon->bus, &this->public, new,
2171 TRUE);
cadb5d16 2172 charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
04d6583e 2173 status = SUCCESS;
96926b00 2174 }
04d6583e
MW
2175 charon->bus->set_sa(charon->bus, &this->public);
2176 return status;
96926b00
MW
2177}
2178
f20e00fe
TB
2179/**
2180 * Resolve the given gateway ID
2181 */
2182static host_t *resolve_gateway_id(identification_t *gateway)
c126ddd0
TB
2183{
2184 char gw[BUF_LEN];
f20e00fe 2185 host_t *addr;
c126ddd0 2186
f20e00fe
TB
2187 snprintf(gw, sizeof(gw), "%Y", gateway);
2188 gw[sizeof(gw)-1] = '\0';
2189 addr = host_create_from_dns(gw, AF_UNSPEC, IKEV2_UDP_PORT);
2190 if (!addr)
2191 {
2192 DBG1(DBG_IKE, "unable to resolve gateway ID '%Y', redirect failed",
2193 gateway);
2194 }
2195 return addr;
2196}
2197
2198/**
2199 * Redirect the current SA to the given target host
2200 */
2201static bool redirect_established(private_ike_sa_t *this, identification_t *to)
2202{
2203 private_ike_sa_t *new_priv;
2204 ike_sa_t *new;
2205 host_t *other;
c6ebd033 2206 time_t redirect;
f20e00fe
TB
2207
2208 new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
2209 this->version, TRUE);
2210 if (!new)
489d154e 2211 {
489d154e
TB
2212 return FALSE;
2213 }
f20e00fe
TB
2214 new_priv = (private_ike_sa_t*)new;
2215 new->set_peer_cfg(new, this->peer_cfg);
2216 new_priv->redirected_from = this->other_host->clone(this->other_host);
2217 charon->bus->ike_reestablish_pre(charon->bus, &this->public, new);
2218 other = resolve_gateway_id(to);
2219 if (other)
2220 {
2221 set_my_host(new_priv, this->my_host->clone(this->my_host));
2222 /* this allows us to force the remote address while we still properly
2223 * resolve the local address */
2224 new_priv->remote_host = other;
2225 resolve_hosts(new_priv);
c6ebd033
TB
2226 new_priv->redirected_at = array_create(sizeof(time_t), MAX_REDIRECTS);
2227 while (array_remove(this->redirected_at, ARRAY_HEAD, &redirect))
2228 {
2229 array_insert(new_priv->redirected_at, ARRAY_TAIL, &redirect);
2230 }
f20e00fe
TB
2231 if (reestablish_children(this, new, TRUE) != DESTROY_ME)
2232 {
2233#ifdef USE_IKEV2
2234 new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
2235 this->ike_sa_id));
2236#endif
2237 charon->bus->ike_reestablish_post(charon->bus, &this->public, new,
2238 TRUE);
2239 charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
2240 charon->bus->set_sa(charon->bus, &this->public);
2241 return TRUE;
2242 }
2243 }
2244 charon->bus->ike_reestablish_post(charon->bus, &this->public, new,
2245 FALSE);
2246 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
2247 charon->bus->set_sa(charon->bus, &this->public);
2248 return FALSE;
2249}
c126ddd0 2250
f20e00fe
TB
2251/**
2252 * Redirect the current connecting SA to the given target host
2253 */
2254static bool redirect_connecting(private_ike_sa_t *this, identification_t *to)
2255{
2256 host_t *other;
2257
2258 other = resolve_gateway_id(to);
c126ddd0
TB
2259 if (!other)
2260 {
c126ddd0
TB
2261 return FALSE;
2262 }
c3539961 2263 reset(this, TRUE);
f20e00fe
TB
2264 DESTROY_IF(this->redirected_from);
2265 this->redirected_from = this->other_host->clone(this->other_host);
2266 DESTROY_IF(this->remote_host);
2267 /* this allows us to force the remote address while we still properly
2268 * resolve the local address */
2269 this->remote_host = other;
2270 resolve_hosts(this);
2271 return TRUE;
2272}
2273
c6ebd033
TB
2274/**
2275 * Check if the current redirect exceeds the limits for redirects
2276 */
2277static bool redirect_count_exceeded(private_ike_sa_t *this)
2278{
2279 time_t now, redirect;
2280
2281 now = time_monotonic(NULL);
2282 /* remove entries outside the defined period */
2283 while (array_get(this->redirected_at, ARRAY_HEAD, &redirect) &&
2284 now - redirect >= REDIRECT_LOOP_DETECT_PERIOD)
2285 {
2286 array_remove(this->redirected_at, ARRAY_HEAD, NULL);
2287 }
2288 if (array_count(this->redirected_at) < MAX_REDIRECTS)
2289 {
2290 if (!this->redirected_at)
2291 {
2292 this->redirected_at = array_create(sizeof(time_t), MAX_REDIRECTS);
2293 }
2294 array_insert(this->redirected_at, ARRAY_TAIL, &now);
2295 return FALSE;
2296 }
2297 return TRUE;
2298}
2299
f20e00fe
TB
2300METHOD(ike_sa_t, handle_redirect, bool,
2301 private_ike_sa_t *this, identification_t *gateway)
2302{
2303 DBG1(DBG_IKE, "redirected to %Y", gateway);
2304 if (!this->follow_redirects)
2305 {
2306 DBG1(DBG_IKE, "server sent REDIRECT even though we disabled it");
2307 return FALSE;
2308 }
c6ebd033
TB
2309 if (redirect_count_exceeded(this))
2310 {
2311 DBG1(DBG_IKE, "only %d redirects are allowed within %d seconds",
2312 MAX_REDIRECTS, REDIRECT_LOOP_DETECT_PERIOD);
2313 return FALSE;
2314 }
f20e00fe 2315
c126ddd0
TB
2316 switch (this->state)
2317 {
2318 case IKE_CONNECTING:
f20e00fe
TB
2319 return redirect_connecting(this, gateway);
2320 case IKE_ESTABLISHED:
2321 return redirect_established(this, gateway);
c126ddd0
TB
2322 default:
2323 DBG1(DBG_IKE, "unable to handle redirect for IKE_SA in state %N",
2324 ike_sa_state_names, this->state);
c126ddd0
TB
2325 return FALSE;
2326 }
2327}
2328
71c70705
TB
2329METHOD(ike_sa_t, redirect, status_t,
2330 private_ike_sa_t *this, identification_t *gateway)
2331{
2332 switch (this->state)
2333 {
2334 case IKE_CONNECTING:
2335 case IKE_ESTABLISHED:
2336 case IKE_REKEYING:
2337 if (has_condition(this, COND_REDIRECTED))
2338 { /* IKE_SA already got redirected */
2339 return SUCCESS;
2340 }
2341 if (has_condition(this, COND_ORIGINAL_INITIATOR))
2342 {
2343 DBG1(DBG_IKE, "unable to redirect IKE_SA as initiator");
2344 return FAILED;
2345 }
2346 if (this->version == IKEV1)
2347 {
2348 DBG1(DBG_IKE, "unable to redirect IKEv1 SA");
2349 return FAILED;
2350 }
2351 if (!supports_extension(this, EXT_IKE_REDIRECTION))
2352 {
2353 DBG1(DBG_IKE, "client does not support IKE redirection");
2354 return FAILED;
2355 }
2356#ifdef USE_IKEV2
2357 this->task_manager->queue_task(this->task_manager,
2358 (task_t*)ike_redirect_create(&this->public, gateway));
2359#endif
2360 return this->task_manager->initiate(this->task_manager);
2361 default:
2362 DBG1(DBG_IKE, "unable to redirect IKE_SA in state %N",
2363 ike_sa_state_names, this->state);
2364 return INVALID_STATE;
2365 }
2366}
2367
8bced61b 2368METHOD(ike_sa_t, retransmit, status_t,
b12c53ce 2369 private_ike_sa_t *this, uint32_t message_id)
96926b00 2370{
916cdca8
MW
2371 if (this->state == IKE_PASSIVE)
2372 {
2373 return INVALID_STATE;
2374 }
6180a558 2375 this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
96926b00
MW
2376 if (this->task_manager->retransmit(this->task_manager, message_id) != SUCCESS)
2377 {
2378 /* send a proper signal to brief interested bus listeners */
2379 switch (this->state)
2380 {
2381 case IKE_CONNECTING:
2382 {
d9c1dae2 2383 /* retry IKE_SA_INIT/Main Mode if we have multiple keyingtries */
b12c53ce 2384 uint32_t tries = this->peer_cfg->get_keyingtries(this->peer_cfg);
1d6dc627
TB
2385 charon->bus->alert(charon->bus, ALERT_PEER_INIT_UNREACHABLE,
2386 this->keyingtry);
96926b00
MW
2387 this->keyingtry++;
2388 if (tries == 0 || tries > this->keyingtry)
2389 {
a985db3f
MW
2390 DBG1(DBG_IKE, "peer not responding, trying again (%d/%d)",
2391 this->keyingtry + 1, tries);
c3539961 2392 reset(this, TRUE);
4d7a2128 2393 resolve_hosts(this);
96926b00
MW
2394 return this->task_manager->initiate(this->task_manager);
2395 }
a985db3f 2396 DBG1(DBG_IKE, "establishing IKE_SA failed, peer not responding");
ebc6defa
TB
2397
2398 if (this->version == IKEV1 && array_count(this->child_sas))
2399 {
eb822106
TB
2400 enumerator_t *enumerator;
2401 child_sa_t *child_sa;
2402
ebc6defa
TB
2403 /* if reauthenticating an IKEv1 SA failed (assumed for an SA
2404 * in this state with CHILD_SAs), try again from scratch */
2405 DBG1(DBG_IKE, "reauthentication failed, trying to "
2406 "reestablish IKE_SA");
2407 reestablish(this);
eb822106
TB
2408 /* trigger down events for the CHILD_SAs, as no down event
2409 * is triggered below for IKE SAs in this state */
2410 enumerator = array_create_enumerator(this->child_sas);
2411 while (enumerator->enumerate(enumerator, &child_sa))
2412 {
2413 if (child_sa->get_state(child_sa) != CHILD_REKEYED &&
2414 child_sa->get_state(child_sa) != CHILD_DELETED)
2415 {
2416 charon->bus->child_updown(charon->bus, child_sa,
2417 FALSE);
2418 }
2419 }
2420 enumerator->destroy(enumerator);
ebc6defa 2421 }
96926b00
MW
2422 break;
2423 }
96926b00 2424 case IKE_DELETING:
a985db3f 2425 DBG1(DBG_IKE, "proper IKE_SA delete failed, peer not responding");
10f8834b
TB
2426 if (has_condition(this, COND_REAUTHENTICATING) &&
2427 !lib->settings->get_bool(lib->settings,
2428 "%s.make_before_break", FALSE, lib->ns))
74571430
TB
2429 {
2430 DBG1(DBG_IKE, "delete during reauthentication failed, "
2431 "trying to reestablish IKE_SA anyway");
2432 reestablish(this);
2433 }
96926b00 2434 break;
348af092 2435 case IKE_REKEYING:
a985db3f 2436 DBG1(DBG_IKE, "rekeying IKE_SA failed, peer not responding");
348af092 2437 /* FALL */
96926b00 2438 default:
348af092 2439 reestablish(this);
96926b00
MW
2440 break;
2441 }
bb389973
TB
2442 if (this->state != IKE_CONNECTING &&
2443 this->state != IKE_REKEYED)
3babde90
TB
2444 {
2445 charon->bus->ike_updown(charon->bus, &this->public, FALSE);
2446 }
96926b00
MW
2447 return DESTROY_ME;
2448 }
2449 return SUCCESS;
2450}
2451
a07b6973 2452METHOD(ike_sa_t, set_auth_lifetime, status_t,
b12c53ce 2453 private_ike_sa_t *this, uint32_t lifetime)
ee614711 2454{
b12c53ce 2455 uint32_t diff, hard, soft, now;
a07b6973 2456 bool send_update;
ee614711 2457
bdcf4417
MW
2458 diff = this->peer_cfg->get_over_time(this->peer_cfg);
2459 now = time_monotonic(NULL);
2460 hard = now + lifetime;
2461 soft = hard - diff;
2462
a07b6973
MW
2463 /* check if we have to send an AUTH_LIFETIME to enforce the new lifetime.
2464 * We send the notify in IKE_AUTH if not yet ESTABLISHED. */
b1f2f05c 2465 send_update = this->state == IKE_ESTABLISHED && this->version == IKEV2 &&
a07b6973 2466 !has_condition(this, COND_ORIGINAL_INITIATOR) &&
893da041 2467 (array_count(this->other_vips) != 0 ||
a07b6973
MW
2468 has_condition(this, COND_EAP_AUTHENTICATED));
2469
bdcf4417 2470 if (lifetime < diff)
ee614711 2471 {
bdcf4417 2472 this->stats[STAT_REAUTH] = now;
a07b6973
MW
2473
2474 if (!send_update)
2475 {
2476 DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
2477 "starting reauthentication", lifetime);
2478 lib->processor->queue_job(lib->processor,
b9b8a98f 2479 (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE));
a07b6973 2480 }
ee614711 2481 }
85ac2fa5 2482 else if (this->stats[STAT_REAUTH] == 0 ||
bdcf4417 2483 this->stats[STAT_REAUTH] > soft)
ee614711 2484 {
bdcf4417 2485 this->stats[STAT_REAUTH] = soft;
a07b6973
MW
2486 if (!send_update)
2487 {
2488 DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling "
2489 "reauthentication in %ds", lifetime, lifetime - diff);
2490 lib->scheduler->schedule_job(lib->scheduler,
6554b5e4 2491 (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
bdcf4417 2492 lifetime - diff);
a07b6973 2493 }
3fd9c757
AS
2494 }
2495 else
2496 {
6180a558
MW
2497 DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
2498 "reauthentication already scheduled in %ds", lifetime,
2499 this->stats[STAT_REAUTH] - time_monotonic(NULL));
a07b6973 2500 send_update = FALSE;
ee614711 2501 }
bdcf4417
MW
2502 /* give at least some seconds to reauthenticate */
2503 this->stats[STAT_DELETE] = max(hard, now + 10);
a07b6973 2504
2d39f79b 2505#ifdef USE_IKEV2
a07b6973
MW
2506 if (send_update)
2507 {
2d39f79b
TB
2508 ike_auth_lifetime_t *task;
2509
a07b6973
MW
2510 task = ike_auth_lifetime_create(&this->public, TRUE);
2511 this->task_manager->queue_task(this->task_manager, &task->task);
2512 return this->task_manager->initiate(this->task_manager);
2513 }
2d39f79b 2514#endif
a07b6973 2515 return SUCCESS;
ee614711
MW
2516}
2517
bab56a4a
TB
2518/**
2519 * Check if the current combination of source and destination address is still
2520 * valid.
2521 */
2522static bool is_current_path_valid(private_ike_sa_t *this)
2523{
2524 bool valid = FALSE;
2525 host_t *src;
597e8c9e
MW
2526
2527 if (supports_extension(this, EXT_MOBIKE) &&
2528 lib->settings->get_bool(lib->settings,
2529 "%s.prefer_best_path", FALSE, lib->ns))
2530 {
2531 /* check if the current path is the best path; migrate otherwise */
2532 src = charon->kernel->get_source_addr(charon->kernel, this->other_host,
2533 NULL);
2534 if (src)
2535 {
2536 valid = src->ip_equals(src, this->my_host);
2537 src->destroy(src);
2538 }
2539 if (!valid)
2540 {
2541 DBG1(DBG_IKE, "old path is not preferred anymore");
2542 }
2543 return valid;
2544 }
8394ea2a
TB
2545 src = charon->kernel->get_source_addr(charon->kernel, this->other_host,
2546 this->my_host);
bab56a4a
TB
2547 if (src)
2548 {
2549 if (src->ip_equals(src, this->my_host))
2550 {
2551 valid = TRUE;
2552 }
2553 src->destroy(src);
2554 }
597e8c9e
MW
2555 if (!valid)
2556 {
2557 DBG1(DBG_IKE, "old path is not available anymore, try to find another");
2558 }
bab56a4a
TB
2559 return valid;
2560}
2561
2562/**
2563 * Check if we have any path avialable for this IKE SA.
2564 */
2565static bool is_any_path_valid(private_ike_sa_t *this)
2566{
2567 bool valid = FALSE;
2568 enumerator_t *enumerator;
ae9ce835 2569 host_t *src = NULL, *addr;
ff601341
TB
2570 int family = AF_UNSPEC;
2571
2572 switch (charon->socket->supported_families(charon->socket))
2573 {
2574 case SOCKET_FAMILY_IPV4:
2575 family = AF_INET;
2576 break;
2577 case SOCKET_FAMILY_IPV6:
2578 family = AF_INET6;
2579 break;
2580 case SOCKET_FAMILY_BOTH:
2581 case SOCKET_FAMILY_NONE:
2582 break;
2583 }
72b28112 2584
12715f19 2585 enumerator = create_peer_address_enumerator(this);
72b28112 2586 while (enumerator->enumerate(enumerator, &addr))
bab56a4a 2587 {
ff601341
TB
2588 if (family != AF_UNSPEC && addr->get_family(addr) != family)
2589 {
2590 continue;
2591 }
72b28112 2592 DBG1(DBG_IKE, "looking for a route to %H ...", addr);
8394ea2a 2593 src = charon->kernel->get_source_addr(charon->kernel, addr, NULL);
72b28112 2594 if (src)
bab56a4a 2595 {
72b28112 2596 break;
bab56a4a 2597 }
bab56a4a 2598 }
72b28112 2599 enumerator->destroy(enumerator);
bab56a4a
TB
2600 if (src)
2601 {
2602 valid = TRUE;
2603 src->destroy(src);
2604 }
2605 return valid;
2606}
2607
8bced61b
MW
2608METHOD(ike_sa_t, roam, status_t,
2609 private_ike_sa_t *this, bool address)
17d92e97 2610{
011b1cca
MW
2611 switch (this->state)
2612 {
2613 case IKE_CREATED:
2614 case IKE_DELETING:
7afd9d66 2615 case IKE_DESTROYING:
c610f424 2616 case IKE_PASSIVE:
bb389973 2617 case IKE_REKEYED:
011b1cca
MW
2618 return SUCCESS;
2619 default:
2620 break;
2621 }
7daf5226 2622
007a2701
TB
2623 if (!this->ike_cfg)
2624 { /* this is the case for new HA SAs not yet in state IKE_PASSIVE and
2625 * without config assigned */
2626 return SUCCESS;
2627 }
8929c700
TB
2628 if (this->version == IKEV1)
2629 { /* ignore roam events for IKEv1 where we don't have MOBIKE and would
2630 * have to reestablish from scratch (reauth is not enough) */
2631 return SUCCESS;
2632 }
007a2701 2633
be27e768
TB
2634 /* ignore roam events if MOBIKE is not supported/enabled and the local
2635 * address is statically configured */
8929c700 2636 if (!supports_extension(this, EXT_MOBIKE) &&
be27e768
TB
2637 ike_cfg_has_address(this->ike_cfg, this->my_host, TRUE))
2638 {
2639 DBG2(DBG_IKE, "keeping statically configured path %H - %H",
2640 this->my_host, this->other_host);
2641 return SUCCESS;
2642 }
2643
ce5b1708 2644 /* keep existing path if possible */
bab56a4a 2645 if (is_current_path_valid(this))
face844a 2646 {
bab56a4a
TB
2647 DBG2(DBG_IKE, "keeping connection path %H - %H",
2648 this->my_host, this->other_host);
2649 set_condition(this, COND_STALE, FALSE);
261b2572
TB
2650
2651 if (supports_extension(this, EXT_MOBIKE) && address)
2652 { /* if any addresses changed, send an updated list */
2653 DBG1(DBG_IKE, "sending address list update using MOBIKE");
873df908 2654 this->task_manager->queue_mobike(this->task_manager, FALSE, TRUE);
261b2572
TB
2655 return this->task_manager->initiate(this->task_manager);
2656 }
bab56a4a 2657 return SUCCESS;
7afd9d66 2658 }
261b2572 2659
bab56a4a 2660 if (!is_any_path_valid(this))
7afd9d66 2661 {
bab56a4a
TB
2662 DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred",
2663 this->other_host);
2664 set_condition(this, COND_STALE, TRUE);
2665 return SUCCESS;
17d92e97 2666 }
7afd9d66 2667 set_condition(this, COND_STALE, FALSE);
7daf5226 2668
face844a
MW
2669 /* update addresses with mobike, if supported ... */
2670 if (supports_extension(this, EXT_MOBIKE))
2671 {
57744088
TB
2672 if (!has_condition(this, COND_ORIGINAL_INITIATOR))
2673 { /* responder updates the peer about changed address config */
2674 DBG1(DBG_IKE, "sending address list update using MOBIKE, "
2675 "implicitly requesting an address change");
2676 address = TRUE;
2677 }
2678 else
2679 {
2680 DBG1(DBG_IKE, "requesting address change using MOBIKE");
2681 }
873df908 2682 this->task_manager->queue_mobike(this->task_manager, TRUE, address);
face844a
MW
2683 return this->task_manager->initiate(this->task_manager);
2684 }
57744088 2685
96926b00 2686 /* ... reauth if not */
57744088
TB
2687 if (!has_condition(this, COND_ORIGINAL_INITIATOR))
2688 { /* responder does not reauthenticate */
2689 set_condition(this, COND_STALE, TRUE);
2690 return SUCCESS;
2691 }
2692 DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change");
a46fe568
TB
2693 /* since our previous path is not valid anymore, try and find a new one */
2694 resolve_hosts(this);
96926b00 2695 return reauth(this);
17d92e97 2696}
6fe03b0a 2697
8bced61b
MW
2698METHOD(ike_sa_t, add_configuration_attribute, void,
2699 private_ike_sa_t *this, attribute_handler_t *handler,
2700 configuration_attribute_type_t type, chunk_t data)
7f56b494 2701{
893da041
MW
2702 attribute_entry_t entry = {
2703 .handler = handler,
2704 .type = type,
2705 .data = chunk_clone(data),
2706 };
2707 array_insert(this->attributes, ARRAY_TAIL, &entry);
7f56b494
MW
2708}
2709
525cc46c
TB
2710CALLBACK(filter_attribute, bool,
2711 void *null, enumerator_t *orig, va_list args)
9d257034 2712{
525cc46c
TB
2713 attribute_entry_t *entry;
2714 configuration_attribute_type_t *type;
2715 chunk_t *data;
2716 bool *handled;
2717
2718 VA_ARGS_VGET(args, type, data, handled);
2719
2720 if (orig->enumerate(orig, &entry))
2721 {
2722 *type = entry->type;
2723 *data = entry->data;
2724 *handled = entry->handler != NULL;
2725 return TRUE;
2726 }
2727 return FALSE;
9d257034
MW
2728}
2729
2730METHOD(ike_sa_t, create_attribute_enumerator, enumerator_t*,
2731 private_ike_sa_t *this)
2732{
2733 return enumerator_create_filter(array_create_enumerator(this->attributes),
525cc46c 2734 filter_attribute, NULL, NULL);
9d257034
MW
2735}
2736
ea340ee8
MW
2737METHOD(ike_sa_t, create_task_enumerator, enumerator_t*,
2738 private_ike_sa_t *this, task_queue_t queue)
2739{
2740 return this->task_manager->create_task_enumerator(this->task_manager, queue);
2741}
2742
b7160401
TB
2743METHOD(ike_sa_t, remove_task, void,
2744 private_ike_sa_t *this, enumerator_t *enumerator)
2745{
2746 return this->task_manager->remove_task(this->task_manager, enumerator);
2747}
2748
cbc1a20f
MW
2749METHOD(ike_sa_t, flush_queue, void,
2750 private_ike_sa_t *this, task_queue_t queue)
2751{
2752 this->task_manager->flush_queue(this->task_manager, queue);
2753}
2754
69adeb5b
MW
2755METHOD(ike_sa_t, queue_task, void,
2756 private_ike_sa_t *this, task_t *task)
2757{
2758 this->task_manager->queue_task(this->task_manager, task);
2759}
2760
208678e6
TB
2761METHOD(ike_sa_t, queue_task_delayed, void,
2762 private_ike_sa_t *this, task_t *task, uint32_t delay)
2763{
2764 this->task_manager->queue_task_delayed(this->task_manager, task, delay);
2765}
2766
5e97a5e6
TB
2767/**
2768 * Migrate and queue child-creating tasks from another IKE_SA
2769 */
2770static void migrate_child_tasks(private_ike_sa_t *this, ike_sa_t *other,
2771 task_queue_t queue)
00c889f4 2772{
5e97a5e6
TB
2773 enumerator_t *enumerator;
2774 task_t *task;
00c889f4 2775
5e97a5e6
TB
2776 enumerator = other->create_task_enumerator(other, queue);
2777 while (enumerator->enumerate(enumerator, &task))
2778 {
2779 if (task->get_type(task) == TASK_CHILD_CREATE ||
2780 task->get_type(task) == TASK_QUICK_MODE)
2781 {
2782 other->remove_task(other, enumerator);
2783 task->migrate(task, &this->public);
2784 queue_task(this, task);
2785 }
2786 }
2787 enumerator->destroy(enumerator);
2788}
2789
2790METHOD(ike_sa_t, adopt_child_tasks, void,
2791 private_ike_sa_t *this, ike_sa_t *other)
2792{
2793 migrate_child_tasks(this, other, TASK_QUEUE_ACTIVE);
2794 migrate_child_tasks(this, other, TASK_QUEUE_QUEUED);
00c889f4
TB
2795}
2796
713a1122
MW
2797METHOD(ike_sa_t, inherit_pre, void,
2798 private_ike_sa_t *this, ike_sa_t *other_public)
2799{
2800 private_ike_sa_t *other = (private_ike_sa_t*)other_public;
2801
2802 /* apply config and hosts */
2803 set_peer_cfg(this, other->peer_cfg);
2804 set_my_host(this, other->my_host->clone(other->my_host));
2805 set_other_host(this, other->other_host->clone(other->other_host));
094963d1
MW
2806
2807 /* apply extensions and conditions with a few exceptions */
2808 this->extensions = other->extensions;
2809 this->conditions = other->conditions;
2810 this->conditions &= ~COND_STALE;
2811 this->conditions &= ~COND_REAUTHENTICATING;
713a1122
MW
2812}
2813
2814METHOD(ike_sa_t, inherit_post, void,
8bced61b 2815 private_ike_sa_t *this, ike_sa_t *other_public)
3183006d 2816{
8bced61b 2817 private_ike_sa_t *other = (private_ike_sa_t*)other_public;
c60c7694 2818 child_sa_t *child_sa;
5d6b9815 2819 enumerator_t *enumerator;
893da041 2820 attribute_entry_t entry;
5d6b9815 2821 auth_cfg_t *cfg;
101d26ba 2822 host_t *vip;
7daf5226 2823
c60c7694
MW
2824 /* apply hosts and ids */
2825 this->my_host->destroy(this->my_host);
2826 this->other_host->destroy(this->other_host);
2827 this->my_id->destroy(this->my_id);
2828 this->other_id->destroy(this->other_id);
2829 this->my_host = other->my_host->clone(other->my_host);
2830 this->other_host = other->other_host->clone(other->other_host);
2831 this->my_id = other->my_id->clone(other->my_id);
2832 this->other_id = other->other_id->clone(other->other_id);
dec3c184
TB
2833 this->if_id_in = other->if_id_in;
2834 this->if_id_out = other->if_id_out;
7daf5226 2835
101d26ba 2836 /* apply assigned virtual IPs... */
893da041 2837 while (array_remove(other->my_vips, ARRAY_HEAD, &vip))
c60c7694 2838 {
893da041 2839 array_insert_create(&this->my_vips, ARRAY_TAIL, vip);
c60c7694 2840 }
893da041 2841 while (array_remove(other->other_vips, ARRAY_HEAD, &vip))
c60c7694 2842 {
893da041 2843 array_insert_create(&this->other_vips, ARRAY_TAIL, vip);
c60c7694 2844 }
7daf5226 2845
b8ecdfd8
MW
2846 /* MOBIKE additional addresses */
2847 while (array_remove(other->peer_addresses, ARRAY_HEAD, &vip))
2848 {
2849 array_insert_create(&this->peer_addresses, ARRAY_TAIL, vip);
2850 }
2851
5d6b9815 2852 /* authentication information */
893da041 2853 enumerator = array_create_enumerator(other->my_auths);
5d6b9815
MW
2854 while (enumerator->enumerate(enumerator, &cfg))
2855 {
893da041 2856 array_insert(this->my_auths, ARRAY_TAIL, cfg->clone(cfg));
5d6b9815
MW
2857 }
2858 enumerator->destroy(enumerator);
893da041 2859 enumerator = array_create_enumerator(other->other_auths);
5d6b9815
MW
2860 while (enumerator->enumerate(enumerator, &cfg))
2861 {
893da041 2862 array_insert(this->other_auths, ARRAY_TAIL, cfg->clone(cfg));
5d6b9815
MW
2863 }
2864 enumerator->destroy(enumerator);
2865
7f56b494 2866 /* ... and configuration attributes */
893da041 2867 while (array_remove(other->attributes, ARRAY_HEAD, &entry))
c60c7694 2868 {
893da041 2869 array_insert(this->attributes, ARRAY_TAIL, &entry);
c60c7694 2870 }
b0e40caa 2871
faf9569f 2872 /* inherit all conditions */
b0e40caa
AS
2873 this->conditions = other->conditions;
2874 if (this->conditions & COND_NAT_HERE)
2875 {
efd7fa7b 2876 send_keepalive(this, FALSE);
b0e40caa 2877 }
7daf5226 2878
22452f70
TB
2879#ifdef ME
2880 if (other->is_mediation_server)
2881 {
2882 act_as_mediation_server(this);
2883 }
2884 else if (other->server_reflexive_host)
2885 {
2886 this->server_reflexive_host = other->server_reflexive_host->clone(
2887 other->server_reflexive_host);
2888 }
2889#endif /* ME */
b0e40caa 2890
c60c7694 2891 /* adopt all children */
893da041 2892 while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa))
c60c7694 2893 {
38227d0e
MW
2894 charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
2895 add_child_sa(this, child_sa);
c60c7694 2896 }
7daf5226 2897
e23a59f6
MW
2898 /* move pending tasks to the new IKE_SA */
2899 this->task_manager->adopt_tasks(this->task_manager, other->task_manager);
7daf5226 2900
ee614711 2901 /* reauthentication timeout survives a rekeying */
85ac2fa5 2902 if (other->stats[STAT_REAUTH])
ee614711 2903 {
6180a558 2904 time_t reauth, delete, now = time_monotonic(NULL);
7daf5226 2905
85ac2fa5
MW
2906 this->stats[STAT_REAUTH] = other->stats[STAT_REAUTH];
2907 reauth = this->stats[STAT_REAUTH] - now;
ee614711 2908 delete = reauth + this->peer_cfg->get_over_time(this->peer_cfg);
85ac2fa5 2909 this->stats[STAT_DELETE] = this->stats[STAT_REAUTH] + delete;
ee614711
MW
2910 DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, "
2911 "lifetime reduced to %ds", reauth, delete);
bb381e26 2912 lib->scheduler->schedule_job(lib->scheduler,
6554b5e4 2913 (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), reauth);
bb381e26 2914 lib->scheduler->schedule_job(lib->scheduler,
6554b5e4 2915 (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), delete);
ee614711 2916 }
3183006d
MW
2917}
2918
8bced61b
MW
2919METHOD(ike_sa_t, destroy, void,
2920 private_ike_sa_t *this)
60356f33 2921{
893da041 2922 attribute_entry_t entry;
2b0c8ee3 2923 child_sa_t *child_sa;
101d26ba 2924 host_t *vip;
7daf5226 2925
65c907cd 2926 charon->bus->set_sa(charon->bus, &this->public);
7daf5226 2927
a985db3f 2928 set_state(this, IKE_DESTROYING);
b1908994
TE
2929 if (this->task_manager)
2930 {
2931 this->task_manager->flush(this->task_manager);
2932 }
7daf5226 2933
7f56b494 2934 /* remove attributes first, as we pass the IKE_SA to the handler */
eef7427b 2935 charon->bus->handle_vips(charon->bus, &this->public, FALSE);
893da041 2936 while (array_remove(this->attributes, ARRAY_TAIL, &entry))
7f56b494 2937 {
5ae32210
MW
2938 if (entry.handler)
2939 {
75136327 2940 charon->attributes->release(charon->attributes, entry.handler,
a12f357b 2941 &this->public, entry.type, entry.data);
5ae32210 2942 }
893da041 2943 free(entry.data.ptr);
7f56b494 2944 }
2b0c8ee3
MW
2945 /* uninstall CHILD_SAs before virtual IPs, otherwise we might kill
2946 * routes that the CHILD_SA tries to uninstall. */
2947 while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa))
2948 {
38227d0e 2949 charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
2b0c8ee3
MW
2950 child_sa->destroy(child_sa);
2951 }
893da041 2952 while (array_remove(this->my_vips, ARRAY_TAIL, &vip))
c60c7694 2953 {
8394ea2a 2954 charon->kernel->del_ip(charon->kernel, vip, -1, TRUE);
101d26ba 2955 vip->destroy(vip);
c60c7694 2956 }
893da041 2957 if (array_count(this->other_vips))
12fa1784
AS
2958 {
2959 charon->bus->assign_vips(charon->bus, &this->public, FALSE);
2960 }
893da041 2961 while (array_remove(this->other_vips, ARRAY_TAIL, &vip))
cdcfe777 2962 {
497ce2cf 2963 if (this->peer_cfg)
cdcfe777 2964 {
28a3d5bf 2965 linked_list_t *pools;
28a3d5bf 2966
28a3d5bf
MW
2967 pools = linked_list_create_from_enumerator(
2968 this->peer_cfg->create_pool_enumerator(this->peer_cfg));
75136327 2969 charon->attributes->release_address(charon->attributes,
a16058a4 2970 pools, vip, &this->public);
28a3d5bf 2971 pools->destroy(pools);
cdcfe777 2972 }
101d26ba 2973 vip->destroy(vip);
cdcfe777 2974 }
a3854d83
MW
2975
2976 /* unset SA after here to avoid usage by the listeners */
2977 charon->bus->set_sa(charon->bus, NULL);
2978
2b0c8ee3 2979 array_destroy(this->child_sas);
b1908994 2980 DESTROY_IF(this->task_manager);
a3854d83 2981 DESTROY_IF(this->keymat);
893da041
MW
2982 array_destroy(this->attributes);
2983 array_destroy(this->my_vips);
2984 array_destroy(this->other_vips);
2985 array_destroy_offset(this->peer_addresses, offsetof(host_t, destroy));
dc04b7c7 2986#ifdef ME
22452f70 2987 if (this->is_mediation_server)
d5cc1758 2988 {
484a06bc
TB
2989 charon->mediation_manager->remove(charon->mediation_manager,
2990 this->ike_sa_id);
d5cc1758
TB
2991 }
2992 DESTROY_IF(this->server_reflexive_host);
9c2a905d 2993 chunk_free(&this->connect_id);
dc04b7c7 2994#endif /* ME */
9d9a772e 2995 free(this->nat_detection_dest.ptr);
7daf5226 2996
8dfbe71b
MW
2997 DESTROY_IF(this->my_host);
2998 DESTROY_IF(this->other_host);
2999 DESTROY_IF(this->my_id);
3000 DESTROY_IF(this->other_id);
d487b4b7
AS
3001 DESTROY_IF(this->local_host);
3002 DESTROY_IF(this->remote_host);
e4af6e6b 3003 DESTROY_IF(this->redirected_from);
c6ebd033 3004 array_destroy(this->redirected_at);
7daf5226 3005
e0fe7651
MW
3006 DESTROY_IF(this->ike_cfg);
3007 DESTROY_IF(this->peer_cfg);
5dffdea1 3008 DESTROY_IF(this->proposal);
a44bb934
MW
3009 this->my_auth->destroy(this->my_auth);
3010 this->other_auth->destroy(this->other_auth);
893da041
MW
3011 array_destroy_offset(this->my_auths, offsetof(auth_cfg_t, destroy));
3012 array_destroy_offset(this->other_auths, offsetof(auth_cfg_t, destroy));
7daf5226 3013
87a217f9 3014 this->ike_sa_id->destroy(this->ike_sa_id);
5113680f 3015 free(this);
7ba38761
JH
3016}
3017
3018/*
39b2903f 3019 * Described in header.
7ba38761 3020 */
17ec1c74
MW
3021ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
3022 ike_version_t version)
7ba38761 3023{
8bced61b 3024 private_ike_sa_t *this;
3568abe7 3025 static refcount_t unique_id = 0;
7daf5226 3026
3d54ae94
MW
3027 if (version == IKE_ANY)
3028 { /* prefer IKEv2 if protocol not specified */
3029#ifdef USE_IKEV2
3030 version = IKEV2;
3031#else
3032 version = IKEV1;
3033#endif
3034 }
3035
8bced61b
MW
3036 INIT(this,
3037 .public = {
0b611540 3038 .get_version = _get_version,
8bced61b
MW
3039 .get_state = _get_state,
3040 .set_state = _set_state,
3041 .get_name = _get_name,
3042 .get_statistic = _get_statistic,
44ff1153 3043 .set_statistic = _set_statistic,
8bced61b
MW
3044 .process_message = _process_message,
3045 .initiate = _initiate,
77e42826 3046 .retry_initiate = _retry_initiate,
8bced61b
MW
3047 .get_ike_cfg = _get_ike_cfg,
3048 .set_ike_cfg = _set_ike_cfg,
3049 .get_peer_cfg = _get_peer_cfg,
3050 .set_peer_cfg = _set_peer_cfg,
3051 .get_auth_cfg = _get_auth_cfg,
3052 .create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
1b9c1ae0 3053 .verify_peer_certificate = _verify_peer_certificate,
8bced61b
MW
3054 .add_auth_cfg = _add_auth_cfg,
3055 .get_proposal = _get_proposal,
3056 .set_proposal = _set_proposal,
3057 .get_id = _get_id,
3058 .get_my_host = _get_my_host,
3059 .set_my_host = _set_my_host,
3060 .get_other_host = _get_other_host,
3061 .set_other_host = _set_other_host,
3062 .set_message_id = _set_message_id,
347c403c 3063 .get_message_id = _get_message_id,
277f02ce 3064 .float_ports = _float_ports,
8bced61b
MW
3065 .update_hosts = _update_hosts,
3066 .get_my_id = _get_my_id,
3067 .set_my_id = _set_my_id,
3068 .get_other_id = _get_other_id,
3069 .set_other_id = _set_other_id,
3070 .get_other_eap_id = _get_other_eap_id,
3071 .enable_extension = _enable_extension,
3072 .supports_extension = _supports_extension,
3073 .set_condition = _set_condition,
3074 .has_condition = _has_condition,
94bbc602
TB
3075 .create_peer_address_enumerator = _create_peer_address_enumerator,
3076 .add_peer_address = _add_peer_address,
3077 .clear_peer_addresses = _clear_peer_addresses,
8bced61b
MW
3078 .has_mapping_changed = _has_mapping_changed,
3079 .retransmit = _retransmit,
3080 .delete = _delete_,
3081 .destroy = _destroy,
3082 .send_dpd = _send_dpd,
3083 .send_keepalive = _send_keepalive,
71c70705 3084 .redirect = _redirect,
c126ddd0 3085 .handle_redirect = _handle_redirect,
e4af6e6b 3086 .get_redirected_from = _get_redirected_from,
8bced61b
MW
3087 .get_keymat = _get_keymat,
3088 .add_child_sa = _add_child_sa,
3089 .get_child_sa = _get_child_sa,
4bbce1ef
TB
3090 .get_child_count = _get_child_count,
3091 .create_child_sa_enumerator = _create_child_sa_enumerator,
3092 .remove_child_sa = _remove_child_sa,
8bced61b
MW
3093 .rekey_child_sa = _rekey_child_sa,
3094 .delete_child_sa = _delete_child_sa,
3095 .destroy_child_sa = _destroy_child_sa,
3096 .rekey = _rekey,
3097 .reauth = _reauth,
3098 .reestablish = _reestablish,
3099 .set_auth_lifetime = _set_auth_lifetime,
3100 .roam = _roam,
713a1122
MW
3101 .inherit_pre = _inherit_pre,
3102 .inherit_post = _inherit_post,
8bced61b 3103 .generate_message = _generate_message,
40bab9a1 3104 .generate_message_fragmented = _generate_message_fragmented,
8bced61b
MW
3105 .reset = _reset,
3106 .get_unique_id = _get_unique_id,
101d26ba 3107 .add_virtual_ip = _add_virtual_ip,
d2e8f20d 3108 .clear_virtual_ips = _clear_virtual_ips,
101d26ba 3109 .create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
8bced61b 3110 .add_configuration_attribute = _add_configuration_attribute,
9d257034 3111 .create_attribute_enumerator = _create_attribute_enumerator,
dec3c184 3112 .get_if_id = _get_if_id,
8bced61b 3113 .set_kmaddress = _set_kmaddress,
ea340ee8 3114 .create_task_enumerator = _create_task_enumerator,
b7160401 3115 .remove_task = _remove_task,
cbc1a20f 3116 .flush_queue = _flush_queue,
69adeb5b 3117 .queue_task = _queue_task,
208678e6 3118 .queue_task_delayed = _queue_task_delayed,
00c889f4 3119 .adopt_child_tasks = _adopt_child_tasks,
dc04b7c7 3120#ifdef ME
8bced61b
MW
3121 .act_as_mediation_server = _act_as_mediation_server,
3122 .get_server_reflexive_host = _get_server_reflexive_host,
3123 .set_server_reflexive_host = _set_server_reflexive_host,
3124 .get_connect_id = _get_connect_id,
3125 .initiate_mediation = _initiate_mediation,
3126 .initiate_mediated = _initiate_mediated,
3127 .relay = _relay,
3128 .callback = _callback,
3129 .respond = _respond,
dc04b7c7 3130#endif /* ME */
8bced61b
MW
3131 },
3132 .ike_sa_id = ike_sa_id->clone(ike_sa_id),
0b611540 3133 .version = version,
8bced61b
MW
3134 .my_host = host_create_any(AF_INET),
3135 .other_host = host_create_any(AF_INET),
3136 .my_id = identification_create_from_encoding(ID_ANY, chunk_empty),
3137 .other_id = identification_create_from_encoding(ID_ANY, chunk_empty),
17ec1c74 3138 .keymat = keymat_create(version, initiator),
8bced61b
MW
3139 .state = IKE_CREATED,
3140 .stats[STAT_INBOUND] = time_monotonic(NULL),
3141 .stats[STAT_OUTBOUND] = time_monotonic(NULL),
3142 .my_auth = auth_cfg_create(),
3143 .other_auth = auth_cfg_create(),
893da041
MW
3144 .my_auths = array_create(0, 0),
3145 .other_auths = array_create(0, 0),
3146 .attributes = array_create(sizeof(attribute_entry_t), 0),
3568abe7 3147 .unique_id = ref_get(&unique_id),
8bced61b 3148 .keepalive_interval = lib->settings->get_time(lib->settings,
d223fe80 3149 "%s.keep_alive", KEEPALIVE_INTERVAL, lib->ns),
60c82591 3150 .retry_initiate_interval = lib->settings->get_time(lib->settings,
d223fe80 3151 "%s.retry_initiate_interval", 0, lib->ns),
b24b73b7 3152 .flush_auth_cfg = lib->settings->get_bool(lib->settings,
d223fe80 3153 "%s.flush_auth_cfg", FALSE, lib->ns),
40bab9a1 3154 .fragment_size = lib->settings->get_int(lib->settings,
0642f42b 3155 "%s.fragment_size", 1280, lib->ns),
489d154e
TB
3156 .follow_redirects = lib->settings->get_bool(lib->settings,
3157 "%s.follow_redirects", TRUE, lib->ns),
8bced61b 3158 );
4b64a1a1 3159
11aadd77
MW
3160 if (version == IKEV2)
3161 { /* always supported with IKEv2 */
3162 enable_extension(this, EXT_DPD);
3163 }
3164
5baaaa5e 3165 this->task_manager = task_manager_create(&this->public);
b223d517
TB
3166 this->my_host->set_port(this->my_host,
3167 charon->socket->get_port(charon->socket, FALSE));
7daf5226 3168
3d54ae94
MW
3169 if (!this->task_manager || !this->keymat)
3170 {
3171 DBG1(DBG_IKE, "IKE version %d not supported", this->version);
3172 destroy(this);
3173 return NULL;
3174 }
3dd3c5f3 3175 return &this->public;
7ba38761 3176}