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