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