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