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 * currently active authenticator, to authenticate us
73 authenticator_t
*my_auth
;
76 * currently active authenticator, to authenticate peer
78 authenticator_t
*other_auth
;
81 * peer_cfg candidates, ordered by priority
83 linked_list_t
*candidates
;
86 * selected peer config (might change when using multiple authentications)
91 * have we planned an(other) authentication exchange?
96 * has the peer announced another authentication exchange?
98 bool expect_another_auth
;
101 * should we send a AUTHENTICATION_FAILED notify?
103 bool authentication_failed
;
107 * check if multiple authentication extension is enabled, configuration-wise
109 static bool multiple_auth_enabled()
111 return lib
->settings
->get_bool(lib
->settings
,
112 "charon.multiple_authentication", TRUE
);
116 * collect the needed information in the IKE_SA_INIT exchange from our message
118 static status_t
collect_my_init_data(private_ike_auth_t
*this,
121 nonce_payload_t
*nonce
;
123 /* get the nonce that was generated in ike_init */
124 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
129 this->my_nonce
= nonce
->get_nonce(nonce
);
131 /* pre-generate the message, keep a copy */
132 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
133 &this->my_packet
) != SUCCESS
)
141 * collect the needed information in the IKE_SA_INIT exchange from others message
143 static status_t
collect_other_init_data(private_ike_auth_t
*this,
146 /* we collect the needed information in the IKE_SA_INIT exchange */
147 nonce_payload_t
*nonce
;
149 /* get the nonce that was generated in ike_init */
150 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
155 this->other_nonce
= nonce
->get_nonce(nonce
);
157 /* keep a copy of the received packet */
158 this->other_packet
= message
->get_packet(message
);
163 * Get the next authentication configuration
165 static auth_cfg_t
*get_auth_cfg(private_ike_auth_t
*this, bool local
)
167 enumerator_t
*e1
, *e2
;
168 auth_cfg_t
*c1
, *c2
, *next
= NULL
;
170 /* find an available config not already done */
171 e1
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, local
);
172 while (e1
->enumerate(e1
, &c1
))
176 e2
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, local
);
177 while (e2
->enumerate(e2
, &c2
))
179 if (c2
->complies(c2
, c1
, FALSE
))
197 * Check if we have should initiate another authentication round
199 static bool do_another_auth(private_ike_auth_t
*this)
201 bool do_another
= FALSE
;
202 enumerator_t
*done
, *todo
;
203 auth_cfg_t
*done_cfg
, *todo_cfg
;
205 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
210 done
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, TRUE
);
211 todo
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, TRUE
);
212 while (todo
->enumerate(todo
, &todo_cfg
))
214 if (!done
->enumerate(done
, &done_cfg
))
216 done_cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
218 if (!done_cfg
->complies(done_cfg
, todo_cfg
, FALSE
))
230 * Get peer configuration candidates from backends
232 static bool load_cfg_candidates(private_ike_auth_t
*this)
234 enumerator_t
*enumerator
;
235 peer_cfg_t
*peer_cfg
;
237 identification_t
*my_id
, *other_id
;
239 me
= this->ike_sa
->get_my_host(this->ike_sa
);
240 other
= this->ike_sa
->get_other_host(this->ike_sa
);
241 my_id
= this->ike_sa
->get_my_id(this->ike_sa
);
242 other_id
= this->ike_sa
->get_other_id(this->ike_sa
);
244 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
245 me
, other
, my_id
, other_id
);
246 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
248 peer_cfg
->get_ref(peer_cfg
);
249 if (this->peer_cfg
== NULL
)
251 this->peer_cfg
= peer_cfg
;
252 this->ike_sa
->set_peer_cfg(this->ike_sa
, peer_cfg
);
256 this->candidates
->insert_last(this->candidates
, peer_cfg
);
259 enumerator
->destroy(enumerator
);
262 DBG1(DBG_CFG
, "selected peer config '%s'",
263 this->peer_cfg
->get_name(this->peer_cfg
));
266 DBG1(DBG_CFG
, "no matching peer config found");
271 * update the current peer candidate if necessary, using candidates
273 static bool update_cfg_candidates(private_ike_auth_t
*this, bool strict
)
279 bool complies
= TRUE
;
280 enumerator_t
*e1
, *e2
, *tmp
;
283 e1
= this->ike_sa
->create_auth_cfg_enumerator(this->ike_sa
, FALSE
);
284 e2
= this->peer_cfg
->create_auth_cfg_enumerator(this->peer_cfg
, FALSE
);
287 { /* swap lists in strict mode: all configured rounds must be
288 * fulfilled. If !strict, we check only the rounds done so far. */
293 while (e1
->enumerate(e1
, &c1
))
295 /* check if done authentications comply to configured ones */
296 if ((!e2
->enumerate(e2
, &c2
)) ||
297 (!strict
&& !c1
->complies(c1
, c2
, TRUE
)) ||
298 (strict
&& !c2
->complies(c2
, c1
, TRUE
)))
310 DBG1(DBG_CFG
, "selected peer config '%s' inacceptable",
311 this->peer_cfg
->get_name(this->peer_cfg
));
312 this->peer_cfg
->destroy(this->peer_cfg
);
314 if (this->candidates
->remove_first(this->candidates
,
315 (void**)&this->peer_cfg
) != SUCCESS
)
317 DBG1(DBG_CFG
, "no alternative config found");
318 this->peer_cfg
= NULL
;
322 DBG1(DBG_CFG
, "switching to peer config '%s'",
323 this->peer_cfg
->get_name(this->peer_cfg
));
324 this->ike_sa
->set_peer_cfg(this->ike_sa
, this->peer_cfg
);
327 while (this->peer_cfg
);
329 return this->peer_cfg
!= NULL
;
333 * Implementation of task_t.build for initiator
335 static status_t
build_i(private_ike_auth_t
*this, message_t
*message
)
339 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
341 return collect_my_init_data(this, message
);
344 if (this->peer_cfg
== NULL
)
346 this->peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
347 this->peer_cfg
->get_ref(this->peer_cfg
);
350 if (message
->get_message_id(message
) == 1 &&
351 this->ike_sa
->supports_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
))
352 { /* in the first IKE_AUTH, indicate support for multiple authentication */
353 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
, chunk_empty
);
356 if (!this->do_another_auth
&& !this->my_auth
)
357 { /* we have done our rounds */
361 /* check if an authenticator is in progress */
362 if (this->my_auth
== NULL
)
364 identification_t
*id
;
365 id_payload_t
*id_payload
;
367 /* clean up authentication config from a previous round */
368 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
369 cfg
->purge(cfg
, TRUE
);
371 /* add (optional) IDr */
372 cfg
= get_auth_cfg(this, FALSE
);
375 id
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
376 if (id
&& !id
->contains_wildcards(id
))
378 this->ike_sa
->set_other_id(this->ike_sa
, id
->clone(id
));
379 id_payload
= id_payload_create_from_identification(
381 message
->add_payload(message
, (payload_t
*)id_payload
);
385 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
386 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
387 id
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
390 DBG1(DBG_CFG
, "configuration misses IDi");
393 this->ike_sa
->set_my_id(this->ike_sa
, id
->clone(id
));
394 id_payload
= id_payload_create_from_identification(ID_INITIATOR
, id
);
395 message
->add_payload(message
, (payload_t
*)id_payload
);
397 /* build authentication data */
398 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
399 this->other_nonce
, this->my_nonce
,
400 this->other_packet
->get_data(this->other_packet
),
401 this->my_packet
->get_data(this->my_packet
));
407 switch (this->my_auth
->build(this->my_auth
, message
))
410 /* authentication step complete, reset authenticator */
411 cfg
= auth_cfg_create();
412 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
), TRUE
);
413 this->ike_sa
->add_auth_cfg(this->ike_sa
, TRUE
, cfg
);
414 this->my_auth
->destroy(this->my_auth
);
415 this->my_auth
= NULL
;
423 /* check for additional authentication rounds */
424 if (do_another_auth(this))
426 if (message
->get_payload(message
, AUTHENTICATION
))
428 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
433 this->do_another_auth
= FALSE
;
439 * Implementation of task_t.process for responder
441 static status_t
process_r(private_ike_auth_t
*this, message_t
*message
)
443 auth_cfg_t
*cfg
, *cand
;
444 id_payload_t
*id_payload
;
445 identification_t
*id
;
447 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
449 return collect_other_init_data(this, message
);
452 if (this->my_auth
== NULL
&& this->do_another_auth
)
454 /* handle (optional) IDr payload, apply proposed identity */
455 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_RESPONDER
);
458 id
= id_payload
->get_identification(id_payload
);
462 id
= identification_create_from_encoding(ID_ANY
, chunk_empty
);
464 this->ike_sa
->set_my_id(this->ike_sa
, id
);
467 if (!this->expect_another_auth
)
471 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
))
473 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
476 if (this->other_auth
== NULL
)
478 /* handle IDi payload */
479 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_INITIATOR
);
482 DBG1(DBG_IKE
, "IDi payload missing");
485 id
= id_payload
->get_identification(id_payload
);
486 this->ike_sa
->set_other_id(this->ike_sa
, id
);
487 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
488 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
490 if (this->peer_cfg
== NULL
)
492 if (!load_cfg_candidates(this))
494 this->authentication_failed
= TRUE
;
498 if (message
->get_payload(message
, AUTHENTICATION
) == NULL
)
499 { /* before authenticating with EAP, we need a EAP config */
500 cand
= get_auth_cfg(this, FALSE
);
502 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_TYPE
) == EAP_NAK
&&
503 (uintptr_t)cand
->get(cand
, AUTH_RULE_EAP_VENDOR
) == 0))
504 { /* peer requested EAP, but current config does not match */
505 this->peer_cfg
->destroy(this->peer_cfg
);
506 this->peer_cfg
= NULL
;
507 if (!update_cfg_candidates(this, FALSE
))
509 this->authentication_failed
= TRUE
;
512 cand
= get_auth_cfg(this, FALSE
);
514 cfg
->merge(cfg
, cand
, TRUE
);
517 /* verify authentication data */
518 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
519 message
, this->other_nonce
, this->my_nonce
,
520 this->other_packet
->get_data(this->other_packet
),
521 this->my_packet
->get_data(this->my_packet
));
522 if (!this->other_auth
)
524 this->authentication_failed
= TRUE
;
528 switch (this->other_auth
->process(this->other_auth
, message
))
531 this->other_auth
->destroy(this->other_auth
);
532 this->other_auth
= NULL
;
535 if (message
->get_payload(message
, AUTHENTICATION
))
536 { /* AUTH verification successful, but another build() needed */
541 this->authentication_failed
= TRUE
;
545 /* store authentication information */
546 cfg
= auth_cfg_create();
547 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
), FALSE
);
548 this->ike_sa
->add_auth_cfg(this->ike_sa
, FALSE
, cfg
);
550 /* another auth round done, invoke authorize hook */
551 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
553 DBG1(DBG_IKE
, "authorization hook forbids IKE_SA, cancelling");
554 this->authentication_failed
= TRUE
;
558 if (!update_cfg_candidates(this, FALSE
))
560 this->authentication_failed
= TRUE
;
564 if (message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
) == NULL
)
566 this->expect_another_auth
= FALSE
;
567 if (!update_cfg_candidates(this, TRUE
))
569 this->authentication_failed
= TRUE
;
577 * Implementation of task_t.build for responder
579 static status_t
build_r(private_ike_auth_t
*this, message_t
*message
)
583 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
585 if (multiple_auth_enabled())
587 message
->add_notify(message
, FALSE
, MULTIPLE_AUTH_SUPPORTED
,
590 return collect_my_init_data(this, message
);
593 if (this->authentication_failed
|| this->peer_cfg
== NULL
)
595 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
599 if (this->my_auth
== NULL
&& this->do_another_auth
)
601 identification_t
*id
, *id_cfg
;
602 id_payload_t
*id_payload
;
605 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
606 cfg
->purge(cfg
, TRUE
);
607 cfg
->merge(cfg
, get_auth_cfg(this, TRUE
), TRUE
);
609 id_cfg
= cfg
->get(cfg
, AUTH_RULE_IDENTITY
);
610 id
= this->ike_sa
->get_my_id(this->ike_sa
);
611 if (id
->get_type(id
) == ID_ANY
)
612 { /* no IDr received, apply configured ID */
613 if (!id_cfg
|| id_cfg
->contains_wildcards(id_cfg
))
615 DBG1(DBG_CFG
, "IDr not configured and negotiation failed");
616 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
620 this->ike_sa
->set_my_id(this->ike_sa
, id_cfg
->clone(id_cfg
));
624 { /* IDr received, check if it matches configuration */
625 if (id_cfg
&& !id
->matches(id
, id_cfg
))
627 DBG1(DBG_CFG
, "received IDr %Y, but require %Y", id
, id_cfg
);
628 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
634 id_payload
= id_payload_create_from_identification(ID_RESPONDER
, id
);
635 message
->add_payload(message
, (payload_t
*)id_payload
);
637 /* build authentication data */
638 this->my_auth
= authenticator_create_builder(this->ike_sa
, cfg
,
639 this->other_nonce
, this->my_nonce
,
640 this->other_packet
->get_data(this->other_packet
),
641 this->my_packet
->get_data(this->my_packet
));
644 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
649 if (this->other_auth
)
651 switch (this->other_auth
->build(this->other_auth
, message
))
654 this->other_auth
->destroy(this->other_auth
);
655 this->other_auth
= NULL
;
660 if (!message
->get_payload(message
, EXTENSIBLE_AUTHENTICATION
))
661 { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
662 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
670 switch (this->my_auth
->build(this->my_auth
, message
))
673 cfg
= auth_cfg_create();
674 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
),
676 this->ike_sa
->add_auth_cfg(this->ike_sa
, TRUE
, cfg
);
677 this->my_auth
->destroy(this->my_auth
);
678 this->my_auth
= NULL
;
683 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
689 /* check for additional authentication rounds */
690 if (do_another_auth(this))
692 message
->add_notify(message
, FALSE
, ANOTHER_AUTH_FOLLOWS
, chunk_empty
);
696 this->do_another_auth
= FALSE
;
698 if (!this->do_another_auth
&& !this->expect_another_auth
)
700 if (charon
->ike_sa_manager
->check_uniqueness(charon
->ike_sa_manager
,
703 DBG1(DBG_IKE
, "cancelling IKE_SA setup due uniqueness policy");
704 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
708 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
710 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, cancelling");
711 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
,
715 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
716 this->ike_sa
->get_name(this->ike_sa
),
717 this->ike_sa
->get_unique_id(this->ike_sa
),
718 this->ike_sa
->get_my_host(this->ike_sa
),
719 this->ike_sa
->get_my_id(this->ike_sa
),
720 this->ike_sa
->get_other_host(this->ike_sa
),
721 this->ike_sa
->get_other_id(this->ike_sa
));
722 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
723 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
730 * Implementation of task_t.process for initiator
732 static status_t
process_i(private_ike_auth_t
*this, message_t
*message
)
734 enumerator_t
*enumerator
;
738 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
740 if (message
->get_notify(message
, MULTIPLE_AUTH_SUPPORTED
) &&
741 multiple_auth_enabled())
743 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MULTIPLE_AUTH
);
745 return collect_other_init_data(this, message
);
748 enumerator
= message
->create_payload_enumerator(message
);
749 while (enumerator
->enumerate(enumerator
, &payload
))
751 if (payload
->get_type(payload
) == NOTIFY
)
753 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
754 notify_type_t type
= notify
->get_notify_type(notify
);
758 case NO_PROPOSAL_CHOSEN
:
759 case SINGLE_PAIR_REQUIRED
:
760 case NO_ADDITIONAL_SAS
:
761 case INTERNAL_ADDRESS_FAILURE
:
762 case FAILED_CP_REQUIRED
:
763 case TS_UNACCEPTABLE
:
764 case INVALID_SELECTORS
:
765 /* these are errors, but are not critical as only the
766 * CHILD_SA won't get build, but IKE_SA establishes anyway */
768 case MOBIKE_SUPPORTED
:
769 case ADDITIONAL_IP4_ADDRESS
:
770 case ADDITIONAL_IP6_ADDRESS
:
771 /* handled in ike_mobike task */
774 /* handled in ike_auth_lifetime task */
777 /* handled in ike_me task */
783 DBG1(DBG_IKE
, "received %N notify error",
784 notify_type_names
, type
);
785 enumerator
->destroy(enumerator
);
788 DBG2(DBG_IKE
, "received %N notify",
789 notify_type_names
, type
);
795 enumerator
->destroy(enumerator
);
799 switch (this->my_auth
->process(this->my_auth
, message
))
802 cfg
= auth_cfg_create();
803 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
),
805 this->ike_sa
->add_auth_cfg(this->ike_sa
, TRUE
, cfg
);
806 this->my_auth
->destroy(this->my_auth
);
807 this->my_auth
= NULL
;
808 this->do_another_auth
= do_another_auth(this);
817 if (this->expect_another_auth
)
819 if (this->other_auth
== NULL
)
821 id_payload_t
*id_payload
;
822 identification_t
*id
;
824 /* responder is not allowed to do EAP */
825 if (!message
->get_payload(message
, AUTHENTICATION
))
827 DBG1(DBG_IKE
, "AUTH payload missing");
831 /* handle IDr payload */
832 id_payload
= (id_payload_t
*)message
->get_payload(message
,
836 DBG1(DBG_IKE
, "IDr payload missing");
839 id
= id_payload
->get_identification(id_payload
);
840 this->ike_sa
->set_other_id(this->ike_sa
, id
);
841 cfg
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
842 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, id
->clone(id
));
844 /* verify authentication data */
845 this->other_auth
= authenticator_create_verifier(this->ike_sa
,
846 message
, this->other_nonce
, this->my_nonce
,
847 this->other_packet
->get_data(this->other_packet
),
848 this->my_packet
->get_data(this->my_packet
));
849 if (!this->other_auth
)
854 switch (this->other_auth
->process(this->other_auth
, message
))
863 /* store authentication information, reset authenticator */
864 cfg
= auth_cfg_create();
865 cfg
->merge(cfg
, this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
), FALSE
);
866 this->ike_sa
->add_auth_cfg(this->ike_sa
, FALSE
, cfg
);
867 this->other_auth
->destroy(this->other_auth
);
868 this->other_auth
= NULL
;
870 /* another auth round done, invoke authorize hook */
871 if (!charon
->bus
->authorize(charon
->bus
, FALSE
))
873 DBG1(DBG_IKE
, "authorization forbids IKE_SA, cancelling");
878 if (message
->get_notify(message
, ANOTHER_AUTH_FOLLOWS
) == NULL
)
880 this->expect_another_auth
= FALSE
;
882 if (!this->expect_another_auth
&& !this->do_another_auth
&& !this->my_auth
)
884 if (!update_cfg_candidates(this, TRUE
))
888 if (!charon
->bus
->authorize(charon
->bus
, TRUE
))
890 DBG1(DBG_IKE
, "final authorization hook forbids IKE_SA, cancelling");
893 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
894 this->ike_sa
->get_name(this->ike_sa
),
895 this->ike_sa
->get_unique_id(this->ike_sa
),
896 this->ike_sa
->get_my_host(this->ike_sa
),
897 this->ike_sa
->get_my_id(this->ike_sa
),
898 this->ike_sa
->get_other_host(this->ike_sa
),
899 this->ike_sa
->get_other_id(this->ike_sa
));
900 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
901 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
908 * Implementation of task_t.get_type
910 static task_type_t
get_type(private_ike_auth_t
*this)
912 return IKE_AUTHENTICATE
;
916 * Implementation of task_t.migrate
918 static void migrate(private_ike_auth_t
*this, ike_sa_t
*ike_sa
)
920 chunk_free(&this->my_nonce
);
921 chunk_free(&this->other_nonce
);
922 DESTROY_IF(this->my_packet
);
923 DESTROY_IF(this->other_packet
);
924 DESTROY_IF(this->peer_cfg
);
925 DESTROY_IF(this->my_auth
);
926 DESTROY_IF(this->other_auth
);
927 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
929 this->my_packet
= NULL
;
930 this->other_packet
= NULL
;
931 this->ike_sa
= ike_sa
;
932 this->peer_cfg
= NULL
;
933 this->my_auth
= NULL
;
934 this->other_auth
= NULL
;
935 this->do_another_auth
= TRUE
;
936 this->expect_another_auth
= TRUE
;
937 this->authentication_failed
= FALSE
;
938 this->candidates
= linked_list_create();
942 * Implementation of task_t.destroy
944 static void destroy(private_ike_auth_t
*this)
946 chunk_free(&this->my_nonce
);
947 chunk_free(&this->other_nonce
);
948 DESTROY_IF(this->my_packet
);
949 DESTROY_IF(this->other_packet
);
950 DESTROY_IF(this->my_auth
);
951 DESTROY_IF(this->other_auth
);
952 DESTROY_IF(this->peer_cfg
);
953 this->candidates
->destroy_offset(this->candidates
, offsetof(peer_cfg_t
, destroy
));
958 * Described in header.
960 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
, bool initiator
)
962 private_ike_auth_t
*this = malloc_thing(private_ike_auth_t
);
964 this->public.task
.get_type
= (task_type_t(*)(task_t
*))get_type
;
965 this->public.task
.migrate
= (void(*)(task_t
*,ike_sa_t
*))migrate
;
966 this->public.task
.destroy
= (void(*)(task_t
*))destroy
;
970 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_i
;
971 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_i
;
975 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_r
;
976 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_r
;
979 this->ike_sa
= ike_sa
;
980 this->initiator
= initiator
;
981 this->my_nonce
= chunk_empty
;
982 this->other_nonce
= chunk_empty
;
983 this->my_packet
= NULL
;
984 this->other_packet
= NULL
;
985 this->peer_cfg
= NULL
;
986 this->candidates
= linked_list_create();
987 this->my_auth
= NULL
;
988 this->other_auth
= NULL
;
989 this->do_another_auth
= TRUE
;
990 this->expect_another_auth
= TRUE
;
991 this->authentication_failed
= FALSE
;
993 return &this->public;