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