Annotation of embedaddon/strongswan/src/libcharon/processing/jobs/initiate_mediation_job.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2007-2008 Tobias Brunner
3: * HSR 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: METHOD(job_t, destroy, void,
45: private_initiate_mediation_job_t *this)
46: {
47: DESTROY_IF(this->mediation_sa_id);
48: DESTROY_IF(this->mediated_sa_id);
49: free(this);
50: }
51:
52: /**
53: * Callback to handle initiation of mediation connection
54: */
55: static bool initiate_callback(private_initiate_mediation_job_t *this,
56: debug_t group, level_t level, ike_sa_t *ike_sa,
57: char *message)
58: {
59: if (ike_sa && !this->mediation_sa_id)
60: {
61: this->mediation_sa_id = ike_sa->get_id(ike_sa);
62: this->mediation_sa_id = this->mediation_sa_id->clone(this->mediation_sa_id);
63: }
64: return TRUE;
65: }
66:
67: METHOD(job_t, initiate, job_requeue_t,
68: private_initiate_mediation_job_t *this)
69: {
70: ike_sa_t *mediated_sa, *mediation_sa;
71: peer_cfg_t *mediated_cfg, *mediation_cfg;
72: enumerator_t *enumerator;
73: auth_cfg_t *auth_cfg;
74:
75: mediated_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
76: this->mediated_sa_id);
77: if (mediated_sa)
78: {
79: DBG1(DBG_IKE, "initiating mediation connection");
80: mediated_cfg = mediated_sa->get_peer_cfg(mediated_sa);
81: mediated_cfg->get_ref(mediated_cfg);
82:
83: charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
84:
85: mediation_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
86: mediated_cfg->get_mediated_by(mediated_cfg));
87: if (!mediation_cfg)
88: {
89: DBG1(DBG_IKE, "mediation connection '%s' not found, aborting",
90: mediated_cfg->get_mediated_by(mediated_cfg));
91: mediated_cfg->destroy(mediated_cfg);
92: return JOB_REQUEUE_NONE;
93: }
94: if (!mediation_cfg->is_mediation(mediation_cfg))
95: {
96: DBG1(DBG_CFG, "connection '%s' as referred to by '%s' is no "
97: "mediation connection, aborting",
98: mediated_cfg->get_mediated_by(mediated_cfg),
99: mediated_cfg->get_name(mediated_cfg));
100: mediated_cfg->destroy(mediated_cfg);
101: mediation_cfg->destroy(mediation_cfg);
102: return JOB_REQUEUE_NONE;
103: }
104:
105: enumerator = mediation_cfg->create_auth_cfg_enumerator(mediation_cfg,
106: TRUE);
107: if (!enumerator->enumerate(enumerator, &auth_cfg) ||
108: auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY) == NULL)
109: {
110: mediated_cfg->destroy(mediated_cfg);
111: mediation_cfg->destroy(mediation_cfg);
112: enumerator->destroy(enumerator);
113: return JOB_REQUEUE_NONE;
114: }
115: enumerator->destroy(enumerator);
116:
117: if (charon->connect_manager->check_and_register(charon->connect_manager,
118: auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY),
119: mediated_cfg->get_peer_id(mediated_cfg),
120: this->mediated_sa_id))
121: {
122: mediated_cfg->destroy(mediated_cfg);
123: mediation_cfg->destroy(mediation_cfg);
124:
125: mediated_sa = charon->ike_sa_manager->checkout(
126: charon->ike_sa_manager, this->mediated_sa_id);
127: if (mediated_sa)
128: {
129: DBG1(DBG_IKE, "mediation with the same peer is already in "
130: "progress, queued");
131: charon->ike_sa_manager->checkin(
132: charon->ike_sa_manager, mediated_sa);
133: }
134: return JOB_REQUEUE_NONE;
135: }
136: /* we need an additional reference because initiate consumes one */
137: mediation_cfg->get_ref(mediation_cfg);
138:
139: if (charon->controller->initiate(charon->controller, mediation_cfg, NULL,
140: (controller_cb_t)initiate_callback, this, 0, FALSE) != SUCCESS)
141: {
142: mediation_cfg->destroy(mediation_cfg);
143: mediated_cfg->destroy(mediated_cfg);
144: mediated_sa = charon->ike_sa_manager->checkout(
145: charon->ike_sa_manager, this->mediated_sa_id);
146: if (mediated_sa)
147: {
148: DBG1(DBG_IKE, "initiating mediation connection failed");
149: charon->ike_sa_manager->checkin_and_destroy(
150: charon->ike_sa_manager, mediated_sa);
151: }
152: return JOB_REQUEUE_NONE;
153: }
154: mediation_cfg->destroy(mediation_cfg);
155:
156: mediation_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
157: this->mediation_sa_id);
158: if (mediation_sa)
159: {
160: if (mediation_sa->initiate_mediation(mediation_sa,
161: mediated_cfg) != SUCCESS)
162: {
163: mediated_cfg->destroy(mediated_cfg);
164: charon->ike_sa_manager->checkin_and_destroy(
165: charon->ike_sa_manager, mediation_sa);
166: mediated_sa = charon->ike_sa_manager->checkout(
167: charon->ike_sa_manager, this->mediated_sa_id);
168: if (mediated_sa)
169: {
170: DBG1(DBG_IKE, "establishing mediation connection failed");
171: charon->ike_sa_manager->checkin_and_destroy(
172: charon->ike_sa_manager, mediated_sa);
173: }
174: return JOB_REQUEUE_NONE;
175: }
176: charon->ike_sa_manager->checkin(charon->ike_sa_manager,
177: mediation_sa);
178: }
179: mediated_cfg->destroy(mediated_cfg);
180: }
181: else
182: { /* newly created IKE_SA is not checked in yet, try again */
183: return JOB_RESCHEDULE_MS(100);
184: }
185: return JOB_REQUEUE_NONE;
186: }
187:
188: METHOD(job_t, reinitiate, job_requeue_t,
189: private_initiate_mediation_job_t *this)
190: {
191: ike_sa_t *mediated_sa, *mediation_sa;
192: peer_cfg_t *mediated_cfg;
193:
194: mediated_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
195: this->mediated_sa_id);
196: if (mediated_sa)
197: {
198: mediated_cfg = mediated_sa->get_peer_cfg(mediated_sa);
199: mediated_cfg->get_ref(mediated_cfg);
200: charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
201:
202: mediation_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
203: this->mediation_sa_id);
204: if (mediation_sa)
205: {
206: if (mediation_sa->initiate_mediation(mediation_sa,
207: mediated_cfg) != SUCCESS)
208: {
209: DBG1(DBG_JOB, "initiating mediated connection '%s' failed",
210: mediated_cfg->get_name(mediated_cfg));
211: mediated_cfg->destroy(mediated_cfg);
212: charon->ike_sa_manager->checkin_and_destroy(
213: charon->ike_sa_manager,
214: mediation_sa);
215: mediated_sa = charon->ike_sa_manager->checkout(
216: charon->ike_sa_manager,
217: this->mediated_sa_id);
218: if (mediated_sa)
219: {
220: DBG1(DBG_IKE, "establishing mediation connection failed");
221: charon->ike_sa_manager->checkin_and_destroy(
222: charon->ike_sa_manager,
223: mediated_sa);
224: }
225: return JOB_REQUEUE_NONE;
226: }
227: charon->ike_sa_manager->checkin(charon->ike_sa_manager,
228: mediation_sa);
229: }
230:
231: mediated_cfg->destroy(mediated_cfg);
232: }
233: return JOB_REQUEUE_NONE;
234: }
235:
236: METHOD(job_t, get_priority, job_priority_t,
237: private_initiate_mediation_job_t *this)
238: {
239: return JOB_PRIO_MEDIUM;
240: }
241:
242: /**
243: * Creates an empty job
244: */
245: static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
246: {
247: private_initiate_mediation_job_t *this;
248: INIT(this,
249: .public = {
250: .job_interface = {
251: .get_priority = _get_priority,
252: .destroy = _destroy,
253: },
254: },
255: );
256: return this;
257: }
258:
259: /*
260: * Described in header
261: */
262: initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id)
263: {
264: private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
265:
266: this->public.job_interface.execute = _initiate;
267: this->mediated_sa_id = ike_sa_id->clone(ike_sa_id);
268:
269: return &this->public;
270: }
271:
272: /*
273: * Described in header
274: */
275: initiate_mediation_job_t *reinitiate_mediation_job_create(ike_sa_id_t *mediation_sa_id,
276: ike_sa_id_t *mediated_sa_id)
277: {
278: private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
279:
280: this->public.job_interface.execute = _reinitiate;
281: this->mediation_sa_id = mediation_sa_id->clone(mediation_sa_id);
282: this->mediated_sa_id = mediated_sa_id->clone(mediated_sa_id);
283:
284: return &this->public;
285: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>