added missing files to the last commit
[strongswan.git] / src / charon / sa / tasks / ike_reauth.c
1 /**
2 * @file ike_reauth.c
3 *
4 * @brief Implementation of the ike_reauth task.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006-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 "ike_reauth.h"
24
25 #include <daemon.h>
26 #include <sa/tasks/ike_delete.h>
27
28
29 typedef struct private_ike_reauth_t private_ike_reauth_t;
30
31 /**
32 * Private members of a ike_reauth_t task.
33 */
34 struct private_ike_reauth_t {
35
36 /**
37 * Public methods and task_t interface.
38 */
39 ike_reauth_t public;
40
41 /**
42 * Assigned IKE_SA.
43 */
44 ike_sa_t *ike_sa;
45
46 /**
47 * reused ike_delete task
48 */
49 ike_delete_t *ike_delete;
50 };
51
52 /**
53 * Implementation of task_t.build for initiator
54 */
55 static status_t build_i(private_ike_reauth_t *this, message_t *message)
56 {
57 return this->ike_delete->task.build(&this->ike_delete->task, message);
58 }
59
60 /**
61 * Implementation of task_t.process for initiator
62 */
63 static status_t process_i(private_ike_reauth_t *this, message_t *message)
64 {
65 ike_sa_t *new;
66 host_t *host;
67 iterator_t *iterator;
68 child_sa_t *child_sa;
69
70 /* process delete response first */
71 this->ike_delete->task.process(&this->ike_delete->task, message);
72
73 /* reestablish only if we have children */
74 iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa);
75 if (iterator->get_count(iterator) == 0)
76 {
77 DBG1(DBG_IKE, "unable to reestablish IKE_SA, no CHILD_SA to recreate");
78 iterator->destroy(iterator);
79 return FAILED;
80 }
81
82 new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, TRUE);
83
84 new->set_peer_cfg(new, this->ike_sa->get_peer_cfg(this->ike_sa));
85 host = this->ike_sa->get_other_host(this->ike_sa);
86 new->set_other_host(new, host->clone(host));
87 /* if we already have a virtual IP, we reuse it */
88 host = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
89 if (host)
90 {
91 new->set_virtual_ip(new, TRUE, host);
92 }
93
94 while (iterator->iterate(iterator, (void**)&child_sa))
95 {
96 switch (child_sa->get_state(child_sa))
97 {
98 case CHILD_ROUTED:
99 {
100 /* move routed child directly */
101 iterator->remove(iterator);
102 new->add_child_sa(new, child_sa);
103 break;
104 }
105 default:
106 {
107 /* initiate/queue all child SAs */
108 child_cfg_t *child_cfg = child_sa->get_config(child_sa);
109 child_cfg->get_ref(child_cfg);
110 if (new->initiate(new, child_cfg) == DESTROY_ME)
111 {
112 iterator->destroy(iterator);
113 charon->ike_sa_manager->checkin_and_destroy(
114 charon->ike_sa_manager, new);
115 DBG1(DBG_IKE, "reestablishing IKE_SA failed");
116 return FAILED;
117 }
118 break;
119 }
120 }
121 }
122 iterator->destroy(iterator);
123 charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
124
125 /* we always return failed to delete the obsolete IKE_SA */
126 return FAILED;
127 }
128
129 /**
130 * Implementation of task_t.get_type
131 */
132 static task_type_t get_type(private_ike_reauth_t *this)
133 {
134 return IKE_REAUTH;
135 }
136
137 /**
138 * Implementation of task_t.migrate
139 */
140 static void migrate(private_ike_reauth_t *this, ike_sa_t *ike_sa)
141 {
142 this->ike_delete->task.migrate(&this->ike_delete->task, ike_sa);
143 this->ike_sa = ike_sa;
144 }
145
146 /**
147 * Implementation of task_t.destroy
148 */
149 static void destroy(private_ike_reauth_t *this)
150 {
151 this->ike_delete->task.destroy(&this->ike_delete->task);
152 free(this);
153 }
154
155 /*
156 * Described in header.
157 */
158 ike_reauth_t *ike_reauth_create(ike_sa_t *ike_sa)
159 {
160 private_ike_reauth_t *this = malloc_thing(private_ike_reauth_t);
161
162 this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
163 this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
164 this->public.task.destroy = (void(*)(task_t*))destroy;
165 this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
166 this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
167
168 this->ike_sa = ike_sa;
169 this->ike_delete = ike_delete_create(ike_sa, TRUE);
170
171 return &this->public;
172 }
173