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