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