implemented IKE/CHILD_SA close through manager
[strongswan.git] / src / manager / controller / status_controller.c
1 /**
2 * @file status_controller.c
3 *
4 * @brief Implementation of status_controller_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 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 "status_controller.h"
24 #include "../manager.h"
25 #include "../gateway.h"
26
27 #include <xml.h>
28
29 #include <library.h>
30
31
32 typedef struct private_status_controller_t private_status_controller_t;
33
34 /**
35 * private data of the task manager
36 */
37 struct private_status_controller_t {
38
39 /**
40 * public functions
41 */
42 status_controller_t public;
43
44 /**
45 * manager instance
46 */
47 manager_t *manager;
48 };
49
50 /**
51 * read XML of a childsa element and fill template
52 */
53 static void process_childsa(private_status_controller_t *this, char *id,
54 enumerator_t *e, request_t *r)
55 {
56 xml_t *xml;
57 enumerator_t *e1, *e2;
58 char *name, *value, *reqid = "", *section = "";
59 int num = 0;
60
61 while (e->enumerate(e, &xml, &name, &value))
62 {
63 if (streq(name, "reqid"))
64 {
65 reqid = value;
66 }
67 else if (streq(name, "local") || streq(name, "remote"))
68 {
69 section = name;
70 e1 = xml->children(xml);
71 while (e1->enumerate(e1, &xml, &name, &value))
72 {
73 if (streq(name, "networks"))
74 {
75 e2 = xml->children(xml);
76 while (e2->enumerate(e2, &xml, &name, &value))
77 {
78 if (streq(name, "network"))
79 {
80 r->setf(r, "ikesas.%s.childsas.%s.%s.networks.%d=%s",
81 id, reqid, section, ++num, value);
82 }
83 }
84 e2->destroy(e2);
85 }
86 else
87 {
88 r->setf(r, "ikesas.%s.childsas.%s.%s.%s=%s",
89 id, reqid, section, name, value);
90 }
91 }
92 e1->destroy(e1);
93 }
94 else
95 {
96 r->setf(r, "ikesas.%s.childsas.%s.%s=%s",
97 id, reqid, name, value);
98 }
99 }
100 }
101
102 /**
103 * read XML of a ikesa element and fill template
104 */
105 static void process_ikesa(private_status_controller_t *this,
106 enumerator_t *e, request_t *r)
107 {
108 xml_t *xml;
109 enumerator_t *e1, *e2;
110 char *name, *value, *id = "", *section = "";
111
112 while (e->enumerate(e, &xml, &name, &value))
113 {
114 if (streq(name, "id"))
115 {
116 id = value;
117 }
118 else if (streq(name, "local") || streq(name, "remote"))
119 {
120 section = name;
121 e1 = xml->children(xml);
122 while (e1->enumerate(e1, &xml, &name, &value))
123 {
124 r->setf(r, "ikesas.%s.%s.%s=%s", id, section, name, value);
125 }
126 e1->destroy(e1);
127 }
128 else if (streq(name, "childsalist"))
129 {
130 e1 = xml->children(xml);
131 while (e1->enumerate(e1, &xml, &name, &value))
132 {
133 if (streq(name, "childsa"))
134 {
135 e2 = xml->children(xml);
136 process_childsa(this, id, e2, r);
137 e2->destroy(e2);
138 }
139 }
140 e1->destroy(e1);
141 }
142 else
143 {
144 r->setf(r, "ikesas.%s.%s=%s", id, name, value);
145 }
146 }
147 }
148
149 static void ikesalist(private_status_controller_t *this, request_t *r)
150 {
151 gateway_t *gateway;
152 xml_t *xml;
153 enumerator_t *e1, *e2;
154 char *name, *value;
155
156 gateway = this->manager->select_gateway(this->manager, 0);
157 e1 = gateway->query_ikesalist(gateway);
158 if (e1 == NULL)
159 {
160 r->set(r, "title", "Error");
161 r->set(r, "error", "querying the gateway failed");
162 r->render(r, "templates/error.cs");
163 }
164 else
165 {
166 r->set(r, "title", "IKE SA overview");
167
168 while (e1->enumerate(e1, &xml, &name, &value))
169 {
170 if (streq(name, "ikesa"))
171 {
172 e2 = xml->children(xml);
173 process_ikesa(this, e2, r);
174 e2->destroy(e2);
175 }
176 }
177 e1->destroy(e1);
178
179 r->render(r, "templates/status/ikesalist.cs");
180 }
181 }
182
183 /**
184 * Implementation of controller_t.get_name
185 */
186 static char* get_name(private_status_controller_t *this)
187 {
188 return "status";
189 }
190
191 /**
192 * Implementation of controller_t.handle
193 */
194 static void handle(private_status_controller_t *this,
195 request_t *request, char *action)
196 {
197 if (!this->manager->logged_in(this->manager))
198 {
199 return request->redirect(request, "auth/login");
200 }
201 if (this->manager->select_gateway(this->manager, 0) == NULL)
202 {
203 return request->redirect(request, "gateway/list");
204 }
205 if (action)
206 {
207 if (streq(action, "ikesalist"))
208 {
209 return ikesalist(this, request);
210 }
211 }
212 return request->redirect(request, "status/ikesalist");
213 }
214
215 /**
216 * Implementation of controller_t.destroy
217 */
218 static void destroy(private_status_controller_t *this)
219 {
220 free(this);
221 }
222
223 /*
224 * see header file
225 */
226 controller_t *status_controller_create(context_t *context, void *param)
227 {
228 private_status_controller_t *this = malloc_thing(private_status_controller_t);
229
230 this->public.controller.get_name = (char*(*)(controller_t*))get_name;
231 this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
232 this->public.controller.destroy = (void(*)(controller_t*))destroy;
233
234 this->manager = (manager_t*)context;
235
236 return &this->public.controller;
237 }
238