sending an SPI of 0 as responder when IKE_SA_INIT fails
[strongswan.git] / src / charon / sa / task_manager.c
1 /**
2 * @file task_manager.c
3 *
4 * @brief Implementation of task_manager_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2007 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "task_manager.h"
24
25 #include <daemon.h>
26 #include <sa/tasks/ike_init.h>
27 #include <sa/tasks/ike_natd.h>
28 #include <sa/tasks/ike_auth.h>
29 #include <sa/tasks/ike_cert.h>
30 #include <sa/tasks/ike_rekey.h>
31 #include <sa/tasks/ike_delete.h>
32 #include <sa/tasks/ike_config.h>
33 #include <sa/tasks/ike_dpd.h>
34 #include <sa/tasks/child_create.h>
35 #include <sa/tasks/child_rekey.h>
36 #include <sa/tasks/child_delete.h>
37 #include <encoding/payloads/delete_payload.h>
38 #include <queues/jobs/retransmit_job.h>
39
40 typedef struct exchange_t exchange_t;
41
42 /**
43 * An exchange in the air, used do detect and handle retransmission
44 */
45 struct exchange_t {
46
47 /**
48 * Message ID used for this transaction
49 */
50 u_int32_t mid;
51
52 /**
53 * generated packet for retransmission
54 */
55 packet_t *packet;
56 };
57
58 typedef struct private_task_manager_t private_task_manager_t;
59
60 /**
61 * private data of the task manager
62 */
63 struct private_task_manager_t {
64
65 /**
66 * public functions
67 */
68 task_manager_t public;
69
70 /**
71 * associated IKE_SA we are serving
72 */
73 ike_sa_t *ike_sa;
74
75 /**
76 * Exchange we are currently handling as responder
77 */
78 struct {
79 /**
80 * Message ID of the exchange
81 */
82 u_int32_t mid;
83
84 /**
85 * packet for retransmission
86 */
87 packet_t *packet;
88
89 } responding;
90
91 /**
92 * Exchange we are currently handling as initiator
93 */
94 struct {
95 /**
96 * Message ID of the exchange
97 */
98 u_int32_t mid;
99
100 /**
101 * how many times we have retransmitted so far
102 */
103 u_int retransmitted;
104
105 /**
106 * packet for retransmission
107 */
108 packet_t *packet;
109
110 /**
111 * type of the initated exchange
112 */
113 exchange_type_t type;
114
115 } initiating;
116
117 /**
118 * List of queued tasks not yet in action
119 */
120 linked_list_t *queued_tasks;
121
122 /**
123 * List of active tasks, initiated by ourselve
124 */
125 linked_list_t *active_tasks;
126
127 /**
128 * List of tasks initiated by peer
129 */
130 linked_list_t *passive_tasks;
131
132 /**
133 * ike_sa_init message we sent, stored here for later authentication
134 */
135 packet_t *ike_sa_init;
136 };
137
138 /**
139 * move a task of a specific type from the queue to the active list
140 */
141 static bool activate_task(private_task_manager_t *this, task_type_t type)
142 {
143 iterator_t *iterator;
144 task_t *task;
145 bool found = FALSE;
146
147 iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE);
148 while (iterator->iterate(iterator, (void**)&task))
149 {
150 if (task->get_type(task) == type)
151 {
152 DBG2(DBG_IKE, " activating %N task", task_type_names, type);
153 iterator->remove(iterator);
154 this->active_tasks->insert_last(this->active_tasks, task);
155 found = TRUE;
156 break;
157 }
158 }
159 iterator->destroy(iterator);
160 return found;
161 }
162
163 /**
164 * Implementation of task_manager_t.retransmit
165 */
166 static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
167 {
168 if (message_id == this->initiating.mid)
169 {
170 u_int32_t timeout;
171 job_t *job;
172
173 timeout = charon->configuration->get_retransmit_timeout(
174 charon->configuration, this->initiating.retransmitted);
175 if (timeout == 0)
176 {
177 DBG1(DBG_IKE, "giving up after %d retransmits",
178 this->initiating.retransmitted - 1);
179 return DESTROY_ME;
180 }
181
182 if (this->initiating.retransmitted)
183 {
184 DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
185 this->initiating.retransmitted, message_id);
186 }
187 this->initiating.retransmitted++;
188
189 charon->send_queue->add(charon->send_queue,
190 this->initiating.packet->clone(this->initiating.packet));
191 job = (job_t*)retransmit_job_create(this->initiating.mid,
192 this->ike_sa->get_id(this->ike_sa));
193 charon->event_queue->add_relative(charon->event_queue, job, timeout);
194 }
195 return SUCCESS;
196 }
197
198 /**
199 * build a request using the active task list
200 * Implementation of task_manager_t.initiate
201 */
202 static status_t build_request(private_task_manager_t *this)
203 {
204 iterator_t *iterator;
205 task_t *task;
206 message_t *message;
207 status_t status;
208 exchange_type_t exchange = 0;
209
210 if (this->active_tasks->get_count(this->active_tasks) == 0)
211 {
212 DBG2(DBG_IKE, "activating new tasks");
213 switch (this->ike_sa->get_state(this->ike_sa))
214 {
215 case IKE_CREATED:
216 if (activate_task(this, IKE_INIT))
217 {
218 exchange = IKE_SA_INIT;
219 activate_task(this, IKE_NATD);
220 activate_task(this, IKE_CERT);
221 activate_task(this, IKE_AUTHENTICATE);
222 activate_task(this, IKE_CONFIG);
223 activate_task(this, CHILD_CREATE);
224 }
225 break;
226 case IKE_ESTABLISHED:
227 if (activate_task(this, CHILD_CREATE))
228 {
229 exchange = CREATE_CHILD_SA;
230 activate_task(this, IKE_CONFIG);
231 break;
232 }
233 if (activate_task(this, CHILD_DELETE))
234 {
235 exchange = INFORMATIONAL;
236 break;
237 }
238 if (activate_task(this, CHILD_REKEY))
239 {
240 exchange = CREATE_CHILD_SA;
241 break;
242 }
243 if (activate_task(this, IKE_DELETE))
244 {
245 exchange = INFORMATIONAL;
246 break;
247 }
248 if (activate_task(this, IKE_REKEY))
249 {
250 exchange = CREATE_CHILD_SA;
251 break;
252 }
253 if (activate_task(this, IKE_DEADPEER))
254 {
255 exchange = INFORMATIONAL;
256 break;
257 }
258 case IKE_REKEYING:
259 if (activate_task(this, IKE_DELETE))
260 {
261 exchange = INFORMATIONAL;
262 break;
263 }
264 case IKE_DELETING:
265 default:
266 break;
267 }
268 }
269 else
270 {
271 DBG2(DBG_IKE, "reinitiating already active tasks");
272 iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
273 while (iterator->iterate(iterator, (void**)&task))
274 {
275 DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
276 switch (task->get_type(task))
277 {
278 case IKE_INIT:
279 exchange = IKE_SA_INIT;
280 break;
281 case IKE_AUTHENTICATE:
282 exchange = IKE_AUTH;
283 break;
284 default:
285 continue;
286 }
287 break;
288 }
289 iterator->destroy(iterator);
290 }
291
292 if (exchange == 0)
293 {
294 DBG2(DBG_IKE, "nothing to initiate");
295 /* nothing to do yet... */
296 return SUCCESS;
297 }
298
299 message = message_create();
300 message->set_message_id(message, this->initiating.mid);
301 message->set_exchange_type(message, exchange);
302 this->initiating.type = exchange;
303 this->initiating.retransmitted = 0;
304
305 iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
306 while (iterator->iterate(iterator, (void*)&task))
307 {
308 switch (task->build(task, message))
309 {
310 case SUCCESS:
311 /* task completed, remove it */
312 iterator->remove(iterator);
313 task->destroy(task);
314 break;
315 case NEED_MORE:
316 /* processed, but task needs another exchange */
317 break;
318 case FAILED:
319 default:
320 /* critical failure, destroy IKE_SA */
321 iterator->destroy(iterator);
322 message->destroy(message);
323 return DESTROY_ME;
324 }
325 }
326 iterator->destroy(iterator);
327
328 DESTROY_IF(this->initiating.packet);
329 status = this->ike_sa->generate_message(this->ike_sa, message,
330 &this->initiating.packet);
331 message->destroy(message);
332 if (status != SUCCESS)
333 {
334 /* message generation failed. There is nothing more to do than to
335 * close the SA */
336 return DESTROY_ME;
337 }
338
339 return retransmit(this, this->initiating.mid);
340 }
341
342 /**
343 * handle an incoming response message
344 */
345 static status_t process_response(private_task_manager_t *this,
346 message_t *message)
347 {
348 iterator_t *iterator;
349 task_t *task;
350
351 if (message->get_exchange_type(message) != this->initiating.type)
352 {
353 DBG1(DBG_IKE, "received %N response, but expected %N",
354 exchange_type_names, message->get_exchange_type(message),
355 exchange_type_names, this->initiating.type);
356 return DESTROY_ME;
357 }
358
359 iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
360 while (iterator->iterate(iterator, (void*)&task))
361 {
362 switch (task->process(task, message))
363 {
364 case SUCCESS:
365 /* task completed, remove it */
366 iterator->remove(iterator);
367 task->destroy(task);
368 break;
369 case NEED_MORE:
370 /* processed, but task needs another exchange */
371 break;
372 case FAILED:
373 default:
374 /* critical failure, destroy IKE_SA */
375 iterator->destroy(iterator);
376 return DESTROY_ME;
377 }
378 }
379 iterator->destroy(iterator);
380
381 this->initiating.mid++;
382
383 return build_request(this);
384 }
385
386 /**
387 * build a response depending on the "passive" task list
388 */
389 static status_t build_response(private_task_manager_t *this,
390 exchange_type_t exchange)
391 {
392 iterator_t *iterator;
393 task_t *task;
394 message_t *message;
395 bool delete = FALSE;
396 status_t status;
397
398 message = message_create();
399 message->set_exchange_type(message, exchange);
400 message->set_message_id(message, this->responding.mid);
401 message->set_request(message, FALSE);
402
403 iterator = this->passive_tasks->create_iterator(this->passive_tasks, TRUE);
404 while (iterator->iterate(iterator, (void*)&task))
405 {
406 switch (task->build(task, message))
407 {
408 case SUCCESS:
409 /* task completed, remove it */
410 iterator->remove(iterator);
411 task->destroy(task);
412 break;
413 case NEED_MORE:
414 /* processed, but task needs another exchange */
415 break;
416 case FAILED:
417 default:
418 /* destroy IKE_SA, but SEND response first */
419 delete = TRUE;
420 break;
421 }
422 if (delete)
423 {
424 break;
425 }
426 }
427 iterator->destroy(iterator);
428
429 /* remove resonder SPI if IKE_SA_INIT failed */
430 if (delete && exchange == IKE_SA_INIT)
431 {
432 ike_sa_id_t *id = this->ike_sa->get_id(this->ike_sa);
433 id->set_responder_spi(id, 0);
434 }
435
436 /* message complete, send it */
437 DESTROY_IF(this->responding.packet);
438 status = this->ike_sa->generate_message(this->ike_sa, message,
439 &this->responding.packet);
440 message->destroy(message);
441 if (status != SUCCESS)
442 {
443 return DESTROY_ME;
444 }
445
446 charon->send_queue->add(charon->send_queue,
447 this->responding.packet->clone(this->responding.packet));
448 if (delete)
449 {
450 return DESTROY_ME;
451 }
452 return SUCCESS;
453 }
454
455 /**
456 * handle an incoming request message
457 */
458 static status_t process_request(private_task_manager_t *this,
459 message_t *message)
460 {
461 iterator_t *iterator;
462 task_t *task = NULL;
463 exchange_type_t exchange;
464 payload_t *payload;
465 notify_payload_t *notify;
466
467 exchange = message->get_exchange_type(message);
468
469 /* create tasks depending on request type */
470 switch (exchange)
471 {
472 case IKE_SA_INIT:
473 {
474 task = (task_t*)ike_init_create(this->ike_sa, FALSE, NULL);
475 this->passive_tasks->insert_last(this->passive_tasks, task);
476 task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
477 this->passive_tasks->insert_last(this->passive_tasks, task);
478 task = (task_t*)ike_cert_create(this->ike_sa, FALSE);
479 this->passive_tasks->insert_last(this->passive_tasks, task);
480 task = (task_t*)ike_config_create(this->ike_sa, NULL);
481 this->passive_tasks->insert_last(this->passive_tasks, task);
482 task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
483 this->passive_tasks->insert_last(this->passive_tasks, task);
484 task = (task_t*)child_create_create(this->ike_sa, NULL);
485 this->passive_tasks->insert_last(this->passive_tasks, task);
486 break;
487 }
488 case CREATE_CHILD_SA:
489 {
490 bool notify_found = FALSE, ts_found = FALSE;
491 iterator = message->get_payload_iterator(message);
492 while (iterator->iterate(iterator, (void**)&payload))
493 {
494 switch (payload->get_type(payload))
495 {
496 case NOTIFY:
497 {
498 /* if we find a rekey notify, its CHILD_SA rekeying */
499 notify = (notify_payload_t*)payload;
500 if (notify->get_notify_type(notify) == REKEY_SA &&
501 (notify->get_protocol_id(notify) == PROTO_AH ||
502 notify->get_protocol_id(notify) == PROTO_ESP))
503 {
504 notify_found = TRUE;
505 }
506 break;
507 }
508 case TRAFFIC_SELECTOR_INITIATOR:
509 case TRAFFIC_SELECTOR_RESPONDER:
510 {
511 /* if we don't find a TS, its IKE rekeying */
512 ts_found = TRUE;
513 break;
514 }
515 default:
516 break;
517 }
518 }
519 iterator->destroy(iterator);
520
521 if (ts_found)
522 {
523 if (notify_found)
524 {
525 task = (task_t*)child_rekey_create(this->ike_sa, NULL);
526 }
527 else
528 {
529 task = (task_t*)child_create_create(this->ike_sa, NULL);
530 }
531 }
532 else
533 {
534 task = (task_t*)ike_rekey_create(this->ike_sa, FALSE);
535 }
536 this->passive_tasks->insert_last(this->passive_tasks, task);
537
538 break;
539 }
540 case INFORMATIONAL:
541 {
542 delete_payload_t *delete;
543
544 delete = (delete_payload_t*)message->get_payload(message, DELETE);
545 if (delete)
546 {
547 if (delete->get_protocol_id(delete) == PROTO_IKE)
548 {
549 task = (task_t*)ike_delete_create(this->ike_sa, FALSE);
550 this->passive_tasks->insert_last(this->passive_tasks, task);
551 }
552 else
553 {
554 task = (task_t*)child_delete_create(this->ike_sa, NULL);
555 this->passive_tasks->insert_last(this->passive_tasks, task);
556 }
557 }
558 else
559 {
560 task = (task_t*)ike_dpd_create(FALSE);
561 this->passive_tasks->insert_last(this->passive_tasks, task);
562 }
563 break;
564 }
565 default:
566 break;
567 }
568
569 /* let the tasks process the message */
570 iterator = this->passive_tasks->create_iterator(this->passive_tasks, TRUE);
571 while (iterator->iterate(iterator, (void*)&task))
572 {
573 switch (task->process(task, message))
574 {
575 case SUCCESS:
576 /* task completed, remove it */
577 iterator->remove(iterator);
578 task->destroy(task);
579 break;
580 case NEED_MORE:
581 /* processed, but task needs at least another call to build() */
582 break;
583 case FAILED:
584 default:
585 /* critical failure, destroy IKE_SA */
586 iterator->destroy(iterator);
587 return DESTROY_ME;
588 }
589 }
590 iterator->destroy(iterator);
591
592 return build_response(this, exchange);
593 }
594
595 /**
596 * Implementation of task_manager_t.process_message
597 */
598 static status_t process_message(private_task_manager_t *this, message_t *msg)
599 {
600 u_int32_t mid = msg->get_message_id(msg);
601
602 if (msg->get_request(msg))
603 {
604 if (mid == this->responding.mid)
605 {
606 if (process_request(this, msg) != SUCCESS)
607 {
608 return DESTROY_ME;
609 }
610 this->responding.mid++;
611 }
612 else if ((mid == this->responding.mid - 1) && this->responding.packet)
613 {
614 DBG1(DBG_IKE, "received retransmit of request with ID %d, "
615 "retransmitting response", mid);
616 charon->send_queue->add(charon->send_queue,
617 this->responding.packet->clone(
618 this->responding.packet));
619 }
620 else
621 {
622 DBG1(DBG_IKE, "received message ID %d, excepted %d. Ignored",
623 mid, this->responding.mid);
624 }
625 }
626 else
627 {
628 if (mid == this->initiating.mid)
629 {
630 if (process_response(this, msg) != SUCCESS)
631 {
632 return DESTROY_ME;
633 }
634 }
635 else
636 {
637 DBG1(DBG_IKE, "received message ID %d, excepted %d. Ignored",
638 mid, this->initiating.mid);
639 return SUCCESS;
640 }
641 }
642 return SUCCESS;
643 }
644
645 /**
646 * Implementation of task_manager_t.queue_task
647 */
648 static void queue_task(private_task_manager_t *this, task_t *task)
649 {
650 DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
651 this->queued_tasks->insert_last(this->queued_tasks, task);
652 }
653
654 /**
655 * Implementation of task_manager_t.adopt_tasks
656 */
657 static void adopt_tasks(private_task_manager_t *this, private_task_manager_t *other)
658 {
659 task_t *task;
660
661 /* move queued tasks from other to this */
662 while (other->queued_tasks->remove_last(other->queued_tasks,
663 (void**)&task) == SUCCESS)
664 {
665 task->migrate(task, this->ike_sa);
666 this->queued_tasks->insert_first(this->queued_tasks, task);
667 }
668
669 /* reset active tasks and move them to others queued tasks */
670 while (other->active_tasks->remove_last(other->active_tasks,
671 (void**)&task) == SUCCESS)
672 {
673 task->migrate(task, this->ike_sa);
674 this->queued_tasks->insert_first(this->queued_tasks, task);
675 }
676 }
677
678 /**
679 * Implementation of task_manager_t.busy
680 */
681 static bool busy(private_task_manager_t *this)
682 {
683 return (this->active_tasks->get_count(this->active_tasks) > 0);
684 }
685
686 /**
687 * Implementation of task_manager_t.reset
688 */
689 static void reset(private_task_manager_t *this)
690 {
691 task_t *task;
692
693 /* reset message counters and retransmit packets */
694 DESTROY_IF(this->responding.packet);
695 DESTROY_IF(this->initiating.packet);
696 DESTROY_IF(this->ike_sa_init);
697 this->responding.packet = NULL;
698 this->initiating.packet = NULL;
699 this->ike_sa_init = NULL;
700 this->responding.mid = 0;
701 this->initiating.mid = -1;
702
703 /* reset active tasks */
704 while (this->active_tasks->remove_last(this->active_tasks,
705 (void**)&task) == SUCCESS)
706 {
707 task->migrate(task, this->ike_sa);
708 this->queued_tasks->insert_first(this->queued_tasks, task);
709 }
710 }
711
712 /**
713 * Implementation of task_manager_t.destroy
714 */
715 static void destroy(private_task_manager_t *this)
716 {
717 task_t *task;
718
719 this->queued_tasks->destroy_offset(this->queued_tasks,
720 offsetof(task_t, destroy));
721 this->passive_tasks->destroy_offset(this->passive_tasks,
722 offsetof(task_t, destroy));
723
724 /* emmit outstanding signals for tasks */
725 while (this->active_tasks->remove_last(this->active_tasks,
726 (void**)&task) == SUCCESS)
727 {
728 switch (task->get_type(task))
729 {
730 case IKE_AUTH:
731 SIG(IKE_UP_FAILED, "establishing IKE_SA failed");
732 break;
733 case IKE_DELETE:
734 SIG(IKE_DOWN_FAILED, "deleting IKE_SA properly failed");
735 break;
736 case IKE_REKEY:
737 SIG(IKE_REKEY_FAILED, "rekeying IKE_SA failed");
738 break;
739 case CHILD_CREATE:
740 SIG(CHILD_UP_FAILED, "establishing CHILD_SA failed");
741 break;
742 case CHILD_DELETE:
743 SIG(CHILD_DOWN_FAILED, "deleting CHILD_SA failed");
744 break;
745 case CHILD_REKEY:
746 SIG(IKE_REKEY_FAILED, "rekeying CHILD_SA failed");
747 break;
748 default:
749 break;
750 }
751 task->destroy(task);
752 }
753 this->active_tasks->destroy(this->active_tasks);
754 DESTROY_IF(this->responding.packet);
755 DESTROY_IF(this->initiating.packet);
756 DESTROY_IF(this->ike_sa_init);
757 free(this);
758 }
759
760 /*
761 * see header file
762 */
763 task_manager_t *task_manager_create(ike_sa_t *ike_sa)
764 {
765 private_task_manager_t *this = malloc_thing(private_task_manager_t);
766
767 this->public.process_message = (status_t(*)(task_manager_t*,message_t*))process_message;
768 this->public.queue_task = (void(*)(task_manager_t*,task_t*))queue_task;
769 this->public.initiate = (status_t(*)(task_manager_t*))build_request;
770 this->public.retransmit = (status_t(*)(task_manager_t*,u_int32_t))retransmit;
771 this->public.reset = (void(*)(task_manager_t*))reset;
772 this->public.adopt_tasks = (void(*)(task_manager_t*,task_manager_t*))adopt_tasks;
773 this->public.busy = (bool(*)(task_manager_t*))busy;
774 this->public.destroy = (void(*)(task_manager_t*))destroy;
775
776 this->ike_sa = ike_sa;
777 this->responding.packet = NULL;
778 this->initiating.packet = NULL;
779 this->responding.mid = 0;
780 this->initiating.mid = 0;
781 this->queued_tasks = linked_list_create();
782 this->active_tasks = linked_list_create();
783 this->passive_tasks = linked_list_create();
784 this->ike_sa_init = NULL;
785
786 return &this->public;
787 }