2 * Copyright (C) 2012-2018 Tobias Brunner
3 * Copyright (C) 2005-2009 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * HSR 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/keymat_v2.h>
28 #include <sa/ikev2/authenticators/eap_authenticator.h>
29 #include <processing/jobs/delete_ike_sa_job.h>
31 typedef struct private_ike_auth_t private_ike_auth_t
;
34 * Private members of a ike_auth_t task.
36 struct private_ike_auth_t
{
39 * Public methods and task_t interface.
49 * Are we the initiator?
54 * Nonce chosen by us in ike_init
59 * Nonce chosen by peer in ike_init
64 * PPK_ID sent or received
66 identification_t
*ppk_id
;
74 * IKE_SA_INIT message sent by us
79 * IKE_SA_INIT message sent by peer
81 packet_t
*other_packet
;
84 * Reserved bytes of ID payload
89 * currently active authenticator, to authenticate us
91 authenticator_t
*my_auth
;
94 * currently active authenticator, to authenticate peer
96 authenticator_t
*other_auth
;
99 * peer_cfg candidates, ordered by priority
101 linked_list_t
*candidates
;
104 * selected peer config (might change when using multiple authentications)
106 peer_cfg_t
*peer_cfg
;
109 * have we planned an(other) authentication exchange?
111 bool do_another_auth
;
114 * has the peer announced another authentication exchange?
116 bool expect_another_auth
;
119 * should we send a AUTHENTICATION_FAILED notify?
121 bool authentication_failed
;
124 * received an INITIAL_CONTACT?
126 bool initial_contact
;
129 * Is EAP acceptable, did we strictly authenticate peer?
134 * Gateway ID if redirected
136 identification_t
*redirect_to
;
140 * check if multiple authentication extension is enabled, configuration-wise
142 static bool multiple_auth_enabled()
144 return lib
->settings
->get_bool(lib
->settings
,
145 "%s.multiple_authentication", TRUE
, lib
->ns
);
149 * collect the needed information in the IKE_SA_INIT exchange from our message
151 static status_t
collect_my_init_data(private_ike_auth_t
*this,
154 nonce_payload_t
*nonce
;
156 /* get the nonce that was generated in ike_init */
157 nonce
= (nonce_payload_t
*)message
->get_payload(message
, PLV2_NONCE
);
162 this->my_nonce
= nonce
->get_nonce(nonce
);
164 /* pre-generate the message, keep a copy */
165 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
166 &this->my_packet
) != SUCCESS
)
174 * collect the needed information in the IKE_SA_INIT exchange from others message
176 static status_t
collect_other_init_data(private_ike_auth_t
*this,
179 /* we collect the needed information in the IKE_SA_INIT exchange */
180 nonce_payload_t
*nonce
;
182 /* get the nonce that was generated in ike_init */
183 nonce
= (nonce_payload_t
*)message
->get_payload(message
, PLV2_NONCE
);
188 this->other_nonce
= nonce
->get_nonce(nonce
);
190 /* keep a copy of the received packet */
191 this->other_packet
= message
->get_packet(message
);
196 * Get and store reserved bytes of id_payload, required for AUTH payload
198 static void get_reserved_id_bytes(private_ike_auth_t
*this, id_payload_t
*id
)
203 for (i
= 0; i
< countof(this->reserved
); i
++)
205 byte
= payload_get_field(&id
->payload_interface
, RESERVED_BYTE
, i
);
208 this->reserved
[i
] = *byte
;
214 * Get the next authentication configuration
216 static auth_cfg_t
*get_auth_cfg(private_ike_auth_t
*this, bool local
)
218 enumerator_t
*e1
, *e2
;
219 auth_cfg_t
*c1
, *c2
, *next
= NULL
;
221 /* find an available config not already done */
222 e1
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, local
);
223 while (e1
->enumerate(e1
, &c1
))
227 e2
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, local
);
228 while (e2
->enumerate(e2
, &c2
))
230 if (c2
->complies(c2
, c1
, FALSE
))
248 * Move the currently active auth config to the auth configs completed
250 static void apply_auth_cfg(private_ike_auth_t
*this, bool local
)
254 cfg
= auth_cfg_create();
255 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, local
), local
);
256 this->ike_sa
->add_auth_cfg(this->ike_sa
, local
, cfg
);
260 * Check if we have should initiate another authentication round
262 static bool do_another_auth(private_ike_auth_t
*this)
264 bool do_another
= FALSE
;
265 enumerator_t
*done
, *todo
;
266 auth_cfg_t
*done_cfg
, *todo_cfg
;
268 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
273 done
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, TRUE
);
274 todo
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, TRUE
);
275 while (todo
->enumerate(todo
, &todo_cfg
))
277 if (!done
->enumerate(done
, &done_cfg
))
279 done_cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
281 if (!done_cfg
->complies(done_cfg
, todo_cfg
, FALSE
))
293 * Check if this is the first authentication round
295 static bool is_first_round(private_ike_auth_t
*this, bool local
)
300 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
305 done
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, local
);
306 if (done
->enumerate(done
, &cfg
))
316 * Get peer configuration candidates from backends
318 static bool load_cfg_candidates(private_ike_auth_t
*this)
320 enumerator_t
*enumerator
;
321 peer_cfg_t
*peer_cfg
;
324 identification_t
*my_id
, *other_id
;
325 proposal_t
*ike_proposal
;
328 me
= this->ike_sa
->get_my_host(this->ike_sa
);
329 other
= this->ike_sa
->get_other_host(this->ike_sa
);
330 my_id
= this->ike_sa
->get_my_id(this->ike_sa
);
331 other_id
= this->ike_sa
->get_other_id(this->ike_sa
);
332 ike_proposal
= this->ike_sa
->get_proposal(this->ike_sa
);
333 private = this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
) ||
334 lib
->settings
->get_bool(lib
->settings
, "%s.accept_private_algs",
337 DBG1(DBG_CFG
, "looking for peer configs matching %H[%Y]...%H[%Y]",
338 me
, my_id
, other
, other_id
);
339 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
340 me
, other
, my_id
, other_id
, IKEV2
);
341 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
343 /* ignore all configs that have no matching IKE proposal */
344 ike_cfg
= peer_cfg
->get_ike_cfg(peer_cfg
);
345 if (!ike_cfg
->has_proposal(ike_cfg
, ike_proposal
, private))
347 DBG2(DBG_CFG
, "ignore candidate '%s' without matching IKE proposal",
348 peer_cfg
->get_name(peer_cfg
));
351 peer_cfg
->get_ref(peer_cfg
);
354 this->peer_cfg
= peer_cfg
;
358 this->candidates
->insert_last(this->candidates
, peer_cfg
);
361 enumerator
->destroy(enumerator
);
364 this->ike_sa
->set_peer_cfg(this->ike_sa
, this->peer_cfg
);
365 DBG1(DBG_CFG
, "selected peer config '%s'",
366 this->peer_cfg
->get_name(this->peer_cfg
));
369 DBG1(DBG_CFG
, "no matching peer config found");
374 * update the current peer candidate if necessary, using candidates
376 static bool update_cfg_candidates(private_ike_auth_t
*this, bool strict
)
382 char *comply_error
= NULL
;
383 enumerator_t
*e1
, *e2
, *tmp
;
386 e1
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, FALSE
);
387 e2
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, FALSE
);
390 { /* swap lists in strict mode: all configured rounds must be
391 * fulfilled. If !strict, we check only the rounds done so far. */
396 while (e1
->enumerate(e1
, &c1
))
398 /* check if done authentications comply to configured ones */
399 if (!e2
->enumerate(e2
, &c2
))
401 comply_error
= "insufficient authentication rounds";
404 if (!strict
&& !c1
->complies(c1
, c2
, TRUE
))
406 comply_error
= "non-matching authentication done";
409 if (strict
&& !c2
->complies(c2
, c1
, TRUE
))
411 comply_error
= "constraint checking failed";
421 DBG1(DBG_CFG
, "selected peer config '%s' unacceptable: %s",
422 this->peer_cfg
->get_name(this->peer_cfg
), comply_error
);
423 this->peer_cfg
->destroy(this->peer_cfg
);
425 if (this->candidates
->remove_first(this->candidates
,
426 (void**)&this->peer_cfg
) != SUCCESS
)
428 DBG1(DBG_CFG
, "no alternative config found");
429 this->peer_cfg
= NULL
;
433 DBG1(DBG_CFG
, "switching to peer config '%s'",
434 this->peer_cfg
->get_name(this->peer_cfg
));
435 this->ike_sa
->set_peer_cfg(this->ike_sa
, this->peer_cfg
);
438 while (this->peer_cfg
);
440 return this->peer_cfg
!= NULL
;
444 * Currently defined PPK_ID types
446 #define PPK_ID_OPAQUE 1
447 #define PPK_ID_FIXED 2
450 * Parse the payload data of the given PPK_IDENTITY notify
452 static bool parse_ppk_identity(notify_payload_t
*notify
, identification_t
**id
)
456 data
= notify
->get_notification_data(notify
);
464 data
= chunk_skip(data
, 1);
469 *id
= identification_create_from_data(data
);
474 * Add a PPK_IDENTITY with the given PPK_ID to the given message
476 static void add_ppk_identity(identification_t
*id
, message_t
*msg
)
479 uint8_t type
= PPK_ID_FIXED
;
481 /* we currently only support one type */
482 data
= chunk_cata("cc", chunk_from_thing(type
), id
->get_encoding(id
));
483 msg
->add_notify(msg
, FALSE
, PPK_IDENTITY
, data
);
487 * Use the given PPK_ID to find a PPK and store it and the ID in the task
489 static bool get_ppk(private_ike_auth_t
*this, identification_t
*ppk_id
)
493 key
= lib
->credmgr
->get_shared(lib
->credmgr
, SHARED_PPK
, ppk_id
, NULL
);
496 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
498 DBG1(DBG_CFG
, "PPK required but no PPK found for '%Y'", ppk_id
);
501 DBG1(DBG_CFG
, "no PPK for '%Y' found, ignored because PPK is not "
505 this->ppk
= chunk_clone(key
->get_key(key
));
506 this->ppk_id
= ppk_id
->clone(ppk_id
);
512 * Check if we have a PPK available and, if not, whether we require one as
515 static bool get_ppk_i(private_ike_auth_t
*this)
517 identification_t
*ppk_id
;
519 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_PPK
))
521 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
523 DBG1(DBG_CFG
, "PPK required but peer does not support PPK");
529 ppk_id
= this->peer_cfg
->get_ppk_id(this->peer_cfg
);
532 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
534 DBG1(DBG_CFG
, "PPK required but no PPK_ID configured");
539 return get_ppk(this, ppk_id
);
543 * Check if we have a PPK available and if not whether we require one as
546 static bool get_ppk_r(private_ike_auth_t
*this, message_t
*msg
)
548 notify_payload_t
*notify
;
549 identification_t
*ppk_id
, *ppk_id_cfg
;
552 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_PPK
))
554 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
556 DBG1(DBG_CFG
, "PPK required but peer does not support PPK");
562 notify
= msg
->get_notify(msg
, PPK_IDENTITY
);
563 if (!notify
|| !parse_ppk_identity(notify
, &ppk_id
))
565 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
567 DBG1(DBG_CFG
, "PPK required but no PPK_IDENTITY received");
573 ppk_id_cfg
= this->peer_cfg
->get_ppk_id(this->peer_cfg
);
574 if (ppk_id_cfg
&& !ppk_id
->matches(ppk_id
, ppk_id_cfg
))
576 DBG1(DBG_CFG
, "received PPK_ID '%Y', but require '%Y'", ppk_id
,
578 ppk_id
->destroy(ppk_id
);
581 result
= get_ppk(this, ppk_id
);
582 ppk_id
->destroy(ppk_id
);
586 METHOD(task_t
, build_i
, status_t
,
587 private_ike_auth_t
*this, message_t
*message
)
591 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
593 return collect_my_init_data(this, message
);
598 this->peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
599 this->peer_cfg
->get_ref(this->peer_cfg
);
602 if (message
->get_message_id(message
) == 1)
603 { /* in the first IKE_AUTH ... */
604 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
605 { /* indicate support for multiple authentication */
606 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
609 /* indicate support for EAP-only authentication */
610 message
->add_notify(message
, FALSE
, EAP_ONLY_AUTHENTICATION
,
612 /* indicate support for RFC 6311 Message ID synchronization */
613 message
->add_notify(message
, FALSE
, IKEV2_MESSAGE_ID_SYNC_SUPPORTED
,
615 /* only use a PPK in the first round */
616 if (!get_ppk_i(this))
618 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
623 if (!this->do_another_auth
&& !this->my_auth
)
624 { /* we have done our rounds */
628 /* check if an authenticator is in progress */
631 identification_t
*idi
, *idr
= NULL
;
632 id_payload_t
*id_payload
;
634 /* clean up authentication config from a previous round */
635 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
636 cfg
->purge(cfg
, TRUE
);
638 /* add (optional) IDr */
639 cfg
= get_auth_cfg(this, FALSE
);
642 idr
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
643 if (!cfg
->get(cfg
, AUTH_RULE_IDENTITY_LOOSE
) && idr
&&
644 !idr
->contains_wildcards(idr
))
646 this->ike_sa
->set_other_id(this->ike_sa
, idr
->clone(idr
));
647 id_payload
= id_payload_create_from_identification(
648 PLV2_ID_RESPONDER
, idr
);
649 message
->add_payload(message
, (payload_t
*)id_payload
);
653 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
654 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
655 idi
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
656 if (!idi
|| idi
->get_type(idi
) == ID_ANY
)
657 { /* ID_ANY is invalid as IDi, use local IP address instead */
660 DBG1(DBG_CFG
, "no IDi configured, fall back on IP address");
661 me
= this->ike_sa
->get_my_host(this->ike_sa
);
662 idi
= identification_create_from_sockaddr(me
->get_sockaddr(me
));
663 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, idi
);
665 this->ike_sa
->set_my_id(this->ike_sa
, idi
->clone(idi
));
666 id_payload
= id_payload_create_from_identification(PLV2_ID_INITIATOR
, idi
);
667 get_reserved_id_bytes(this, id_payload
);
668 message
->add_payload(message
, (payload_t
*)id_payload
);
670 if (idr
&& !idr
->contains_wildcards(idr
) &&
671 message
->get_message_id(message
) == 1 &&
672 this->peer_cfg
->get_unique_policy(this->peer_cfg
) != UNIQUE_NEVER
)
676 host
= this->ike_sa
->get_other_host(this->ike_sa
);
677 if (!charon
->ike_sa_manager
->has_contact(charon
->ike_sa_manager
,
678 idi
, idr
, host
->get_family(host
)))
680 message
->add_notify(message
, FALSE
, INITIAL_CONTACT
, chunk_empty
);
684 /* build authentication data */
685 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
686 this->other_nonce
, this->my_nonce
,
687 this->other_packet
->get_data(this->other_packet
),
688 this->my_packet
->get_data(this->my_packet
),
692 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
696 /* for authentication methods that return NEED_MORE, the PPK will be reset
697 * in process_i() for messages without PPK_ID notify, so we always set it
698 * during the first round (afterwards the PPK won't be available) */
699 if (this->ppk
.ptr
&& this->my_auth
->use_ppk
)
701 this->my_auth
->use_ppk(this->my_auth
, this->ppk
,
702 !this->peer_cfg
->ppk_required(this->peer_cfg
));
704 switch (this->my_auth
->build(this->my_auth
, message
))
707 apply_auth_cfg(this, TRUE
);
708 this->my_auth
->destroy(this->my_auth
);
709 this->my_auth
= NULL
;
714 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
718 /* add a PPK_IDENTITY notify to the message that contains AUTH */
719 if (this->ppk_id
&& message
->get_payload(message
, PLV2_AUTH
))
721 add_ppk_identity(this->ppk_id
, message
);
724 /* check for additional authentication rounds */
725 if (do_another_auth(this))
727 if (message
->get_payload(message
, PLV2_AUTH
))
729 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
734 this->do_another_auth
= FALSE
;
739 METHOD(task_t
, process_r
, status_t
,
740 private_ike_auth_t
*this, message_t
*message
)
742 auth_cfg_t
*cfg
, *cand
;
743 id_payload_t
*id_payload
;
744 identification_t
*id
;
746 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
748 return collect_other_init_data(this, message
);
751 if (!this->my_auth
&& this->do_another_auth
)
753 /* handle (optional) IDr payload, apply proposed identity */
754 id_payload
= (id_payload_t
*)message
->get_payload(message
, PLV2_ID_RESPONDER
);
757 id
= id_payload
->get_identification(id_payload
);
761 id
= identification_create_from_encoding(ID_ANY
, chunk_empty
);
763 this->ike_sa
->set_my_id(this->ike_sa
, id
);
766 if (!this->expect_another_auth
)
771 if (message
->get_message_id(message
) == 1)
772 { /* check for extensions in the first IKE_AUTH */
773 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
))
775 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
777 if (message
->get_notify(message
, EAP_ONLY_AUTHENTICATION
))
779 this->ike_sa
->enable_extension(this->ike_sa
,
780 EXT_EAP_ONLY_AUTHENTICATION
);
782 if (message
->get_notify(message
, INITIAL_CONTACT
))
784 this->initial_contact
= TRUE
;
788 if (!this->other_auth
)
790 /* handle IDi payload */
791 id_payload
= (id_payload_t
*)message
->get_payload(message
, PLV2_ID_INITIATOR
);
794 DBG1(DBG_IKE
, "IDi payload missing");
797 id
= id_payload
->get_identification(id_payload
);
798 get_reserved_id_bytes(this, id_payload
);
799 this->ike_sa
->set_other_id(this->ike_sa
, id
);
800 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
801 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
805 if (!load_cfg_candidates(this))
807 this->authentication_failed
= TRUE
;
811 if (!message
->get_payload(message
, PLV2_AUTH
))
812 { /* before authenticating with EAP, we need a EAP config */
813 cand
= get_auth_cfg(this, FALSE
);
815 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_TYPE
) == EAP_NAK
&&
816 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_VENDOR
) == 0))
817 { /* peer requested EAP, but current config does not match */
818 DBG1(DBG_IKE
, "peer requested EAP, config unacceptable");
819 this->peer_cfg
->destroy(this->peer_cfg
);
820 this->peer_cfg
= NULL
;
821 if (!update_cfg_candidates(this, FALSE
))
823 this->authentication_failed
= TRUE
;
826 cand
= get_auth_cfg(this, FALSE
);
828 /* copy over the EAP specific rules for authentication */
829 cfg
->add(cfg
, AUTH_RULE_EAP_TYPE
,
830 cand
->get(cand
, AUTH_RULE_EAP_TYPE
));
831 cfg
->add(cfg
, AUTH_RULE_EAP_VENDOR
,
832 cand
->get(cand
, AUTH_RULE_EAP_VENDOR
));
833 id
= (identification_t
*)cand
->get(cand
, AUTH_RULE_EAP_IDENTITY
);
836 cfg
->add(cfg
, AUTH_RULE_EAP_IDENTITY
, id
->clone(id
));
838 id
= (identification_t
*)cand
->get(cand
, AUTH_RULE_AAA_IDENTITY
);
841 cfg
->add(cfg
, AUTH_RULE_AAA_IDENTITY
, id
->clone(id
));
845 /* verify authentication data */
846 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
847 message
, this->other_nonce
, this->my_nonce
,
848 this->other_packet
->get_data(this->other_packet
),
849 this->my_packet
->get_data(this->my_packet
),
851 if (!this->other_auth
)
853 this->authentication_failed
= TRUE
;
857 if (message
->get_payload(message
, PLV2_AUTH
) &&
858 is_first_round(this, FALSE
))
860 if (!get_ppk_r(this, message
))
862 this->authentication_failed
= TRUE
;
865 else if (this->ppk
.ptr
&& this->other_auth
->use_ppk
)
867 this->other_auth
->use_ppk(this->other_auth
, this->ppk
, FALSE
);
870 switch (this->other_auth
->process(this->other_auth
, message
))
873 this->other_auth
->destroy(this->other_auth
);
874 this->other_auth
= NULL
;
877 if (message
->get_payload(message
, PLV2_AUTH
))
878 { /* AUTH verification successful, but another build() needed */
883 this->authentication_failed
= TRUE
;
887 /* another auth round done, invoke authorize hook */
888 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
890 DBG1(DBG_IKE
, "authorization hook forbids IKE_SA, cancelling");
891 this->authentication_failed
= TRUE
;
895 apply_auth_cfg(this, FALSE
);
897 if (!update_cfg_candidates(this, FALSE
))
899 this->authentication_failed
= TRUE
;
903 if (!message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
))
905 this->expect_another_auth
= FALSE
;
906 if (!update_cfg_candidates(this, TRUE
))
908 this->authentication_failed
= TRUE
;
916 * Clear the PPK and PPK_ID
918 static void clear_ppk(private_ike_auth_t
*this)
920 DESTROY_IF(this->ppk_id
);
922 chunk_clear(&this->ppk
);
926 * Derive new keys and clear the PPK
928 static bool apply_ppk(private_ike_auth_t
*this)
934 keymat
= (keymat_v2_t
*)this->ike_sa
->get_keymat(this->ike_sa
);
935 if (!keymat
->derive_ike_keys_ppk(keymat
, this->ppk
))
939 DBG1(DBG_CFG
, "using PPK for PPK_ID '%Y'", this->ppk_id
);
940 this->ike_sa
->set_condition(this->ike_sa
, COND_PPK
, TRUE
);
946 METHOD(task_t
, build_r
, status_t
,
947 private_ike_auth_t
*this, message_t
*message
)
949 identification_t
*gateway
;
952 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
954 if (multiple_auth_enabled())
956 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
959 return collect_my_init_data(this, message
);
962 if (this->authentication_failed
|| !this->peer_cfg
)
964 goto peer_auth_failed
;
967 if (!this->my_auth
&& this->do_another_auth
)
969 identification_t
*id
, *id_cfg
;
970 id_payload_t
*id_payload
;
973 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
974 cfg
->purge(cfg
, TRUE
);
975 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
977 id_cfg
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
978 id
= this->ike_sa
->get_my_id(this->ike_sa
);
979 if (id
->get_type(id
) == ID_ANY
)
980 { /* no IDr received, apply configured ID */
981 if (!id_cfg
|| id_cfg
->contains_wildcards(id_cfg
))
982 { /* no ID configured, use local IP address */
985 DBG1(DBG_CFG
, "no IDr configured, fall back on IP address");
986 me
= this->ike_sa
->get_my_host(this->ike_sa
);
987 id_cfg
= identification_create_from_sockaddr(
988 me
->get_sockaddr(me
));
989 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id_cfg
);
991 this->ike_sa
->set_my_id(this->ike_sa
, id_cfg
->clone(id_cfg
));
995 { /* IDr received, check if it matches configuration */
996 if (id_cfg
&& !id
->matches(id
, id_cfg
))
998 DBG1(DBG_CFG
, "received IDr %Y, but require %Y", id
, id_cfg
);
999 goto peer_auth_failed
;
1003 id_payload
= id_payload_create_from_identification(PLV2_ID_RESPONDER
, id
);
1004 get_reserved_id_bytes(this, id_payload
);
1005 message
->add_payload(message
, (payload_t
*)id_payload
);
1007 if ((uintptr_t)cfg
->get(cfg
, AUTH_RULE_AUTH_CLASS
) == AUTH_CLASS_EAP
)
1008 { /* EAP-only authentication */
1009 if (!this->ike_sa
->supports_extension(this->ike_sa
,
1010 EXT_EAP_ONLY_AUTHENTICATION
))
1012 DBG1(DBG_IKE
, "configured EAP-only authentication, but peer "
1013 "does not support it");
1014 goto peer_auth_failed
;
1019 /* build authentication data */
1020 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
1021 this->other_nonce
, this->my_nonce
,
1022 this->other_packet
->get_data(this->other_packet
),
1023 this->my_packet
->get_data(this->my_packet
),
1027 goto local_auth_failed
;
1032 if (this->other_auth
)
1034 switch (this->other_auth
->build(this->other_auth
, message
))
1037 this->other_auth
->destroy(this->other_auth
);
1038 this->other_auth
= NULL
;
1043 if (message
->get_payload(message
, PLV2_EAP
))
1044 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
1045 goto peer_auth_failed_no_notify
;
1047 goto peer_auth_failed
;
1052 if (this->ppk
.ptr
&& this->my_auth
->use_ppk
)
1054 this->my_auth
->use_ppk(this->my_auth
, this->ppk
, FALSE
);
1056 switch (this->my_auth
->build(this->my_auth
, message
))
1059 apply_auth_cfg(this, TRUE
);
1060 this->my_auth
->destroy(this->my_auth
);
1061 this->my_auth
= NULL
;
1066 goto local_auth_failed
;
1070 /* add a PPK_IDENTITY notify and derive new keys and clear the PPK */
1073 message
->add_notify(message
, FALSE
, PPK_IDENTITY
, chunk_empty
);
1074 if (!apply_ppk(this))
1076 goto local_auth_failed
;
1080 /* check for additional authentication rounds */
1081 if (do_another_auth(this))
1083 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
1087 this->do_another_auth
= FALSE
;
1089 if (this->do_another_auth
|| this->expect_another_auth
)
1094 if (charon
->ike_sa_manager
->check_uniqueness(charon
->ike_sa_manager
,
1095 this->ike_sa
, this->initial_contact
))
1097 DBG1(DBG_IKE
, "cancelling IKE_SA setup due to uniqueness policy");
1098 charon
->bus
->alert(charon
->bus
, ALERT_UNIQUE_KEEP
);
1099 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
1103 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
1105 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, cancelling");
1106 goto peer_auth_failed
;
1108 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_IKE_REDIRECTION
) &&
1109 charon
->redirect
->redirect_on_auth(charon
->redirect
, this->ike_sa
,
1112 delete_ike_sa_job_t
*job
;
1115 DBG1(DBG_IKE
, "redirecting peer to %Y", gateway
);
1116 data
= redirect_data_create(gateway
, chunk_empty
);
1117 message
->add_notify(message
, FALSE
, REDIRECT
, data
);
1118 gateway
->destroy(gateway
);
1120 /* we use this condition to prevent the CHILD_SA from getting created */
1121 this->ike_sa
->set_condition(this->ike_sa
, COND_REDIRECTED
, TRUE
);
1122 /* if the peer does not delete the SA we do so after a while */
1123 job
= delete_ike_sa_job_create(this->ike_sa
->get_id(this->ike_sa
), TRUE
);
1124 lib
->scheduler
->schedule_job(lib
->scheduler
, (job_t
*)job
,
1125 lib
->settings
->get_int(lib
->settings
,
1126 "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT
,
1129 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1130 this->ike_sa
->get_name(this->ike_sa
),
1131 this->ike_sa
->get_unique_id(this->ike_sa
),
1132 this->ike_sa
->get_my_host(this->ike_sa
),
1133 this->ike_sa
->get_my_id(this->ike_sa
),
1134 this->ike_sa
->get_other_host(this->ike_sa
),
1135 this->ike_sa
->get_other_id(this->ike_sa
));
1136 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
1137 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
1141 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
1142 peer_auth_failed_no_notify
:
1143 charon
->bus
->alert(charon
->bus
, ALERT_PEER_AUTH_FAILED
);
1146 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
1147 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
1152 * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA
1154 static void send_auth_failed_informational(private_ike_auth_t
*this,
1161 message
= message_create(IKEV2_MAJOR_VERSION
, IKEV2_MINOR_VERSION
);
1162 message
->set_message_id(message
, reply
->get_message_id(reply
) + 1);
1163 host
= this->ike_sa
->get_my_host(this->ike_sa
);
1164 message
->set_source(message
, host
->clone(host
));
1165 host
= this->ike_sa
->get_other_host(this->ike_sa
);
1166 message
->set_destination(message
, host
->clone(host
));
1167 message
->set_exchange_type(message
, INFORMATIONAL
);
1168 message
->add_notify(message
, FALSE
, AUTHENTICATION_FAILED
, chunk_empty
);
1170 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
1171 &packet
) == SUCCESS
)
1173 charon
->sender
->send(charon
->sender
, packet
);
1175 message
->destroy(message
);
1179 * Check if strict constraint fulfillment required to continue current auth
1181 static bool require_strict(private_ike_auth_t
*this, bool mutual_eap
)
1185 if (this->eap_acceptable
)
1190 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
1191 switch ((uintptr_t)cfg
->get(cfg
, AUTH_RULE_AUTH_CLASS
))
1193 case AUTH_CLASS_EAP
:
1194 if (mutual_eap
&& this->my_auth
)
1196 this->eap_acceptable
= TRUE
;
1197 return !this->my_auth
->is_mutual(this->my_auth
);
1200 case AUTH_CLASS_PSK
:
1202 case AUTH_CLASS_PUBKEY
:
1203 case AUTH_CLASS_ANY
:
1209 METHOD(task_t
, process_i
, status_t
,
1210 private_ike_auth_t
*this, message_t
*message
)
1212 enumerator_t
*enumerator
;
1215 bool mutual_eap
= FALSE
, ppk_id_received
= FALSE
;
1217 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
1219 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
) &&
1220 multiple_auth_enabled())
1222 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
1224 return collect_other_init_data(this, message
);
1227 enumerator
= message
->create_payload_enumerator(message
);
1228 while (enumerator
->enumerate(enumerator
, &payload
))
1230 if (payload
->get_type(payload
) == PLV2_NOTIFY
)
1232 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1233 notify_type_t type
= notify
->get_notify_type(notify
);
1237 case NO_PROPOSAL_CHOSEN
:
1238 case SINGLE_PAIR_REQUIRED
:
1239 case NO_ADDITIONAL_SAS
:
1240 case INTERNAL_ADDRESS_FAILURE
:
1241 case FAILED_CP_REQUIRED
:
1242 case TS_UNACCEPTABLE
:
1243 case INVALID_SELECTORS
:
1244 /* these are errors, but are not critical as only the
1245 * CHILD_SA won't get build, but IKE_SA establishes anyway */
1247 case MOBIKE_SUPPORTED
:
1248 case ADDITIONAL_IP4_ADDRESS
:
1249 case ADDITIONAL_IP6_ADDRESS
:
1250 /* handled in ike_mobike task */
1253 /* handled in ike_auth_lifetime task */
1256 /* handled in ike_me task */
1259 DESTROY_IF(this->redirect_to
);
1260 this->redirect_to
= redirect_data_parse(
1261 notify
->get_notification_data(notify
), NULL
);
1262 if (!this->redirect_to
)
1264 DBG1(DBG_IKE
, "received invalid REDIRECT notify");
1267 case IKEV2_MESSAGE_ID_SYNC_SUPPORTED
:
1268 this->ike_sa
->enable_extension(this->ike_sa
,
1269 EXT_IKE_MESSAGE_ID_SYNC
);
1272 ppk_id_received
= TRUE
;
1278 DBG1(DBG_IKE
, "received %N notify error",
1279 notify_type_names
, type
);
1280 enumerator
->destroy(enumerator
);
1281 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
1284 DBG2(DBG_IKE
, "received %N notify",
1285 notify_type_names
, type
);
1291 enumerator
->destroy(enumerator
);
1293 if (this->expect_another_auth
)
1295 if (!this->other_auth
)
1297 id_payload_t
*id_payload
;
1298 identification_t
*id
;
1300 /* handle IDr payload */
1301 id_payload
= (id_payload_t
*)message
->get_payload(message
,
1305 DBG1(DBG_IKE
, "IDr payload missing");
1306 goto peer_auth_failed
;
1308 id
= id_payload
->get_identification(id_payload
);
1309 get_reserved_id_bytes(this, id_payload
);
1310 this->ike_sa
->set_other_id(this->ike_sa
, id
);
1311 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
1312 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
1314 if (message
->get_payload(message
, PLV2_AUTH
))
1316 /* verify authentication data */
1317 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
1318 message
, this->other_nonce
, this->my_nonce
,
1319 this->other_packet
->get_data(this->other_packet
),
1320 this->my_packet
->get_data(this->my_packet
),
1322 if (!this->other_auth
)
1324 goto peer_auth_failed
;
1329 /* responder omitted AUTH payload, indicating EAP-only */
1333 if (this->other_auth
)
1335 if (ppk_id_received
&& is_first_round(this, FALSE
) &&
1336 this->other_auth
->use_ppk
)
1338 this->other_auth
->use_ppk(this->other_auth
, this->ppk
, FALSE
);
1340 switch (this->other_auth
->process(this->other_auth
, message
))
1347 goto peer_auth_failed
;
1349 this->other_auth
->destroy(this->other_auth
);
1350 this->other_auth
= NULL
;
1352 /* another auth round done, invoke authorize hook */
1353 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
1355 DBG1(DBG_IKE
, "authorization forbids IKE_SA, cancelling");
1356 goto peer_auth_failed
;
1361 apply_auth_cfg(this, FALSE
);
1365 if (require_strict(this, mutual_eap
))
1367 if (!update_cfg_candidates(this, TRUE
))
1369 goto peer_auth_failed
;
1375 /* while we already set the PPK in build_i(), we MUST not use it if
1376 * the peer did not reply with a PPK_ID notify */
1377 if (this->ppk
.ptr
&& this->my_auth
->use_ppk
)
1379 this->my_auth
->use_ppk(this->my_auth
,
1380 ppk_id_received
? this->ppk
: chunk_empty
,
1383 switch (this->my_auth
->process(this->my_auth
, message
))
1386 apply_auth_cfg(this, TRUE
);
1387 if (this->my_auth
->is_mutual(this->my_auth
))
1389 apply_auth_cfg(this, FALSE
);
1391 this->my_auth
->destroy(this->my_auth
);
1392 this->my_auth
= NULL
;
1393 this->do_another_auth
= do_another_auth(this);
1398 goto local_auth_failed
;
1402 /* change keys and clear PPK after we are done with our authentication, so
1403 * we only explicitly use it for the first round, afterwards we just use the
1404 * changed SK_p keys implicitly */
1405 if (!this->my_auth
&& this->ppk_id
)
1407 if (ppk_id_received
)
1409 if (!apply_ppk(this))
1411 goto local_auth_failed
;
1416 DBG1(DBG_CFG
, "peer didn't use PPK for PPK_ID '%Y'", this->ppk_id
);
1423 if (!this->my_auth
|| !this->my_auth
->is_mutual(this->my_auth
))
1425 DBG1(DBG_IKE
, "do not allow non-mutual EAP-only authentication");
1426 goto peer_auth_failed
;
1428 DBG1(DBG_IKE
, "allow mutual EAP-only authentication");
1431 if (!message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
))
1433 this->expect_another_auth
= FALSE
;
1435 if (this->expect_another_auth
|| this->do_another_auth
|| this->my_auth
)
1439 if (!update_cfg_candidates(this, TRUE
))
1441 goto peer_auth_failed
;
1443 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
1445 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, "
1447 goto peer_auth_failed
;
1449 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1450 this->ike_sa
->get_name(this->ike_sa
),
1451 this->ike_sa
->get_unique_id(this->ike_sa
),
1452 this->ike_sa
->get_my_host(this->ike_sa
),
1453 this->ike_sa
->get_my_id(this->ike_sa
),
1454 this->ike_sa
->get_other_host(this->ike_sa
),
1455 this->ike_sa
->get_other_id(this->ike_sa
));
1456 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
1457 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
1459 if (this->redirect_to
)
1461 this->ike_sa
->handle_redirect(this->ike_sa
, this->redirect_to
);
1466 charon
->bus
->alert(charon
->bus
, ALERT_PEER_AUTH_FAILED
);
1467 send_auth_failed_informational(this, message
);
1470 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
1471 send_auth_failed_informational(this, message
);
1475 METHOD(task_t
, get_type
, task_type_t
,
1476 private_ike_auth_t
*this)
1478 return TASK_IKE_AUTH
;
1481 METHOD(task_t
, migrate
, void,
1482 private_ike_auth_t
*this, ike_sa_t
*ike_sa
)
1485 chunk_free(&this->my_nonce
);
1486 chunk_free(&this->other_nonce
);
1487 DESTROY_IF(this->my_packet
);
1488 DESTROY_IF(this->other_packet
);
1489 DESTROY_IF(this->peer_cfg
);
1490 DESTROY_IF(this->my_auth
);
1491 DESTROY_IF(this->other_auth
);
1492 DESTROY_IF(this->redirect_to
);
1493 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
1495 this->my_packet
= NULL
;
1496 this->other_packet
= NULL
;
1497 this->ike_sa
= ike_sa
;
1498 this->peer_cfg
= NULL
;
1499 this->my_auth
= NULL
;
1500 this->other_auth
= NULL
;
1501 this->redirect_to
= NULL
;
1502 this->do_another_auth
= TRUE
;
1503 this->expect_another_auth
= TRUE
;
1504 this->authentication_failed
= FALSE
;
1505 this->candidates
= linked_list_create();
1508 METHOD(task_t
, destroy
, void,
1509 private_ike_auth_t
*this)
1512 chunk_free(&this->my_nonce
);
1513 chunk_free(&this->other_nonce
);
1514 DESTROY_IF(this->my_packet
);
1515 DESTROY_IF(this->other_packet
);
1516 DESTROY_IF(this->my_auth
);
1517 DESTROY_IF(this->other_auth
);
1518 DESTROY_IF(this->peer_cfg
);
1519 DESTROY_IF(this->redirect_to
);
1520 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
1525 * Described in header.
1527 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
, bool initiator
)
1529 private_ike_auth_t
*this;
1534 .get_type
= _get_type
,
1535 .migrate
= _migrate
,
1537 .process
= _process_r
,
1538 .destroy
= _destroy
,
1542 .initiator
= initiator
,
1543 .candidates
= linked_list_create(),
1544 .do_another_auth
= TRUE
,
1545 .expect_another_auth
= TRUE
,
1549 this->public.task
.build
= _build_i
;
1550 this->public.task
.process
= _process_i
;
1552 return &this->public;