]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libcharon/sa/ikev2/tasks/ike_auth.c
ike: Optionally allow private algorithms for IKE/CHILD_SAs
[thirdparty/strongswan.git] / src / libcharon / sa / ikev2 / tasks / ike_auth.c
CommitLineData
c60c7694 1/*
a9e60c96 2 * Copyright (C) 2012-2018 Tobias Brunner
a44bb934 3 * Copyright (C) 2005-2009 Martin Willi
c60c7694 4 * Copyright (C) 2005 Jan Hutter
1b671669 5 * HSR Hochschule fuer Technik Rapperswil
c60c7694
MW
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
01bc9bf4 15 * for more details.
c60c7694
MW
16 */
17
18#include "ike_auth.h"
19
20#include <string.h>
21
22#include <daemon.h>
c60c7694
MW
23#include <encoding/payloads/id_payload.h>
24#include <encoding/payloads/auth_payload.h>
49e8ac05 25#include <encoding/payloads/eap_payload.h>
c60c7694 26#include <encoding/payloads/nonce_payload.h>
a9e60c96 27#include <sa/ikev2/keymat_v2.h>
15a682f4 28#include <sa/ikev2/authenticators/eap_authenticator.h>
19233ef9 29#include <processing/jobs/delete_ike_sa_job.h>
49e8ac05 30
c60c7694
MW
31typedef struct private_ike_auth_t private_ike_auth_t;
32
33/**
34 * Private members of a ike_auth_t task.
35 */
36struct private_ike_auth_t {
7daf5226 37
c60c7694
MW
38 /**
39 * Public methods and task_t interface.
40 */
41 ike_auth_t public;
7daf5226 42
c60c7694
MW
43 /**
44 * Assigned IKE_SA.
45 */
46 ike_sa_t *ike_sa;
7daf5226 47
c60c7694
MW
48 /**
49 * Are we the initiator?
50 */
51 bool initiator;
7daf5226 52
c60c7694
MW
53 /**
54 * Nonce chosen by us in ike_init
55 */
56 chunk_t my_nonce;
7daf5226 57
c60c7694
MW
58 /**
59 * Nonce chosen by peer in ike_init
60 */
61 chunk_t other_nonce;
7daf5226 62
a9e60c96
TB
63 /**
64 * PPK_ID sent or received
65 */
66 identification_t *ppk_id;
67
68 /**
69 * Optional PPK to use
70 */
71 chunk_t ppk;
72
c60c7694
MW
73 /**
74 * IKE_SA_INIT message sent by us
75 */
76 packet_t *my_packet;
7daf5226 77
c60c7694
MW
78 /**
79 * IKE_SA_INIT message sent by peer
80 */
81 packet_t *other_packet;
7daf5226 82
5f15faeb
MW
83 /**
84 * Reserved bytes of ID payload
85 */
86 char reserved[3];
87
c60c7694 88 /**
a44bb934 89 * currently active authenticator, to authenticate us
c60c7694 90 */
a44bb934 91 authenticator_t *my_auth;
7daf5226 92
a44bb934
MW
93 /**
94 * currently active authenticator, to authenticate peer
95 */
96 authenticator_t *other_auth;
7daf5226 97
a44bb934
MW
98 /**
99 * peer_cfg candidates, ordered by priority
100 */
101 linked_list_t *candidates;
7daf5226 102
a44bb934
MW
103 /**
104 * selected peer config (might change when using multiple authentications)
105 */
106 peer_cfg_t *peer_cfg;
7daf5226 107
a44bb934
MW
108 /**
109 * have we planned an(other) authentication exchange?
110 */
111 bool do_another_auth;
7daf5226 112
a44bb934
MW
113 /**
114 * has the peer announced another authentication exchange?
115 */
116 bool expect_another_auth;
7daf5226 117
a44bb934
MW
118 /**
119 * should we send a AUTHENTICATION_FAILED notify?
120 */
121 bool authentication_failed;
6f5892f5
MW
122
123 /**
124 * received an INITIAL_CONTACT?
125 */
126 bool initial_contact;
0020b25a
MW
127
128 /**
129 * Is EAP acceptable, did we strictly authenticate peer?
130 */
131 bool eap_acceptable;
f5a9025c
TB
132
133 /**
134 * Gateway ID if redirected
135 */
136 identification_t *redirect_to;
a44bb934 137};
49e8ac05
MW
138
139/**
a44bb934 140 * check if multiple authentication extension is enabled, configuration-wise
49e8ac05 141 */
a44bb934 142static bool multiple_auth_enabled()
49e8ac05 143{
a44bb934 144 return lib->settings->get_bool(lib->settings,
d223fe80 145 "%s.multiple_authentication", TRUE, lib->ns);
c60c7694
MW
146}
147
148/**
149 * collect the needed information in the IKE_SA_INIT exchange from our message
150 */
a44bb934
MW
151static status_t collect_my_init_data(private_ike_auth_t *this,
152 message_t *message)
c60c7694
MW
153{
154 nonce_payload_t *nonce;
7daf5226 155
c60c7694 156 /* get the nonce that was generated in ike_init */
3ecfc83c 157 nonce = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
94f9f421 158 if (!nonce)
c60c7694
MW
159 {
160 return FAILED;
161 }
162 this->my_nonce = nonce->get_nonce(nonce);
7daf5226 163
a44bb934 164 /* pre-generate the message, keep a copy */
c60c7694
MW
165 if (this->ike_sa->generate_message(this->ike_sa, message,
166 &this->my_packet) != SUCCESS)
167 {
168 return FAILED;
169 }
7daf5226 170 return NEED_MORE;
c60c7694
MW
171}
172
173/**
174 * collect the needed information in the IKE_SA_INIT exchange from others message
175 */
a44bb934
MW
176static status_t collect_other_init_data(private_ike_auth_t *this,
177 message_t *message)
c60c7694
MW
178{
179 /* we collect the needed information in the IKE_SA_INIT exchange */
180 nonce_payload_t *nonce;
7daf5226 181
c60c7694 182 /* get the nonce that was generated in ike_init */
3ecfc83c 183 nonce = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
94f9f421 184 if (!nonce)
c60c7694
MW
185 {
186 return FAILED;
187 }
188 this->other_nonce = nonce->get_nonce(nonce);
7daf5226 189
a44bb934 190 /* keep a copy of the received packet */
c60c7694 191 this->other_packet = message->get_packet(message);
7daf5226 192 return NEED_MORE;
c60c7694
MW
193}
194
5f15faeb
MW
195/**
196 * Get and store reserved bytes of id_payload, required for AUTH payload
197 */
198static void get_reserved_id_bytes(private_ike_auth_t *this, id_payload_t *id)
199{
b12c53ce 200 uint8_t *byte;
5f15faeb
MW
201 int i;
202
203 for (i = 0; i < countof(this->reserved); i++)
204 {
205 byte = payload_get_field(&id->payload_interface, RESERVED_BYTE, i);
206 if (byte)
207 {
208 this->reserved[i] = *byte;
209 }
210 }
211}
212
49e8ac05 213/**
a44bb934 214 * Get the next authentication configuration
49e8ac05 215 */
a44bb934 216static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local)
49e8ac05 217{
a44bb934
MW
218 enumerator_t *e1, *e2;
219 auth_cfg_t *c1, *c2, *next = NULL;
7daf5226 220
a44bb934
MW
221 /* find an available config not already done */
222 e1 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, local);
223 while (e1->enumerate(e1, &c1))
95f1735f 224 {
a44bb934 225 bool found = FALSE;
7daf5226 226
44ce7493 227 e2 = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, local);
a44bb934
MW
228 while (e2->enumerate(e2, &c2))
229 {
230 if (c2->complies(c2, c1, FALSE))
231 {
232 found = TRUE;
233 break;
234 }
235 }
236 e2->destroy(e2);
237 if (!found)
238 {
239 next = c1;
240 break;
49e8ac05 241 }
49e8ac05 242 }
a44bb934
MW
243 e1->destroy(e1);
244 return next;
49e8ac05
MW
245}
246
289b9b7b
MW
247/**
248 * Move the currently active auth config to the auth configs completed
249 */
250static void apply_auth_cfg(private_ike_auth_t *this, bool local)
251{
252 auth_cfg_t *cfg;
253
254 cfg = auth_cfg_create();
255 cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, local), local);
256 this->ike_sa->add_auth_cfg(this->ike_sa, local, cfg);
257}
258
49e8ac05 259/**
a44bb934 260 * Check if we have should initiate another authentication round
49e8ac05 261 */
a44bb934 262static bool do_another_auth(private_ike_auth_t *this)
49e8ac05 263{
a44bb934
MW
264 bool do_another = FALSE;
265 enumerator_t *done, *todo;
266 auth_cfg_t *done_cfg, *todo_cfg;
7daf5226 267
a44bb934 268 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
49e8ac05 269 {
a44bb934 270 return FALSE;
49e8ac05 271 }
7daf5226 272
44ce7493 273 done = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, TRUE);
a44bb934
MW
274 todo = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, TRUE);
275 while (todo->enumerate(todo, &todo_cfg))
49e8ac05 276 {
a44bb934 277 if (!done->enumerate(done, &done_cfg))
49e8ac05 278 {
a44bb934
MW
279 done_cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
280 }
281 if (!done_cfg->complies(done_cfg, todo_cfg, FALSE))
282 {
283 do_another = TRUE;
284 break;
49e8ac05 285 }
49e8ac05 286 }
a44bb934
MW
287 done->destroy(done);
288 todo->destroy(todo);
289 return do_another;
49e8ac05
MW
290}
291
a9e60c96
TB
292/**
293 * Check if this is the first authentication round
294 */
295static bool is_first_round(private_ike_auth_t *this, bool local)
296{
297 enumerator_t *done;
298 auth_cfg_t *cfg;
299
300 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
301 {
302 return TRUE;
303 }
304
305 done = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, local);
306 if (done->enumerate(done, &cfg))
307 {
308 done->destroy(done);
309 return FALSE;
310 }
311 done->destroy(done);
312 return TRUE;
313}
314
49e8ac05 315/**
a44bb934 316 * Get peer configuration candidates from backends
49e8ac05 317 */
a44bb934 318static bool load_cfg_candidates(private_ike_auth_t *this)
49e8ac05 319{
a44bb934
MW
320 enumerator_t *enumerator;
321 peer_cfg_t *peer_cfg;
da288a07 322 ike_cfg_t *ike_cfg;
a44bb934
MW
323 host_t *me, *other;
324 identification_t *my_id, *other_id;
da288a07
TB
325 proposal_t *ike_proposal;
326 bool private;
7daf5226 327
a44bb934
MW
328 me = this->ike_sa->get_my_host(this->ike_sa);
329 other = this->ike_sa->get_other_host(this->ike_sa);
330 my_id = this->ike_sa->get_my_id(this->ike_sa);
331 other_id = this->ike_sa->get_other_id(this->ike_sa);
da288a07 332 ike_proposal = this->ike_sa->get_proposal(this->ike_sa);
05e373ae
TE
333 private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) ||
334 lib->settings->get_bool(lib->settings, "%s.accept_private_algs",
335 FALSE, lib->ns);
7daf5226 336
033dfba0
MW
337 DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]",
338 me, my_id, other, other_id);
a44bb934 339 enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
ac009df1 340 me, other, my_id, other_id, IKEV2);
a44bb934
MW
341 while (enumerator->enumerate(enumerator, &peer_cfg))
342 {
da288a07
TB
343 /* ignore all configs that have no matching IKE proposal */
344 ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
345 if (!ike_cfg->has_proposal(ike_cfg, ike_proposal, private))
346 {
347 DBG2(DBG_CFG, "ignore candidate '%s' without matching IKE proposal",
348 peer_cfg->get_name(peer_cfg));
349 continue;
350 }
a44bb934 351 peer_cfg->get_ref(peer_cfg);
94f9f421 352 if (!this->peer_cfg)
a44bb934
MW
353 { /* best match */
354 this->peer_cfg = peer_cfg;
a44bb934
MW
355 }
356 else
357 {
358 this->candidates->insert_last(this->candidates, peer_cfg);
359 }
f5fbad4a 360 }
a44bb934
MW
361 enumerator->destroy(enumerator);
362 if (this->peer_cfg)
49e8ac05 363 {
da288a07 364 this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
a44bb934
MW
365 DBG1(DBG_CFG, "selected peer config '%s'",
366 this->peer_cfg->get_name(this->peer_cfg));
367 return TRUE;
49e8ac05 368 }
a44bb934
MW
369 DBG1(DBG_CFG, "no matching peer config found");
370 return FALSE;
f5fbad4a
MW
371}
372
373/**
a44bb934 374 * update the current peer candidate if necessary, using candidates
f5fbad4a 375 */
a44bb934 376static bool update_cfg_candidates(private_ike_auth_t *this, bool strict)
f5fbad4a 377{
a44bb934 378 do
49e8ac05 379 {
a44bb934
MW
380 if (this->peer_cfg)
381 {
cc787697 382 char *comply_error = NULL;
a44bb934
MW
383 enumerator_t *e1, *e2, *tmp;
384 auth_cfg_t *c1, *c2;
7daf5226 385
44ce7493 386 e1 = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, FALSE);
a44bb934 387 e2 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, FALSE);
7daf5226 388
a44bb934
MW
389 if (strict)
390 { /* swap lists in strict mode: all configured rounds must be
391 * fulfilled. If !strict, we check only the rounds done so far. */
392 tmp = e1;
393 e1 = e2;
394 e2 = tmp;
395 }
396 while (e1->enumerate(e1, &c1))
397 {
398 /* check if done authentications comply to configured ones */
cc787697 399 if (!e2->enumerate(e2, &c2))
a44bb934 400 {
cc787697
MW
401 comply_error = "insufficient authentication rounds";
402 break;
403 }
404 if (!strict && !c1->complies(c1, c2, TRUE))
405 {
406 comply_error = "non-matching authentication done";
407 break;
408 }
409 if (strict && !c2->complies(c2, c1, TRUE))
410 {
411 comply_error = "constraint checking failed";
a44bb934
MW
412 break;
413 }
414 }
415 e1->destroy(e1);
416 e2->destroy(e2);
cc787697 417 if (!comply_error)
a44bb934
MW
418 {
419 break;
420 }
2ad1df95 421 DBG1(DBG_CFG, "selected peer config '%s' unacceptable: %s",
cc787697 422 this->peer_cfg->get_name(this->peer_cfg), comply_error);
a44bb934
MW
423 this->peer_cfg->destroy(this->peer_cfg);
424 }
425 if (this->candidates->remove_first(this->candidates,
426 (void**)&this->peer_cfg) != SUCCESS)
427 {
428 DBG1(DBG_CFG, "no alternative config found");
429 this->peer_cfg = NULL;
430 }
431 else
432 {
433 DBG1(DBG_CFG, "switching to peer config '%s'",
434 this->peer_cfg->get_name(this->peer_cfg));
435 this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
436 }
49e8ac05 437 }
a44bb934 438 while (this->peer_cfg);
7daf5226 439
a44bb934 440 return this->peer_cfg != NULL;
49e8ac05
MW
441}
442
a9e60c96
TB
443/**
444 * Currently defined PPK_ID types
445 */
446#define PPK_ID_OPAQUE 1
447#define PPK_ID_FIXED 2
448
449/**
450 * Parse the payload data of the given PPK_IDENTITY notify
451 */
452static bool parse_ppk_identity(notify_payload_t *notify, identification_t **id)
453{
454 chunk_t data;
455
456 data = notify->get_notification_data(notify);
457 if (data.len < 2)
458 {
459 return FALSE;
460 }
461 switch (data.ptr[0])
462 {
a9e60c96
TB
463 case PPK_ID_FIXED:
464 data = chunk_skip(data, 1);
465 break;
85afe81e
TB
466 default:
467 return FALSE;
a9e60c96
TB
468 }
469 *id = identification_create_from_data(data);
470 return TRUE;
471}
472
473/**
474 * Add a PPK_IDENTITY with the given PPK_ID to the given message
475 */
476static void add_ppk_identity(identification_t *id, message_t *msg)
477{
478 chunk_t data;
479 uint8_t type = PPK_ID_FIXED;
480
481 /* we currently only support one type */
482 data = chunk_cata("cc", chunk_from_thing(type), id->get_encoding(id));
483 msg->add_notify(msg, FALSE, PPK_IDENTITY, data);
484}
485
486/**
487 * Use the given PPK_ID to find a PPK and store it and the ID in the task
488 */
489static bool get_ppk(private_ike_auth_t *this, identification_t *ppk_id)
490{
491 shared_key_t *key;
492
493 key = lib->credmgr->get_shared(lib->credmgr, SHARED_PPK, ppk_id, NULL);
494 if (!key)
495 {
496 if (this->peer_cfg->ppk_required(this->peer_cfg))
497 {
498 DBG1(DBG_CFG, "PPK required but no PPK found for '%Y'", ppk_id);
499 return FALSE;
500 }
501 DBG1(DBG_CFG, "no PPK for '%Y' found, ignored because PPK is not "
502 "required", ppk_id);
503 return TRUE;
504 }
505 this->ppk = chunk_clone(key->get_key(key));
506 this->ppk_id = ppk_id->clone(ppk_id);
507 key->destroy(key);
508 return TRUE;
509}
510
511/**
512 * Check if we have a PPK available and, if not, whether we require one as
513 * initiator
514 */
515static bool get_ppk_i(private_ike_auth_t *this)
516{
517 identification_t *ppk_id;
518
519 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_PPK))
520 {
521 if (this->peer_cfg->ppk_required(this->peer_cfg))
522 {
523 DBG1(DBG_CFG, "PPK required but peer does not support PPK");
524 return FALSE;
525 }
526 return TRUE;
527 }
528
529 ppk_id = this->peer_cfg->get_ppk_id(this->peer_cfg);
530 if (!ppk_id)
531 {
532 if (this->peer_cfg->ppk_required(this->peer_cfg))
533 {
534 DBG1(DBG_CFG, "PPK required but no PPK_ID configured");
535 return FALSE;
536 }
537 return TRUE;
538 }
539 return get_ppk(this, ppk_id);
540}
541
542/**
543 * Check if we have a PPK available and if not whether we require one as
544 * responder
545 */
546static bool get_ppk_r(private_ike_auth_t *this, message_t *msg)
547{
548 notify_payload_t *notify;
549 identification_t *ppk_id, *ppk_id_cfg;
550 bool result;
551
552 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_PPK))
553 {
554 if (this->peer_cfg->ppk_required(this->peer_cfg))
555 {
556 DBG1(DBG_CFG, "PPK required but peer does not support PPK");
557 return FALSE;
558 }
559 return TRUE;
560 }
561
562 notify = msg->get_notify(msg, PPK_IDENTITY);
563 if (!notify || !parse_ppk_identity(notify, &ppk_id))
564 {
565 if (this->peer_cfg->ppk_required(this->peer_cfg))
566 {
567 DBG1(DBG_CFG, "PPK required but no PPK_IDENTITY received");
568 return FALSE;
569 }
570 return TRUE;
571 }
572
573 ppk_id_cfg = this->peer_cfg->get_ppk_id(this->peer_cfg);
574 if (ppk_id_cfg && !ppk_id->matches(ppk_id, ppk_id_cfg))
575 {
576 DBG1(DBG_CFG, "received PPK_ID '%Y', but require '%Y'", ppk_id,
577 ppk_id_cfg);
578 ppk_id->destroy(ppk_id);
579 return FALSE;
580 }
581 result = get_ppk(this, ppk_id);
582 ppk_id->destroy(ppk_id);
583 return result;
584}
585
2b7686b5
MW
586METHOD(task_t, build_i, status_t,
587 private_ike_auth_t *this, message_t *message)
c60c7694 588{
a44bb934 589 auth_cfg_t *cfg;
7daf5226 590
c60c7694
MW
591 if (message->get_exchange_type(message) == IKE_SA_INIT)
592 {
593 return collect_my_init_data(this, message);
594 }
7daf5226 595
94f9f421 596 if (!this->peer_cfg)
8b8dd69d 597 {
a44bb934
MW
598 this->peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
599 this->peer_cfg->get_ref(this->peer_cfg);
8b8dd69d 600 }
7daf5226 601
12fca6cc
MW
602 if (message->get_message_id(message) == 1)
603 { /* in the first IKE_AUTH ... */
604 if (this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
605 { /* indicate support for multiple authentication */
606 message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
607 chunk_empty);
608 }
609 /* indicate support for EAP-only authentication */
610 message->add_notify(message, FALSE, EAP_ONLY_AUTHENTICATION,
611 chunk_empty);
d6ffa85f
TB
612 /* indicate support for RFC 6311 Message ID synchronization */
613 message->add_notify(message, FALSE, IKEV2_MESSAGE_ID_SYNC_SUPPORTED,
614 chunk_empty);
a9e60c96
TB
615 /* only use a PPK in the first round */
616 if (!get_ppk_i(this))
617 {
618 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
619 return FAILED;
620 }
49e8ac05 621 }
7daf5226 622
a44bb934
MW
623 if (!this->do_another_auth && !this->my_auth)
624 { /* we have done our rounds */
625 return NEED_MORE;
626 }
7daf5226 627
a44bb934 628 /* check if an authenticator is in progress */
94f9f421 629 if (!this->my_auth)
49e8ac05 630 {
a4a1e24d 631 identification_t *idi, *idr = NULL;
a44bb934 632 id_payload_t *id_payload;
7daf5226 633
a44bb934
MW
634 /* clean up authentication config from a previous round */
635 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
636 cfg->purge(cfg, TRUE);
7daf5226 637
a44bb934
MW
638 /* add (optional) IDr */
639 cfg = get_auth_cfg(this, FALSE);
640 if (cfg)
641 {
a4a1e24d 642 idr = cfg->get(cfg, AUTH_RULE_IDENTITY);
3a8852c7
TB
643 if (!cfg->get(cfg, AUTH_RULE_IDENTITY_LOOSE) && idr &&
644 !idr->contains_wildcards(idr))
a44bb934 645 {
a4a1e24d 646 this->ike_sa->set_other_id(this->ike_sa, idr->clone(idr));
a44bb934 647 id_payload = id_payload_create_from_identification(
3ecfc83c 648 PLV2_ID_RESPONDER, idr);
a44bb934
MW
649 message->add_payload(message, (payload_t*)id_payload);
650 }
651 }
652 /* add IDi */
653 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
654 cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
a4a1e24d 655 idi = cfg->get(cfg, AUTH_RULE_IDENTITY);
b241a374 656 if (!idi || idi->get_type(idi) == ID_ANY)
4b32bde4 657 { /* ID_ANY is invalid as IDi, use local IP address instead */
4b32bde4 658 host_t *me;
4b32bde4 659
b241a374 660 DBG1(DBG_CFG, "no IDi configured, fall back on IP address");
4b32bde4
TB
661 me = this->ike_sa->get_my_host(this->ike_sa);
662 idi = identification_create_from_sockaddr(me->get_sockaddr(me));
7e84c427 663 cfg->add(cfg, AUTH_RULE_IDENTITY, idi);
4b32bde4 664 }
a4a1e24d 665 this->ike_sa->set_my_id(this->ike_sa, idi->clone(idi));
3ecfc83c 666 id_payload = id_payload_create_from_identification(PLV2_ID_INITIATOR, idi);
5f15faeb 667 get_reserved_id_bytes(this, id_payload);
a44bb934 668 message->add_payload(message, (payload_t*)id_payload);
7daf5226 669
2f95c552
TB
670 if (idr && !idr->contains_wildcards(idr) &&
671 message->get_message_id(message) == 1 &&
f4cc7ea1 672 this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NEVER)
a4a1e24d
MW
673 {
674 host_t *host;
675
676 host = this->ike_sa->get_other_host(this->ike_sa);
677 if (!charon->ike_sa_manager->has_contact(charon->ike_sa_manager,
678 idi, idr, host->get_family(host)))
679 {
680 message->add_notify(message, FALSE, INITIAL_CONTACT, chunk_empty);
681 }
682 }
683
a44bb934 684 /* build authentication data */
25f2d52f
MW
685 this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
686 this->other_nonce, this->my_nonce,
687 this->other_packet->get_data(this->other_packet),
5f15faeb
MW
688 this->my_packet->get_data(this->my_packet),
689 this->reserved);
a44bb934 690 if (!this->my_auth)
49e8ac05 691 {
3f7f5388 692 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
49e8ac05
MW
693 return FAILED;
694 }
695 }
a9e60c96
TB
696 /* for authentication methods that return NEED_MORE, the PPK will be reset
697 * in process_i() for messages without PPK_ID notify, so we always set it
698 * during the first round (afterwards the PPK won't be available) */
699 if (this->ppk.ptr && this->my_auth->use_ppk)
700 {
701 this->my_auth->use_ppk(this->my_auth, this->ppk,
702 !this->peer_cfg->ppk_required(this->peer_cfg));
703 }
a44bb934
MW
704 switch (this->my_auth->build(this->my_auth, message))
705 {
706 case SUCCESS:
289b9b7b 707 apply_auth_cfg(this, TRUE);
a44bb934
MW
708 this->my_auth->destroy(this->my_auth);
709 this->my_auth = NULL;
710 break;
711 case NEED_MORE:
712 break;
713 default:
3f7f5388 714 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
a44bb934
MW
715 return FAILED;
716 }
7daf5226 717
a9e60c96
TB
718 /* add a PPK_IDENTITY notify to the message that contains AUTH */
719 if (this->ppk_id && message->get_payload(message, PLV2_AUTH))
720 {
721 add_ppk_identity(this->ppk_id, message);
722 }
723
a44bb934
MW
724 /* check for additional authentication rounds */
725 if (do_another_auth(this))
726 {
3ecfc83c 727 if (message->get_payload(message, PLV2_AUTH))
a44bb934
MW
728 {
729 message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
730 }
731 }
732 else
733 {
734 this->do_another_auth = FALSE;
735 }
49e8ac05 736 return NEED_MORE;
c60c7694
MW
737}
738
2b7686b5
MW
739METHOD(task_t, process_r, status_t,
740 private_ike_auth_t *this, message_t *message)
e0fe7651 741{
a44bb934
MW
742 auth_cfg_t *cfg, *cand;
743 id_payload_t *id_payload;
744 identification_t *id;
7daf5226 745
c60c7694
MW
746 if (message->get_exchange_type(message) == IKE_SA_INIT)
747 {
748 return collect_other_init_data(this, message);
749 }
7daf5226 750
94f9f421 751 if (!this->my_auth && this->do_another_auth)
a44bb934
MW
752 {
753 /* handle (optional) IDr payload, apply proposed identity */
3ecfc83c 754 id_payload = (id_payload_t*)message->get_payload(message, PLV2_ID_RESPONDER);
a44bb934
MW
755 if (id_payload)
756 {
757 id = id_payload->get_identification(id_payload);
758 }
759 else
760 {
761 id = identification_create_from_encoding(ID_ANY, chunk_empty);
762 }
763 this->ike_sa->set_my_id(this->ike_sa, id);
764 }
7daf5226 765
a44bb934 766 if (!this->expect_another_auth)
49e8ac05
MW
767 {
768 return NEED_MORE;
769 }
12fca6cc
MW
770
771 if (message->get_message_id(message) == 1)
772 { /* check for extensions in the first IKE_AUTH */
773 if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED))
774 {
775 this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
776 }
83628fd6
TB
777 if (message->get_notify(message, EAP_ONLY_AUTHENTICATION))
778 {
12fca6cc
MW
779 this->ike_sa->enable_extension(this->ike_sa,
780 EXT_EAP_ONLY_AUTHENTICATION);
781 }
a6289d93
TB
782 if (message->get_notify(message, INITIAL_CONTACT))
783 {
784 this->initial_contact = TRUE;
785 }
a44bb934 786 }
7daf5226 787
94f9f421 788 if (!this->other_auth)
a44bb934
MW
789 {
790 /* handle IDi payload */
3ecfc83c 791 id_payload = (id_payload_t*)message->get_payload(message, PLV2_ID_INITIATOR);
a44bb934
MW
792 if (!id_payload)
793 {
794 DBG1(DBG_IKE, "IDi payload missing");
795 return FAILED;
796 }
797 id = id_payload->get_identification(id_payload);
5f15faeb 798 get_reserved_id_bytes(this, id_payload);
a44bb934
MW
799 this->ike_sa->set_other_id(this->ike_sa, id);
800 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
801 cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
7daf5226 802
94f9f421 803 if (!this->peer_cfg)
a44bb934
MW
804 {
805 if (!load_cfg_candidates(this))
806 {
807 this->authentication_failed = TRUE;
808 return NEED_MORE;
809 }
810 }
94f9f421 811 if (!message->get_payload(message, PLV2_AUTH))
a44bb934
MW
812 { /* before authenticating with EAP, we need a EAP config */
813 cand = get_auth_cfg(this, FALSE);
814 while (!cand || (
815 (uintptr_t)cand->get(cand, AUTH_RULE_EAP_TYPE) == EAP_NAK &&
816 (uintptr_t)cand->get(cand, AUTH_RULE_EAP_VENDOR) == 0))
817 { /* peer requested EAP, but current config does not match */
2ad1df95 818 DBG1(DBG_IKE, "peer requested EAP, config unacceptable");
a44bb934
MW
819 this->peer_cfg->destroy(this->peer_cfg);
820 this->peer_cfg = NULL;
821 if (!update_cfg_candidates(this, FALSE))
822 {
823 this->authentication_failed = TRUE;
824 return NEED_MORE;
825 }
826 cand = get_auth_cfg(this, FALSE);
827 }
ec6caa13
MW
828 /* copy over the EAP specific rules for authentication */
829 cfg->add(cfg, AUTH_RULE_EAP_TYPE,
830 cand->get(cand, AUTH_RULE_EAP_TYPE));
831 cfg->add(cfg, AUTH_RULE_EAP_VENDOR,
832 cand->get(cand, AUTH_RULE_EAP_VENDOR));
833 id = (identification_t*)cand->get(cand, AUTH_RULE_EAP_IDENTITY);
834 if (id)
835 {
836 cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id));
837 }
36eafea2
MW
838 id = (identification_t*)cand->get(cand, AUTH_RULE_AAA_IDENTITY);
839 if (id)
840 {
841 cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, id->clone(id));
842 }
a44bb934 843 }
7daf5226 844
a44bb934 845 /* verify authentication data */
25f2d52f
MW
846 this->other_auth = authenticator_create_verifier(this->ike_sa,
847 message, this->other_nonce, this->my_nonce,
848 this->other_packet->get_data(this->other_packet),
5f15faeb
MW
849 this->my_packet->get_data(this->my_packet),
850 this->reserved);
a44bb934
MW
851 if (!this->other_auth)
852 {
853 this->authentication_failed = TRUE;
854 return NEED_MORE;
855 }
856 }
a9e60c96
TB
857 if (message->get_payload(message, PLV2_AUTH) &&
858 is_first_round(this, FALSE))
859 {
860 if (!get_ppk_r(this, message))
861 {
862 this->authentication_failed = TRUE;
863 return NEED_MORE;
864 }
865 else if (this->ppk.ptr && this->other_auth->use_ppk)
866 {
867 this->other_auth->use_ppk(this->other_auth, this->ppk, FALSE);
868 }
869 }
a44bb934 870 switch (this->other_auth->process(this->other_auth, message))
49e8ac05
MW
871 {
872 case SUCCESS:
a44bb934
MW
873 this->other_auth->destroy(this->other_auth);
874 this->other_auth = NULL;
49e8ac05 875 break;
a44bb934 876 case NEED_MORE:
3ecfc83c 877 if (message->get_payload(message, PLV2_AUTH))
a44bb934
MW
878 { /* AUTH verification successful, but another build() needed */
879 break;
880 }
881 return NEED_MORE;
49e8ac05 882 default:
a44bb934 883 this->authentication_failed = TRUE;
552cc11b 884 return NEED_MORE;
49e8ac05 885 }
7daf5226 886
a44bb934 887 /* another auth round done, invoke authorize hook */
44ce7493 888 if (!charon->bus->authorize(charon->bus, FALSE))
a44bb934 889 {
44ce7493 890 DBG1(DBG_IKE, "authorization hook forbids IKE_SA, cancelling");
a44bb934
MW
891 this->authentication_failed = TRUE;
892 return NEED_MORE;
893 }
7daf5226 894
289b9b7b 895 apply_auth_cfg(this, FALSE);
b49d047b 896
a44bb934 897 if (!update_cfg_candidates(this, FALSE))
6e04f253 898 {
a44bb934
MW
899 this->authentication_failed = TRUE;
900 return NEED_MORE;
6e04f253 901 }
7daf5226 902
94f9f421 903 if (!message->get_notify(message, ANOTHER_AUTH_FOLLOWS))
a44bb934
MW
904 {
905 this->expect_another_auth = FALSE;
906 if (!update_cfg_candidates(this, TRUE))
907 {
908 this->authentication_failed = TRUE;
909 return NEED_MORE;
910 }
82290106 911 }
c60c7694
MW
912 return NEED_MORE;
913}
914
a9e60c96
TB
915/**
916 * Clear the PPK and PPK_ID
917 */
918static void clear_ppk(private_ike_auth_t *this)
919{
920 DESTROY_IF(this->ppk_id);
921 this->ppk_id = NULL;
922 chunk_clear(&this->ppk);
923}
924
925/**
926 * Derive new keys and clear the PPK
927 */
928static bool apply_ppk(private_ike_auth_t *this)
929{
930 keymat_v2_t *keymat;
931
932 if (this->ppk.ptr)
933 {
934 keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
935 if (!keymat->derive_ike_keys_ppk(keymat, this->ppk))
936 {
937 return FALSE;
938 }
939 DBG1(DBG_CFG, "using PPK for PPK_ID '%Y'", this->ppk_id);
e4d85011 940 this->ike_sa->set_condition(this->ike_sa, COND_PPK, TRUE);
a9e60c96
TB
941 }
942 clear_ppk(this);
943 return TRUE;
944}
945
2b7686b5
MW
946METHOD(task_t, build_r, status_t,
947 private_ike_auth_t *this, message_t *message)
c60c7694 948{
19233ef9 949 identification_t *gateway;
a44bb934 950 auth_cfg_t *cfg;
7daf5226 951
c60c7694
MW
952 if (message->get_exchange_type(message) == IKE_SA_INIT)
953 {
a44bb934
MW
954 if (multiple_auth_enabled())
955 {
956 message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
957 chunk_empty);
958 }
c60c7694
MW
959 return collect_my_init_data(this, message);
960 }
7daf5226 961
94f9f421 962 if (this->authentication_failed || !this->peer_cfg)
552cc11b 963 {
ccbe3803 964 goto peer_auth_failed;
552cc11b 965 }
7daf5226 966
94f9f421 967 if (!this->my_auth && this->do_another_auth)
f007a700 968 {
a44bb934
MW
969 identification_t *id, *id_cfg;
970 id_payload_t *id_payload;
7daf5226 971
a44bb934
MW
972 /* add IDr */
973 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
974 cfg->purge(cfg, TRUE);
975 cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
7daf5226 976
a44bb934
MW
977 id_cfg = cfg->get(cfg, AUTH_RULE_IDENTITY);
978 id = this->ike_sa->get_my_id(this->ike_sa);
979 if (id->get_type(id) == ID_ANY)
980 { /* no IDr received, apply configured ID */
981 if (!id_cfg || id_cfg->contains_wildcards(id_cfg))
7fd6c078
TB
982 { /* no ID configured, use local IP address */
983 host_t *me;
984
985 DBG1(DBG_CFG, "no IDr configured, fall back on IP address");
986 me = this->ike_sa->get_my_host(this->ike_sa);
987 id_cfg = identification_create_from_sockaddr(
988 me->get_sockaddr(me));
7e84c427 989 cfg->add(cfg, AUTH_RULE_IDENTITY, id_cfg);
a44bb934
MW
990 }
991 this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg));
992 id = id_cfg;
993 }
994 else
995 { /* IDr received, check if it matches configuration */
996 if (id_cfg && !id->matches(id, id_cfg))
997 {
d24a74c5 998 DBG1(DBG_CFG, "received IDr %Y, but require %Y", id, id_cfg);
ccbe3803 999 goto peer_auth_failed;
a44bb934
MW
1000 }
1001 }
7daf5226 1002
3ecfc83c 1003 id_payload = id_payload_create_from_identification(PLV2_ID_RESPONDER, id);
5f15faeb 1004 get_reserved_id_bytes(this, id_payload);
a44bb934 1005 message->add_payload(message, (payload_t*)id_payload);
7daf5226 1006
f34702ff
MW
1007 if ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS) == AUTH_CLASS_EAP)
1008 { /* EAP-only authentication */
1009 if (!this->ike_sa->supports_extension(this->ike_sa,
1010 EXT_EAP_ONLY_AUTHENTICATION))
1011 {
1012 DBG1(DBG_IKE, "configured EAP-only authentication, but peer "
1013 "does not support it");
ccbe3803 1014 goto peer_auth_failed;
f34702ff
MW
1015 }
1016 }
1017 else
a44bb934 1018 {
f34702ff
MW
1019 /* build authentication data */
1020 this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
1021 this->other_nonce, this->my_nonce,
1022 this->other_packet->get_data(this->other_packet),
5f15faeb
MW
1023 this->my_packet->get_data(this->my_packet),
1024 this->reserved);
f34702ff
MW
1025 if (!this->my_auth)
1026 {
3f7f5388 1027 goto local_auth_failed;
f34702ff 1028 }
a44bb934 1029 }
f007a700 1030 }
7daf5226 1031
a44bb934 1032 if (this->other_auth)
49e8ac05 1033 {
a44bb934
MW
1034 switch (this->other_auth->build(this->other_auth, message))
1035 {
1036 case SUCCESS:
1037 this->other_auth->destroy(this->other_auth);
1038 this->other_auth = NULL;
1039 break;
1040 case NEED_MORE:
1041 break;
1042 default:
3ecfc83c 1043 if (message->get_payload(message, PLV2_EAP))
a44bb934 1044 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
ccbe3803 1045 goto peer_auth_failed_no_notify;
a44bb934 1046 }
ccbe3803 1047 goto peer_auth_failed;
a44bb934 1048 }
49e8ac05 1049 }
a44bb934 1050 if (this->my_auth)
0644ebd3 1051 {
a9e60c96
TB
1052 if (this->ppk.ptr && this->my_auth->use_ppk)
1053 {
1054 this->my_auth->use_ppk(this->my_auth, this->ppk, FALSE);
1055 }
a44bb934
MW
1056 switch (this->my_auth->build(this->my_auth, message))
1057 {
1058 case SUCCESS:
289b9b7b 1059 apply_auth_cfg(this, TRUE);
a44bb934
MW
1060 this->my_auth->destroy(this->my_auth);
1061 this->my_auth = NULL;
1062 break;
1063 case NEED_MORE:
1064 break;
1065 default:
3f7f5388 1066 goto local_auth_failed;
a44bb934 1067 }
0644ebd3 1068 }
7daf5226 1069
a9e60c96
TB
1070 /* add a PPK_IDENTITY notify and derive new keys and clear the PPK */
1071 if (this->ppk.ptr)
1072 {
1073 message->add_notify(message, FALSE, PPK_IDENTITY, chunk_empty);
1074 if (!apply_ppk(this))
1075 {
1076 goto local_auth_failed;
1077 }
1078 }
1079
a44bb934
MW
1080 /* check for additional authentication rounds */
1081 if (do_another_auth(this))
1082 {
1083 message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
1084 }
1085 else
1086 {
1087 this->do_another_auth = FALSE;
1088 }
19233ef9 1089 if (this->do_another_auth || this->expect_another_auth)
c60c7694 1090 {
19233ef9 1091 return NEED_MORE;
c60c7694 1092 }
19233ef9
TB
1093
1094 if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
a6289d93 1095 this->ike_sa, this->initial_contact))
19233ef9
TB
1096 {
1097 DBG1(DBG_IKE, "cancelling IKE_SA setup due to uniqueness policy");
1098 charon->bus->alert(charon->bus, ALERT_UNIQUE_KEEP);
1099 message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
1100 chunk_empty);
1101 return FAILED;
1102 }
1103 if (!charon->bus->authorize(charon->bus, TRUE))
1104 {
1105 DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
1106 goto peer_auth_failed;
1107 }
1108 if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
1109 charon->redirect->redirect_on_auth(charon->redirect, this->ike_sa,
1110 &gateway))
1111 {
1112 delete_ike_sa_job_t *job;
1113 chunk_t data;
1114
1115 DBG1(DBG_IKE, "redirecting peer to %Y", gateway);
1116 data = redirect_data_create(gateway, chunk_empty);
1117 message->add_notify(message, FALSE, REDIRECT, data);
1118 gateway->destroy(gateway);
1119 chunk_free(&data);
1120 /* we use this condition to prevent the CHILD_SA from getting created */
1121 this->ike_sa->set_condition(this->ike_sa, COND_REDIRECTED, TRUE);
1122 /* if the peer does not delete the SA we do so after a while */
1123 job = delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE);
1124 lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
1125 lib->settings->get_int(lib->settings,
1126 "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
1127 lib->ns));
1128 }
1129 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1130 this->ike_sa->get_name(this->ike_sa),
1131 this->ike_sa->get_unique_id(this->ike_sa),
1132 this->ike_sa->get_my_host(this->ike_sa),
1133 this->ike_sa->get_my_id(this->ike_sa),
1134 this->ike_sa->get_other_host(this->ike_sa),
1135 this->ike_sa->get_other_id(this->ike_sa));
1136 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1137 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
1138 return SUCCESS;
ccbe3803
TB
1139
1140peer_auth_failed:
3f7f5388 1141 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
ccbe3803
TB
1142peer_auth_failed_no_notify:
1143 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
1144 return FAILED;
3f7f5388
MW
1145local_auth_failed:
1146 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
1147 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1148 return FAILED;
c60c7694
MW
1149}
1150
eaafcec1
MW
1151/**
1152 * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA
1153 */
1154static void send_auth_failed_informational(private_ike_auth_t *this,
1155 message_t *reply)
1156{
1157 message_t *message;
1158 packet_t *packet;
1159 host_t *host;
1160
1161 message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
1162 message->set_message_id(message, reply->get_message_id(reply) + 1);
1163 host = this->ike_sa->get_my_host(this->ike_sa);
1164 message->set_source(message, host->clone(host));
1165 host = this->ike_sa->get_other_host(this->ike_sa);
1166 message->set_destination(message, host->clone(host));
1167 message->set_exchange_type(message, INFORMATIONAL);
1168 message->add_notify(message, FALSE, AUTHENTICATION_FAILED, chunk_empty);
1169
1170 if (this->ike_sa->generate_message(this->ike_sa, message,
1171 &packet) == SUCCESS)
1172 {
1173 charon->sender->send(charon->sender, packet);
1174 }
1175 message->destroy(message);
1176}
1177
0020b25a 1178/**
b3ab7a48 1179 * Check if strict constraint fulfillment required to continue current auth
0020b25a
MW
1180 */
1181static bool require_strict(private_ike_auth_t *this, bool mutual_eap)
1182{
1183 auth_cfg_t *cfg;
1184
1185 if (this->eap_acceptable)
1186 {
1187 return FALSE;
1188 }
1189
1190 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
1191 switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS))
1192 {
1193 case AUTH_CLASS_EAP:
1194 if (mutual_eap && this->my_auth)
1195 {
1196 this->eap_acceptable = TRUE;
1197 return !this->my_auth->is_mutual(this->my_auth);
1198 }
1199 return TRUE;
1200 case AUTH_CLASS_PSK:
1201 return TRUE;
1202 case AUTH_CLASS_PUBKEY:
1203 case AUTH_CLASS_ANY:
1204 default:
1205 return FALSE;
1206 }
1207}
1208
2b7686b5
MW
1209METHOD(task_t, process_i, status_t,
1210 private_ike_auth_t *this, message_t *message)
c60c7694 1211{
a44bb934 1212 enumerator_t *enumerator;
c60c7694 1213 payload_t *payload;
a44bb934 1214 auth_cfg_t *cfg;
a9e60c96 1215 bool mutual_eap = FALSE, ppk_id_received = FALSE;
7daf5226 1216
c60c7694
MW
1217 if (message->get_exchange_type(message) == IKE_SA_INIT)
1218 {
a44bb934
MW
1219 if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) &&
1220 multiple_auth_enabled())
1221 {
1222 this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
1223 }
c60c7694
MW
1224 return collect_other_init_data(this, message);
1225 }
7daf5226 1226
a44bb934
MW
1227 enumerator = message->create_payload_enumerator(message);
1228 while (enumerator->enumerate(enumerator, &payload))
c60c7694 1229 {
3ecfc83c 1230 if (payload->get_type(payload) == PLV2_NOTIFY)
c60c7694
MW
1231 {
1232 notify_payload_t *notify = (notify_payload_t*)payload;
1233 notify_type_t type = notify->get_notify_type(notify);
7daf5226 1234
c60c7694
MW
1235 switch (type)
1236 {
1237 case NO_PROPOSAL_CHOSEN:
1238 case SINGLE_PAIR_REQUIRED:
1239 case NO_ADDITIONAL_SAS:
1240 case INTERNAL_ADDRESS_FAILURE:
1241 case FAILED_CP_REQUIRED:
1242 case TS_UNACCEPTABLE:
1243 case INVALID_SELECTORS:
1244 /* these are errors, but are not critical as only the
1245 * CHILD_SA won't get build, but IKE_SA establishes anyway */
17d92e97
MW
1246 break;
1247 case MOBIKE_SUPPORTED:
1248 case ADDITIONAL_IP4_ADDRESS:
1249 case ADDITIONAL_IP6_ADDRESS:
1250 /* handled in ike_mobike task */
1251 break;
ee614711 1252 case AUTH_LIFETIME:
7805ad30 1253 /* handled in ike_auth_lifetime task */
ee614711 1254 break;
dc04b7c7
TB
1255 case ME_ENDPOINT:
1256 /* handled in ike_me task */
3af51375 1257 break;
f5a9025c
TB
1258 case REDIRECT:
1259 DESTROY_IF(this->redirect_to);
1260 this->redirect_to = redirect_data_parse(
1261 notify->get_notification_data(notify), NULL);
1262 if (!this->redirect_to)
1263 {
1264 DBG1(DBG_IKE, "received invalid REDIRECT notify");
1265 }
1266 break;
d6ffa85f
TB
1267 case IKEV2_MESSAGE_ID_SYNC_SUPPORTED:
1268 this->ike_sa->enable_extension(this->ike_sa,
1269 EXT_IKE_MESSAGE_ID_SYNC);
1270 break;
a9e60c96
TB
1271 case PPK_IDENTITY:
1272 ppk_id_received = TRUE;
1273 break;
c60c7694
MW
1274 default:
1275 {
3c354b6d 1276 if (type <= 16383)
c60c7694 1277 {
a985db3f 1278 DBG1(DBG_IKE, "received %N notify error",
c60c7694 1279 notify_type_names, type);
a44bb934 1280 enumerator->destroy(enumerator);
965348cd 1281 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
7daf5226 1282 return FAILED;
c60c7694 1283 }
196b28a4 1284 DBG2(DBG_IKE, "received %N notify",
e5a7f1cd
MW
1285 notify_type_names, type);
1286 break;
c60c7694
MW
1287 }
1288 }
1289 }
1290 }
a44bb934 1291 enumerator->destroy(enumerator);
7daf5226 1292
a44bb934 1293 if (this->expect_another_auth)
49e8ac05 1294 {
94f9f421 1295 if (!this->other_auth)
a44bb934
MW
1296 {
1297 id_payload_t *id_payload;
1298 identification_t *id;
7daf5226 1299
a44bb934
MW
1300 /* handle IDr payload */
1301 id_payload = (id_payload_t*)message->get_payload(message,
3ecfc83c 1302 PLV2_ID_RESPONDER);
a44bb934
MW
1303 if (!id_payload)
1304 {
1305 DBG1(DBG_IKE, "IDr payload missing");
ccbe3803 1306 goto peer_auth_failed;
a44bb934
MW
1307 }
1308 id = id_payload->get_identification(id_payload);
5f15faeb 1309 get_reserved_id_bytes(this, id_payload);
a44bb934
MW
1310 this->ike_sa->set_other_id(this->ike_sa, id);
1311 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
1312 cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
7daf5226 1313
3ecfc83c 1314 if (message->get_payload(message, PLV2_AUTH))
a44bb934 1315 {
f34702ff
MW
1316 /* verify authentication data */
1317 this->other_auth = authenticator_create_verifier(this->ike_sa,
1318 message, this->other_nonce, this->my_nonce,
1319 this->other_packet->get_data(this->other_packet),
5f15faeb
MW
1320 this->my_packet->get_data(this->my_packet),
1321 this->reserved);
f34702ff
MW
1322 if (!this->other_auth)
1323 {
ccbe3803 1324 goto peer_auth_failed;
f34702ff
MW
1325 }
1326 }
1327 else
2aa553d7
MW
1328 {
1329 /* responder omitted AUTH payload, indicating EAP-only */
1330 mutual_eap = TRUE;
a44bb934
MW
1331 }
1332 }
f34702ff 1333 if (this->other_auth)
a44bb934 1334 {
a9e60c96
TB
1335 if (ppk_id_received && is_first_round(this, FALSE) &&
1336 this->other_auth->use_ppk)
1337 {
1338 this->other_auth->use_ppk(this->other_auth, this->ppk, FALSE);
1339 }
f34702ff
MW
1340 switch (this->other_auth->process(this->other_auth, message))
1341 {
1342 case SUCCESS:
1343 break;
1344 case NEED_MORE:
1345 return NEED_MORE;
1346 default:
ccbe3803 1347 goto peer_auth_failed;
f34702ff
MW
1348 }
1349 this->other_auth->destroy(this->other_auth);
1350 this->other_auth = NULL;
a44bb934 1351 }
a44bb934 1352 /* another auth round done, invoke authorize hook */
44ce7493 1353 if (!charon->bus->authorize(charon->bus, FALSE))
a44bb934 1354 {
44ce7493 1355 DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling");
ccbe3803 1356 goto peer_auth_failed;
a44bb934 1357 }
b49d047b 1358
d8a94c18
MW
1359 if (!mutual_eap)
1360 {
1361 apply_auth_cfg(this, FALSE);
1362 }
49e8ac05 1363 }
7daf5226 1364
0020b25a
MW
1365 if (require_strict(this, mutual_eap))
1366 {
1367 if (!update_cfg_candidates(this, TRUE))
1368 {
1369 goto peer_auth_failed;
1370 }
1371 }
1372
2aa553d7
MW
1373 if (this->my_auth)
1374 {
a9e60c96
TB
1375 /* while we already set the PPK in build_i(), we MUST not use it if
1376 * the peer did not reply with a PPK_ID notify */
1377 if (this->ppk.ptr && this->my_auth->use_ppk)
1378 {
1379 this->my_auth->use_ppk(this->my_auth,
1380 ppk_id_received ? this->ppk : chunk_empty,
1381 FALSE);
1382 }
2aa553d7
MW
1383 switch (this->my_auth->process(this->my_auth, message))
1384 {
1385 case SUCCESS:
289b9b7b 1386 apply_auth_cfg(this, TRUE);
d8a94c18
MW
1387 if (this->my_auth->is_mutual(this->my_auth))
1388 {
1389 apply_auth_cfg(this, FALSE);
1390 }
2aa553d7
MW
1391 this->my_auth->destroy(this->my_auth);
1392 this->my_auth = NULL;
1393 this->do_another_auth = do_another_auth(this);
1394 break;
1395 case NEED_MORE:
1396 break;
1397 default:
a9e60c96
TB
1398 goto local_auth_failed;
1399 }
1400 }
1401
1402 /* change keys and clear PPK after we are done with our authentication, so
1403 * we only explicitly use it for the first round, afterwards we just use the
1404 * changed SK_p keys implicitly */
1405 if (!this->my_auth && this->ppk_id)
1406 {
1407 if (ppk_id_received)
1408 {
1409 if (!apply_ppk(this))
1410 {
1411 goto local_auth_failed;
1412 }
1413 }
1414 else
1415 {
1416 DBG1(DBG_CFG, "peer didn't use PPK for PPK_ID '%Y'", this->ppk_id);
2aa553d7 1417 }
a9e60c96 1418 clear_ppk(this);
2aa553d7 1419 }
a9e60c96 1420
2aa553d7
MW
1421 if (mutual_eap)
1422 {
1423 if (!this->my_auth || !this->my_auth->is_mutual(this->my_auth))
1424 {
1425 DBG1(DBG_IKE, "do not allow non-mutual EAP-only authentication");
ccbe3803 1426 goto peer_auth_failed;
2aa553d7
MW
1427 }
1428 DBG1(DBG_IKE, "allow mutual EAP-only authentication");
1429 }
1430
94f9f421 1431 if (!message->get_notify(message, ANOTHER_AUTH_FOLLOWS))
552cc11b 1432 {
a44bb934 1433 this->expect_another_auth = FALSE;
552cc11b 1434 }
f5a9025c 1435 if (this->expect_another_auth || this->do_another_auth || this->my_auth)
a44bb934 1436 {
f5a9025c 1437 return NEED_MORE;
a44bb934 1438 }
f5a9025c
TB
1439 if (!update_cfg_candidates(this, TRUE))
1440 {
1441 goto peer_auth_failed;
1442 }
1443 if (!charon->bus->authorize(charon->bus, TRUE))
1444 {
1445 DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, "
1446 "cancelling");
1447 goto peer_auth_failed;
1448 }
1449 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1450 this->ike_sa->get_name(this->ike_sa),
1451 this->ike_sa->get_unique_id(this->ike_sa),
1452 this->ike_sa->get_my_host(this->ike_sa),
1453 this->ike_sa->get_my_id(this->ike_sa),
1454 this->ike_sa->get_other_host(this->ike_sa),
1455 this->ike_sa->get_other_id(this->ike_sa));
1456 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1457 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
1458
1459 if (this->redirect_to)
1460 {
1461 this->ike_sa->handle_redirect(this->ike_sa, this->redirect_to);
1462 }
1463 return SUCCESS;
ff4b25f9 1464
ccbe3803
TB
1465peer_auth_failed:
1466 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
eaafcec1 1467 send_auth_failed_informational(this, message);
ff4b25f9 1468 return FAILED;
a9e60c96
TB
1469local_auth_failed:
1470 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1471 send_auth_failed_informational(this, message);
1472 return FAILED;
c60c7694
MW
1473}
1474
2b7686b5
MW
1475METHOD(task_t, get_type, task_type_t,
1476 private_ike_auth_t *this)
c60c7694 1477{
a09972df 1478 return TASK_IKE_AUTH;
c60c7694
MW
1479}
1480
2b7686b5
MW
1481METHOD(task_t, migrate, void,
1482 private_ike_auth_t *this, ike_sa_t *ike_sa)
c60c7694 1483{
a9e60c96 1484 clear_ppk(this);
c60c7694
MW
1485 chunk_free(&this->my_nonce);
1486 chunk_free(&this->other_nonce);
1487 DESTROY_IF(this->my_packet);
1488 DESTROY_IF(this->other_packet);
a44bb934
MW
1489 DESTROY_IF(this->peer_cfg);
1490 DESTROY_IF(this->my_auth);
1491 DESTROY_IF(this->other_auth);
f5a9025c 1492 DESTROY_IF(this->redirect_to);
a44bb934 1493 this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
7daf5226 1494
c60c7694
MW
1495 this->my_packet = NULL;
1496 this->other_packet = NULL;
c60c7694 1497 this->ike_sa = ike_sa;
a44bb934
MW
1498 this->peer_cfg = NULL;
1499 this->my_auth = NULL;
1500 this->other_auth = NULL;
f5a9025c 1501 this->redirect_to = NULL;
a44bb934
MW
1502 this->do_another_auth = TRUE;
1503 this->expect_another_auth = TRUE;
1504 this->authentication_failed = FALSE;
a44bb934 1505 this->candidates = linked_list_create();
c60c7694
MW
1506}
1507
2b7686b5
MW
1508METHOD(task_t, destroy, void,
1509 private_ike_auth_t *this)
c60c7694 1510{
a9e60c96 1511 clear_ppk(this);
c60c7694
MW
1512 chunk_free(&this->my_nonce);
1513 chunk_free(&this->other_nonce);
1514 DESTROY_IF(this->my_packet);
1515 DESTROY_IF(this->other_packet);
a44bb934
MW
1516 DESTROY_IF(this->my_auth);
1517 DESTROY_IF(this->other_auth);
1518 DESTROY_IF(this->peer_cfg);
f5a9025c 1519 DESTROY_IF(this->redirect_to);
a44bb934 1520 this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
c60c7694
MW
1521 free(this);
1522}
1523
1524/*
1525 * Described in header.
1526 */
1527ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
1528{
2b7686b5
MW
1529 private_ike_auth_t *this;
1530
1531 INIT(this,
1532 .public = {
1533 .task = {
1534 .get_type = _get_type,
1535 .migrate = _migrate,
1536 .build = _build_r,
1537 .process = _process_r,
1538 .destroy = _destroy,
1539 },
1540 },
1541 .ike_sa = ike_sa,
1542 .initiator = initiator,
1543 .candidates = linked_list_create(),
1544 .do_another_auth = TRUE,
1545 .expect_another_auth = TRUE,
1546 );
c60c7694
MW
1547 if (initiator)
1548 {
2b7686b5
MW
1549 this->public.task.build = _build_i;
1550 this->public.task.process = _process_i;
c60c7694 1551 }
c60c7694
MW
1552 return &this->public;
1553}