ike-auth: Handle REDIRECT notifies during IKE_AUTH
[strongswan.git] / src / libcharon / sa / ikev2 / tasks / ike_auth.c
1 /*
2 * Copyright (C) 2012-2015 Tobias Brunner
3 * Copyright (C) 2005-2009 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
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/authenticators/eap_authenticator.h>
28 #include <processing/jobs/delete_ike_sa_job.h>
29
30 typedef struct private_ike_auth_t private_ike_auth_t;
31
32 /**
33 * Private members of a ike_auth_t task.
34 */
35 struct private_ike_auth_t {
36
37 /**
38 * Public methods and task_t interface.
39 */
40 ike_auth_t public;
41
42 /**
43 * Assigned IKE_SA.
44 */
45 ike_sa_t *ike_sa;
46
47 /**
48 * Are we the initiator?
49 */
50 bool initiator;
51
52 /**
53 * Nonce chosen by us in ike_init
54 */
55 chunk_t my_nonce;
56
57 /**
58 * Nonce chosen by peer in ike_init
59 */
60 chunk_t other_nonce;
61
62 /**
63 * IKE_SA_INIT message sent by us
64 */
65 packet_t *my_packet;
66
67 /**
68 * IKE_SA_INIT message sent by peer
69 */
70 packet_t *other_packet;
71
72 /**
73 * Reserved bytes of ID payload
74 */
75 char reserved[3];
76
77 /**
78 * currently active authenticator, to authenticate us
79 */
80 authenticator_t *my_auth;
81
82 /**
83 * currently active authenticator, to authenticate peer
84 */
85 authenticator_t *other_auth;
86
87 /**
88 * peer_cfg candidates, ordered by priority
89 */
90 linked_list_t *candidates;
91
92 /**
93 * selected peer config (might change when using multiple authentications)
94 */
95 peer_cfg_t *peer_cfg;
96
97 /**
98 * have we planned an(other) authentication exchange?
99 */
100 bool do_another_auth;
101
102 /**
103 * has the peer announced another authentication exchange?
104 */
105 bool expect_another_auth;
106
107 /**
108 * should we send a AUTHENTICATION_FAILED notify?
109 */
110 bool authentication_failed;
111
112 /**
113 * received an INITIAL_CONTACT?
114 */
115 bool initial_contact;
116
117 /**
118 * Is EAP acceptable, did we strictly authenticate peer?
119 */
120 bool eap_acceptable;
121
122 /**
123 * Gateway ID if redirected
124 */
125 identification_t *redirect_to;
126 };
127
128 /**
129 * check if multiple authentication extension is enabled, configuration-wise
130 */
131 static bool multiple_auth_enabled()
132 {
133 return lib->settings->get_bool(lib->settings,
134 "%s.multiple_authentication", TRUE, lib->ns);
135 }
136
137 /**
138 * collect the needed information in the IKE_SA_INIT exchange from our message
139 */
140 static status_t collect_my_init_data(private_ike_auth_t *this,
141 message_t *message)
142 {
143 nonce_payload_t *nonce;
144
145 /* get the nonce that was generated in ike_init */
146 nonce = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
147 if (nonce == NULL)
148 {
149 return FAILED;
150 }
151 this->my_nonce = nonce->get_nonce(nonce);
152
153 /* pre-generate the message, keep a copy */
154 if (this->ike_sa->generate_message(this->ike_sa, message,
155 &this->my_packet) != SUCCESS)
156 {
157 return FAILED;
158 }
159 return NEED_MORE;
160 }
161
162 /**
163 * collect the needed information in the IKE_SA_INIT exchange from others message
164 */
165 static status_t collect_other_init_data(private_ike_auth_t *this,
166 message_t *message)
167 {
168 /* we collect the needed information in the IKE_SA_INIT exchange */
169 nonce_payload_t *nonce;
170
171 /* get the nonce that was generated in ike_init */
172 nonce = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
173 if (nonce == NULL)
174 {
175 return FAILED;
176 }
177 this->other_nonce = nonce->get_nonce(nonce);
178
179 /* keep a copy of the received packet */
180 this->other_packet = message->get_packet(message);
181 return NEED_MORE;
182 }
183
184 /**
185 * Get and store reserved bytes of id_payload, required for AUTH payload
186 */
187 static void get_reserved_id_bytes(private_ike_auth_t *this, id_payload_t *id)
188 {
189 u_int8_t *byte;
190 int i;
191
192 for (i = 0; i < countof(this->reserved); i++)
193 {
194 byte = payload_get_field(&id->payload_interface, RESERVED_BYTE, i);
195 if (byte)
196 {
197 this->reserved[i] = *byte;
198 }
199 }
200 }
201
202 /**
203 * Get the next authentication configuration
204 */
205 static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local)
206 {
207 enumerator_t *e1, *e2;
208 auth_cfg_t *c1, *c2, *next = NULL;
209
210 /* find an available config not already done */
211 e1 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, local);
212 while (e1->enumerate(e1, &c1))
213 {
214 bool found = FALSE;
215
216 e2 = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, local);
217 while (e2->enumerate(e2, &c2))
218 {
219 if (c2->complies(c2, c1, FALSE))
220 {
221 found = TRUE;
222 break;
223 }
224 }
225 e2->destroy(e2);
226 if (!found)
227 {
228 next = c1;
229 break;
230 }
231 }
232 e1->destroy(e1);
233 return next;
234 }
235
236 /**
237 * Move the currently active auth config to the auth configs completed
238 */
239 static void apply_auth_cfg(private_ike_auth_t *this, bool local)
240 {
241 auth_cfg_t *cfg;
242
243 cfg = auth_cfg_create();
244 cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, local), local);
245 this->ike_sa->add_auth_cfg(this->ike_sa, local, cfg);
246 }
247
248 /**
249 * Check if we have should initiate another authentication round
250 */
251 static bool do_another_auth(private_ike_auth_t *this)
252 {
253 bool do_another = FALSE;
254 enumerator_t *done, *todo;
255 auth_cfg_t *done_cfg, *todo_cfg;
256
257 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
258 {
259 return FALSE;
260 }
261
262 done = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, TRUE);
263 todo = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, TRUE);
264 while (todo->enumerate(todo, &todo_cfg))
265 {
266 if (!done->enumerate(done, &done_cfg))
267 {
268 done_cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
269 }
270 if (!done_cfg->complies(done_cfg, todo_cfg, FALSE))
271 {
272 do_another = TRUE;
273 break;
274 }
275 }
276 done->destroy(done);
277 todo->destroy(todo);
278 return do_another;
279 }
280
281 /**
282 * Get peer configuration candidates from backends
283 */
284 static bool load_cfg_candidates(private_ike_auth_t *this)
285 {
286 enumerator_t *enumerator;
287 peer_cfg_t *peer_cfg;
288 host_t *me, *other;
289 identification_t *my_id, *other_id;
290
291 me = this->ike_sa->get_my_host(this->ike_sa);
292 other = this->ike_sa->get_other_host(this->ike_sa);
293 my_id = this->ike_sa->get_my_id(this->ike_sa);
294 other_id = this->ike_sa->get_other_id(this->ike_sa);
295
296 DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]",
297 me, my_id, other, other_id);
298 enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
299 me, other, my_id, other_id, IKEV2);
300 while (enumerator->enumerate(enumerator, &peer_cfg))
301 {
302 peer_cfg->get_ref(peer_cfg);
303 if (this->peer_cfg == NULL)
304 { /* best match */
305 this->peer_cfg = peer_cfg;
306 this->ike_sa->set_peer_cfg(this->ike_sa, peer_cfg);
307 }
308 else
309 {
310 this->candidates->insert_last(this->candidates, peer_cfg);
311 }
312 }
313 enumerator->destroy(enumerator);
314 if (this->peer_cfg)
315 {
316 DBG1(DBG_CFG, "selected peer config '%s'",
317 this->peer_cfg->get_name(this->peer_cfg));
318 return TRUE;
319 }
320 DBG1(DBG_CFG, "no matching peer config found");
321 return FALSE;
322 }
323
324 /**
325 * update the current peer candidate if necessary, using candidates
326 */
327 static bool update_cfg_candidates(private_ike_auth_t *this, bool strict)
328 {
329 do
330 {
331 if (this->peer_cfg)
332 {
333 char *comply_error = NULL;
334 enumerator_t *e1, *e2, *tmp;
335 auth_cfg_t *c1, *c2;
336
337 e1 = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, FALSE);
338 e2 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, FALSE);
339
340 if (strict)
341 { /* swap lists in strict mode: all configured rounds must be
342 * fulfilled. If !strict, we check only the rounds done so far. */
343 tmp = e1;
344 e1 = e2;
345 e2 = tmp;
346 }
347 while (e1->enumerate(e1, &c1))
348 {
349 /* check if done authentications comply to configured ones */
350 if (!e2->enumerate(e2, &c2))
351 {
352 comply_error = "insufficient authentication rounds";
353 break;
354 }
355 if (!strict && !c1->complies(c1, c2, TRUE))
356 {
357 comply_error = "non-matching authentication done";
358 break;
359 }
360 if (strict && !c2->complies(c2, c1, TRUE))
361 {
362 comply_error = "constraint checking failed";
363 break;
364 }
365 }
366 e1->destroy(e1);
367 e2->destroy(e2);
368 if (!comply_error)
369 {
370 break;
371 }
372 DBG1(DBG_CFG, "selected peer config '%s' inacceptable: %s",
373 this->peer_cfg->get_name(this->peer_cfg), comply_error);
374 this->peer_cfg->destroy(this->peer_cfg);
375 }
376 if (this->candidates->remove_first(this->candidates,
377 (void**)&this->peer_cfg) != SUCCESS)
378 {
379 DBG1(DBG_CFG, "no alternative config found");
380 this->peer_cfg = NULL;
381 }
382 else
383 {
384 DBG1(DBG_CFG, "switching to peer config '%s'",
385 this->peer_cfg->get_name(this->peer_cfg));
386 this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
387 }
388 }
389 while (this->peer_cfg);
390
391 return this->peer_cfg != NULL;
392 }
393
394 METHOD(task_t, build_i, status_t,
395 private_ike_auth_t *this, message_t *message)
396 {
397 auth_cfg_t *cfg;
398
399 if (message->get_exchange_type(message) == IKE_SA_INIT)
400 {
401 return collect_my_init_data(this, message);
402 }
403
404 if (this->peer_cfg == NULL)
405 {
406 this->peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
407 this->peer_cfg->get_ref(this->peer_cfg);
408 }
409
410 if (message->get_message_id(message) == 1)
411 { /* in the first IKE_AUTH ... */
412 if (this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
413 { /* indicate support for multiple authentication */
414 message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
415 chunk_empty);
416 }
417 /* indicate support for EAP-only authentication */
418 message->add_notify(message, FALSE, EAP_ONLY_AUTHENTICATION,
419 chunk_empty);
420 }
421
422 if (!this->do_another_auth && !this->my_auth)
423 { /* we have done our rounds */
424 return NEED_MORE;
425 }
426
427 /* check if an authenticator is in progress */
428 if (this->my_auth == NULL)
429 {
430 identification_t *idi, *idr = NULL;
431 id_payload_t *id_payload;
432
433 /* clean up authentication config from a previous round */
434 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
435 cfg->purge(cfg, TRUE);
436
437 /* add (optional) IDr */
438 cfg = get_auth_cfg(this, FALSE);
439 if (cfg)
440 {
441 idr = cfg->get(cfg, AUTH_RULE_IDENTITY);
442 if (!cfg->get(cfg, AUTH_RULE_IDENTITY_LOOSE) && idr &&
443 !idr->contains_wildcards(idr))
444 {
445 this->ike_sa->set_other_id(this->ike_sa, idr->clone(idr));
446 id_payload = id_payload_create_from_identification(
447 PLV2_ID_RESPONDER, idr);
448 message->add_payload(message, (payload_t*)id_payload);
449 }
450 }
451 /* add IDi */
452 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
453 cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
454 idi = cfg->get(cfg, AUTH_RULE_IDENTITY);
455 if (!idi || idi->get_type(idi) == ID_ANY)
456 { /* ID_ANY is invalid as IDi, use local IP address instead */
457 host_t *me;
458
459 DBG1(DBG_CFG, "no IDi configured, fall back on IP address");
460 me = this->ike_sa->get_my_host(this->ike_sa);
461 idi = identification_create_from_sockaddr(me->get_sockaddr(me));
462 cfg->add(cfg, AUTH_RULE_IDENTITY, idi);
463 }
464 this->ike_sa->set_my_id(this->ike_sa, idi->clone(idi));
465 id_payload = id_payload_create_from_identification(PLV2_ID_INITIATOR, idi);
466 get_reserved_id_bytes(this, id_payload);
467 message->add_payload(message, (payload_t*)id_payload);
468
469 if (idr && message->get_message_id(message) == 1 &&
470 this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NO &&
471 this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NEVER)
472 {
473 host_t *host;
474
475 host = this->ike_sa->get_other_host(this->ike_sa);
476 if (!charon->ike_sa_manager->has_contact(charon->ike_sa_manager,
477 idi, idr, host->get_family(host)))
478 {
479 message->add_notify(message, FALSE, INITIAL_CONTACT, chunk_empty);
480 }
481 }
482
483 /* build authentication data */
484 this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
485 this->other_nonce, this->my_nonce,
486 this->other_packet->get_data(this->other_packet),
487 this->my_packet->get_data(this->my_packet),
488 this->reserved);
489 if (!this->my_auth)
490 {
491 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
492 return FAILED;
493 }
494 }
495 switch (this->my_auth->build(this->my_auth, message))
496 {
497 case SUCCESS:
498 apply_auth_cfg(this, TRUE);
499 this->my_auth->destroy(this->my_auth);
500 this->my_auth = NULL;
501 break;
502 case NEED_MORE:
503 break;
504 default:
505 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
506 return FAILED;
507 }
508
509 /* check for additional authentication rounds */
510 if (do_another_auth(this))
511 {
512 if (message->get_payload(message, PLV2_AUTH))
513 {
514 message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
515 }
516 }
517 else
518 {
519 this->do_another_auth = FALSE;
520 }
521 return NEED_MORE;
522 }
523
524 METHOD(task_t, process_r, status_t,
525 private_ike_auth_t *this, message_t *message)
526 {
527 auth_cfg_t *cfg, *cand;
528 id_payload_t *id_payload;
529 identification_t *id;
530
531 if (message->get_exchange_type(message) == IKE_SA_INIT)
532 {
533 return collect_other_init_data(this, message);
534 }
535
536 if (this->my_auth == NULL && this->do_another_auth)
537 {
538 /* handle (optional) IDr payload, apply proposed identity */
539 id_payload = (id_payload_t*)message->get_payload(message, PLV2_ID_RESPONDER);
540 if (id_payload)
541 {
542 id = id_payload->get_identification(id_payload);
543 }
544 else
545 {
546 id = identification_create_from_encoding(ID_ANY, chunk_empty);
547 }
548 this->ike_sa->set_my_id(this->ike_sa, id);
549 }
550
551 if (!this->expect_another_auth)
552 {
553 return NEED_MORE;
554 }
555
556 if (message->get_message_id(message) == 1)
557 { /* check for extensions in the first IKE_AUTH */
558 if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED))
559 {
560 this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
561 }
562 if (message->get_notify(message, EAP_ONLY_AUTHENTICATION))
563 {
564 this->ike_sa->enable_extension(this->ike_sa,
565 EXT_EAP_ONLY_AUTHENTICATION);
566 }
567 }
568
569 if (this->other_auth == NULL)
570 {
571 /* handle IDi payload */
572 id_payload = (id_payload_t*)message->get_payload(message, PLV2_ID_INITIATOR);
573 if (!id_payload)
574 {
575 DBG1(DBG_IKE, "IDi payload missing");
576 return FAILED;
577 }
578 id = id_payload->get_identification(id_payload);
579 get_reserved_id_bytes(this, id_payload);
580 this->ike_sa->set_other_id(this->ike_sa, id);
581 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
582 cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
583
584 if (this->peer_cfg == NULL)
585 {
586 if (!load_cfg_candidates(this))
587 {
588 this->authentication_failed = TRUE;
589 return NEED_MORE;
590 }
591 }
592 if (message->get_payload(message, PLV2_AUTH) == NULL)
593 { /* before authenticating with EAP, we need a EAP config */
594 cand = get_auth_cfg(this, FALSE);
595 while (!cand || (
596 (uintptr_t)cand->get(cand, AUTH_RULE_EAP_TYPE) == EAP_NAK &&
597 (uintptr_t)cand->get(cand, AUTH_RULE_EAP_VENDOR) == 0))
598 { /* peer requested EAP, but current config does not match */
599 DBG1(DBG_IKE, "peer requested EAP, config inacceptable");
600 this->peer_cfg->destroy(this->peer_cfg);
601 this->peer_cfg = NULL;
602 if (!update_cfg_candidates(this, FALSE))
603 {
604 this->authentication_failed = TRUE;
605 return NEED_MORE;
606 }
607 cand = get_auth_cfg(this, FALSE);
608 }
609 /* copy over the EAP specific rules for authentication */
610 cfg->add(cfg, AUTH_RULE_EAP_TYPE,
611 cand->get(cand, AUTH_RULE_EAP_TYPE));
612 cfg->add(cfg, AUTH_RULE_EAP_VENDOR,
613 cand->get(cand, AUTH_RULE_EAP_VENDOR));
614 id = (identification_t*)cand->get(cand, AUTH_RULE_EAP_IDENTITY);
615 if (id)
616 {
617 cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id));
618 }
619 id = (identification_t*)cand->get(cand, AUTH_RULE_AAA_IDENTITY);
620 if (id)
621 {
622 cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, id->clone(id));
623 }
624 }
625
626 /* verify authentication data */
627 this->other_auth = authenticator_create_verifier(this->ike_sa,
628 message, this->other_nonce, this->my_nonce,
629 this->other_packet->get_data(this->other_packet),
630 this->my_packet->get_data(this->my_packet),
631 this->reserved);
632 if (!this->other_auth)
633 {
634 this->authentication_failed = TRUE;
635 return NEED_MORE;
636 }
637 }
638 switch (this->other_auth->process(this->other_auth, message))
639 {
640 case SUCCESS:
641 this->other_auth->destroy(this->other_auth);
642 this->other_auth = NULL;
643 break;
644 case NEED_MORE:
645 if (message->get_payload(message, PLV2_AUTH))
646 { /* AUTH verification successful, but another build() needed */
647 break;
648 }
649 return NEED_MORE;
650 default:
651 this->authentication_failed = TRUE;
652 return NEED_MORE;
653 }
654
655 /* If authenticated (with non-EAP) and received INITIAL_CONTACT,
656 * delete any existing IKE_SAs with that peer. */
657 if (message->get_message_id(message) == 1 &&
658 message->get_notify(message, INITIAL_CONTACT))
659 {
660 this->initial_contact = TRUE;
661 }
662
663 /* another auth round done, invoke authorize hook */
664 if (!charon->bus->authorize(charon->bus, FALSE))
665 {
666 DBG1(DBG_IKE, "authorization hook forbids IKE_SA, cancelling");
667 this->authentication_failed = TRUE;
668 return NEED_MORE;
669 }
670
671 apply_auth_cfg(this, FALSE);
672
673 if (!update_cfg_candidates(this, FALSE))
674 {
675 this->authentication_failed = TRUE;
676 return NEED_MORE;
677 }
678
679 if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS) == NULL)
680 {
681 this->expect_another_auth = FALSE;
682 if (!update_cfg_candidates(this, TRUE))
683 {
684 this->authentication_failed = TRUE;
685 return NEED_MORE;
686 }
687 }
688 return NEED_MORE;
689 }
690
691 METHOD(task_t, build_r, status_t,
692 private_ike_auth_t *this, message_t *message)
693 {
694 identification_t *gateway;
695 auth_cfg_t *cfg;
696
697 if (message->get_exchange_type(message) == IKE_SA_INIT)
698 {
699 if (multiple_auth_enabled())
700 {
701 message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
702 chunk_empty);
703 }
704 return collect_my_init_data(this, message);
705 }
706
707 if (this->authentication_failed || this->peer_cfg == NULL)
708 {
709 goto peer_auth_failed;
710 }
711
712 if (this->my_auth == NULL && this->do_another_auth)
713 {
714 identification_t *id, *id_cfg;
715 id_payload_t *id_payload;
716
717 /* add IDr */
718 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
719 cfg->purge(cfg, TRUE);
720 cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
721
722 id_cfg = cfg->get(cfg, AUTH_RULE_IDENTITY);
723 id = this->ike_sa->get_my_id(this->ike_sa);
724 if (id->get_type(id) == ID_ANY)
725 { /* no IDr received, apply configured ID */
726 if (!id_cfg || id_cfg->contains_wildcards(id_cfg))
727 { /* no ID configured, use local IP address */
728 host_t *me;
729
730 DBG1(DBG_CFG, "no IDr configured, fall back on IP address");
731 me = this->ike_sa->get_my_host(this->ike_sa);
732 id_cfg = identification_create_from_sockaddr(
733 me->get_sockaddr(me));
734 cfg->add(cfg, AUTH_RULE_IDENTITY, id_cfg);
735 }
736 this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg));
737 id = id_cfg;
738 }
739 else
740 { /* IDr received, check if it matches configuration */
741 if (id_cfg && !id->matches(id, id_cfg))
742 {
743 DBG1(DBG_CFG, "received IDr %Y, but require %Y", id, id_cfg);
744 goto peer_auth_failed;
745 }
746 }
747
748 id_payload = id_payload_create_from_identification(PLV2_ID_RESPONDER, id);
749 get_reserved_id_bytes(this, id_payload);
750 message->add_payload(message, (payload_t*)id_payload);
751
752 if (this->initial_contact)
753 {
754 charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
755 this->ike_sa, TRUE);
756 this->initial_contact = FALSE;
757 }
758
759 if ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS) == AUTH_CLASS_EAP)
760 { /* EAP-only authentication */
761 if (!this->ike_sa->supports_extension(this->ike_sa,
762 EXT_EAP_ONLY_AUTHENTICATION))
763 {
764 DBG1(DBG_IKE, "configured EAP-only authentication, but peer "
765 "does not support it");
766 goto peer_auth_failed;
767 }
768 }
769 else
770 {
771 /* build authentication data */
772 this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
773 this->other_nonce, this->my_nonce,
774 this->other_packet->get_data(this->other_packet),
775 this->my_packet->get_data(this->my_packet),
776 this->reserved);
777 if (!this->my_auth)
778 {
779 goto local_auth_failed;
780 }
781 }
782 }
783
784 if (this->other_auth)
785 {
786 switch (this->other_auth->build(this->other_auth, message))
787 {
788 case SUCCESS:
789 this->other_auth->destroy(this->other_auth);
790 this->other_auth = NULL;
791 break;
792 case NEED_MORE:
793 break;
794 default:
795 if (message->get_payload(message, PLV2_EAP))
796 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
797 goto peer_auth_failed_no_notify;
798 }
799 goto peer_auth_failed;
800 }
801 }
802 if (this->my_auth)
803 {
804 switch (this->my_auth->build(this->my_auth, message))
805 {
806 case SUCCESS:
807 apply_auth_cfg(this, TRUE);
808 this->my_auth->destroy(this->my_auth);
809 this->my_auth = NULL;
810 break;
811 case NEED_MORE:
812 break;
813 default:
814 goto local_auth_failed;
815 }
816 }
817
818 /* check for additional authentication rounds */
819 if (do_another_auth(this))
820 {
821 message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
822 }
823 else
824 {
825 this->do_another_auth = FALSE;
826 }
827 if (this->do_another_auth || this->expect_another_auth)
828 {
829 return NEED_MORE;
830 }
831
832 if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
833 this->ike_sa, FALSE))
834 {
835 DBG1(DBG_IKE, "cancelling IKE_SA setup due to uniqueness policy");
836 charon->bus->alert(charon->bus, ALERT_UNIQUE_KEEP);
837 message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
838 chunk_empty);
839 return FAILED;
840 }
841 if (!charon->bus->authorize(charon->bus, TRUE))
842 {
843 DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
844 goto peer_auth_failed;
845 }
846 if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
847 charon->redirect->redirect_on_auth(charon->redirect, this->ike_sa,
848 &gateway))
849 {
850 delete_ike_sa_job_t *job;
851 chunk_t data;
852
853 DBG1(DBG_IKE, "redirecting peer to %Y", gateway);
854 data = redirect_data_create(gateway, chunk_empty);
855 message->add_notify(message, FALSE, REDIRECT, data);
856 gateway->destroy(gateway);
857 chunk_free(&data);
858 /* we use this condition to prevent the CHILD_SA from getting created */
859 this->ike_sa->set_condition(this->ike_sa, COND_REDIRECTED, TRUE);
860 /* if the peer does not delete the SA we do so after a while */
861 job = delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE);
862 lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
863 lib->settings->get_int(lib->settings,
864 "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
865 lib->ns));
866 }
867 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
868 this->ike_sa->get_name(this->ike_sa),
869 this->ike_sa->get_unique_id(this->ike_sa),
870 this->ike_sa->get_my_host(this->ike_sa),
871 this->ike_sa->get_my_id(this->ike_sa),
872 this->ike_sa->get_other_host(this->ike_sa),
873 this->ike_sa->get_other_id(this->ike_sa));
874 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
875 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
876 return SUCCESS;
877
878 peer_auth_failed:
879 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
880 peer_auth_failed_no_notify:
881 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
882 return FAILED;
883 local_auth_failed:
884 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
885 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
886 return FAILED;
887 }
888
889 /**
890 * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA
891 */
892 static void send_auth_failed_informational(private_ike_auth_t *this,
893 message_t *reply)
894 {
895 message_t *message;
896 packet_t *packet;
897 host_t *host;
898
899 message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
900 message->set_message_id(message, reply->get_message_id(reply) + 1);
901 host = this->ike_sa->get_my_host(this->ike_sa);
902 message->set_source(message, host->clone(host));
903 host = this->ike_sa->get_other_host(this->ike_sa);
904 message->set_destination(message, host->clone(host));
905 message->set_exchange_type(message, INFORMATIONAL);
906 message->add_notify(message, FALSE, AUTHENTICATION_FAILED, chunk_empty);
907
908 if (this->ike_sa->generate_message(this->ike_sa, message,
909 &packet) == SUCCESS)
910 {
911 charon->sender->send(charon->sender, packet);
912 }
913 message->destroy(message);
914 }
915
916 /**
917 * Check if strict constraint fullfillment required to continue current auth
918 */
919 static bool require_strict(private_ike_auth_t *this, bool mutual_eap)
920 {
921 auth_cfg_t *cfg;
922
923 if (this->eap_acceptable)
924 {
925 return FALSE;
926 }
927
928 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
929 switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS))
930 {
931 case AUTH_CLASS_EAP:
932 if (mutual_eap && this->my_auth)
933 {
934 this->eap_acceptable = TRUE;
935 return !this->my_auth->is_mutual(this->my_auth);
936 }
937 return TRUE;
938 case AUTH_CLASS_PSK:
939 return TRUE;
940 case AUTH_CLASS_PUBKEY:
941 case AUTH_CLASS_ANY:
942 default:
943 return FALSE;
944 }
945 }
946
947 METHOD(task_t, process_i, status_t,
948 private_ike_auth_t *this, message_t *message)
949 {
950 enumerator_t *enumerator;
951 payload_t *payload;
952 auth_cfg_t *cfg;
953 bool mutual_eap = FALSE;
954
955 if (message->get_exchange_type(message) == IKE_SA_INIT)
956 {
957 if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) &&
958 multiple_auth_enabled())
959 {
960 this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
961 }
962 return collect_other_init_data(this, message);
963 }
964
965 enumerator = message->create_payload_enumerator(message);
966 while (enumerator->enumerate(enumerator, &payload))
967 {
968 if (payload->get_type(payload) == PLV2_NOTIFY)
969 {
970 notify_payload_t *notify = (notify_payload_t*)payload;
971 notify_type_t type = notify->get_notify_type(notify);
972
973 switch (type)
974 {
975 case NO_PROPOSAL_CHOSEN:
976 case SINGLE_PAIR_REQUIRED:
977 case NO_ADDITIONAL_SAS:
978 case INTERNAL_ADDRESS_FAILURE:
979 case FAILED_CP_REQUIRED:
980 case TS_UNACCEPTABLE:
981 case INVALID_SELECTORS:
982 /* these are errors, but are not critical as only the
983 * CHILD_SA won't get build, but IKE_SA establishes anyway */
984 break;
985 case MOBIKE_SUPPORTED:
986 case ADDITIONAL_IP4_ADDRESS:
987 case ADDITIONAL_IP6_ADDRESS:
988 /* handled in ike_mobike task */
989 break;
990 case AUTH_LIFETIME:
991 /* handled in ike_auth_lifetime task */
992 break;
993 case ME_ENDPOINT:
994 /* handled in ike_me task */
995 break;
996 case REDIRECT:
997 DESTROY_IF(this->redirect_to);
998 this->redirect_to = redirect_data_parse(
999 notify->get_notification_data(notify), NULL);
1000 if (!this->redirect_to)
1001 {
1002 DBG1(DBG_IKE, "received invalid REDIRECT notify");
1003 }
1004 break;
1005 default:
1006 {
1007 if (type <= 16383)
1008 {
1009 DBG1(DBG_IKE, "received %N notify error",
1010 notify_type_names, type);
1011 enumerator->destroy(enumerator);
1012 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1013 return FAILED;
1014 }
1015 DBG2(DBG_IKE, "received %N notify",
1016 notify_type_names, type);
1017 break;
1018 }
1019 }
1020 }
1021 }
1022 enumerator->destroy(enumerator);
1023
1024 if (this->expect_another_auth)
1025 {
1026 if (this->other_auth == NULL)
1027 {
1028 id_payload_t *id_payload;
1029 identification_t *id;
1030
1031 /* handle IDr payload */
1032 id_payload = (id_payload_t*)message->get_payload(message,
1033 PLV2_ID_RESPONDER);
1034 if (!id_payload)
1035 {
1036 DBG1(DBG_IKE, "IDr payload missing");
1037 goto peer_auth_failed;
1038 }
1039 id = id_payload->get_identification(id_payload);
1040 get_reserved_id_bytes(this, id_payload);
1041 this->ike_sa->set_other_id(this->ike_sa, id);
1042 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
1043 cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
1044
1045 if (message->get_payload(message, PLV2_AUTH))
1046 {
1047 /* verify authentication data */
1048 this->other_auth = authenticator_create_verifier(this->ike_sa,
1049 message, this->other_nonce, this->my_nonce,
1050 this->other_packet->get_data(this->other_packet),
1051 this->my_packet->get_data(this->my_packet),
1052 this->reserved);
1053 if (!this->other_auth)
1054 {
1055 goto peer_auth_failed;
1056 }
1057 }
1058 else
1059 {
1060 /* responder omitted AUTH payload, indicating EAP-only */
1061 mutual_eap = TRUE;
1062 }
1063 }
1064 if (this->other_auth)
1065 {
1066 switch (this->other_auth->process(this->other_auth, message))
1067 {
1068 case SUCCESS:
1069 break;
1070 case NEED_MORE:
1071 return NEED_MORE;
1072 default:
1073 goto peer_auth_failed;
1074 }
1075 this->other_auth->destroy(this->other_auth);
1076 this->other_auth = NULL;
1077 }
1078 /* another auth round done, invoke authorize hook */
1079 if (!charon->bus->authorize(charon->bus, FALSE))
1080 {
1081 DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling");
1082 goto peer_auth_failed;
1083 }
1084
1085 if (!mutual_eap)
1086 {
1087 apply_auth_cfg(this, FALSE);
1088 }
1089 }
1090
1091 if (require_strict(this, mutual_eap))
1092 {
1093 if (!update_cfg_candidates(this, TRUE))
1094 {
1095 goto peer_auth_failed;
1096 }
1097 }
1098
1099 if (this->my_auth)
1100 {
1101 switch (this->my_auth->process(this->my_auth, message))
1102 {
1103 case SUCCESS:
1104 apply_auth_cfg(this, TRUE);
1105 if (this->my_auth->is_mutual(this->my_auth))
1106 {
1107 apply_auth_cfg(this, FALSE);
1108 }
1109 this->my_auth->destroy(this->my_auth);
1110 this->my_auth = NULL;
1111 this->do_another_auth = do_another_auth(this);
1112 break;
1113 case NEED_MORE:
1114 break;
1115 default:
1116 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1117 send_auth_failed_informational(this, message);
1118 return FAILED;
1119 }
1120 }
1121 if (mutual_eap)
1122 {
1123 if (!this->my_auth || !this->my_auth->is_mutual(this->my_auth))
1124 {
1125 DBG1(DBG_IKE, "do not allow non-mutual EAP-only authentication");
1126 goto peer_auth_failed;
1127 }
1128 DBG1(DBG_IKE, "allow mutual EAP-only authentication");
1129 }
1130
1131 if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS) == NULL)
1132 {
1133 this->expect_another_auth = FALSE;
1134 }
1135 if (this->expect_another_auth || this->do_another_auth || this->my_auth)
1136 {
1137 return NEED_MORE;
1138 }
1139 if (!update_cfg_candidates(this, TRUE))
1140 {
1141 goto peer_auth_failed;
1142 }
1143 if (!charon->bus->authorize(charon->bus, TRUE))
1144 {
1145 DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, "
1146 "cancelling");
1147 goto peer_auth_failed;
1148 }
1149 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1150 this->ike_sa->get_name(this->ike_sa),
1151 this->ike_sa->get_unique_id(this->ike_sa),
1152 this->ike_sa->get_my_host(this->ike_sa),
1153 this->ike_sa->get_my_id(this->ike_sa),
1154 this->ike_sa->get_other_host(this->ike_sa),
1155 this->ike_sa->get_other_id(this->ike_sa));
1156 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1157 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
1158
1159 if (this->redirect_to)
1160 {
1161 this->ike_sa->handle_redirect(this->ike_sa, this->redirect_to);
1162 }
1163 return SUCCESS;
1164
1165 peer_auth_failed:
1166 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
1167 send_auth_failed_informational(this, message);
1168 return FAILED;
1169 }
1170
1171 METHOD(task_t, get_type, task_type_t,
1172 private_ike_auth_t *this)
1173 {
1174 return TASK_IKE_AUTH;
1175 }
1176
1177 METHOD(task_t, migrate, void,
1178 private_ike_auth_t *this, ike_sa_t *ike_sa)
1179 {
1180 chunk_free(&this->my_nonce);
1181 chunk_free(&this->other_nonce);
1182 DESTROY_IF(this->my_packet);
1183 DESTROY_IF(this->other_packet);
1184 DESTROY_IF(this->peer_cfg);
1185 DESTROY_IF(this->my_auth);
1186 DESTROY_IF(this->other_auth);
1187 DESTROY_IF(this->redirect_to);
1188 this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
1189
1190 this->my_packet = NULL;
1191 this->other_packet = NULL;
1192 this->ike_sa = ike_sa;
1193 this->peer_cfg = NULL;
1194 this->my_auth = NULL;
1195 this->other_auth = NULL;
1196 this->redirect_to = NULL;
1197 this->do_another_auth = TRUE;
1198 this->expect_another_auth = TRUE;
1199 this->authentication_failed = FALSE;
1200 this->candidates = linked_list_create();
1201 }
1202
1203 METHOD(task_t, destroy, void,
1204 private_ike_auth_t *this)
1205 {
1206 chunk_free(&this->my_nonce);
1207 chunk_free(&this->other_nonce);
1208 DESTROY_IF(this->my_packet);
1209 DESTROY_IF(this->other_packet);
1210 DESTROY_IF(this->my_auth);
1211 DESTROY_IF(this->other_auth);
1212 DESTROY_IF(this->peer_cfg);
1213 DESTROY_IF(this->redirect_to);
1214 this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
1215 free(this);
1216 }
1217
1218 /*
1219 * Described in header.
1220 */
1221 ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
1222 {
1223 private_ike_auth_t *this;
1224
1225 INIT(this,
1226 .public = {
1227 .task = {
1228 .get_type = _get_type,
1229 .migrate = _migrate,
1230 .build = _build_r,
1231 .process = _process_r,
1232 .destroy = _destroy,
1233 },
1234 },
1235 .ike_sa = ike_sa,
1236 .initiator = initiator,
1237 .candidates = linked_list_create(),
1238 .do_another_auth = TRUE,
1239 .expect_another_auth = TRUE,
1240 );
1241 if (initiator)
1242 {
1243 this->public.task.build = _build_i;
1244 this->public.task.process = _process_i;
1245 }
1246 return &this->public;
1247 }