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