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