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
);
335 DBG1(DBG_CFG
, "looking for peer configs matching %H[%Y]...%H[%Y]",
336 me
, my_id
, other
, other_id
);
337 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
338 me
, other
, my_id
, other_id
, IKEV2
);
339 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
341 /* ignore all configs that have no matching IKE proposal */
342 ike_cfg
= peer_cfg
->get_ike_cfg(peer_cfg
);
343 if (!ike_cfg
->has_proposal(ike_cfg
, ike_proposal
, private))
345 DBG2(DBG_CFG
, "ignore candidate '%s' without matching IKE proposal",
346 peer_cfg
->get_name(peer_cfg
));
349 peer_cfg
->get_ref(peer_cfg
);
352 this->peer_cfg
= peer_cfg
;
356 this->candidates
->insert_last(this->candidates
, peer_cfg
);
359 enumerator
->destroy(enumerator
);
362 this->ike_sa
->set_peer_cfg(this->ike_sa
, this->peer_cfg
);
363 DBG1(DBG_CFG
, "selected peer config '%s'",
364 this->peer_cfg
->get_name(this->peer_cfg
));
367 DBG1(DBG_CFG
, "no matching peer config found");
372 * update the current peer candidate if necessary, using candidates
374 static bool update_cfg_candidates(private_ike_auth_t
*this, bool strict
)
380 char *comply_error
= NULL
;
381 enumerator_t
*e1
, *e2
, *tmp
;
384 e1
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, FALSE
);
385 e2
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, FALSE
);
388 { /* swap lists in strict mode: all configured rounds must be
389 * fulfilled. If !strict, we check only the rounds done so far. */
394 while (e1
->enumerate(e1
, &c1
))
396 /* check if done authentications comply to configured ones */
397 if (!e2
->enumerate(e2
, &c2
))
399 comply_error
= "insufficient authentication rounds";
402 if (!strict
&& !c1
->complies(c1
, c2
, TRUE
))
404 comply_error
= "non-matching authentication done";
407 if (strict
&& !c2
->complies(c2
, c1
, TRUE
))
409 comply_error
= "constraint checking failed";
419 DBG1(DBG_CFG
, "selected peer config '%s' unacceptable: %s",
420 this->peer_cfg
->get_name(this->peer_cfg
), comply_error
);
421 this->peer_cfg
->destroy(this->peer_cfg
);
423 if (this->candidates
->remove_first(this->candidates
,
424 (void**)&this->peer_cfg
) != SUCCESS
)
426 DBG1(DBG_CFG
, "no alternative config found");
427 this->peer_cfg
= NULL
;
431 DBG1(DBG_CFG
, "switching to peer config '%s'",
432 this->peer_cfg
->get_name(this->peer_cfg
));
433 this->ike_sa
->set_peer_cfg(this->ike_sa
, this->peer_cfg
);
436 while (this->peer_cfg
);
438 return this->peer_cfg
!= NULL
;
442 * Currently defined PPK_ID types
444 #define PPK_ID_OPAQUE 1
445 #define PPK_ID_FIXED 2
448 * Parse the payload data of the given PPK_IDENTITY notify
450 static bool parse_ppk_identity(notify_payload_t
*notify
, identification_t
**id
)
454 data
= notify
->get_notification_data(notify
);
462 data
= chunk_skip(data
, 1);
467 *id
= identification_create_from_data(data
);
472 * Add a PPK_IDENTITY with the given PPK_ID to the given message
474 static void add_ppk_identity(identification_t
*id
, message_t
*msg
)
477 uint8_t type
= PPK_ID_FIXED
;
479 /* we currently only support one type */
480 data
= chunk_cata("cc", chunk_from_thing(type
), id
->get_encoding(id
));
481 msg
->add_notify(msg
, FALSE
, PPK_IDENTITY
, data
);
485 * Use the given PPK_ID to find a PPK and store it and the ID in the task
487 static bool get_ppk(private_ike_auth_t
*this, identification_t
*ppk_id
)
491 key
= lib
->credmgr
->get_shared(lib
->credmgr
, SHARED_PPK
, ppk_id
, NULL
);
494 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
496 DBG1(DBG_CFG
, "PPK required but no PPK found for '%Y'", ppk_id
);
499 DBG1(DBG_CFG
, "no PPK for '%Y' found, ignored because PPK is not "
503 this->ppk
= chunk_clone(key
->get_key(key
));
504 this->ppk_id
= ppk_id
->clone(ppk_id
);
510 * Check if we have a PPK available and, if not, whether we require one as
513 static bool get_ppk_i(private_ike_auth_t
*this)
515 identification_t
*ppk_id
;
517 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_PPK
))
519 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
521 DBG1(DBG_CFG
, "PPK required but peer does not support PPK");
527 ppk_id
= this->peer_cfg
->get_ppk_id(this->peer_cfg
);
530 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
532 DBG1(DBG_CFG
, "PPK required but no PPK_ID configured");
537 return get_ppk(this, ppk_id
);
541 * Check if we have a PPK available and if not whether we require one as
544 static bool get_ppk_r(private_ike_auth_t
*this, message_t
*msg
)
546 notify_payload_t
*notify
;
547 identification_t
*ppk_id
, *ppk_id_cfg
;
550 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_PPK
))
552 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
554 DBG1(DBG_CFG
, "PPK required but peer does not support PPK");
560 notify
= msg
->get_notify(msg
, PPK_IDENTITY
);
561 if (!notify
|| !parse_ppk_identity(notify
, &ppk_id
))
563 if (this->peer_cfg
->ppk_required(this->peer_cfg
))
565 DBG1(DBG_CFG
, "PPK required but no PPK_IDENTITY received");
571 ppk_id_cfg
= this->peer_cfg
->get_ppk_id(this->peer_cfg
);
572 if (ppk_id_cfg
&& !ppk_id
->matches(ppk_id
, ppk_id_cfg
))
574 DBG1(DBG_CFG
, "received PPK_ID '%Y', but require '%Y'", ppk_id
,
576 ppk_id
->destroy(ppk_id
);
579 result
= get_ppk(this, ppk_id
);
580 ppk_id
->destroy(ppk_id
);
584 METHOD(task_t
, build_i
, status_t
,
585 private_ike_auth_t
*this, message_t
*message
)
589 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
591 return collect_my_init_data(this, message
);
596 this->peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
597 this->peer_cfg
->get_ref(this->peer_cfg
);
600 if (message
->get_message_id(message
) == 1)
601 { /* in the first IKE_AUTH ... */
602 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
603 { /* indicate support for multiple authentication */
604 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
607 /* indicate support for EAP-only authentication */
608 message
->add_notify(message
, FALSE
, EAP_ONLY_AUTHENTICATION
,
610 /* indicate support for RFC 6311 Message ID synchronization */
611 message
->add_notify(message
, FALSE
, IKEV2_MESSAGE_ID_SYNC_SUPPORTED
,
613 /* only use a PPK in the first round */
614 if (!get_ppk_i(this))
616 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
621 if (!this->do_another_auth
&& !this->my_auth
)
622 { /* we have done our rounds */
626 /* check if an authenticator is in progress */
629 identification_t
*idi
, *idr
= NULL
;
630 id_payload_t
*id_payload
;
632 /* clean up authentication config from a previous round */
633 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
634 cfg
->purge(cfg
, TRUE
);
636 /* add (optional) IDr */
637 cfg
= get_auth_cfg(this, FALSE
);
640 idr
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
641 if (!cfg
->get(cfg
, AUTH_RULE_IDENTITY_LOOSE
) && idr
&&
642 !idr
->contains_wildcards(idr
))
644 this->ike_sa
->set_other_id(this->ike_sa
, idr
->clone(idr
));
645 id_payload
= id_payload_create_from_identification(
646 PLV2_ID_RESPONDER
, idr
);
647 message
->add_payload(message
, (payload_t
*)id_payload
);
651 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
652 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
653 idi
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
654 if (!idi
|| idi
->get_type(idi
) == ID_ANY
)
655 { /* ID_ANY is invalid as IDi, use local IP address instead */
658 DBG1(DBG_CFG
, "no IDi configured, fall back on IP address");
659 me
= this->ike_sa
->get_my_host(this->ike_sa
);
660 idi
= identification_create_from_sockaddr(me
->get_sockaddr(me
));
661 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, idi
);
663 this->ike_sa
->set_my_id(this->ike_sa
, idi
->clone(idi
));
664 id_payload
= id_payload_create_from_identification(PLV2_ID_INITIATOR
, idi
);
665 get_reserved_id_bytes(this, id_payload
);
666 message
->add_payload(message
, (payload_t
*)id_payload
);
668 if (idr
&& !idr
->contains_wildcards(idr
) &&
669 message
->get_message_id(message
) == 1 &&
670 this->peer_cfg
->get_unique_policy(this->peer_cfg
) != UNIQUE_NEVER
)
674 host
= this->ike_sa
->get_other_host(this->ike_sa
);
675 if (!charon
->ike_sa_manager
->has_contact(charon
->ike_sa_manager
,
676 idi
, idr
, host
->get_family(host
)))
678 message
->add_notify(message
, FALSE
, INITIAL_CONTACT
, chunk_empty
);
682 /* build authentication data */
683 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
684 this->other_nonce
, this->my_nonce
,
685 this->other_packet
->get_data(this->other_packet
),
686 this->my_packet
->get_data(this->my_packet
),
690 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
694 /* for authentication methods that return NEED_MORE, the PPK will be reset
695 * in process_i() for messages without PPK_ID notify, so we always set it
696 * during the first round (afterwards the PPK won't be available) */
697 if (this->ppk
.ptr
&& this->my_auth
->use_ppk
)
699 this->my_auth
->use_ppk(this->my_auth
, this->ppk
,
700 !this->peer_cfg
->ppk_required(this->peer_cfg
));
702 switch (this->my_auth
->build(this->my_auth
, message
))
705 apply_auth_cfg(this, TRUE
);
706 this->my_auth
->destroy(this->my_auth
);
707 this->my_auth
= NULL
;
712 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
716 /* add a PPK_IDENTITY notify to the message that contains AUTH */
717 if (this->ppk_id
&& message
->get_payload(message
, PLV2_AUTH
))
719 add_ppk_identity(this->ppk_id
, message
);
722 /* check for additional authentication rounds */
723 if (do_another_auth(this))
725 if (message
->get_payload(message
, PLV2_AUTH
))
727 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
732 this->do_another_auth
= FALSE
;
737 METHOD(task_t
, process_r
, status_t
,
738 private_ike_auth_t
*this, message_t
*message
)
740 auth_cfg_t
*cfg
, *cand
;
741 id_payload_t
*id_payload
;
742 identification_t
*id
;
744 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
746 return collect_other_init_data(this, message
);
749 if (!this->my_auth
&& this->do_another_auth
)
751 /* handle (optional) IDr payload, apply proposed identity */
752 id_payload
= (id_payload_t
*)message
->get_payload(message
, PLV2_ID_RESPONDER
);
755 id
= id_payload
->get_identification(id_payload
);
759 id
= identification_create_from_encoding(ID_ANY
, chunk_empty
);
761 this->ike_sa
->set_my_id(this->ike_sa
, id
);
764 if (!this->expect_another_auth
)
769 if (message
->get_message_id(message
) == 1)
770 { /* check for extensions in the first IKE_AUTH */
771 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
))
773 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
775 if (message
->get_notify(message
, EAP_ONLY_AUTHENTICATION
))
777 this->ike_sa
->enable_extension(this->ike_sa
,
778 EXT_EAP_ONLY_AUTHENTICATION
);
780 if (message
->get_notify(message
, INITIAL_CONTACT
))
782 this->initial_contact
= TRUE
;
786 if (!this->other_auth
)
788 /* handle IDi payload */
789 id_payload
= (id_payload_t
*)message
->get_payload(message
, PLV2_ID_INITIATOR
);
792 DBG1(DBG_IKE
, "IDi payload missing");
795 id
= id_payload
->get_identification(id_payload
);
796 get_reserved_id_bytes(this, id_payload
);
797 this->ike_sa
->set_other_id(this->ike_sa
, id
);
798 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
799 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
803 if (!load_cfg_candidates(this))
805 this->authentication_failed
= TRUE
;
809 if (!message
->get_payload(message
, PLV2_AUTH
))
810 { /* before authenticating with EAP, we need a EAP config */
811 cand
= get_auth_cfg(this, FALSE
);
813 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_TYPE
) == EAP_NAK
&&
814 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_VENDOR
) == 0))
815 { /* peer requested EAP, but current config does not match */
816 DBG1(DBG_IKE
, "peer requested EAP, config unacceptable");
817 this->peer_cfg
->destroy(this->peer_cfg
);
818 this->peer_cfg
= NULL
;
819 if (!update_cfg_candidates(this, FALSE
))
821 this->authentication_failed
= TRUE
;
824 cand
= get_auth_cfg(this, FALSE
);
826 /* copy over the EAP specific rules for authentication */
827 cfg
->add(cfg
, AUTH_RULE_EAP_TYPE
,
828 cand
->get(cand
, AUTH_RULE_EAP_TYPE
));
829 cfg
->add(cfg
, AUTH_RULE_EAP_VENDOR
,
830 cand
->get(cand
, AUTH_RULE_EAP_VENDOR
));
831 id
= (identification_t
*)cand
->get(cand
, AUTH_RULE_EAP_IDENTITY
);
834 cfg
->add(cfg
, AUTH_RULE_EAP_IDENTITY
, id
->clone(id
));
836 id
= (identification_t
*)cand
->get(cand
, AUTH_RULE_AAA_IDENTITY
);
839 cfg
->add(cfg
, AUTH_RULE_AAA_IDENTITY
, id
->clone(id
));
843 /* verify authentication data */
844 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
845 message
, this->other_nonce
, this->my_nonce
,
846 this->other_packet
->get_data(this->other_packet
),
847 this->my_packet
->get_data(this->my_packet
),
849 if (!this->other_auth
)
851 this->authentication_failed
= TRUE
;
855 if (message
->get_payload(message
, PLV2_AUTH
) &&
856 is_first_round(this, FALSE
))
858 if (!get_ppk_r(this, message
))
860 this->authentication_failed
= TRUE
;
863 else if (this->ppk
.ptr
&& this->other_auth
->use_ppk
)
865 this->other_auth
->use_ppk(this->other_auth
, this->ppk
, FALSE
);
868 switch (this->other_auth
->process(this->other_auth
, message
))
871 this->other_auth
->destroy(this->other_auth
);
872 this->other_auth
= NULL
;
875 if (message
->get_payload(message
, PLV2_AUTH
))
876 { /* AUTH verification successful, but another build() needed */
881 this->authentication_failed
= TRUE
;
885 /* another auth round done, invoke authorize hook */
886 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
888 DBG1(DBG_IKE
, "authorization hook forbids IKE_SA, cancelling");
889 this->authentication_failed
= TRUE
;
893 apply_auth_cfg(this, FALSE
);
895 if (!update_cfg_candidates(this, FALSE
))
897 this->authentication_failed
= TRUE
;
901 if (!message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
))
903 this->expect_another_auth
= FALSE
;
904 if (!update_cfg_candidates(this, TRUE
))
906 this->authentication_failed
= TRUE
;
914 * Clear the PPK and PPK_ID
916 static void clear_ppk(private_ike_auth_t
*this)
918 DESTROY_IF(this->ppk_id
);
920 chunk_clear(&this->ppk
);
924 * Derive new keys and clear the PPK
926 static bool apply_ppk(private_ike_auth_t
*this)
932 keymat
= (keymat_v2_t
*)this->ike_sa
->get_keymat(this->ike_sa
);
933 if (!keymat
->derive_ike_keys_ppk(keymat
, this->ppk
))
937 DBG1(DBG_CFG
, "using PPK for PPK_ID '%Y'", this->ppk_id
);
938 this->ike_sa
->set_condition(this->ike_sa
, COND_PPK
, TRUE
);
944 METHOD(task_t
, build_r
, status_t
,
945 private_ike_auth_t
*this, message_t
*message
)
947 identification_t
*gateway
;
950 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
952 if (multiple_auth_enabled())
954 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
957 return collect_my_init_data(this, message
);
960 if (this->authentication_failed
|| !this->peer_cfg
)
962 goto peer_auth_failed
;
965 if (!this->my_auth
&& this->do_another_auth
)
967 identification_t
*id
, *id_cfg
;
968 id_payload_t
*id_payload
;
971 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
972 cfg
->purge(cfg
, TRUE
);
973 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
975 id_cfg
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
976 id
= this->ike_sa
->get_my_id(this->ike_sa
);
977 if (id
->get_type(id
) == ID_ANY
)
978 { /* no IDr received, apply configured ID */
979 if (!id_cfg
|| id_cfg
->contains_wildcards(id_cfg
))
980 { /* no ID configured, use local IP address */
983 DBG1(DBG_CFG
, "no IDr configured, fall back on IP address");
984 me
= this->ike_sa
->get_my_host(this->ike_sa
);
985 id_cfg
= identification_create_from_sockaddr(
986 me
->get_sockaddr(me
));
987 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id_cfg
);
989 this->ike_sa
->set_my_id(this->ike_sa
, id_cfg
->clone(id_cfg
));
993 { /* IDr received, check if it matches configuration */
994 if (id_cfg
&& !id
->matches(id
, id_cfg
))
996 DBG1(DBG_CFG
, "received IDr %Y, but require %Y", id
, id_cfg
);
997 goto peer_auth_failed
;
1001 id_payload
= id_payload_create_from_identification(PLV2_ID_RESPONDER
, id
);
1002 get_reserved_id_bytes(this, id_payload
);
1003 message
->add_payload(message
, (payload_t
*)id_payload
);
1005 if ((uintptr_t)cfg
->get(cfg
, AUTH_RULE_AUTH_CLASS
) == AUTH_CLASS_EAP
)
1006 { /* EAP-only authentication */
1007 if (!this->ike_sa
->supports_extension(this->ike_sa
,
1008 EXT_EAP_ONLY_AUTHENTICATION
))
1010 DBG1(DBG_IKE
, "configured EAP-only authentication, but peer "
1011 "does not support it");
1012 goto peer_auth_failed
;
1017 /* build authentication data */
1018 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
1019 this->other_nonce
, this->my_nonce
,
1020 this->other_packet
->get_data(this->other_packet
),
1021 this->my_packet
->get_data(this->my_packet
),
1025 goto local_auth_failed
;
1030 if (this->other_auth
)
1032 switch (this->other_auth
->build(this->other_auth
, message
))
1035 this->other_auth
->destroy(this->other_auth
);
1036 this->other_auth
= NULL
;
1041 if (message
->get_payload(message
, PLV2_EAP
))
1042 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
1043 goto peer_auth_failed_no_notify
;
1045 goto peer_auth_failed
;
1050 if (this->ppk
.ptr
&& this->my_auth
->use_ppk
)
1052 this->my_auth
->use_ppk(this->my_auth
, this->ppk
, FALSE
);
1054 switch (this->my_auth
->build(this->my_auth
, message
))
1057 apply_auth_cfg(this, TRUE
);
1058 this->my_auth
->destroy(this->my_auth
);
1059 this->my_auth
= NULL
;
1064 goto local_auth_failed
;
1068 /* add a PPK_IDENTITY notify and derive new keys and clear the PPK */
1071 message
->add_notify(message
, FALSE
, PPK_IDENTITY
, chunk_empty
);
1072 if (!apply_ppk(this))
1074 goto local_auth_failed
;
1078 /* check for additional authentication rounds */
1079 if (do_another_auth(this))
1081 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
1085 this->do_another_auth
= FALSE
;
1087 if (this->do_another_auth
|| this->expect_another_auth
)
1092 if (charon
->ike_sa_manager
->check_uniqueness(charon
->ike_sa_manager
,
1093 this->ike_sa
, this->initial_contact
))
1095 DBG1(DBG_IKE
, "cancelling IKE_SA setup due to uniqueness policy");
1096 charon
->bus
->alert(charon
->bus
, ALERT_UNIQUE_KEEP
);
1097 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
1101 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
1103 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, cancelling");
1104 goto peer_auth_failed
;
1106 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_IKE_REDIRECTION
) &&
1107 charon
->redirect
->redirect_on_auth(charon
->redirect
, this->ike_sa
,
1110 delete_ike_sa_job_t
*job
;
1113 DBG1(DBG_IKE
, "redirecting peer to %Y", gateway
);
1114 data
= redirect_data_create(gateway
, chunk_empty
);
1115 message
->add_notify(message
, FALSE
, REDIRECT
, data
);
1116 gateway
->destroy(gateway
);
1118 /* we use this condition to prevent the CHILD_SA from getting created */
1119 this->ike_sa
->set_condition(this->ike_sa
, COND_REDIRECTED
, TRUE
);
1120 /* if the peer does not delete the SA we do so after a while */
1121 job
= delete_ike_sa_job_create(this->ike_sa
->get_id(this->ike_sa
), TRUE
);
1122 lib
->scheduler
->schedule_job(lib
->scheduler
, (job_t
*)job
,
1123 lib
->settings
->get_int(lib
->settings
,
1124 "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT
,
1127 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1128 this->ike_sa
->get_name(this->ike_sa
),
1129 this->ike_sa
->get_unique_id(this->ike_sa
),
1130 this->ike_sa
->get_my_host(this->ike_sa
),
1131 this->ike_sa
->get_my_id(this->ike_sa
),
1132 this->ike_sa
->get_other_host(this->ike_sa
),
1133 this->ike_sa
->get_other_id(this->ike_sa
));
1134 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
1135 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
1139 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
1140 peer_auth_failed_no_notify
:
1141 charon
->bus
->alert(charon
->bus
, ALERT_PEER_AUTH_FAILED
);
1144 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
1145 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
1150 * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA
1152 static void send_auth_failed_informational(private_ike_auth_t
*this,
1159 message
= message_create(IKEV2_MAJOR_VERSION
, IKEV2_MINOR_VERSION
);
1160 message
->set_message_id(message
, reply
->get_message_id(reply
) + 1);
1161 host
= this->ike_sa
->get_my_host(this->ike_sa
);
1162 message
->set_source(message
, host
->clone(host
));
1163 host
= this->ike_sa
->get_other_host(this->ike_sa
);
1164 message
->set_destination(message
, host
->clone(host
));
1165 message
->set_exchange_type(message
, INFORMATIONAL
);
1166 message
->add_notify(message
, FALSE
, AUTHENTICATION_FAILED
, chunk_empty
);
1168 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
1169 &packet
) == SUCCESS
)
1171 charon
->sender
->send(charon
->sender
, packet
);
1173 message
->destroy(message
);
1177 * Check if strict constraint fulfillment required to continue current auth
1179 static bool require_strict(private_ike_auth_t
*this, bool mutual_eap
)
1183 if (this->eap_acceptable
)
1188 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
1189 switch ((uintptr_t)cfg
->get(cfg
, AUTH_RULE_AUTH_CLASS
))
1191 case AUTH_CLASS_EAP
:
1192 if (mutual_eap
&& this->my_auth
)
1194 this->eap_acceptable
= TRUE
;
1195 return !this->my_auth
->is_mutual(this->my_auth
);
1198 case AUTH_CLASS_PSK
:
1200 case AUTH_CLASS_PUBKEY
:
1201 case AUTH_CLASS_ANY
:
1207 METHOD(task_t
, process_i
, status_t
,
1208 private_ike_auth_t
*this, message_t
*message
)
1210 enumerator_t
*enumerator
;
1213 bool mutual_eap
= FALSE
, ppk_id_received
= FALSE
;
1215 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
1217 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
) &&
1218 multiple_auth_enabled())
1220 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
1222 return collect_other_init_data(this, message
);
1225 enumerator
= message
->create_payload_enumerator(message
);
1226 while (enumerator
->enumerate(enumerator
, &payload
))
1228 if (payload
->get_type(payload
) == PLV2_NOTIFY
)
1230 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1231 notify_type_t type
= notify
->get_notify_type(notify
);
1235 case NO_PROPOSAL_CHOSEN
:
1236 case SINGLE_PAIR_REQUIRED
:
1237 case NO_ADDITIONAL_SAS
:
1238 case INTERNAL_ADDRESS_FAILURE
:
1239 case FAILED_CP_REQUIRED
:
1240 case TS_UNACCEPTABLE
:
1241 case INVALID_SELECTORS
:
1242 /* these are errors, but are not critical as only the
1243 * CHILD_SA won't get build, but IKE_SA establishes anyway */
1245 case MOBIKE_SUPPORTED
:
1246 case ADDITIONAL_IP4_ADDRESS
:
1247 case ADDITIONAL_IP6_ADDRESS
:
1248 /* handled in ike_mobike task */
1251 /* handled in ike_auth_lifetime task */
1254 /* handled in ike_me task */
1257 DESTROY_IF(this->redirect_to
);
1258 this->redirect_to
= redirect_data_parse(
1259 notify
->get_notification_data(notify
), NULL
);
1260 if (!this->redirect_to
)
1262 DBG1(DBG_IKE
, "received invalid REDIRECT notify");
1265 case IKEV2_MESSAGE_ID_SYNC_SUPPORTED
:
1266 this->ike_sa
->enable_extension(this->ike_sa
,
1267 EXT_IKE_MESSAGE_ID_SYNC
);
1270 ppk_id_received
= TRUE
;
1276 DBG1(DBG_IKE
, "received %N notify error",
1277 notify_type_names
, type
);
1278 enumerator
->destroy(enumerator
);
1279 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
1282 DBG2(DBG_IKE
, "received %N notify",
1283 notify_type_names
, type
);
1289 enumerator
->destroy(enumerator
);
1291 if (this->expect_another_auth
)
1293 if (!this->other_auth
)
1295 id_payload_t
*id_payload
;
1296 identification_t
*id
;
1298 /* handle IDr payload */
1299 id_payload
= (id_payload_t
*)message
->get_payload(message
,
1303 DBG1(DBG_IKE
, "IDr payload missing");
1304 goto peer_auth_failed
;
1306 id
= id_payload
->get_identification(id_payload
);
1307 get_reserved_id_bytes(this, id_payload
);
1308 this->ike_sa
->set_other_id(this->ike_sa
, id
);
1309 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
1310 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
1312 if (message
->get_payload(message
, PLV2_AUTH
))
1314 /* verify authentication data */
1315 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
1316 message
, this->other_nonce
, this->my_nonce
,
1317 this->other_packet
->get_data(this->other_packet
),
1318 this->my_packet
->get_data(this->my_packet
),
1320 if (!this->other_auth
)
1322 goto peer_auth_failed
;
1327 /* responder omitted AUTH payload, indicating EAP-only */
1331 if (this->other_auth
)
1333 if (ppk_id_received
&& is_first_round(this, FALSE
) &&
1334 this->other_auth
->use_ppk
)
1336 this->other_auth
->use_ppk(this->other_auth
, this->ppk
, FALSE
);
1338 switch (this->other_auth
->process(this->other_auth
, message
))
1345 goto peer_auth_failed
;
1347 this->other_auth
->destroy(this->other_auth
);
1348 this->other_auth
= NULL
;
1350 /* another auth round done, invoke authorize hook */
1351 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
1353 DBG1(DBG_IKE
, "authorization forbids IKE_SA, cancelling");
1354 goto peer_auth_failed
;
1359 apply_auth_cfg(this, FALSE
);
1363 if (require_strict(this, mutual_eap
))
1365 if (!update_cfg_candidates(this, TRUE
))
1367 goto peer_auth_failed
;
1373 /* while we already set the PPK in build_i(), we MUST not use it if
1374 * the peer did not reply with a PPK_ID notify */
1375 if (this->ppk
.ptr
&& this->my_auth
->use_ppk
)
1377 this->my_auth
->use_ppk(this->my_auth
,
1378 ppk_id_received
? this->ppk
: chunk_empty
,
1381 switch (this->my_auth
->process(this->my_auth
, message
))
1384 apply_auth_cfg(this, TRUE
);
1385 if (this->my_auth
->is_mutual(this->my_auth
))
1387 apply_auth_cfg(this, FALSE
);
1389 this->my_auth
->destroy(this->my_auth
);
1390 this->my_auth
= NULL
;
1391 this->do_another_auth
= do_another_auth(this);
1396 goto local_auth_failed
;
1400 /* change keys and clear PPK after we are done with our authentication, so
1401 * we only explicitly use it for the first round, afterwards we just use the
1402 * changed SK_p keys implicitly */
1403 if (!this->my_auth
&& this->ppk_id
)
1405 if (ppk_id_received
)
1407 if (!apply_ppk(this))
1409 goto local_auth_failed
;
1414 DBG1(DBG_CFG
, "peer didn't use PPK for PPK_ID '%Y'", this->ppk_id
);
1421 if (!this->my_auth
|| !this->my_auth
->is_mutual(this->my_auth
))
1423 DBG1(DBG_IKE
, "do not allow non-mutual EAP-only authentication");
1424 goto peer_auth_failed
;
1426 DBG1(DBG_IKE
, "allow mutual EAP-only authentication");
1429 if (!message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
))
1431 this->expect_another_auth
= FALSE
;
1433 if (this->expect_another_auth
|| this->do_another_auth
|| this->my_auth
)
1437 if (!update_cfg_candidates(this, TRUE
))
1439 goto peer_auth_failed
;
1441 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
1443 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, "
1445 goto peer_auth_failed
;
1447 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1448 this->ike_sa
->get_name(this->ike_sa
),
1449 this->ike_sa
->get_unique_id(this->ike_sa
),
1450 this->ike_sa
->get_my_host(this->ike_sa
),
1451 this->ike_sa
->get_my_id(this->ike_sa
),
1452 this->ike_sa
->get_other_host(this->ike_sa
),
1453 this->ike_sa
->get_other_id(this->ike_sa
));
1454 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
1455 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
1457 if (this->redirect_to
)
1459 this->ike_sa
->handle_redirect(this->ike_sa
, this->redirect_to
);
1464 charon
->bus
->alert(charon
->bus
, ALERT_PEER_AUTH_FAILED
);
1465 send_auth_failed_informational(this, message
);
1468 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
1469 send_auth_failed_informational(this, message
);
1473 METHOD(task_t
, get_type
, task_type_t
,
1474 private_ike_auth_t
*this)
1476 return TASK_IKE_AUTH
;
1479 METHOD(task_t
, migrate
, void,
1480 private_ike_auth_t
*this, ike_sa_t
*ike_sa
)
1483 chunk_free(&this->my_nonce
);
1484 chunk_free(&this->other_nonce
);
1485 DESTROY_IF(this->my_packet
);
1486 DESTROY_IF(this->other_packet
);
1487 DESTROY_IF(this->peer_cfg
);
1488 DESTROY_IF(this->my_auth
);
1489 DESTROY_IF(this->other_auth
);
1490 DESTROY_IF(this->redirect_to
);
1491 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
1493 this->my_packet
= NULL
;
1494 this->other_packet
= NULL
;
1495 this->ike_sa
= ike_sa
;
1496 this->peer_cfg
= NULL
;
1497 this->my_auth
= NULL
;
1498 this->other_auth
= NULL
;
1499 this->redirect_to
= NULL
;
1500 this->do_another_auth
= TRUE
;
1501 this->expect_another_auth
= TRUE
;
1502 this->authentication_failed
= FALSE
;
1503 this->candidates
= linked_list_create();
1506 METHOD(task_t
, destroy
, void,
1507 private_ike_auth_t
*this)
1510 chunk_free(&this->my_nonce
);
1511 chunk_free(&this->other_nonce
);
1512 DESTROY_IF(this->my_packet
);
1513 DESTROY_IF(this->other_packet
);
1514 DESTROY_IF(this->my_auth
);
1515 DESTROY_IF(this->other_auth
);
1516 DESTROY_IF(this->peer_cfg
);
1517 DESTROY_IF(this->redirect_to
);
1518 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
1523 * Described in header.
1525 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
, bool initiator
)
1527 private_ike_auth_t
*this;
1532 .get_type
= _get_type
,
1533 .migrate
= _migrate
,
1535 .process
= _process_r
,
1536 .destroy
= _destroy
,
1540 .initiator
= initiator
,
1541 .candidates
= linked_list_create(),
1542 .do_another_auth
= TRUE
,
1543 .expect_another_auth
= TRUE
,
1547 this->public.task
.build
= _build_i
;
1548 this->public.task
.process
= _process_i
;
1550 return &this->public;