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