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