Removed strayed code fragment
[strongswan.git] / src / charon / processing / jobs / initiate_mediation_job.c
1 /*
2 * Copyright (C) 2007-2008 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "initiate_mediation_job.h"
17
18 #include <sa/ike_sa.h>
19 #include <daemon.h>
20
21
22 typedef struct private_initiate_mediation_job_t private_initiate_mediation_job_t;
23
24 /**
25 * Private data of an initiate_mediation_job_t Object
26 */
27 struct private_initiate_mediation_job_t {
28 /**
29 * public initiate_mediation_job_t interface
30 */
31 initiate_mediation_job_t public;
32
33 /**
34 * ID of the IKE_SA of the mediated connection.
35 */
36 ike_sa_id_t *mediated_sa_id;
37
38 /**
39 * ID of the IKE_SA of the mediation connection.
40 */
41 ike_sa_id_t *mediation_sa_id;
42 };
43
44 /**
45 * Implements job_t.destroy.
46 */
47 static void destroy(private_initiate_mediation_job_t *this)
48 {
49 DESTROY_IF(this->mediation_sa_id);
50 DESTROY_IF(this->mediated_sa_id);
51 free(this);
52 }
53
54 /**
55 * Callback to handle initiation of mediation connection
56 */
57 static bool initiate_callback(private_initiate_mediation_job_t *this,
58 debug_t group, level_t level, ike_sa_t *ike_sa,
59 char *format, va_list args)
60 {
61 if (ike_sa && !this->mediation_sa_id)
62 {
63 this->mediation_sa_id = ike_sa->get_id(ike_sa);
64 this->mediation_sa_id = this->mediation_sa_id->clone(this->mediation_sa_id);
65 }
66 return TRUE;
67 }
68
69 /**
70 * Implementation of job_t.execute.
71 */
72 static void initiate(private_initiate_mediation_job_t *this)
73 {
74 ike_sa_t *mediated_sa, *mediation_sa;
75 peer_cfg_t *mediated_cfg, *mediation_cfg;
76 enumerator_t *enumerator;
77 auth_cfg_t *auth_cfg;
78
79 mediated_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
80 this->mediated_sa_id);
81 if (mediated_sa)
82 {
83 DBG1(DBG_IKE, "initiating mediation connection");
84 mediated_cfg = mediated_sa->get_peer_cfg(mediated_sa);
85 mediated_cfg->get_ref(mediated_cfg);
86
87 charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
88
89 mediation_cfg = mediated_cfg->get_mediated_by(mediated_cfg);
90 mediation_cfg->get_ref(mediation_cfg);
91
92 enumerator = mediation_cfg->create_auth_cfg_enumerator(mediation_cfg,
93 TRUE);
94 if (!enumerator->enumerate(enumerator, &auth_cfg) ||
95 auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY) == NULL)
96 {
97 mediated_cfg->destroy(mediated_cfg);
98 mediation_cfg->destroy(mediation_cfg);
99 enumerator->destroy(enumerator);
100 destroy(this);
101 return;
102 }
103 enumerator->destroy(enumerator);
104
105 if (charon->connect_manager->check_and_register(charon->connect_manager,
106 auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY),
107 mediated_cfg->get_peer_id(mediated_cfg),
108 this->mediated_sa_id))
109 {
110 mediated_cfg->destroy(mediated_cfg);
111 mediation_cfg->destroy(mediation_cfg);
112
113 mediated_sa = charon->ike_sa_manager->checkout(
114 charon->ike_sa_manager, this->mediated_sa_id);
115 if (mediated_sa)
116 {
117 DBG1(DBG_IKE, "mediation with the same peer is already in "
118 "progress, queued");
119 charon->ike_sa_manager->checkin(
120 charon->ike_sa_manager, mediated_sa);
121 }
122 destroy(this);
123 return;
124 }
125 /* we need an additional reference because initiate consumes one */
126 mediation_cfg->get_ref(mediation_cfg);
127
128 if (charon->controller->initiate(charon->controller, mediation_cfg,
129 NULL, (controller_cb_t)initiate_callback, this) != SUCCESS)
130 {
131 mediation_cfg->destroy(mediation_cfg);
132 mediated_cfg->destroy(mediated_cfg);
133 mediated_sa = charon->ike_sa_manager->checkout(
134 charon->ike_sa_manager, this->mediated_sa_id);
135 if (mediated_sa)
136 {
137 DBG1(DBG_IKE, "initiating mediation connection failed");
138 charon->ike_sa_manager->checkin_and_destroy(
139 charon->ike_sa_manager, mediated_sa);
140 }
141 destroy(this);
142 return;
143 }
144 mediation_cfg->destroy(mediation_cfg);
145
146 mediation_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
147 this->mediation_sa_id);
148 if (mediation_sa)
149 {
150 if (mediation_sa->initiate_mediation(mediation_sa,
151 mediated_cfg) != SUCCESS)
152 {
153 mediated_cfg->destroy(mediated_cfg);
154 charon->ike_sa_manager->checkin_and_destroy(
155 charon->ike_sa_manager, mediation_sa);
156 mediated_sa = charon->ike_sa_manager->checkout(
157 charon->ike_sa_manager, this->mediated_sa_id);
158 if (mediated_sa)
159 {
160 DBG1(DBG_IKE, "establishing mediation connection failed");
161 charon->ike_sa_manager->checkin_and_destroy(
162 charon->ike_sa_manager, mediated_sa);
163 }
164 destroy(this);
165 return;
166 }
167 charon->ike_sa_manager->checkin(charon->ike_sa_manager,
168 mediation_sa);
169 }
170 mediated_cfg->destroy(mediated_cfg);
171 }
172 destroy(this);
173 }
174
175 /**
176 * Implementation of job_t.execute.
177 */
178 static void reinitiate(private_initiate_mediation_job_t *this)
179 {
180 ike_sa_t *mediated_sa, *mediation_sa;
181 peer_cfg_t *mediated_cfg;
182
183 mediated_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
184 this->mediated_sa_id);
185 if (mediated_sa)
186 {
187 mediated_cfg = mediated_sa->get_peer_cfg(mediated_sa);
188 mediated_cfg->get_ref(mediated_cfg);
189 charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
190
191 mediation_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
192 this->mediation_sa_id);
193 if (mediation_sa)
194 {
195 if (mediation_sa->initiate_mediation(mediation_sa,
196 mediated_cfg) != SUCCESS)
197 {
198 DBG1(DBG_JOB, "initiating mediated connection '%s' failed",
199 mediated_cfg->get_name(mediated_cfg));
200 mediated_cfg->destroy(mediated_cfg);
201 charon->ike_sa_manager->checkin_and_destroy(
202 charon->ike_sa_manager,
203 mediation_sa);
204 mediated_sa = charon->ike_sa_manager->checkout(
205 charon->ike_sa_manager,
206 this->mediated_sa_id);
207 if (mediated_sa)
208 {
209 DBG1(DBG_IKE, "establishing mediation connection failed");
210 charon->ike_sa_manager->checkin_and_destroy(
211 charon->ike_sa_manager,
212 mediated_sa);
213 }
214 destroy(this);
215 return;
216 }
217 charon->ike_sa_manager->checkin(charon->ike_sa_manager,
218 mediation_sa);
219 }
220
221 mediated_cfg->destroy(mediated_cfg);
222 }
223 destroy(this);
224 }
225
226 /**
227 * Creates an empty job
228 */
229 static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
230 {
231 private_initiate_mediation_job_t *this = malloc_thing(private_initiate_mediation_job_t);
232
233 /* interface functions */
234 this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
235
236 /* private variables */
237 this->mediation_sa_id = NULL;
238 this->mediated_sa_id = NULL;
239
240 return this;
241 }
242
243 /*
244 * Described in header
245 */
246 initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id)
247 {
248 private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
249
250 this->public.job_interface.execute = (void (*) (job_t *)) initiate;
251
252 this->mediated_sa_id = ike_sa_id->clone(ike_sa_id);
253
254 return &this->public;
255 }
256
257 /*
258 * Described in header
259 */
260 initiate_mediation_job_t *reinitiate_mediation_job_create(ike_sa_id_t *mediation_sa_id,
261 ike_sa_id_t *mediated_sa_id)
262 {
263 private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
264
265 this->public.job_interface.execute = (void (*) (job_t *)) reinitiate;
266
267 this->mediation_sa_id = mediation_sa_id->clone(mediation_sa_id);
268 this->mediated_sa_id = mediated_sa_id->clone(mediated_sa_id);
269
270 return &this->public;
271 }