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
, charon
->name
);
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 * Check if we have should initiate another authentication round
228 static bool do_another_auth(private_ike_auth_t
*this)
230 bool do_another
= FALSE
;
231 enumerator_t
*done
, *todo
;
232 auth_cfg_t
*done_cfg
, *todo_cfg
;
234 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
239 done
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, TRUE
);
240 todo
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, TRUE
);
241 while (todo
->enumerate(todo
, &todo_cfg
))
243 if (!done
->enumerate(done
, &done_cfg
))
245 done_cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
247 if (!done_cfg
->complies(done_cfg
, todo_cfg
, FALSE
))
259 * Get peer configuration candidates from backends
261 static bool load_cfg_candidates(private_ike_auth_t
*this)
263 enumerator_t
*enumerator
;
264 peer_cfg_t
*peer_cfg
;
266 identification_t
*my_id
, *other_id
;
268 me
= this->ike_sa
->get_my_host(this->ike_sa
);
269 other
= this->ike_sa
->get_other_host(this->ike_sa
);
270 my_id
= this->ike_sa
->get_my_id(this->ike_sa
);
271 other_id
= this->ike_sa
->get_other_id(this->ike_sa
);
273 DBG1(DBG_CFG
, "looking for peer configs matching %H[%Y]...%H[%Y]",
274 me
, my_id
, other
, other_id
);
275 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
276 me
, other
, my_id
, other_id
, IKEV2
);
277 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
279 peer_cfg
->get_ref(peer_cfg
);
280 if (this->peer_cfg
== NULL
)
282 this->peer_cfg
= peer_cfg
;
283 this->ike_sa
->set_peer_cfg(this->ike_sa
, peer_cfg
);
287 this->candidates
->insert_last(this->candidates
, peer_cfg
);
290 enumerator
->destroy(enumerator
);
293 DBG1(DBG_CFG
, "selected peer config '%s'",
294 this->peer_cfg
->get_name(this->peer_cfg
));
297 DBG1(DBG_CFG
, "no matching peer config found");
302 * update the current peer candidate if necessary, using candidates
304 static bool update_cfg_candidates(private_ike_auth_t
*this, bool strict
)
310 bool complies
= TRUE
;
311 enumerator_t
*e1
, *e2
, *tmp
;
314 e1
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, FALSE
);
315 e2
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, FALSE
);
318 { /* swap lists in strict mode: all configured rounds must be
319 * fulfilled. If !strict, we check only the rounds done so far. */
324 while (e1
->enumerate(e1
, &c1
))
326 /* check if done authentications comply to configured ones */
327 if ((!e2
->enumerate(e2
, &c2
)) ||
328 (!strict
&& !c1
->complies(c1
, c2
, TRUE
)) ||
329 (strict
&& !c2
->complies(c2
, c1
, TRUE
)))
341 DBG1(DBG_CFG
, "selected peer config '%s' inacceptable",
342 this->peer_cfg
->get_name(this->peer_cfg
));
343 this->peer_cfg
->destroy(this->peer_cfg
);
345 if (this->candidates
->remove_first(this->candidates
,
346 (void**)&this->peer_cfg
) != SUCCESS
)
348 DBG1(DBG_CFG
, "no alternative config found");
349 this->peer_cfg
= NULL
;
353 DBG1(DBG_CFG
, "switching to peer config '%s'",
354 this->peer_cfg
->get_name(this->peer_cfg
));
355 this->ike_sa
->set_peer_cfg(this->ike_sa
, this->peer_cfg
);
358 while (this->peer_cfg
);
360 return this->peer_cfg
!= NULL
;
363 METHOD(task_t
, build_i
, status_t
,
364 private_ike_auth_t
*this, message_t
*message
)
368 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
370 return collect_my_init_data(this, message
);
373 if (this->peer_cfg
== NULL
)
375 this->peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
376 this->peer_cfg
->get_ref(this->peer_cfg
);
379 if (message
->get_message_id(message
) == 1)
380 { /* in the first IKE_AUTH ... */
381 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
382 { /* indicate support for multiple authentication */
383 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
386 /* indicate support for EAP-only authentication */
387 message
->add_notify(message
, FALSE
, EAP_ONLY_AUTHENTICATION
,
391 if (!this->do_another_auth
&& !this->my_auth
)
392 { /* we have done our rounds */
396 /* check if an authenticator is in progress */
397 if (this->my_auth
== NULL
)
399 identification_t
*idi
, *idr
= NULL
;
400 id_payload_t
*id_payload
;
402 /* clean up authentication config from a previous round */
403 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
404 cfg
->purge(cfg
, TRUE
);
406 /* add (optional) IDr */
407 cfg
= get_auth_cfg(this, FALSE
);
410 idr
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
411 if (!cfg
->get(cfg
, AUTH_RULE_IDENTITY_LOOSE
) && idr
&&
412 !idr
->contains_wildcards(idr
))
414 this->ike_sa
->set_other_id(this->ike_sa
, idr
->clone(idr
));
415 id_payload
= id_payload_create_from_identification(
417 message
->add_payload(message
, (payload_t
*)id_payload
);
421 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
422 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
423 idi
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
424 if (!idi
|| idi
->get_type(idi
) == ID_ANY
)
425 { /* ID_ANY is invalid as IDi, use local IP address instead */
428 DBG1(DBG_CFG
, "no IDi configured, fall back on IP address");
429 me
= this->ike_sa
->get_my_host(this->ike_sa
);
430 idi
= identification_create_from_sockaddr(me
->get_sockaddr(me
));
431 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, idi
);
433 this->ike_sa
->set_my_id(this->ike_sa
, idi
->clone(idi
));
434 id_payload
= id_payload_create_from_identification(ID_INITIATOR
, idi
);
435 get_reserved_id_bytes(this, id_payload
);
436 message
->add_payload(message
, (payload_t
*)id_payload
);
438 if (idr
&& message
->get_message_id(message
) == 1 &&
439 this->peer_cfg
->get_unique_policy(this->peer_cfg
) != UNIQUE_NO
&&
440 this->peer_cfg
->get_unique_policy(this->peer_cfg
) != UNIQUE_NEVER
)
444 host
= this->ike_sa
->get_other_host(this->ike_sa
);
445 if (!charon
->ike_sa_manager
->has_contact(charon
->ike_sa_manager
,
446 idi
, idr
, host
->get_family(host
)))
448 message
->add_notify(message
, FALSE
, INITIAL_CONTACT
, chunk_empty
);
452 /* build authentication data */
453 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
454 this->other_nonce
, this->my_nonce
,
455 this->other_packet
->get_data(this->other_packet
),
456 this->my_packet
->get_data(this->my_packet
),
460 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
464 switch (this->my_auth
->build(this->my_auth
, message
))
467 /* authentication step complete, reset authenticator */
468 cfg
= auth_cfg_create();
469 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
), TRUE
);
470 this->ike_sa
->add_auth_cfg(this->ike_sa
, TRUE
, cfg
);
471 this->my_auth
->destroy(this->my_auth
);
472 this->my_auth
= NULL
;
477 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
481 /* check for additional authentication rounds */
482 if (do_another_auth(this))
484 if (message
->get_payload(message
, AUTHENTICATION
))
486 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
491 this->do_another_auth
= FALSE
;
496 METHOD(task_t
, process_r
, status_t
,
497 private_ike_auth_t
*this, message_t
*message
)
499 auth_cfg_t
*cfg
, *cand
;
500 id_payload_t
*id_payload
;
501 identification_t
*id
;
503 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
505 return collect_other_init_data(this, message
);
508 if (this->my_auth
== NULL
&& this->do_another_auth
)
510 /* handle (optional) IDr payload, apply proposed identity */
511 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_RESPONDER
);
514 id
= id_payload
->get_identification(id_payload
);
518 id
= identification_create_from_encoding(ID_ANY
, chunk_empty
);
520 this->ike_sa
->set_my_id(this->ike_sa
, id
);
523 if (!this->expect_another_auth
)
528 if (message
->get_message_id(message
) == 1)
529 { /* check for extensions in the first IKE_AUTH */
530 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
))
532 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
534 if (message
->get_notify(message
, EAP_ONLY_AUTHENTICATION
))
536 this->ike_sa
->enable_extension(this->ike_sa
,
537 EXT_EAP_ONLY_AUTHENTICATION
);
541 if (this->other_auth
== NULL
)
543 /* handle IDi payload */
544 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_INITIATOR
);
547 DBG1(DBG_IKE
, "IDi payload missing");
550 id
= id_payload
->get_identification(id_payload
);
551 get_reserved_id_bytes(this, id_payload
);
552 this->ike_sa
->set_other_id(this->ike_sa
, id
);
553 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
554 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
556 if (this->peer_cfg
== NULL
)
558 if (!load_cfg_candidates(this))
560 this->authentication_failed
= TRUE
;
564 if (message
->get_payload(message
, AUTHENTICATION
) == NULL
)
565 { /* before authenticating with EAP, we need a EAP config */
566 cand
= get_auth_cfg(this, FALSE
);
568 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_TYPE
) == EAP_NAK
&&
569 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_VENDOR
) == 0))
570 { /* peer requested EAP, but current config does not match */
571 DBG1(DBG_IKE
, "peer requested EAP, config inacceptable");
572 this->peer_cfg
->destroy(this->peer_cfg
);
573 this->peer_cfg
= NULL
;
574 if (!update_cfg_candidates(this, FALSE
))
576 this->authentication_failed
= TRUE
;
579 cand
= get_auth_cfg(this, FALSE
);
581 /* copy over the EAP specific rules for authentication */
582 cfg
->add(cfg
, AUTH_RULE_EAP_TYPE
,
583 cand
->get(cand
, AUTH_RULE_EAP_TYPE
));
584 cfg
->add(cfg
, AUTH_RULE_EAP_VENDOR
,
585 cand
->get(cand
, AUTH_RULE_EAP_VENDOR
));
586 id
= (identification_t
*)cand
->get(cand
, AUTH_RULE_EAP_IDENTITY
);
589 cfg
->add(cfg
, AUTH_RULE_EAP_IDENTITY
, id
->clone(id
));
591 id
= (identification_t
*)cand
->get(cand
, AUTH_RULE_AAA_IDENTITY
);
594 cfg
->add(cfg
, AUTH_RULE_AAA_IDENTITY
, id
->clone(id
));
598 /* verify authentication data */
599 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
600 message
, this->other_nonce
, this->my_nonce
,
601 this->other_packet
->get_data(this->other_packet
),
602 this->my_packet
->get_data(this->my_packet
),
604 if (!this->other_auth
)
606 this->authentication_failed
= TRUE
;
610 switch (this->other_auth
->process(this->other_auth
, message
))
613 this->other_auth
->destroy(this->other_auth
);
614 this->other_auth
= NULL
;
617 if (message
->get_payload(message
, AUTHENTICATION
))
618 { /* AUTH verification successful, but another build() needed */
623 this->authentication_failed
= TRUE
;
627 /* If authenticated (with non-EAP) and received INITIAL_CONTACT,
628 * delete any existing IKE_SAs with that peer. */
629 if (message
->get_message_id(message
) == 1 &&
630 message
->get_notify(message
, INITIAL_CONTACT
))
632 this->initial_contact
= TRUE
;
635 /* another auth round done, invoke authorize hook */
636 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
638 DBG1(DBG_IKE
, "authorization hook forbids IKE_SA, cancelling");
639 this->authentication_failed
= TRUE
;
643 /* store authentication information */
644 cfg
= auth_cfg_create();
645 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
), FALSE
);
646 this->ike_sa
->add_auth_cfg(this->ike_sa
, FALSE
, cfg
);
648 if (!update_cfg_candidates(this, FALSE
))
650 this->authentication_failed
= TRUE
;
654 if (message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
) == NULL
)
656 this->expect_another_auth
= FALSE
;
657 if (!update_cfg_candidates(this, TRUE
))
659 this->authentication_failed
= TRUE
;
666 METHOD(task_t
, build_r
, status_t
,
667 private_ike_auth_t
*this, message_t
*message
)
671 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
673 if (multiple_auth_enabled())
675 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
678 return collect_my_init_data(this, message
);
681 if (this->authentication_failed
|| this->peer_cfg
== NULL
)
683 goto peer_auth_failed
;
686 if (this->my_auth
== NULL
&& this->do_another_auth
)
688 identification_t
*id
, *id_cfg
;
689 id_payload_t
*id_payload
;
692 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
693 cfg
->purge(cfg
, TRUE
);
694 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
696 id_cfg
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
697 id
= this->ike_sa
->get_my_id(this->ike_sa
);
698 if (id
->get_type(id
) == ID_ANY
)
699 { /* no IDr received, apply configured ID */
700 if (!id_cfg
|| id_cfg
->contains_wildcards(id_cfg
))
701 { /* no ID configured, use local IP address */
704 DBG1(DBG_CFG
, "no IDr configured, fall back on IP address");
705 me
= this->ike_sa
->get_my_host(this->ike_sa
);
706 id_cfg
= identification_create_from_sockaddr(
707 me
->get_sockaddr(me
));
708 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id_cfg
);
710 this->ike_sa
->set_my_id(this->ike_sa
, id_cfg
->clone(id_cfg
));
714 { /* IDr received, check if it matches configuration */
715 if (id_cfg
&& !id
->matches(id
, id_cfg
))
717 DBG1(DBG_CFG
, "received IDr %Y, but require %Y", id
, id_cfg
);
718 goto peer_auth_failed
;
722 id_payload
= id_payload_create_from_identification(ID_RESPONDER
, id
);
723 get_reserved_id_bytes(this, id_payload
);
724 message
->add_payload(message
, (payload_t
*)id_payload
);
726 if (this->initial_contact
)
728 charon
->ike_sa_manager
->check_uniqueness(charon
->ike_sa_manager
,
730 this->initial_contact
= FALSE
;
733 if ((uintptr_t)cfg
->get(cfg
, AUTH_RULE_AUTH_CLASS
) == AUTH_CLASS_EAP
)
734 { /* EAP-only authentication */
735 if (!this->ike_sa
->supports_extension(this->ike_sa
,
736 EXT_EAP_ONLY_AUTHENTICATION
))
738 DBG1(DBG_IKE
, "configured EAP-only authentication, but peer "
739 "does not support it");
740 goto peer_auth_failed
;
745 /* build authentication data */
746 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
747 this->other_nonce
, this->my_nonce
,
748 this->other_packet
->get_data(this->other_packet
),
749 this->my_packet
->get_data(this->my_packet
),
753 goto local_auth_failed
;
758 if (this->other_auth
)
760 switch (this->other_auth
->build(this->other_auth
, message
))
763 this->other_auth
->destroy(this->other_auth
);
764 this->other_auth
= NULL
;
769 if (message
->get_payload(message
, EXTENSIBLE_AUTHENTICATION
))
770 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
771 goto peer_auth_failed_no_notify
;
773 goto peer_auth_failed
;
778 switch (this->my_auth
->build(this->my_auth
, message
))
781 cfg
= auth_cfg_create();
782 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
),
784 this->ike_sa
->add_auth_cfg(this->ike_sa
, TRUE
, cfg
);
785 this->my_auth
->destroy(this->my_auth
);
786 this->my_auth
= NULL
;
791 goto local_auth_failed
;
795 /* check for additional authentication rounds */
796 if (do_another_auth(this))
798 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
802 this->do_another_auth
= FALSE
;
804 if (!this->do_another_auth
&& !this->expect_another_auth
)
806 if (charon
->ike_sa_manager
->check_uniqueness(charon
->ike_sa_manager
,
807 this->ike_sa
, FALSE
))
809 DBG1(DBG_IKE
, "cancelling IKE_SA setup due to uniqueness policy");
810 charon
->bus
->alert(charon
->bus
, ALERT_UNIQUE_KEEP
);
811 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
815 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
817 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, cancelling");
818 goto peer_auth_failed
;
820 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
821 this->ike_sa
->get_name(this->ike_sa
),
822 this->ike_sa
->get_unique_id(this->ike_sa
),
823 this->ike_sa
->get_my_host(this->ike_sa
),
824 this->ike_sa
->get_my_id(this->ike_sa
),
825 this->ike_sa
->get_other_host(this->ike_sa
),
826 this->ike_sa
->get_other_id(this->ike_sa
));
827 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
828 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
834 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
835 peer_auth_failed_no_notify
:
836 charon
->bus
->alert(charon
->bus
, ALERT_PEER_AUTH_FAILED
);
839 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
840 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
844 METHOD(task_t
, process_i
, status_t
,
845 private_ike_auth_t
*this, message_t
*message
)
847 enumerator_t
*enumerator
;
850 bool mutual_eap
= FALSE
;
852 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
854 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
) &&
855 multiple_auth_enabled())
857 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
859 return collect_other_init_data(this, message
);
862 enumerator
= message
->create_payload_enumerator(message
);
863 while (enumerator
->enumerate(enumerator
, &payload
))
865 if (payload
->get_type(payload
) == NOTIFY
)
867 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
868 notify_type_t type
= notify
->get_notify_type(notify
);
872 case NO_PROPOSAL_CHOSEN
:
873 case SINGLE_PAIR_REQUIRED
:
874 case NO_ADDITIONAL_SAS
:
875 case INTERNAL_ADDRESS_FAILURE
:
876 case FAILED_CP_REQUIRED
:
877 case TS_UNACCEPTABLE
:
878 case INVALID_SELECTORS
:
879 /* these are errors, but are not critical as only the
880 * CHILD_SA won't get build, but IKE_SA establishes anyway */
882 case MOBIKE_SUPPORTED
:
883 case ADDITIONAL_IP4_ADDRESS
:
884 case ADDITIONAL_IP6_ADDRESS
:
885 /* handled in ike_mobike task */
888 /* handled in ike_auth_lifetime task */
891 /* handled in ike_me task */
897 DBG1(DBG_IKE
, "received %N notify error",
898 notify_type_names
, type
);
899 enumerator
->destroy(enumerator
);
902 DBG2(DBG_IKE
, "received %N notify",
903 notify_type_names
, type
);
909 enumerator
->destroy(enumerator
);
911 if (this->expect_another_auth
)
913 if (this->other_auth
== NULL
)
915 id_payload_t
*id_payload
;
916 identification_t
*id
;
918 /* handle IDr payload */
919 id_payload
= (id_payload_t
*)message
->get_payload(message
,
923 DBG1(DBG_IKE
, "IDr payload missing");
924 goto peer_auth_failed
;
926 id
= id_payload
->get_identification(id_payload
);
927 get_reserved_id_bytes(this, id_payload
);
928 this->ike_sa
->set_other_id(this->ike_sa
, id
);
929 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
930 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
932 if (message
->get_payload(message
, AUTHENTICATION
))
934 /* verify authentication data */
935 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
936 message
, this->other_nonce
, this->my_nonce
,
937 this->other_packet
->get_data(this->other_packet
),
938 this->my_packet
->get_data(this->my_packet
),
940 if (!this->other_auth
)
942 goto peer_auth_failed
;
947 /* responder omitted AUTH payload, indicating EAP-only */
951 if (this->other_auth
)
953 switch (this->other_auth
->process(this->other_auth
, message
))
960 goto peer_auth_failed
;
962 this->other_auth
->destroy(this->other_auth
);
963 this->other_auth
= NULL
;
965 /* another auth round done, invoke authorize hook */
966 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
968 DBG1(DBG_IKE
, "authorization forbids IKE_SA, cancelling");
969 goto peer_auth_failed
;
972 /* store authentication information, reset authenticator */
973 cfg
= auth_cfg_create();
974 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
), FALSE
);
975 this->ike_sa
->add_auth_cfg(this->ike_sa
, FALSE
, cfg
);
980 switch (this->my_auth
->process(this->my_auth
, message
))
983 cfg
= auth_cfg_create();
984 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
),
986 this->ike_sa
->add_auth_cfg(this->ike_sa
, TRUE
, cfg
);
987 this->my_auth
->destroy(this->my_auth
);
988 this->my_auth
= NULL
;
989 this->do_another_auth
= do_another_auth(this);
994 charon
->bus
->alert(charon
->bus
, ALERT_LOCAL_AUTH_FAILED
);
1000 if (!this->my_auth
|| !this->my_auth
->is_mutual(this->my_auth
))
1002 DBG1(DBG_IKE
, "do not allow non-mutual EAP-only authentication");
1003 goto peer_auth_failed
;
1005 DBG1(DBG_IKE
, "allow mutual EAP-only authentication");
1008 if (message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
) == NULL
)
1010 this->expect_another_auth
= FALSE
;
1012 if (!this->expect_another_auth
&& !this->do_another_auth
&& !this->my_auth
)
1014 if (!update_cfg_candidates(this, TRUE
))
1016 goto peer_auth_failed
;
1018 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
1020 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, "
1022 goto peer_auth_failed
;
1024 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1025 this->ike_sa
->get_name(this->ike_sa
),
1026 this->ike_sa
->get_unique_id(this->ike_sa
),
1027 this->ike_sa
->get_my_host(this->ike_sa
),
1028 this->ike_sa
->get_my_id(this->ike_sa
),
1029 this->ike_sa
->get_other_host(this->ike_sa
),
1030 this->ike_sa
->get_other_id(this->ike_sa
));
1031 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
1032 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
1038 charon
->bus
->alert(charon
->bus
, ALERT_PEER_AUTH_FAILED
);
1042 METHOD(task_t
, get_type
, task_type_t
,
1043 private_ike_auth_t
*this)
1045 return TASK_IKE_AUTH
;
1048 METHOD(task_t
, migrate
, void,
1049 private_ike_auth_t
*this, ike_sa_t
*ike_sa
)
1051 chunk_free(&this->my_nonce
);
1052 chunk_free(&this->other_nonce
);
1053 DESTROY_IF(this->my_packet
);
1054 DESTROY_IF(this->other_packet
);
1055 DESTROY_IF(this->peer_cfg
);
1056 DESTROY_IF(this->my_auth
);
1057 DESTROY_IF(this->other_auth
);
1058 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
1060 this->my_packet
= NULL
;
1061 this->other_packet
= NULL
;
1062 this->ike_sa
= ike_sa
;
1063 this->peer_cfg
= NULL
;
1064 this->my_auth
= NULL
;
1065 this->other_auth
= NULL
;
1066 this->do_another_auth
= TRUE
;
1067 this->expect_another_auth
= TRUE
;
1068 this->authentication_failed
= FALSE
;
1069 this->candidates
= linked_list_create();
1072 METHOD(task_t
, destroy
, void,
1073 private_ike_auth_t
*this)
1075 chunk_free(&this->my_nonce
);
1076 chunk_free(&this->other_nonce
);
1077 DESTROY_IF(this->my_packet
);
1078 DESTROY_IF(this->other_packet
);
1079 DESTROY_IF(this->my_auth
);
1080 DESTROY_IF(this->other_auth
);
1081 DESTROY_IF(this->peer_cfg
);
1082 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
1087 * Described in header.
1089 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
, bool initiator
)
1091 private_ike_auth_t
*this;
1096 .get_type
= _get_type
,
1097 .migrate
= _migrate
,
1099 .process
= _process_r
,
1100 .destroy
= _destroy
,
1104 .initiator
= initiator
,
1105 .candidates
= linked_list_create(),
1106 .do_another_auth
= TRUE
,
1107 .expect_another_auth
= TRUE
,
1111 this->public.task
.build
= _build_i
;
1112 this->public.task
.process
= _process_i
;
1114 return &this->public;