2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2005-2009 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
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>.
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
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>
29 typedef struct private_ike_auth_t private_ike_auth_t
;
32 * Private members of a ike_auth_t task.
34 struct private_ike_auth_t
{
37 * Public methods and task_t interface.
47 * Are we the initiator?
52 * Nonce chosen by us in ike_init
57 * Nonce chosen by peer in ike_init
62 * IKE_SA_INIT message sent by us
67 * IKE_SA_INIT message sent by peer
69 packet_t
*other_packet
;
72 * Reserved bytes of ID payload
77 * currently active authenticator, to authenticate us
79 authenticator_t
*my_auth
;
82 * currently active authenticator, to authenticate peer
84 authenticator_t
*other_auth
;
87 * peer_cfg candidates, ordered by priority
89 linked_list_t
*candidates
;
92 * selected peer config (might change when using multiple authentications)
97 * have we planned an(other) authentication exchange?
102 * has the peer announced another authentication exchange?
104 bool expect_another_auth
;
107 * should we send a AUTHENTICATION_FAILED notify?
109 bool authentication_failed
;
112 * received an INITIAL_CONTACT?
114 bool initial_contact
;
118 * check if multiple authentication extension is enabled, configuration-wise
120 static bool multiple_auth_enabled()
122 return lib
->settings
->get_bool(lib
->settings
,
123 "%s.multiple_authentication", TRUE
, lib
->ns
);
127 * collect the needed information in the IKE_SA_INIT exchange from our message
129 static status_t
collect_my_init_data(private_ike_auth_t
*this,
132 nonce_payload_t
*nonce
;
134 /* get the nonce that was generated in ike_init */
135 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
140 this->my_nonce
= nonce
->get_nonce(nonce
);
142 /* pre-generate the message, keep a copy */
143 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
144 &this->my_packet
) != SUCCESS
)
152 * collect the needed information in the IKE_SA_INIT exchange from others message
154 static status_t
collect_other_init_data(private_ike_auth_t
*this,
157 /* we collect the needed information in the IKE_SA_INIT exchange */
158 nonce_payload_t
*nonce
;
160 /* get the nonce that was generated in ike_init */
161 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
166 this->other_nonce
= nonce
->get_nonce(nonce
);
168 /* keep a copy of the received packet */
169 this->other_packet
= message
->get_packet(message
);
174 * Get and store reserved bytes of id_payload, required for AUTH payload
176 static void get_reserved_id_bytes(private_ike_auth_t
*this, id_payload_t
*id
)
181 for (i
= 0; i
< countof(this->reserved
); i
++)
183 byte
= payload_get_field(&id
->payload_interface
, RESERVED_BYTE
, i
);
186 this->reserved
[i
] = *byte
;
192 * Get the next authentication configuration
194 static auth_cfg_t
*get_auth_cfg(private_ike_auth_t
*this, bool local
)
196 enumerator_t
*e1
, *e2
;
197 auth_cfg_t
*c1
, *c2
, *next
= NULL
;
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
))
205 e2
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, local
);
206 while (e2
->enumerate(e2
, &c2
))
208 if (c2
->complies(c2
, c1
, FALSE
))
226 * Move the currently active auth config to the auth configs completed
228 static void apply_auth_cfg(private_ike_auth_t
*this, bool local
)
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
);
238 * Check if we have should initiate another authentication round
240 static bool do_another_auth(private_ike_auth_t
*this)
242 bool do_another
= FALSE
;
243 enumerator_t
*done
, *todo
;
244 auth_cfg_t
*done_cfg
, *todo_cfg
;
246 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
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
))
255 if (!done
->enumerate(done
, &done_cfg
))
257 done_cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
259 if (!done_cfg
->complies(done_cfg
, todo_cfg
, FALSE
))
271 * Get peer configuration candidates from backends
273 static bool load_cfg_candidates(private_ike_auth_t
*this)
275 enumerator_t
*enumerator
;
276 peer_cfg_t
*peer_cfg
;
278 identification_t
*my_id
, *other_id
;
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
);
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
))
291 peer_cfg
->get_ref(peer_cfg
);
292 if (this->peer_cfg
== NULL
)
294 this->peer_cfg
= peer_cfg
;
295 this->ike_sa
->set_peer_cfg(this->ike_sa
, peer_cfg
);
299 this->candidates
->insert_last(this->candidates
, peer_cfg
);
302 enumerator
->destroy(enumerator
);
305 DBG1(DBG_CFG
, "selected peer config '%s'",
306 this->peer_cfg
->get_name(this->peer_cfg
));
309 DBG1(DBG_CFG
, "no matching peer config found");
314 * update the current peer candidate if necessary, using candidates
316 static bool update_cfg_candidates(private_ike_auth_t
*this, bool strict
)
322 char *comply_error
= NULL
;
323 enumerator_t
*e1
, *e2
, *tmp
;
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
);
330 { /* swap lists in strict mode: all configured rounds must be
331 * fulfilled. If !strict, we check only the rounds done so far. */
336 while (e1
->enumerate(e1
, &c1
))
338 /* check if done authentications comply to configured ones */
339 if (!e2
->enumerate(e2
, &c2
))
341 comply_error
= "insufficient authentication rounds";
344 if (!strict
&& !c1
->complies(c1
, c2
, TRUE
))
346 comply_error
= "non-matching authentication done";
349 if (strict
&& !c2
->complies(c2
, c1
, TRUE
))
351 comply_error
= "constraint checking failed";
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
);
365 if (this->candidates
->remove_first(this->candidates
,
366 (void**)&this->peer_cfg
) != SUCCESS
)
368 DBG1(DBG_CFG
, "no alternative config found");
369 this->peer_cfg
= NULL
;
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
);
378 while (this->peer_cfg
);
380 return this->peer_cfg
!= NULL
;
383 METHOD(task_t
, build_i
, status_t
,
384 private_ike_auth_t
*this, message_t
*message
)
388 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
390 return collect_my_init_data(this, message
);
393 if (this->peer_cfg
== NULL
)
395 this->peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
396 this->peer_cfg
->get_ref(this->peer_cfg
);
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
,
406 /* indicate support for EAP-only authentication */
407 message
->add_notify(message
, FALSE
, EAP_ONLY_AUTHENTICATION
,
411 if (!this->do_another_auth
&& !this->my_auth
)
412 { /* we have done our rounds */
416 /* check if an authenticator is in progress */
417 if (this->my_auth
== NULL
)
419 identification_t
*idi
, *idr
= NULL
;
420 id_payload_t
*id_payload
;
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
);
426 /* add (optional) IDr */
427 cfg
= get_auth_cfg(this, FALSE
);
430 idr
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
431 if (!cfg
->get(cfg
, AUTH_RULE_IDENTITY_LOOSE
) && idr
&&
432 !idr
->contains_wildcards(idr
))
434 this->ike_sa
->set_other_id(this->ike_sa
, idr
->clone(idr
));
435 id_payload
= id_payload_create_from_identification(
437 message
->add_payload(message
, (payload_t
*)id_payload
);
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 */
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
);
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
);
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
)
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
)))
468 message
->add_notify(message
, FALSE
, INITIAL_CONTACT
, chunk_empty
);
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
),
480 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
484 switch (this->my_auth
->build(this->my_auth
, message
))
487 apply_auth_cfg(this, TRUE
);
488 this->my_auth
->destroy(this->my_auth
);
489 this->my_auth
= NULL
;
494 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
498 /* check for additional authentication rounds */
499 if (do_another_auth(this))
501 if (message
->get_payload(message
, AUTHENTICATION
))
503 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
508 this->do_another_auth
= FALSE
;
513 METHOD(task_t
, process_r
, status_t
,
514 private_ike_auth_t
*this, message_t
*message
)
516 auth_cfg_t
*cfg
, *cand
;
517 id_payload_t
*id_payload
;
518 identification_t
*id
;
520 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
522 return collect_other_init_data(this, message
);
525 if (this->my_auth
== NULL
&& this->do_another_auth
)
527 /* handle (optional) IDr payload, apply proposed identity */
528 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_RESPONDER
);
531 id
= id_payload
->get_identification(id_payload
);
535 id
= identification_create_from_encoding(ID_ANY
, chunk_empty
);
537 this->ike_sa
->set_my_id(this->ike_sa
, id
);
540 if (!this->expect_another_auth
)
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
))
549 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
551 if (message
->get_notify(message
, EAP_ONLY_AUTHENTICATION
))
553 this->ike_sa
->enable_extension(this->ike_sa
,
554 EXT_EAP_ONLY_AUTHENTICATION
);
558 if (this->other_auth
== NULL
)
560 /* handle IDi payload */
561 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_INITIATOR
);
564 DBG1(DBG_IKE
, "IDi payload missing");
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
));
573 if (this->peer_cfg
== NULL
)
575 if (!load_cfg_candidates(this))
577 this->authentication_failed
= TRUE
;
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
);
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
))
593 this->authentication_failed
= TRUE
;
596 cand
= get_auth_cfg(this, FALSE
);
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
);
606 cfg
->add(cfg
, AUTH_RULE_EAP_IDENTITY
, id
->clone(id
));
608 id
= (identification_t
*)cand
->get(cand
, AUTH_RULE_AAA_IDENTITY
);
611 cfg
->add(cfg
, AUTH_RULE_AAA_IDENTITY
, id
->clone(id
));
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
),
621 if (!this->other_auth
)
623 this->authentication_failed
= TRUE
;
627 switch (this->other_auth
->process(this->other_auth
, message
))
630 this->other_auth
->destroy(this->other_auth
);
631 this->other_auth
= NULL
;
634 if (message
->get_payload(message
, AUTHENTICATION
))
635 { /* AUTH verification successful, but another build() needed */
640 this->authentication_failed
= TRUE
;
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
))
649 this->initial_contact
= TRUE
;
652 /* another auth round done, invoke authorize hook */
653 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
655 DBG1(DBG_IKE
, "authorization hook forbids IKE_SA, cancelling");
656 this->authentication_failed
= TRUE
;
660 apply_auth_cfg(this, FALSE
);
662 if (!update_cfg_candidates(this, FALSE
))
664 this->authentication_failed
= TRUE
;
668 if (message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
) == NULL
)
670 this->expect_another_auth
= FALSE
;
671 if (!update_cfg_candidates(this, TRUE
))
673 this->authentication_failed
= TRUE
;
680 METHOD(task_t
, build_r
, status_t
,
681 private_ike_auth_t
*this, message_t
*message
)
685 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
687 if (multiple_auth_enabled())
689 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
692 return collect_my_init_data(this, message
);
695 if (this->authentication_failed
|| this->peer_cfg
== NULL
)
697 goto peer_auth_failed
;
700 if (this->my_auth
== NULL
&& this->do_another_auth
)
702 identification_t
*id
, *id_cfg
;
703 id_payload_t
*id_payload
;
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
);
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 */
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
);
724 this->ike_sa
->set_my_id(this->ike_sa
, id_cfg
->clone(id_cfg
));
728 { /* IDr received, check if it matches configuration */
729 if (id_cfg
&& !id
->matches(id
, id_cfg
))
731 DBG1(DBG_CFG
, "received IDr %Y, but require %Y", id
, id_cfg
);
732 goto peer_auth_failed
;
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
);
740 if (this->initial_contact
)
742 charon
->ike_sa_manager
->check_uniqueness(charon
->ike_sa_manager
,
744 this->initial_contact
= FALSE
;
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
))
752 DBG1(DBG_IKE
, "configured EAP-only authentication, but peer "
753 "does not support it");
754 goto peer_auth_failed
;
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
),
767 goto local_auth_failed
;
772 if (this->other_auth
)
774 switch (this->other_auth
->build(this->other_auth
, message
))
777 this->other_auth
->destroy(this->other_auth
);
778 this->other_auth
= NULL
;
783 if (message
->get_payload(message
, EXTENSIBLE_AUTHENTICATION
))
784 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
785 goto peer_auth_failed_no_notify
;
787 goto peer_auth_failed
;
792 switch (this->my_auth
->build(this->my_auth
, message
))
795 apply_auth_cfg(this, TRUE
);
796 this->my_auth
->destroy(this->my_auth
);
797 this->my_auth
= NULL
;
802 goto local_auth_failed
;
806 /* check for additional authentication rounds */
807 if (do_another_auth(this))
809 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
813 this->do_another_auth
= FALSE
;
815 if (!this->do_another_auth
&& !this->expect_another_auth
)
817 if (charon
->ike_sa_manager
->check_uniqueness(charon
->ike_sa_manager
,
818 this->ike_sa
, FALSE
))
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
,
826 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
828 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, cancelling");
829 goto peer_auth_failed
;
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
);
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
);
850 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
851 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
856 * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA
858 static void send_auth_failed_informational(private_ike_auth_t
*this,
865 message
= message_create(IKEV2_MAJOR_VERSION
, IKEV2_MINOR_VERSION
);
866 message
->set_message_id(message
, reply
->get_message_id(reply
) + 1);
867 host
= this->ike_sa
->get_my_host(this->ike_sa
);
868 message
->set_source(message
, host
->clone(host
));
869 host
= this->ike_sa
->get_other_host(this->ike_sa
);
870 message
->set_destination(message
, host
->clone(host
));
871 message
->set_exchange_type(message
, INFORMATIONAL
);
872 message
->add_notify(message
, FALSE
, AUTHENTICATION_FAILED
, chunk_empty
);
874 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
877 charon
->sender
->send(charon
->sender
, packet
);
879 message
->destroy(message
);
882 METHOD(task_t
, process_i
, status_t
,
883 private_ike_auth_t
*this, message_t
*message
)
885 enumerator_t
*enumerator
;
888 bool mutual_eap
= FALSE
;
890 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
892 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
) &&
893 multiple_auth_enabled())
895 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
897 return collect_other_init_data(this, message
);
900 enumerator
= message
->create_payload_enumerator(message
);
901 while (enumerator
->enumerate(enumerator
, &payload
))
903 if (payload
->get_type(payload
) == NOTIFY
)
905 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
906 notify_type_t type
= notify
->get_notify_type(notify
);
910 case NO_PROPOSAL_CHOSEN
:
911 case SINGLE_PAIR_REQUIRED
:
912 case NO_ADDITIONAL_SAS
:
913 case INTERNAL_ADDRESS_FAILURE
:
914 case FAILED_CP_REQUIRED
:
915 case TS_UNACCEPTABLE
:
916 case INVALID_SELECTORS
:
917 /* these are errors, but are not critical as only the
918 * CHILD_SA won't get build, but IKE_SA establishes anyway */
920 case MOBIKE_SUPPORTED
:
921 case ADDITIONAL_IP4_ADDRESS
:
922 case ADDITIONAL_IP6_ADDRESS
:
923 /* handled in ike_mobike task */
926 /* handled in ike_auth_lifetime task */
929 /* handled in ike_me task */
935 DBG1(DBG_IKE
, "received %N notify error",
936 notify_type_names
, type
);
937 enumerator
->destroy(enumerator
);
938 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
941 DBG2(DBG_IKE
, "received %N notify",
942 notify_type_names
, type
);
948 enumerator
->destroy(enumerator
);
950 if (this->expect_another_auth
)
952 if (this->other_auth
== NULL
)
954 id_payload_t
*id_payload
;
955 identification_t
*id
;
957 /* handle IDr payload */
958 id_payload
= (id_payload_t
*)message
->get_payload(message
,
962 DBG1(DBG_IKE
, "IDr payload missing");
963 goto peer_auth_failed
;
965 id
= id_payload
->get_identification(id_payload
);
966 get_reserved_id_bytes(this, id_payload
);
967 this->ike_sa
->set_other_id(this->ike_sa
, id
);
968 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
969 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
971 if (message
->get_payload(message
, AUTHENTICATION
))
973 /* verify authentication data */
974 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
975 message
, this->other_nonce
, this->my_nonce
,
976 this->other_packet
->get_data(this->other_packet
),
977 this->my_packet
->get_data(this->my_packet
),
979 if (!this->other_auth
)
981 goto peer_auth_failed
;
986 /* responder omitted AUTH payload, indicating EAP-only */
990 if (this->other_auth
)
992 switch (this->other_auth
->process(this->other_auth
, message
))
999 goto peer_auth_failed
;
1001 this->other_auth
->destroy(this->other_auth
);
1002 this->other_auth
= NULL
;
1004 /* another auth round done, invoke authorize hook */
1005 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
1007 DBG1(DBG_IKE
, "authorization forbids IKE_SA, cancelling");
1008 goto peer_auth_failed
;
1013 apply_auth_cfg(this, FALSE
);
1019 switch (this->my_auth
->process(this->my_auth
, message
))
1022 apply_auth_cfg(this, TRUE
);
1023 if (this->my_auth
->is_mutual(this->my_auth
))
1025 apply_auth_cfg(this, FALSE
);
1027 this->my_auth
->destroy(this->my_auth
);
1028 this->my_auth
= NULL
;
1029 this->do_another_auth
= do_another_auth(this);
1034 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
1035 send_auth_failed_informational(this, message
);
1041 if (!this->my_auth
|| !this->my_auth
->is_mutual(this->my_auth
))
1043 DBG1(DBG_IKE
, "do not allow non-mutual EAP-only authentication");
1044 goto peer_auth_failed
;
1046 DBG1(DBG_IKE
, "allow mutual EAP-only authentication");
1049 if (message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
) == NULL
)
1051 this->expect_another_auth
= FALSE
;
1053 if (!this->expect_another_auth
&& !this->do_another_auth
&& !this->my_auth
)
1055 if (!update_cfg_candidates(this, TRUE
))
1057 goto peer_auth_failed
;
1059 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
1061 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, "
1063 goto peer_auth_failed
;
1065 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1066 this->ike_sa
->get_name(this->ike_sa
),
1067 this->ike_sa
->get_unique_id(this->ike_sa
),
1068 this->ike_sa
->get_my_host(this->ike_sa
),
1069 this->ike_sa
->get_my_id(this->ike_sa
),
1070 this->ike_sa
->get_other_host(this->ike_sa
),
1071 this->ike_sa
->get_other_id(this->ike_sa
));
1072 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
1073 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
1079 charon
->bus
->alert(charon
->bus
, ALERT_PEER_AUTH_FAILED
);
1080 send_auth_failed_informational(this, message
);
1084 METHOD(task_t
, get_type
, task_type_t
,
1085 private_ike_auth_t
*this)
1087 return TASK_IKE_AUTH
;
1090 METHOD(task_t
, migrate
, void,
1091 private_ike_auth_t
*this, ike_sa_t
*ike_sa
)
1093 chunk_free(&this->my_nonce
);
1094 chunk_free(&this->other_nonce
);
1095 DESTROY_IF(this->my_packet
);
1096 DESTROY_IF(this->other_packet
);
1097 DESTROY_IF(this->peer_cfg
);
1098 DESTROY_IF(this->my_auth
);
1099 DESTROY_IF(this->other_auth
);
1100 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
1102 this->my_packet
= NULL
;
1103 this->other_packet
= NULL
;
1104 this->ike_sa
= ike_sa
;
1105 this->peer_cfg
= NULL
;
1106 this->my_auth
= NULL
;
1107 this->other_auth
= NULL
;
1108 this->do_another_auth
= TRUE
;
1109 this->expect_another_auth
= TRUE
;
1110 this->authentication_failed
= FALSE
;
1111 this->candidates
= linked_list_create();
1114 METHOD(task_t
, destroy
, void,
1115 private_ike_auth_t
*this)
1117 chunk_free(&this->my_nonce
);
1118 chunk_free(&this->other_nonce
);
1119 DESTROY_IF(this->my_packet
);
1120 DESTROY_IF(this->other_packet
);
1121 DESTROY_IF(this->my_auth
);
1122 DESTROY_IF(this->other_auth
);
1123 DESTROY_IF(this->peer_cfg
);
1124 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
1129 * Described in header.
1131 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
, bool initiator
)
1133 private_ike_auth_t
*this;
1138 .get_type
= _get_type
,
1139 .migrate
= _migrate
,
1141 .process
= _process_r
,
1142 .destroy
= _destroy
,
1146 .initiator
= initiator
,
1147 .candidates
= linked_list_create(),
1148 .do_another_auth
= TRUE
,
1149 .expect_another_auth
= TRUE
,
1153 this->public.task
.build
= _build_i
;
1154 this->public.task
.process
= _process_i
;
1156 return &this->public;