2 * Copyright (C) 2005-2009 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 #include <encoding/payloads/id_payload.h>
23 #include <encoding/payloads/auth_payload.h>
24 #include <encoding/payloads/eap_payload.h>
25 #include <encoding/payloads/nonce_payload.h>
26 #include <sa/authenticators/eap_authenticator.h>
28 typedef struct private_ike_auth_t private_ike_auth_t
;
31 * Private members of a ike_auth_t task.
33 struct private_ike_auth_t
{
36 * Public methods and task_t interface.
46 * Are we the initiator?
51 * Nonce chosen by us in ike_init
56 * Nonce chosen by peer in ike_init
61 * IKE_SA_INIT message sent by us
66 * IKE_SA_INIT message sent by peer
68 packet_t
*other_packet
;
71 * completed authentication configs initiated by us (auth_cfg_t)
73 linked_list_t
*my_cfgs
;
76 * completed authentication configs initiated by other (auth_cfg_t)
78 linked_list_t
*other_cfgs
;;
81 * currently active authenticator, to authenticate us
83 authenticator_t
*my_auth
;
86 * currently active authenticator, to authenticate peer
88 authenticator_t
*other_auth
;
91 * peer_cfg candidates, ordered by priority
93 linked_list_t
*candidates
;
96 * selected peer config (might change when using multiple authentications)
101 * have we planned an(other) authentication exchange?
103 bool do_another_auth
;
106 * has the peer announced another authentication exchange?
108 bool expect_another_auth
;
111 * should we send a AUTHENTICATION_FAILED notify?
113 bool authentication_failed
;
117 * check if multiple authentication extension is enabled, configuration-wise
119 static bool multiple_auth_enabled()
121 return lib
->settings
->get_bool(lib
->settings
,
122 "charon.multiple_authentication", TRUE
);
126 * collect the needed information in the IKE_SA_INIT exchange from our message
128 static status_t
collect_my_init_data(private_ike_auth_t
*this,
131 nonce_payload_t
*nonce
;
133 /* get the nonce that was generated in ike_init */
134 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
139 this->my_nonce
= nonce
->get_nonce(nonce
);
141 /* pre-generate the message, keep a copy */
142 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
143 &this->my_packet
) != SUCCESS
)
151 * collect the needed information in the IKE_SA_INIT exchange from others message
153 static status_t
collect_other_init_data(private_ike_auth_t
*this,
156 /* we collect the needed information in the IKE_SA_INIT exchange */
157 nonce_payload_t
*nonce
;
159 /* get the nonce that was generated in ike_init */
160 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
165 this->other_nonce
= nonce
->get_nonce(nonce
);
167 /* keep a copy of the received packet */
168 this->other_packet
= message
->get_packet(message
);
173 * Get the next authentication configuration
175 static auth_cfg_t
*get_auth_cfg(private_ike_auth_t
*this, bool local
)
177 enumerator_t
*e1
, *e2
;
178 auth_cfg_t
*c1
, *c2
, *next
= NULL
;
180 /* find an available config not already done */
181 e1
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, local
);
182 while (e1
->enumerate(e1
, &c1
))
188 e2
= this->my_cfgs
->create_enumerator(this->my_cfgs
);
192 e2
= this->other_cfgs
->create_enumerator(this->other_cfgs
);
194 while (e2
->enumerate(e2
, &c2
))
196 if (c2
->complies(c2
, c1
, FALSE
))
214 * Check if we have should initiate another authentication round
216 static bool do_another_auth(private_ike_auth_t
*this)
218 bool do_another
= FALSE
;
219 enumerator_t
*done
, *todo
;
220 auth_cfg_t
*done_cfg
, *todo_cfg
;
222 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
227 done
= this->my_cfgs
->create_enumerator(this->my_cfgs
);
228 todo
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, TRUE
);
229 while (todo
->enumerate(todo
, &todo_cfg
))
231 if (!done
->enumerate(done
, &done_cfg
))
233 done_cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
235 if (!done_cfg
->complies(done_cfg
, todo_cfg
, FALSE
))
247 * Get peer configuration candidates from backends
249 static bool load_cfg_candidates(private_ike_auth_t
*this)
251 enumerator_t
*enumerator
;
252 peer_cfg_t
*peer_cfg
;
254 identification_t
*my_id
, *other_id
;
256 me
= this->ike_sa
->get_my_host(this->ike_sa
);
257 other
= this->ike_sa
->get_other_host(this->ike_sa
);
258 my_id
= this->ike_sa
->get_my_id(this->ike_sa
);
259 other_id
= this->ike_sa
->get_other_id(this->ike_sa
);
261 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
262 me
, other
, my_id
, other_id
);
263 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
265 peer_cfg
->get_ref(peer_cfg
);
266 if (this->peer_cfg
== NULL
)
268 this->peer_cfg
= peer_cfg
;
269 this->ike_sa
->set_peer_cfg(this->ike_sa
, peer_cfg
);
273 this->candidates
->insert_last(this->candidates
, peer_cfg
);
276 enumerator
->destroy(enumerator
);
279 DBG1(DBG_CFG
, "selected peer config '%s'",
280 this->peer_cfg
->get_name(this->peer_cfg
));
283 DBG1(DBG_CFG
, "no matching peer config found");
288 * update the current peer candidate if necessary, using candidates
290 static bool update_cfg_candidates(private_ike_auth_t
*this, bool strict
)
296 bool complies
= TRUE
;
297 enumerator_t
*e1
, *e2
, *tmp
;
300 e1
= this->other_cfgs
->create_enumerator(this->other_cfgs
);
301 e2
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, FALSE
);
304 { /* swap lists in strict mode: all configured rounds must be
305 * fulfilled. If !strict, we check only the rounds done so far. */
310 while (e1
->enumerate(e1
, &c1
))
312 /* check if done authentications comply to configured ones */
313 if ((!e2
->enumerate(e2
, &c2
)) ||
314 (!strict
&& !c1
->complies(c1
, c2
, TRUE
)) ||
315 (strict
&& !c2
->complies(c2
, c1
, TRUE
)))
327 DBG1(DBG_CFG
, "selected peer config '%s' inacceptable",
328 this->peer_cfg
->get_name(this->peer_cfg
));
329 this->peer_cfg
->destroy(this->peer_cfg
);
331 if (this->candidates
->remove_first(this->candidates
,
332 (void**)&this->peer_cfg
) != SUCCESS
)
334 DBG1(DBG_CFG
, "no alternative config found");
335 this->peer_cfg
= NULL
;
339 DBG1(DBG_CFG
, "switching to peer config '%s'",
340 this->peer_cfg
->get_name(this->peer_cfg
));
341 this->ike_sa
->set_peer_cfg(this->ike_sa
, this->peer_cfg
);
344 while (this->peer_cfg
);
346 return this->peer_cfg
!= NULL
;
350 * Implementation of task_t.build for initiator
352 static status_t
build_i(private_ike_auth_t
*this, message_t
*message
)
356 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
358 return collect_my_init_data(this, message
);
361 if (this->peer_cfg
== NULL
)
363 this->peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
364 this->peer_cfg
->get_ref(this->peer_cfg
);
367 if (message
->get_message_id(message
) == 1 &&
368 this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
369 { /* in the first IKE_AUTH, indicate support for multiple authentication */
370 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
, chunk_empty
);
373 if (!this->do_another_auth
&& !this->my_auth
)
374 { /* we have done our rounds */
378 /* check if an authenticator is in progress */
379 if (this->my_auth
== NULL
)
381 identification_t
*id
;
382 id_payload_t
*id_payload
;
384 /* clean up authentication config from a previous round */
385 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
386 cfg
->purge(cfg
, TRUE
);
388 /* add (optional) IDr */
389 cfg
= get_auth_cfg(this, FALSE
);
392 id
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
393 if (id
&& !id
->contains_wildcards(id
))
395 this->ike_sa
->set_other_id(this->ike_sa
, id
->clone(id
));
396 id_payload
= id_payload_create_from_identification(
398 message
->add_payload(message
, (payload_t
*)id_payload
);
402 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
403 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
404 id
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
407 DBG1(DBG_CFG
, "configuration misses IDi");
410 this->ike_sa
->set_my_id(this->ike_sa
, id
->clone(id
));
411 id_payload
= id_payload_create_from_identification(ID_INITIATOR
, id
);
412 message
->add_payload(message
, (payload_t
*)id_payload
);
414 /* build authentication data */
415 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
416 this->other_nonce
, this->my_nonce
,
417 this->other_packet
->get_data(this->other_packet
),
418 this->my_packet
->get_data(this->my_packet
));
424 switch (this->my_auth
->build(this->my_auth
, message
))
427 /* authentication step complete, reset authenticator */
428 cfg
= auth_cfg_create();
429 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
), TRUE
);
430 this->my_cfgs
->insert_last(this->my_cfgs
, cfg
);
431 this->my_auth
->destroy(this->my_auth
);
432 this->my_auth
= NULL
;
440 /* check for additional authentication rounds */
441 if (do_another_auth(this))
443 if (message
->get_payload(message
, AUTHENTICATION
))
445 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
450 this->do_another_auth
= FALSE
;
456 * Implementation of task_t.process for responder
458 static status_t
process_r(private_ike_auth_t
*this, message_t
*message
)
460 auth_cfg_t
*cfg
, *cand
;
461 id_payload_t
*id_payload
;
462 identification_t
*id
;
464 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
466 return collect_other_init_data(this, message
);
469 if (this->my_auth
== NULL
&& this->do_another_auth
)
471 /* handle (optional) IDr payload, apply proposed identity */
472 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_RESPONDER
);
475 id
= id_payload
->get_identification(id_payload
);
479 id
= identification_create_from_encoding(ID_ANY
, chunk_empty
);
481 this->ike_sa
->set_my_id(this->ike_sa
, id
);
484 if (!this->expect_another_auth
)
488 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
))
490 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
493 if (this->other_auth
== NULL
)
495 /* handle IDi payload */
496 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_INITIATOR
);
499 DBG1(DBG_IKE
, "IDi payload missing");
502 id
= id_payload
->get_identification(id_payload
);
503 this->ike_sa
->set_other_id(this->ike_sa
, id
);
504 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
505 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
507 if (this->peer_cfg
== NULL
)
509 if (!load_cfg_candidates(this))
511 this->authentication_failed
= TRUE
;
515 if (message
->get_payload(message
, AUTHENTICATION
) == NULL
)
516 { /* before authenticating with EAP, we need a EAP config */
517 cand
= get_auth_cfg(this, FALSE
);
519 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_TYPE
) == EAP_NAK
&&
520 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_VENDOR
) == 0))
521 { /* peer requested EAP, but current config does not match */
522 this->peer_cfg
->destroy(this->peer_cfg
);
523 this->peer_cfg
= NULL
;
524 if (!update_cfg_candidates(this, FALSE
))
526 this->authentication_failed
= TRUE
;
529 cand
= get_auth_cfg(this, FALSE
);
531 cfg
->merge(cfg
, cand
, TRUE
);
534 /* verify authentication data */
535 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
536 message
, this->other_nonce
, this->my_nonce
,
537 this->other_packet
->get_data(this->other_packet
),
538 this->my_packet
->get_data(this->my_packet
));
539 if (!this->other_auth
)
541 this->authentication_failed
= TRUE
;
545 switch (this->other_auth
->process(this->other_auth
, message
))
548 this->other_auth
->destroy(this->other_auth
);
549 this->other_auth
= NULL
;
552 if (message
->get_payload(message
, AUTHENTICATION
))
553 { /* AUTH verification successful, but another build() needed */
558 this->authentication_failed
= TRUE
;
562 /* store authentication information */
563 cfg
= auth_cfg_create();
564 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
), FALSE
);
565 this->other_cfgs
->insert_last(this->other_cfgs
, cfg
);
567 /* another auth round done, invoke authorize hook */
568 if (!charon
->bus
->authorize(charon
->bus
, this->other_cfgs
, FALSE
))
570 DBG1(DBG_IKE
, "round %d authorization hook forbids IKE_SA, cancelling",
571 this->other_cfgs
->get_count(this->other_cfgs
));
572 this->authentication_failed
= TRUE
;
576 if (!update_cfg_candidates(this, FALSE
))
578 this->authentication_failed
= TRUE
;
582 if (message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
) == NULL
)
584 this->expect_another_auth
= FALSE
;
585 if (!update_cfg_candidates(this, TRUE
))
587 this->authentication_failed
= TRUE
;
595 * Implementation of task_t.build for responder
597 static status_t
build_r(private_ike_auth_t
*this, message_t
*message
)
601 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
603 if (multiple_auth_enabled())
605 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
608 return collect_my_init_data(this, message
);
611 if (this->authentication_failed
|| this->peer_cfg
== NULL
)
613 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
617 if (this->my_auth
== NULL
&& this->do_another_auth
)
619 identification_t
*id
, *id_cfg
;
620 id_payload_t
*id_payload
;
623 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
624 cfg
->purge(cfg
, TRUE
);
625 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
627 id_cfg
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
628 id
= this->ike_sa
->get_my_id(this->ike_sa
);
629 if (id
->get_type(id
) == ID_ANY
)
630 { /* no IDr received, apply configured ID */
631 if (!id_cfg
|| id_cfg
->contains_wildcards(id_cfg
))
633 DBG1(DBG_CFG
, "IDr not configured and negotiation failed");
634 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
638 this->ike_sa
->set_my_id(this->ike_sa
, id_cfg
->clone(id_cfg
));
642 { /* IDr received, check if it matches configuration */
643 if (id_cfg
&& !id
->matches(id
, id_cfg
))
645 DBG1(DBG_CFG
, "received IDr %Y, but require %Y", id
, id_cfg
);
646 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
652 id_payload
= id_payload_create_from_identification(ID_RESPONDER
, id
);
653 message
->add_payload(message
, (payload_t
*)id_payload
);
655 /* build authentication data */
656 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
657 this->other_nonce
, this->my_nonce
,
658 this->other_packet
->get_data(this->other_packet
),
659 this->my_packet
->get_data(this->my_packet
));
662 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
667 if (this->other_auth
)
669 switch (this->other_auth
->build(this->other_auth
, message
))
672 this->other_auth
->destroy(this->other_auth
);
673 this->other_auth
= NULL
;
678 if (!message
->get_payload(message
, EXTENSIBLE_AUTHENTICATION
))
679 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
680 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
688 switch (this->my_auth
->build(this->my_auth
, message
))
691 cfg
= auth_cfg_create();
692 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
),
694 this->my_cfgs
->insert_last(this->my_cfgs
, cfg
);
695 this->my_auth
->destroy(this->my_auth
);
696 this->my_auth
= NULL
;
701 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
707 /* check for additional authentication rounds */
708 if (do_another_auth(this))
710 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
714 this->do_another_auth
= FALSE
;
716 if (!this->do_another_auth
&& !this->expect_another_auth
)
718 if (charon
->ike_sa_manager
->check_uniqueness(charon
->ike_sa_manager
,
721 DBG1(DBG_IKE
, "cancelling IKE_SA setup due uniqueness policy");
722 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
726 if (!charon
->bus
->authorize(charon
->bus
, this->other_cfgs
, TRUE
))
728 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, cancelling");
729 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
733 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
734 this->ike_sa
->get_name(this->ike_sa
),
735 this->ike_sa
->get_unique_id(this->ike_sa
),
736 this->ike_sa
->get_my_host(this->ike_sa
),
737 this->ike_sa
->get_my_id(this->ike_sa
),
738 this->ike_sa
->get_other_host(this->ike_sa
),
739 this->ike_sa
->get_other_id(this->ike_sa
));
740 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
741 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
748 * Implementation of task_t.process for initiator
750 static status_t
process_i(private_ike_auth_t
*this, message_t
*message
)
752 enumerator_t
*enumerator
;
756 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
758 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
) &&
759 multiple_auth_enabled())
761 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
763 return collect_other_init_data(this, message
);
766 enumerator
= message
->create_payload_enumerator(message
);
767 while (enumerator
->enumerate(enumerator
, &payload
))
769 if (payload
->get_type(payload
) == NOTIFY
)
771 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
772 notify_type_t type
= notify
->get_notify_type(notify
);
776 case NO_PROPOSAL_CHOSEN
:
777 case SINGLE_PAIR_REQUIRED
:
778 case NO_ADDITIONAL_SAS
:
779 case INTERNAL_ADDRESS_FAILURE
:
780 case FAILED_CP_REQUIRED
:
781 case TS_UNACCEPTABLE
:
782 case INVALID_SELECTORS
:
783 /* these are errors, but are not critical as only the
784 * CHILD_SA won't get build, but IKE_SA establishes anyway */
786 case MOBIKE_SUPPORTED
:
787 case ADDITIONAL_IP4_ADDRESS
:
788 case ADDITIONAL_IP6_ADDRESS
:
789 /* handled in ike_mobike task */
792 /* handled in ike_auth_lifetime task */
795 /* handled in ike_me task */
801 DBG1(DBG_IKE
, "received %N notify error",
802 notify_type_names
, type
);
803 enumerator
->destroy(enumerator
);
806 DBG2(DBG_IKE
, "received %N notify",
807 notify_type_names
, type
);
813 enumerator
->destroy(enumerator
);
817 switch (this->my_auth
->process(this->my_auth
, message
))
820 cfg
= auth_cfg_create();
821 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
),
823 this->my_cfgs
->insert_last(this->my_cfgs
, cfg
);
824 this->my_auth
->destroy(this->my_auth
);
825 this->my_auth
= NULL
;
826 this->do_another_auth
= do_another_auth(this);
835 if (this->expect_another_auth
)
837 if (this->other_auth
== NULL
)
839 id_payload_t
*id_payload
;
840 identification_t
*id
;
842 /* responder is not allowed to do EAP */
843 if (!message
->get_payload(message
, AUTHENTICATION
))
845 DBG1(DBG_IKE
, "AUTH payload missing");
849 /* handle IDr payload */
850 id_payload
= (id_payload_t
*)message
->get_payload(message
,
854 DBG1(DBG_IKE
, "IDr payload missing");
857 id
= id_payload
->get_identification(id_payload
);
858 this->ike_sa
->set_other_id(this->ike_sa
, id
);
859 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
860 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
862 /* verify authentication data */
863 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
864 message
, this->other_nonce
, this->my_nonce
,
865 this->other_packet
->get_data(this->other_packet
),
866 this->my_packet
->get_data(this->my_packet
));
867 if (!this->other_auth
)
872 switch (this->other_auth
->process(this->other_auth
, message
))
881 /* store authentication information, reset authenticator */
882 cfg
= auth_cfg_create();
883 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
), FALSE
);
884 this->other_cfgs
->insert_last(this->other_cfgs
, cfg
);
885 this->other_auth
->destroy(this->other_auth
);
886 this->other_auth
= NULL
;
888 /* another auth round done, invoke authorize hook */
889 if (!charon
->bus
->authorize(charon
->bus
, this->other_cfgs
, FALSE
))
891 DBG1(DBG_IKE
, "round %d authorization forbids IKE_SA, cancelling",
892 this->other_cfgs
->get_count(this->other_cfgs
));
897 if (message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
) == NULL
)
899 this->expect_another_auth
= FALSE
;
901 if (!this->expect_another_auth
&& !this->do_another_auth
&& !this->my_auth
)
903 if (!update_cfg_candidates(this, TRUE
))
907 if (!charon
->bus
->authorize(charon
->bus
, this->other_cfgs
, TRUE
))
909 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, cancelling");
912 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
913 this->ike_sa
->get_name(this->ike_sa
),
914 this->ike_sa
->get_unique_id(this->ike_sa
),
915 this->ike_sa
->get_my_host(this->ike_sa
),
916 this->ike_sa
->get_my_id(this->ike_sa
),
917 this->ike_sa
->get_other_host(this->ike_sa
),
918 this->ike_sa
->get_other_id(this->ike_sa
));
919 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
920 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
927 * Implementation of task_t.get_type
929 static task_type_t
get_type(private_ike_auth_t
*this)
931 return IKE_AUTHENTICATE
;
935 * Implementation of task_t.migrate
937 static void migrate(private_ike_auth_t
*this, ike_sa_t
*ike_sa
)
939 chunk_free(&this->my_nonce
);
940 chunk_free(&this->other_nonce
);
941 DESTROY_IF(this->my_packet
);
942 DESTROY_IF(this->other_packet
);
943 DESTROY_IF(this->peer_cfg
);
944 DESTROY_IF(this->my_auth
);
945 DESTROY_IF(this->other_auth
);
946 this->my_cfgs
->destroy_offset(this->my_cfgs
, offsetof(auth_cfg_t
, destroy
));
947 this->other_cfgs
->destroy_offset(this->other_cfgs
, offsetof(auth_cfg_t
, destroy
));
948 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
950 this->my_packet
= NULL
;
951 this->other_packet
= NULL
;
952 this->ike_sa
= ike_sa
;
953 this->peer_cfg
= NULL
;
954 this->my_auth
= NULL
;
955 this->other_auth
= NULL
;
956 this->do_another_auth
= TRUE
;
957 this->expect_another_auth
= TRUE
;
958 this->authentication_failed
= FALSE
;
959 this->my_cfgs
= linked_list_create();
960 this->other_cfgs
= linked_list_create();
961 this->candidates
= linked_list_create();
965 * Implementation of task_t.destroy
967 static void destroy(private_ike_auth_t
*this)
969 chunk_free(&this->my_nonce
);
970 chunk_free(&this->other_nonce
);
971 DESTROY_IF(this->my_packet
);
972 DESTROY_IF(this->other_packet
);
973 DESTROY_IF(this->my_auth
);
974 DESTROY_IF(this->other_auth
);
975 DESTROY_IF(this->peer_cfg
);
976 this->my_cfgs
->destroy_offset(this->my_cfgs
, offsetof(auth_cfg_t
, destroy
));
977 this->other_cfgs
->destroy_offset(this->other_cfgs
, offsetof(auth_cfg_t
, destroy
));
978 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
983 * Described in header.
985 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
, bool initiator
)
987 private_ike_auth_t
*this = malloc_thing(private_ike_auth_t
);
989 this->public.task
.get_type
= (task_type_t(*)(task_t
*))get_type
;
990 this->public.task
.migrate
= (void(*)(task_t
*,ike_sa_t
*))migrate
;
991 this->public.task
.destroy
= (void(*)(task_t
*))destroy
;
995 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_i
;
996 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_i
;
1000 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_r
;
1001 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_r
;
1004 this->ike_sa
= ike_sa
;
1005 this->initiator
= initiator
;
1006 this->my_nonce
= chunk_empty
;
1007 this->other_nonce
= chunk_empty
;
1008 this->my_packet
= NULL
;
1009 this->other_packet
= NULL
;
1010 this->peer_cfg
= NULL
;
1011 this->my_cfgs
= linked_list_create();
1012 this->other_cfgs
= linked_list_create();
1013 this->candidates
= linked_list_create();
1014 this->my_auth
= NULL
;
1015 this->other_auth
= NULL
;
1016 this->do_another_auth
= TRUE
;
1017 this->expect_another_auth
= TRUE
;
1018 this->authentication_failed
= FALSE
;
1020 return &this->public;