send proper AUTHENTICATION_FAILED if EAP method is successful, but AUTH mismatches
[strongswan.git] / src / charon / sa / tasks / ike_auth.c
1 /*
2 * Copyright (C) 2005-2007 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
5 *
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>.
10 *
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
14 * for more details
15 *
16 * $Id$
17 */
18
19 #include "ike_auth.h"
20
21 #include <string.h>
22
23 #include <daemon.h>
24 #include <crypto/diffie_hellman.h>
25 #include <encoding/payloads/id_payload.h>
26 #include <encoding/payloads/auth_payload.h>
27 #include <encoding/payloads/eap_payload.h>
28 #include <encoding/payloads/nonce_payload.h>
29 #include <sa/authenticators/eap_authenticator.h>
30
31
32 typedef struct private_ike_auth_t private_ike_auth_t;
33
34 /**
35 * Private members of a ike_auth_t task.
36 */
37 struct private_ike_auth_t {
38
39 /**
40 * Public methods and task_t interface.
41 */
42 ike_auth_t public;
43
44 /**
45 * Assigned IKE_SA.
46 */
47 ike_sa_t *ike_sa;
48
49 /**
50 * Are we the initiator?
51 */
52 bool initiator;
53
54 /**
55 * Nonce chosen by us in ike_init
56 */
57 chunk_t my_nonce;
58
59 /**
60 * Nonce chosen by peer in ike_init
61 */
62 chunk_t other_nonce;
63
64 /**
65 * IKE_SA_INIT message sent by us
66 */
67 packet_t *my_packet;
68
69 /**
70 * IKE_SA_INIT message sent by peer
71 */
72 packet_t *other_packet;
73
74 /**
75 * EAP authenticator when using EAP
76 */
77 eap_authenticator_t *eap_auth;
78
79 /**
80 * EAP payload received and ready to process
81 */
82 eap_payload_t *eap_payload;
83
84 /**
85 * has the peer been authenticated successfully?
86 */
87 bool peer_authenticated;
88 };
89
90 /**
91 * get the authentication class of a config
92 */
93 auth_class_t get_auth_class(peer_cfg_t *config)
94 {
95 auth_class_t *class;
96 auth_info_t *auth_info;
97
98 auth_info = config->get_auth(config);
99 if (auth_info->get_item(auth_info, AUTHN_AUTH_CLASS, (void**)&class))
100 {
101 return *class;
102 }
103 /* fallback to pubkey authentication */
104 return AUTH_CLASS_PUBKEY;
105 }
106
107 /**
108 * get the eap type/vendor
109 */
110 static eap_type_t get_eap_type(peer_cfg_t *config, u_int32_t *vendor)
111 {
112 auth_info_t *auth_info;
113 u_int *ptr;
114
115 *vendor = 0;
116 auth_info = config->get_auth(config);
117 if (auth_info->get_item(auth_info, AUTHN_EAP_VENDOR, (void**)&ptr))
118 {
119 *vendor = *ptr;
120 }
121 if (auth_info->get_item(auth_info, AUTHN_EAP_TYPE, (void**)&ptr))
122 {
123 return *ptr;
124 }
125 return EAP_NAK;
126 }
127
128 /**
129 * build the AUTH payload
130 */
131 static status_t build_auth(private_ike_auth_t *this, message_t *message)
132 {
133 authenticator_t *auth;
134 auth_payload_t *auth_payload;
135 peer_cfg_t *config;
136 status_t status;
137
138 /* create own authenticator and add auth payload */
139 config = this->ike_sa->get_peer_cfg(this->ike_sa);
140 if (!config)
141 {
142 DBG1(DBG_IKE, "unable to authenticate, no peer config found");
143 return FAILED;
144 }
145
146 auth = authenticator_create_from_class(this->ike_sa, get_auth_class(config));
147 if (auth == NULL)
148 {
149 DBG1(DBG_IKE, "configured authentication class %N not supported",
150 auth_class_names, get_auth_class(config));
151 return FAILED;
152 }
153
154 status = auth->build(auth, this->my_packet->get_data(this->my_packet),
155 this->other_nonce, &auth_payload);
156 auth->destroy(auth);
157 if (status != SUCCESS)
158 {
159 DBG1(DBG_IKE, "generating authentication data failed");
160 return FAILED;
161 }
162 message->add_payload(message, (payload_t*)auth_payload);
163 return SUCCESS;
164 }
165
166 /**
167 * build ID payload(s)
168 */
169 static status_t build_id(private_ike_auth_t *this, message_t *message)
170 {
171 identification_t *me, *other;
172 id_payload_t *id;
173 peer_cfg_t *config;
174
175 me = this->ike_sa->get_my_id(this->ike_sa);
176 other = this->ike_sa->get_other_id(this->ike_sa);
177 config = this->ike_sa->get_peer_cfg(this->ike_sa);
178
179 if (me->contains_wildcards(me))
180 {
181 me = config->get_my_id(config);
182 if (me->contains_wildcards(me))
183 {
184 DBG1(DBG_IKE, "negotiation of own ID failed");
185 return FAILED;
186 }
187 this->ike_sa->set_my_id(this->ike_sa, me->clone(me));
188 }
189
190 id = id_payload_create_from_identification(this->initiator ? ID_INITIATOR : ID_RESPONDER, me);
191 message->add_payload(message, (payload_t*)id);
192
193 /* as initiator, include other ID if it does not contain wildcards */
194 if (this->initiator && !other->contains_wildcards(other))
195 {
196 id = id_payload_create_from_identification(ID_RESPONDER, other);
197 message->add_payload(message, (payload_t*)id);
198 }
199 return SUCCESS;
200 }
201
202 /**
203 * process AUTH payload
204 */
205 static status_t process_auth(private_ike_auth_t *this, message_t *message)
206 {
207 auth_payload_t *auth_payload;
208 authenticator_t *auth;
209 auth_method_t auth_method;
210 status_t status;
211
212 auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
213
214 if (auth_payload == NULL)
215 {
216 /* AUTH payload is missing, client wants to use EAP authentication */
217 return NOT_FOUND;
218 }
219
220 auth_method = auth_payload->get_auth_method(auth_payload);
221 auth = authenticator_create_from_method(this->ike_sa,
222 auth_payload->get_auth_method(auth_payload));
223 if (auth == NULL)
224 {
225 DBG1(DBG_IKE, "authentication method %N used by '%D' not supported",
226 auth_method_names, auth_method,
227 this->ike_sa->get_other_id(this->ike_sa));
228 return NOT_SUPPORTED;
229 }
230 status = auth->verify(auth, this->other_packet->get_data(this->other_packet),
231 this->my_nonce, auth_payload);
232 auth->destroy(auth);
233 if (status != SUCCESS)
234 {
235 DBG0(DBG_IKE, "authentication of '%D' with %N failed",
236 this->ike_sa->get_other_id(this->ike_sa),
237 auth_method_names, auth_method);
238 return FAILED;
239 }
240 return SUCCESS;
241 }
242
243 /**
244 * process ID payload(s)
245 */
246 static status_t process_id(private_ike_auth_t *this, message_t *message)
247 {
248 identification_t *id, *req;
249 id_payload_t *idr, *idi;
250
251 idi = (id_payload_t*)message->get_payload(message, ID_INITIATOR);
252 idr = (id_payload_t*)message->get_payload(message, ID_RESPONDER);
253
254 if ((this->initiator && idr == NULL) || (!this->initiator && idi == NULL))
255 {
256 DBG1(DBG_IKE, "ID payload missing in message");
257 return FAILED;
258 }
259
260 if (this->initiator)
261 {
262 id = idr->get_identification(idr);
263 req = this->ike_sa->get_other_id(this->ike_sa);
264 if (!id->matches(id, req))
265 {
266 DBG0(DBG_IKE, "peer ID '%D' unacceptable, '%D' required", id, req);
267 id->destroy(id);
268 return FAILED;
269 }
270 this->ike_sa->set_other_id(this->ike_sa, id);
271 }
272 else
273 {
274 id = idi->get_identification(idi);
275 this->ike_sa->set_other_id(this->ike_sa, id);
276 if (idr)
277 {
278 id = idr->get_identification(idr);
279 this->ike_sa->set_my_id(this->ike_sa, id);
280 }
281 }
282 return SUCCESS;
283 }
284
285 /**
286 * collect the needed information in the IKE_SA_INIT exchange from our message
287 */
288 static status_t collect_my_init_data(private_ike_auth_t *this, message_t *message)
289 {
290 nonce_payload_t *nonce;
291
292 /* get the nonce that was generated in ike_init */
293 nonce = (nonce_payload_t*)message->get_payload(message, NONCE);
294 if (nonce == NULL)
295 {
296 return FAILED;
297 }
298 this->my_nonce = nonce->get_nonce(nonce);
299
300 /* pre-generate the message, so we can store it for us */
301 if (this->ike_sa->generate_message(this->ike_sa, message,
302 &this->my_packet) != SUCCESS)
303 {
304 return FAILED;
305 }
306 return NEED_MORE;
307 }
308
309 /**
310 * collect the needed information in the IKE_SA_INIT exchange from others message
311 */
312 static status_t collect_other_init_data(private_ike_auth_t *this, message_t *message)
313 {
314 /* we collect the needed information in the IKE_SA_INIT exchange */
315 nonce_payload_t *nonce;
316
317 /* get the nonce that was generated in ike_init */
318 nonce = (nonce_payload_t*)message->get_payload(message, NONCE);
319 if (nonce == NULL)
320 {
321 return FAILED;
322 }
323 this->other_nonce = nonce->get_nonce(nonce);
324
325 /* pre-generate the message, so we can store it for us */
326 this->other_packet = message->get_packet(message);
327 return NEED_MORE;
328 }
329
330
331 /**
332 * Implementation of task_t.build to create AUTH payload from EAP data
333 */
334 static status_t build_auth_eap(private_ike_auth_t *this, message_t *message)
335 {
336 authenticator_t *auth;
337 auth_payload_t *auth_payload;
338
339 if (!this->initiator && !this->peer_authenticated)
340 {
341 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
342 return FAILED;
343 }
344
345 auth = (authenticator_t*)this->eap_auth;
346 if (auth->build(auth, this->my_packet->get_data(this->my_packet),
347 this->other_nonce, &auth_payload) != SUCCESS)
348 {
349 DBG1(DBG_IKE, "generating authentication data failed");
350 if (!this->initiator)
351 {
352 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
353 }
354 return FAILED;
355 }
356 message->add_payload(message, (payload_t*)auth_payload);
357 if (!this->initiator)
358 {
359 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
360 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
361 this->ike_sa->get_name(this->ike_sa),
362 this->ike_sa->get_unique_id(this->ike_sa),
363 this->ike_sa->get_my_host(this->ike_sa),
364 this->ike_sa->get_my_id(this->ike_sa),
365 this->ike_sa->get_other_host(this->ike_sa),
366 this->ike_sa->get_other_id(this->ike_sa));
367 return SUCCESS;
368 }
369 return NEED_MORE;
370 }
371
372 /**
373 * Implementation of task_t.process to verify AUTH payload after EAP
374 */
375 static status_t process_auth_eap(private_ike_auth_t *this, message_t *message)
376 {
377 auth_payload_t *auth_payload;
378 authenticator_t *auth;
379
380 auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
381 this->peer_authenticated = FALSE;
382
383 if (auth_payload)
384 {
385 auth = (authenticator_t*)this->eap_auth;
386 if (auth->verify(auth, this->other_packet->get_data(this->other_packet),
387 this->my_nonce, auth_payload) == SUCCESS)
388 {
389 this->peer_authenticated = TRUE;
390 }
391 }
392
393 if (!this->peer_authenticated)
394 {
395 DBG0(DBG_IKE, "authentication of '%D' with %N failed",
396 this->ike_sa->get_other_id(this->ike_sa),
397 auth_class_names, AUTH_CLASS_EAP);
398 if (this->initiator)
399 {
400 return FAILED;
401 }
402 return NEED_MORE;
403 }
404 if (this->initiator)
405 {
406 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
407 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
408 this->ike_sa->get_name(this->ike_sa),
409 this->ike_sa->get_unique_id(this->ike_sa),
410 this->ike_sa->get_my_host(this->ike_sa),
411 this->ike_sa->get_my_id(this->ike_sa),
412 this->ike_sa->get_other_host(this->ike_sa),
413 this->ike_sa->get_other_id(this->ike_sa));
414 return SUCCESS;
415 }
416 return NEED_MORE;
417 }
418
419 /**
420 * Implementation of task_t.process for EAP exchanges
421 */
422 static status_t process_eap_i(private_ike_auth_t *this, message_t *message)
423 {
424 eap_payload_t *eap;
425
426 eap = (eap_payload_t*)message->get_payload(message, EXTENSIBLE_AUTHENTICATION);
427 if (eap == NULL)
428 {
429 DBG1(DBG_IKE, "EAP payload missing");
430 return FAILED;
431 }
432 switch (this->eap_auth->process(this->eap_auth, eap, &eap))
433 {
434 case NEED_MORE:
435 this->eap_payload = eap;
436 return NEED_MORE;
437 case SUCCESS:
438 /* EAP exchange completed, now create and process AUTH */
439 this->eap_payload = NULL;
440 this->public.task.build = (status_t(*)(task_t*,message_t*))build_auth_eap;
441 this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap;
442 return NEED_MORE;
443 default:
444 this->eap_payload = NULL;
445 DBG0(DBG_IKE, "failed to authenticate against '%D' using EAP",
446 this->ike_sa->get_other_id(this->ike_sa));
447 return FAILED;
448 }
449 }
450
451 /**
452 * Implementation of task_t.process for EAP exchanges
453 */
454 static status_t process_eap_r(private_ike_auth_t *this, message_t *message)
455 {
456 this->eap_payload = (eap_payload_t*)message->get_payload(message,
457 EXTENSIBLE_AUTHENTICATION);
458 return NEED_MORE;
459 }
460
461 /**
462 * Implementation of task_t.build for EAP exchanges
463 */
464 static status_t build_eap_i(private_ike_auth_t *this, message_t *message)
465 {
466 message->add_payload(message, (payload_t*)this->eap_payload);
467 return NEED_MORE;
468 }
469
470 /**
471 * Implementation of task_t.build for EAP exchanges
472 */
473 static status_t build_eap_r(private_ike_auth_t *this, message_t *message)
474 {
475 status_t status = NEED_MORE;
476 eap_payload_t *eap;
477
478 if (this->eap_payload == NULL)
479 {
480 DBG1(DBG_IKE, "EAP payload missing");
481 return FAILED;
482 }
483
484 switch (this->eap_auth->process(this->eap_auth, this->eap_payload, &eap))
485 {
486 case NEED_MORE:
487
488 break;
489 case SUCCESS:
490 /* EAP exchange completed, now create and process AUTH */
491 this->public.task.build = (status_t(*)(task_t*,message_t*))build_auth_eap;
492 this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap;
493 break;
494 default:
495 DBG0(DBG_IKE, "authentication of '%D' with %N failed",
496 this->ike_sa->get_other_id(this->ike_sa),
497 auth_class_names, AUTH_CLASS_EAP);
498 status = FAILED;
499 break;
500 }
501 message->add_payload(message, (payload_t*)eap);
502 return status;
503 }
504
505 /**
506 * Implementation of task_t.build for initiator
507 */
508 static status_t build_i(private_ike_auth_t *this, message_t *message)
509 {
510 peer_cfg_t *config;
511
512 if (message->get_exchange_type(message) == IKE_SA_INIT)
513 {
514 return collect_my_init_data(this, message);
515 }
516
517 if (build_id(this, message) != SUCCESS)
518 {
519 return FAILED;
520 }
521
522 config = this->ike_sa->get_peer_cfg(this->ike_sa);
523 if (get_auth_class(config) == AUTH_CLASS_EAP)
524 {
525 this->eap_auth = eap_authenticator_create(this->ike_sa);
526 }
527 else
528 {
529 if (build_auth(this, message) != SUCCESS)
530 {
531 return FAILED;
532 }
533 }
534
535 return NEED_MORE;
536 }
537
538 /**
539 * Implementation of task_t.process for responder
540 */
541 static status_t process_r(private_ike_auth_t *this, message_t *message)
542 {
543 peer_cfg_t *config;
544
545 if (message->get_exchange_type(message) == IKE_SA_INIT)
546 {
547 return collect_other_init_data(this, message);
548 }
549
550 if (process_id(this, message) != SUCCESS)
551 {
552 return NEED_MORE;
553 }
554
555 switch (process_auth(this, message))
556 {
557 case SUCCESS:
558 this->peer_authenticated = TRUE;
559 break;
560 case NOT_FOUND:
561 /* use EAP if no AUTH payload found */
562 this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED, TRUE);
563 break;
564 default:
565 return NEED_MORE;
566 }
567
568 config = charon->backends->get_peer_cfg(charon->backends,
569 this->ike_sa->get_my_host(this->ike_sa),
570 this->ike_sa->get_other_host(this->ike_sa),
571 this->ike_sa->get_my_id(this->ike_sa),
572 this->ike_sa->get_other_id(this->ike_sa),
573 this->ike_sa->get_other_auth(this->ike_sa));
574 if (config)
575 {
576 this->ike_sa->set_peer_cfg(this->ike_sa, config);
577 config->destroy(config);
578 }
579 if (!this->peer_authenticated)
580 {
581 this->eap_auth = eap_authenticator_create(this->ike_sa);
582 }
583 return NEED_MORE;
584 }
585
586 /**
587 * Implementation of task_t.build for responder
588 */
589 static status_t build_r(private_ike_auth_t *this, message_t *message)
590 {
591 peer_cfg_t *config;
592 eap_type_t eap_type;
593 u_int32_t eap_vendor;
594 eap_payload_t *eap_payload;
595 status_t status;
596
597 if (message->get_exchange_type(message) == IKE_SA_INIT)
598 {
599 return collect_my_init_data(this, message);
600 }
601
602 if (!this->peer_authenticated && this->eap_auth == NULL)
603 {
604 /* peer not authenticated, nor does it want to use EAP */
605 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
606 return FAILED;
607 }
608
609 config = this->ike_sa->get_peer_cfg(this->ike_sa);
610 if (config == NULL)
611 {
612 DBG1(DBG_IKE, "no matching config found for '%D'...'%D'",
613 this->ike_sa->get_my_id(this->ike_sa),
614 this->ike_sa->get_other_id(this->ike_sa));
615 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
616 return FAILED;
617 }
618
619 if (build_id(this, message) != SUCCESS ||
620 build_auth(this, message) != SUCCESS)
621 {
622 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
623 return FAILED;
624 }
625
626 if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
627 this->ike_sa))
628 {
629 DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
630 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
631 return FAILED;
632 }
633
634 /* use "traditional" authentication if we could authenticate peer */
635 if (this->peer_authenticated)
636 {
637 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
638 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
639 this->ike_sa->get_name(this->ike_sa),
640 this->ike_sa->get_unique_id(this->ike_sa),
641 this->ike_sa->get_my_host(this->ike_sa),
642 this->ike_sa->get_my_id(this->ike_sa),
643 this->ike_sa->get_other_host(this->ike_sa),
644 this->ike_sa->get_other_id(this->ike_sa));
645 return SUCCESS;
646 }
647
648 /* initiate EAP authenitcation */
649 eap_type = get_eap_type(config, &eap_vendor);
650 status = this->eap_auth->initiate(this->eap_auth, eap_type,
651 eap_vendor, &eap_payload);
652 message->add_payload(message, (payload_t*)eap_payload);
653 if (status != NEED_MORE)
654 {
655 DBG1(DBG_IKE, "unable to initiate EAP authentication");
656 return FAILED;
657 }
658
659 /* switch to EAP methods */
660 this->public.task.build = (status_t(*)(task_t*,message_t*))build_eap_r;
661 this->public.task.process = (status_t(*)(task_t*,message_t*))process_eap_r;
662 return NEED_MORE;
663 }
664
665 /**
666 * Implementation of task_t.process for initiator
667 */
668 static status_t process_i(private_ike_auth_t *this, message_t *message)
669 {
670 iterator_t *iterator;
671 payload_t *payload;
672 peer_cfg_t *config;
673 auth_info_t *auth;
674
675 if (message->get_exchange_type(message) == IKE_SA_INIT)
676 {
677 return collect_other_init_data(this, message);
678 }
679
680 iterator = message->get_payload_iterator(message);
681 while (iterator->iterate(iterator, (void**)&payload))
682 {
683 if (payload->get_type(payload) == NOTIFY)
684 {
685 notify_payload_t *notify = (notify_payload_t*)payload;
686 notify_type_t type = notify->get_notify_type(notify);
687
688 switch (type)
689 {
690 case NO_PROPOSAL_CHOSEN:
691 case SINGLE_PAIR_REQUIRED:
692 case NO_ADDITIONAL_SAS:
693 case INTERNAL_ADDRESS_FAILURE:
694 case FAILED_CP_REQUIRED:
695 case TS_UNACCEPTABLE:
696 case INVALID_SELECTORS:
697 /* these are errors, but are not critical as only the
698 * CHILD_SA won't get build, but IKE_SA establishes anyway */
699 break;
700 case MOBIKE_SUPPORTED:
701 case ADDITIONAL_IP4_ADDRESS:
702 case ADDITIONAL_IP6_ADDRESS:
703 /* handled in ike_mobike task */
704 break;
705 case AUTH_LIFETIME:
706 /* handled in ike_auth_lifetime task */
707 break;
708 case ME_ENDPOINT:
709 /* handled in ike_me task */
710 break;
711 default:
712 {
713 if (type < 16383)
714 {
715 DBG1(DBG_IKE, "received %N notify error",
716 notify_type_names, type);
717 iterator->destroy(iterator);
718 return FAILED;
719 }
720 DBG2(DBG_IKE, "received %N notify",
721 notify_type_names, type);
722 break;
723 }
724 }
725 }
726 }
727 iterator->destroy(iterator);
728
729 if (process_id(this, message) != SUCCESS ||
730 process_auth(this, message) != SUCCESS)
731 {
732 return FAILED;
733 }
734
735 if (this->eap_auth)
736 {
737 /* switch to EAP authentication methods */
738 this->public.task.build = (status_t(*)(task_t*,message_t*))build_eap_i;
739 this->public.task.process = (status_t(*)(task_t*,message_t*))process_eap_i;
740 return process_eap_i(this, message);
741 }
742
743 config = this->ike_sa->get_peer_cfg(this->ike_sa);
744 auth = this->ike_sa->get_other_auth(this->ike_sa);
745 if (!auth->complies(auth, config->get_auth(config)))
746 {
747 DBG0(DBG_IKE, "authorization of '%D' for config %s failed",
748 this->ike_sa->get_other_id(this->ike_sa), config->get_name(config));
749 return FAILED;
750 }
751 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
752 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
753 this->ike_sa->get_name(this->ike_sa),
754 this->ike_sa->get_unique_id(this->ike_sa),
755 this->ike_sa->get_my_host(this->ike_sa),
756 this->ike_sa->get_my_id(this->ike_sa),
757 this->ike_sa->get_other_host(this->ike_sa),
758 this->ike_sa->get_other_id(this->ike_sa));
759 return SUCCESS;
760 }
761
762 /**
763 * Implementation of task_t.get_type
764 */
765 static task_type_t get_type(private_ike_auth_t *this)
766 {
767 return IKE_AUTHENTICATE;
768 }
769
770 /**
771 * Implementation of task_t.migrate
772 */
773 static void migrate(private_ike_auth_t *this, ike_sa_t *ike_sa)
774 {
775 chunk_free(&this->my_nonce);
776 chunk_free(&this->other_nonce);
777 DESTROY_IF(this->my_packet);
778 DESTROY_IF(this->other_packet);
779 if (this->eap_auth)
780 {
781 this->eap_auth->authenticator_interface.destroy(
782 &this->eap_auth->authenticator_interface);
783 }
784
785 this->my_packet = NULL;
786 this->other_packet = NULL;
787 this->peer_authenticated = FALSE;
788 this->eap_auth = NULL;
789 this->eap_payload = NULL;
790 this->ike_sa = ike_sa;
791 if (this->initiator)
792 {
793 this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
794 this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
795 }
796 else
797 {
798 this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
799 this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
800 }
801 }
802
803 /**
804 * Implementation of task_t.destroy
805 */
806 static void destroy(private_ike_auth_t *this)
807 {
808 chunk_free(&this->my_nonce);
809 chunk_free(&this->other_nonce);
810 DESTROY_IF(this->my_packet);
811 DESTROY_IF(this->other_packet);
812 if (this->eap_auth)
813 {
814 this->eap_auth->authenticator_interface.destroy(
815 &this->eap_auth->authenticator_interface);
816 }
817 free(this);
818 }
819
820 /*
821 * Described in header.
822 */
823 ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
824 {
825 private_ike_auth_t *this = malloc_thing(private_ike_auth_t);
826
827 this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
828 this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
829 this->public.task.destroy = (void(*)(task_t*))destroy;
830
831 if (initiator)
832 {
833 this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
834 this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
835 }
836 else
837 {
838 this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
839 this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
840 }
841
842 this->ike_sa = ike_sa;
843 this->initiator = initiator;
844 this->my_nonce = chunk_empty;
845 this->other_nonce = chunk_empty;
846 this->my_packet = NULL;
847 this->other_packet = NULL;
848 this->peer_authenticated = FALSE;
849 this->eap_auth = NULL;
850 this->eap_payload = NULL;
851
852 return &this->public;
853 }