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