merged the modularization branch (credentials) back to trunk
[strongswan.git] / src / manager / controller / control_controller.c
1 /*
2 * Copyright (C) 2007 Martin Willi
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 * $Id$
16 */
17
18 #include "control_controller.h"
19 #include "../manager.h"
20 #include "../gateway.h"
21
22 #include <xml.h>
23
24 #include <library.h>
25
26
27 typedef struct private_control_controller_t private_control_controller_t;
28
29 /**
30 * private data of the task manager
31 */
32 struct private_control_controller_t {
33
34 /**
35 * public functions
36 */
37 control_controller_t public;
38
39 /**
40 * manager instance
41 */
42 manager_t *manager;
43 };
44
45 /**
46 * handle the result of a control operation
47 */
48 static void handle_result(private_control_controller_t *this, request_t *r,
49 enumerator_t *e)
50 {
51 enumerator_t *e1;
52 xml_t *xml;
53 char *name, *value;
54 int num = 0;
55
56 if (e)
57 {
58 while (e->enumerate(e, &xml, &name, &value))
59 {
60 if (streq(name, "status"))
61 {
62 if (value && atoi(value) == 0)
63 {
64 r->set(r, "result", "Operation executed successfully:");
65 }
66 else
67 {
68 r->set(r, "result", "Operation failed:");
69 }
70 }
71 else if (streq(name, "log"))
72 {
73 e1 = xml->children(xml);
74 while (e1->enumerate(e1, &xml, &name, &value))
75 {
76 if (streq(name, "item"))
77 {
78 r->setf(r, "log.%d=%s", ++num, value);
79 }
80 }
81 e1->destroy(e1);
82 }
83 }
84 e->destroy(e);
85 r->render(r, "templates/control/result.cs");
86 }
87 else
88 {
89 r->set(r, "title", "Error");
90 r->set(r, "error", "controlling the gateway failed");
91 r->render(r, "templates/error.cs");
92 }
93 }
94
95 /**
96 * initiate an IKE or CHILD SA
97 */
98 static void initiate(private_control_controller_t *this, request_t *r,
99 bool ike, char *config)
100 {
101 gateway_t *gateway;
102 enumerator_t *e;
103
104 r->setf(r, "title=Establishing %s SA %s", ike ? "IKE" : "CHILD", config);
105 gateway = this->manager->select_gateway(this->manager, 0);
106 e = gateway->initiate(gateway, ike, config);
107 handle_result(this, r, e);
108 }
109
110 /**
111 * terminate an IKE or CHILD SA
112 */
113 static void terminate(private_control_controller_t *this, request_t *r,
114 bool ike, u_int32_t id)
115 {
116 gateway_t *gateway;
117 enumerator_t *e;
118
119 r->setf(r, "title=Terminate %s SA %d", ike ? "IKE" : "CHILD", id);
120 gateway = this->manager->select_gateway(this->manager, 0);
121 e = gateway->terminate(gateway, ike, id);
122 handle_result(this, r, e);
123 }
124
125 /**
126 * Implementation of controller_t.get_name
127 */
128 static char* get_name(private_control_controller_t *this)
129 {
130 return "control";
131 }
132
133 /**
134 * Implementation of controller_t.handle
135 */
136 static void handle(private_control_controller_t *this,
137 request_t *request, char *action, char *str)
138 {
139 if (!this->manager->logged_in(this->manager))
140 {
141 return request->redirect(request, "auth/login");
142 }
143 if (this->manager->select_gateway(this->manager, 0) == NULL)
144 {
145 return request->redirect(request, "gateway/list");
146 }
147 if (action)
148 {
149 u_int32_t id;
150
151 if (streq(action, "terminateike"))
152 {
153 if (str && (id = atoi(str)))
154 {
155 return terminate(this, request, TRUE, id);
156 }
157 }
158 if (streq(action, "terminatechild"))
159 {
160 if (str && (id = atoi(str)))
161 {
162 return terminate(this, request, FALSE, id);
163 }
164 }
165 if (streq(action, "initiateike"))
166 {
167 if (str)
168 {
169 return initiate(this, request, TRUE, str);
170 }
171 }
172 if (streq(action, "initiatechild"))
173 {
174 if (str)
175 {
176 return initiate(this, request, FALSE, str);
177 }
178 }
179 }
180 return request->redirect(request, "ikesa/list");
181 }
182
183 /**
184 * Implementation of controller_t.destroy
185 */
186 static void destroy(private_control_controller_t *this)
187 {
188 free(this);
189 }
190
191 /*
192 * see header file
193 */
194 controller_t *control_controller_create(context_t *context, void *param)
195 {
196 private_control_controller_t *this = malloc_thing(private_control_controller_t);
197
198 this->public.controller.get_name = (char*(*)(controller_t*))get_name;
199 this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
200 this->public.controller.destroy = (void(*)(controller_t*))destroy;
201
202 this->manager = (manager_t*)context;
203
204 return &this->public.controller;
205 }
206