036910d0e961e14270cdbd6fef856fce59692b38
[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 uint8_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 if (message->get_notify(message, INITIAL_CONTACT))
568 {
569 this->initial_contact = TRUE;
570 }
571 }
572
573 if (this->other_auth == NULL)
574 {
575 /* handle IDi payload */
576 id_payload = (id_payload_t*)message->get_payload(message, PLV2_ID_INITIATOR);
577 if (!id_payload)
578 {
579 DBG1(DBG_IKE, "IDi payload missing");
580 return FAILED;
581 }
582 id = id_payload->get_identification(id_payload);
583 get_reserved_id_bytes(this, id_payload);
584 this->ike_sa->set_other_id(this->ike_sa, id);
585 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
586 cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
587
588 if (this->peer_cfg == NULL)
589 {
590 if (!load_cfg_candidates(this))
591 {
592 this->authentication_failed = TRUE;
593 return NEED_MORE;
594 }
595 }
596 if (message->get_payload(message, PLV2_AUTH) == NULL)
597 { /* before authenticating with EAP, we need a EAP config */
598 cand = get_auth_cfg(this, FALSE);
599 while (!cand || (
600 (uintptr_t)cand->get(cand, AUTH_RULE_EAP_TYPE) == EAP_NAK &&
601 (uintptr_t)cand->get(cand, AUTH_RULE_EAP_VENDOR) == 0))
602 { /* peer requested EAP, but current config does not match */
603 DBG1(DBG_IKE, "peer requested EAP, config inacceptable");
604 this->peer_cfg->destroy(this->peer_cfg);
605 this->peer_cfg = NULL;
606 if (!update_cfg_candidates(this, FALSE))
607 {
608 this->authentication_failed = TRUE;
609 return NEED_MORE;
610 }
611 cand = get_auth_cfg(this, FALSE);
612 }
613 /* copy over the EAP specific rules for authentication */
614 cfg->add(cfg, AUTH_RULE_EAP_TYPE,
615 cand->get(cand, AUTH_RULE_EAP_TYPE));
616 cfg->add(cfg, AUTH_RULE_EAP_VENDOR,
617 cand->get(cand, AUTH_RULE_EAP_VENDOR));
618 id = (identification_t*)cand->get(cand, AUTH_RULE_EAP_IDENTITY);
619 if (id)
620 {
621 cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id));
622 }
623 id = (identification_t*)cand->get(cand, AUTH_RULE_AAA_IDENTITY);
624 if (id)
625 {
626 cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, id->clone(id));
627 }
628 }
629
630 /* verify authentication data */
631 this->other_auth = authenticator_create_verifier(this->ike_sa,
632 message, this->other_nonce, this->my_nonce,
633 this->other_packet->get_data(this->other_packet),
634 this->my_packet->get_data(this->my_packet),
635 this->reserved);
636 if (!this->other_auth)
637 {
638 this->authentication_failed = TRUE;
639 return NEED_MORE;
640 }
641 }
642 switch (this->other_auth->process(this->other_auth, message))
643 {
644 case SUCCESS:
645 this->other_auth->destroy(this->other_auth);
646 this->other_auth = NULL;
647 break;
648 case NEED_MORE:
649 if (message->get_payload(message, PLV2_AUTH))
650 { /* AUTH verification successful, but another build() needed */
651 break;
652 }
653 return NEED_MORE;
654 default:
655 this->authentication_failed = TRUE;
656 return NEED_MORE;
657 }
658
659 /* another auth round done, invoke authorize hook */
660 if (!charon->bus->authorize(charon->bus, FALSE))
661 {
662 DBG1(DBG_IKE, "authorization hook forbids IKE_SA, cancelling");
663 this->authentication_failed = TRUE;
664 return NEED_MORE;
665 }
666
667 apply_auth_cfg(this, FALSE);
668
669 if (!update_cfg_candidates(this, FALSE))
670 {
671 this->authentication_failed = TRUE;
672 return NEED_MORE;
673 }
674
675 if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS) == NULL)
676 {
677 this->expect_another_auth = FALSE;
678 if (!update_cfg_candidates(this, TRUE))
679 {
680 this->authentication_failed = TRUE;
681 return NEED_MORE;
682 }
683 }
684 return NEED_MORE;
685 }
686
687 METHOD(task_t, build_r, status_t,
688 private_ike_auth_t *this, message_t *message)
689 {
690 identification_t *gateway;
691 auth_cfg_t *cfg;
692
693 if (message->get_exchange_type(message) == IKE_SA_INIT)
694 {
695 if (multiple_auth_enabled())
696 {
697 message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
698 chunk_empty);
699 }
700 return collect_my_init_data(this, message);
701 }
702
703 if (this->authentication_failed || this->peer_cfg == NULL)
704 {
705 goto peer_auth_failed;
706 }
707
708 if (this->my_auth == NULL && this->do_another_auth)
709 {
710 identification_t *id, *id_cfg;
711 id_payload_t *id_payload;
712
713 /* add IDr */
714 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
715 cfg->purge(cfg, TRUE);
716 cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
717
718 id_cfg = cfg->get(cfg, AUTH_RULE_IDENTITY);
719 id = this->ike_sa->get_my_id(this->ike_sa);
720 if (id->get_type(id) == ID_ANY)
721 { /* no IDr received, apply configured ID */
722 if (!id_cfg || id_cfg->contains_wildcards(id_cfg))
723 { /* no ID configured, use local IP address */
724 host_t *me;
725
726 DBG1(DBG_CFG, "no IDr configured, fall back on IP address");
727 me = this->ike_sa->get_my_host(this->ike_sa);
728 id_cfg = identification_create_from_sockaddr(
729 me->get_sockaddr(me));
730 cfg->add(cfg, AUTH_RULE_IDENTITY, id_cfg);
731 }
732 this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg));
733 id = id_cfg;
734 }
735 else
736 { /* IDr received, check if it matches configuration */
737 if (id_cfg && !id->matches(id, id_cfg))
738 {
739 DBG1(DBG_CFG, "received IDr %Y, but require %Y", id, id_cfg);
740 goto peer_auth_failed;
741 }
742 }
743
744 id_payload = id_payload_create_from_identification(PLV2_ID_RESPONDER, id);
745 get_reserved_id_bytes(this, id_payload);
746 message->add_payload(message, (payload_t*)id_payload);
747
748 if ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS) == AUTH_CLASS_EAP)
749 { /* EAP-only authentication */
750 if (!this->ike_sa->supports_extension(this->ike_sa,
751 EXT_EAP_ONLY_AUTHENTICATION))
752 {
753 DBG1(DBG_IKE, "configured EAP-only authentication, but peer "
754 "does not support it");
755 goto peer_auth_failed;
756 }
757 }
758 else
759 {
760 /* build authentication data */
761 this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
762 this->other_nonce, this->my_nonce,
763 this->other_packet->get_data(this->other_packet),
764 this->my_packet->get_data(this->my_packet),
765 this->reserved);
766 if (!this->my_auth)
767 {
768 goto local_auth_failed;
769 }
770 }
771 }
772
773 if (this->other_auth)
774 {
775 switch (this->other_auth->build(this->other_auth, message))
776 {
777 case SUCCESS:
778 this->other_auth->destroy(this->other_auth);
779 this->other_auth = NULL;
780 break;
781 case NEED_MORE:
782 break;
783 default:
784 if (message->get_payload(message, PLV2_EAP))
785 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
786 goto peer_auth_failed_no_notify;
787 }
788 goto peer_auth_failed;
789 }
790 }
791 if (this->my_auth)
792 {
793 switch (this->my_auth->build(this->my_auth, message))
794 {
795 case SUCCESS:
796 apply_auth_cfg(this, TRUE);
797 this->my_auth->destroy(this->my_auth);
798 this->my_auth = NULL;
799 break;
800 case NEED_MORE:
801 break;
802 default:
803 goto local_auth_failed;
804 }
805 }
806
807 /* check for additional authentication rounds */
808 if (do_another_auth(this))
809 {
810 message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
811 }
812 else
813 {
814 this->do_another_auth = FALSE;
815 }
816 if (this->do_another_auth || this->expect_another_auth)
817 {
818 return NEED_MORE;
819 }
820
821 if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
822 this->ike_sa, this->initial_contact))
823 {
824 DBG1(DBG_IKE, "cancelling IKE_SA setup due to uniqueness policy");
825 charon->bus->alert(charon->bus, ALERT_UNIQUE_KEEP);
826 message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
827 chunk_empty);
828 return FAILED;
829 }
830 if (!charon->bus->authorize(charon->bus, TRUE))
831 {
832 DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
833 goto peer_auth_failed;
834 }
835 if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
836 charon->redirect->redirect_on_auth(charon->redirect, this->ike_sa,
837 &gateway))
838 {
839 delete_ike_sa_job_t *job;
840 chunk_t data;
841
842 DBG1(DBG_IKE, "redirecting peer to %Y", gateway);
843 data = redirect_data_create(gateway, chunk_empty);
844 message->add_notify(message, FALSE, REDIRECT, data);
845 gateway->destroy(gateway);
846 chunk_free(&data);
847 /* we use this condition to prevent the CHILD_SA from getting created */
848 this->ike_sa->set_condition(this->ike_sa, COND_REDIRECTED, TRUE);
849 /* if the peer does not delete the SA we do so after a while */
850 job = delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE);
851 lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
852 lib->settings->get_int(lib->settings,
853 "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
854 lib->ns));
855 }
856 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
857 this->ike_sa->get_name(this->ike_sa),
858 this->ike_sa->get_unique_id(this->ike_sa),
859 this->ike_sa->get_my_host(this->ike_sa),
860 this->ike_sa->get_my_id(this->ike_sa),
861 this->ike_sa->get_other_host(this->ike_sa),
862 this->ike_sa->get_other_id(this->ike_sa));
863 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
864 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
865 return SUCCESS;
866
867 peer_auth_failed:
868 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
869 peer_auth_failed_no_notify:
870 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
871 return FAILED;
872 local_auth_failed:
873 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
874 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
875 return FAILED;
876 }
877
878 /**
879 * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA
880 */
881 static void send_auth_failed_informational(private_ike_auth_t *this,
882 message_t *reply)
883 {
884 message_t *message;
885 packet_t *packet;
886 host_t *host;
887
888 message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
889 message->set_message_id(message, reply->get_message_id(reply) + 1);
890 host = this->ike_sa->get_my_host(this->ike_sa);
891 message->set_source(message, host->clone(host));
892 host = this->ike_sa->get_other_host(this->ike_sa);
893 message->set_destination(message, host->clone(host));
894 message->set_exchange_type(message, INFORMATIONAL);
895 message->add_notify(message, FALSE, AUTHENTICATION_FAILED, chunk_empty);
896
897 if (this->ike_sa->generate_message(this->ike_sa, message,
898 &packet) == SUCCESS)
899 {
900 charon->sender->send(charon->sender, packet);
901 }
902 message->destroy(message);
903 }
904
905 /**
906 * Check if strict constraint fullfillment required to continue current auth
907 */
908 static bool require_strict(private_ike_auth_t *this, bool mutual_eap)
909 {
910 auth_cfg_t *cfg;
911
912 if (this->eap_acceptable)
913 {
914 return FALSE;
915 }
916
917 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
918 switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS))
919 {
920 case AUTH_CLASS_EAP:
921 if (mutual_eap && this->my_auth)
922 {
923 this->eap_acceptable = TRUE;
924 return !this->my_auth->is_mutual(this->my_auth);
925 }
926 return TRUE;
927 case AUTH_CLASS_PSK:
928 return TRUE;
929 case AUTH_CLASS_PUBKEY:
930 case AUTH_CLASS_ANY:
931 default:
932 return FALSE;
933 }
934 }
935
936 METHOD(task_t, process_i, status_t,
937 private_ike_auth_t *this, message_t *message)
938 {
939 enumerator_t *enumerator;
940 payload_t *payload;
941 auth_cfg_t *cfg;
942 bool mutual_eap = FALSE;
943
944 if (message->get_exchange_type(message) == IKE_SA_INIT)
945 {
946 if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) &&
947 multiple_auth_enabled())
948 {
949 this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
950 }
951 return collect_other_init_data(this, message);
952 }
953
954 enumerator = message->create_payload_enumerator(message);
955 while (enumerator->enumerate(enumerator, &payload))
956 {
957 if (payload->get_type(payload) == PLV2_NOTIFY)
958 {
959 notify_payload_t *notify = (notify_payload_t*)payload;
960 notify_type_t type = notify->get_notify_type(notify);
961
962 switch (type)
963 {
964 case NO_PROPOSAL_CHOSEN:
965 case SINGLE_PAIR_REQUIRED:
966 case NO_ADDITIONAL_SAS:
967 case INTERNAL_ADDRESS_FAILURE:
968 case FAILED_CP_REQUIRED:
969 case TS_UNACCEPTABLE:
970 case INVALID_SELECTORS:
971 /* these are errors, but are not critical as only the
972 * CHILD_SA won't get build, but IKE_SA establishes anyway */
973 break;
974 case MOBIKE_SUPPORTED:
975 case ADDITIONAL_IP4_ADDRESS:
976 case ADDITIONAL_IP6_ADDRESS:
977 /* handled in ike_mobike task */
978 break;
979 case AUTH_LIFETIME:
980 /* handled in ike_auth_lifetime task */
981 break;
982 case ME_ENDPOINT:
983 /* handled in ike_me task */
984 break;
985 case REDIRECT:
986 DESTROY_IF(this->redirect_to);
987 this->redirect_to = redirect_data_parse(
988 notify->get_notification_data(notify), NULL);
989 if (!this->redirect_to)
990 {
991 DBG1(DBG_IKE, "received invalid REDIRECT notify");
992 }
993 break;
994 default:
995 {
996 if (type <= 16383)
997 {
998 DBG1(DBG_IKE, "received %N notify error",
999 notify_type_names, type);
1000 enumerator->destroy(enumerator);
1001 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1002 return FAILED;
1003 }
1004 DBG2(DBG_IKE, "received %N notify",
1005 notify_type_names, type);
1006 break;
1007 }
1008 }
1009 }
1010 }
1011 enumerator->destroy(enumerator);
1012
1013 if (this->expect_another_auth)
1014 {
1015 if (this->other_auth == NULL)
1016 {
1017 id_payload_t *id_payload;
1018 identification_t *id;
1019
1020 /* handle IDr payload */
1021 id_payload = (id_payload_t*)message->get_payload(message,
1022 PLV2_ID_RESPONDER);
1023 if (!id_payload)
1024 {
1025 DBG1(DBG_IKE, "IDr payload missing");
1026 goto peer_auth_failed;
1027 }
1028 id = id_payload->get_identification(id_payload);
1029 get_reserved_id_bytes(this, id_payload);
1030 this->ike_sa->set_other_id(this->ike_sa, id);
1031 cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
1032 cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
1033
1034 if (message->get_payload(message, PLV2_AUTH))
1035 {
1036 /* verify authentication data */
1037 this->other_auth = authenticator_create_verifier(this->ike_sa,
1038 message, this->other_nonce, this->my_nonce,
1039 this->other_packet->get_data(this->other_packet),
1040 this->my_packet->get_data(this->my_packet),
1041 this->reserved);
1042 if (!this->other_auth)
1043 {
1044 goto peer_auth_failed;
1045 }
1046 }
1047 else
1048 {
1049 /* responder omitted AUTH payload, indicating EAP-only */
1050 mutual_eap = TRUE;
1051 }
1052 }
1053 if (this->other_auth)
1054 {
1055 switch (this->other_auth->process(this->other_auth, message))
1056 {
1057 case SUCCESS:
1058 break;
1059 case NEED_MORE:
1060 return NEED_MORE;
1061 default:
1062 goto peer_auth_failed;
1063 }
1064 this->other_auth->destroy(this->other_auth);
1065 this->other_auth = NULL;
1066 }
1067 /* another auth round done, invoke authorize hook */
1068 if (!charon->bus->authorize(charon->bus, FALSE))
1069 {
1070 DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling");
1071 goto peer_auth_failed;
1072 }
1073
1074 if (!mutual_eap)
1075 {
1076 apply_auth_cfg(this, FALSE);
1077 }
1078 }
1079
1080 if (require_strict(this, mutual_eap))
1081 {
1082 if (!update_cfg_candidates(this, TRUE))
1083 {
1084 goto peer_auth_failed;
1085 }
1086 }
1087
1088 if (this->my_auth)
1089 {
1090 switch (this->my_auth->process(this->my_auth, message))
1091 {
1092 case SUCCESS:
1093 apply_auth_cfg(this, TRUE);
1094 if (this->my_auth->is_mutual(this->my_auth))
1095 {
1096 apply_auth_cfg(this, FALSE);
1097 }
1098 this->my_auth->destroy(this->my_auth);
1099 this->my_auth = NULL;
1100 this->do_another_auth = do_another_auth(this);
1101 break;
1102 case NEED_MORE:
1103 break;
1104 default:
1105 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1106 send_auth_failed_informational(this, message);
1107 return FAILED;
1108 }
1109 }
1110 if (mutual_eap)
1111 {
1112 if (!this->my_auth || !this->my_auth->is_mutual(this->my_auth))
1113 {
1114 DBG1(DBG_IKE, "do not allow non-mutual EAP-only authentication");
1115 goto peer_auth_failed;
1116 }
1117 DBG1(DBG_IKE, "allow mutual EAP-only authentication");
1118 }
1119
1120 if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS) == NULL)
1121 {
1122 this->expect_another_auth = FALSE;
1123 }
1124 if (this->expect_another_auth || this->do_another_auth || this->my_auth)
1125 {
1126 return NEED_MORE;
1127 }
1128 if (!update_cfg_candidates(this, TRUE))
1129 {
1130 goto peer_auth_failed;
1131 }
1132 if (!charon->bus->authorize(charon->bus, TRUE))
1133 {
1134 DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, "
1135 "cancelling");
1136 goto peer_auth_failed;
1137 }
1138 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1139 this->ike_sa->get_name(this->ike_sa),
1140 this->ike_sa->get_unique_id(this->ike_sa),
1141 this->ike_sa->get_my_host(this->ike_sa),
1142 this->ike_sa->get_my_id(this->ike_sa),
1143 this->ike_sa->get_other_host(this->ike_sa),
1144 this->ike_sa->get_other_id(this->ike_sa));
1145 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1146 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
1147
1148 if (this->redirect_to)
1149 {
1150 this->ike_sa->handle_redirect(this->ike_sa, this->redirect_to);
1151 }
1152 return SUCCESS;
1153
1154 peer_auth_failed:
1155 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
1156 send_auth_failed_informational(this, message);
1157 return FAILED;
1158 }
1159
1160 METHOD(task_t, get_type, task_type_t,
1161 private_ike_auth_t *this)
1162 {
1163 return TASK_IKE_AUTH;
1164 }
1165
1166 METHOD(task_t, migrate, void,
1167 private_ike_auth_t *this, ike_sa_t *ike_sa)
1168 {
1169 chunk_free(&this->my_nonce);
1170 chunk_free(&this->other_nonce);
1171 DESTROY_IF(this->my_packet);
1172 DESTROY_IF(this->other_packet);
1173 DESTROY_IF(this->peer_cfg);
1174 DESTROY_IF(this->my_auth);
1175 DESTROY_IF(this->other_auth);
1176 DESTROY_IF(this->redirect_to);
1177 this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
1178
1179 this->my_packet = NULL;
1180 this->other_packet = NULL;
1181 this->ike_sa = ike_sa;
1182 this->peer_cfg = NULL;
1183 this->my_auth = NULL;
1184 this->other_auth = NULL;
1185 this->redirect_to = NULL;
1186 this->do_another_auth = TRUE;
1187 this->expect_another_auth = TRUE;
1188 this->authentication_failed = FALSE;
1189 this->candidates = linked_list_create();
1190 }
1191
1192 METHOD(task_t, destroy, void,
1193 private_ike_auth_t *this)
1194 {
1195 chunk_free(&this->my_nonce);
1196 chunk_free(&this->other_nonce);
1197 DESTROY_IF(this->my_packet);
1198 DESTROY_IF(this->other_packet);
1199 DESTROY_IF(this->my_auth);
1200 DESTROY_IF(this->other_auth);
1201 DESTROY_IF(this->peer_cfg);
1202 DESTROY_IF(this->redirect_to);
1203 this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
1204 free(this);
1205 }
1206
1207 /*
1208 * Described in header.
1209 */
1210 ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
1211 {
1212 private_ike_auth_t *this;
1213
1214 INIT(this,
1215 .public = {
1216 .task = {
1217 .get_type = _get_type,
1218 .migrate = _migrate,
1219 .build = _build_r,
1220 .process = _process_r,
1221 .destroy = _destroy,
1222 },
1223 },
1224 .ike_sa = ike_sa,
1225 .initiator = initiator,
1226 .candidates = linked_list_create(),
1227 .do_another_auth = TRUE,
1228 .expect_another_auth = TRUE,
1229 );
1230 if (initiator)
1231 {
1232 this->public.task.build = _build_i;
1233 this->public.task.process = _process_i;
1234 }
1235 return &this->public;
1236 }