implemented SHA1 encrypted passwords for manager
[strongswan.git] / src / manager / lib / request.c
1 /**
2 * @file request.c
3 *
4 * @brief Implementation of request_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 #define _GNU_SOURCE
24
25 #include "request.h"
26
27 #include <library.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ClearSilver/ClearSilver.h>
31
32 typedef struct private_request_t private_request_t;
33
34 /**
35 * private data of the task manager
36 */
37 struct private_request_t {
38
39 /**
40 * public functions
41 */
42 request_t public;
43
44 /**
45 * FastCGI request object
46 */
47 FCGX_Request *req;
48
49 /**
50 * ClearSilver CGI Kit context
51 */
52 CGI *cgi;
53
54 /**
55 * ClearSilver HDF dataset for this request
56 */
57 HDF *hdf;
58 };
59
60 /**
61 * thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks.
62 * ClearSilver cgiwrap is not threadsave, so we use a private
63 * context for each thread.
64 */
65 static __thread FCGX_Request *req;
66
67 /**
68 * length of param list in req->envp
69 */
70 static __thread int req_env_len;
71
72 /**
73 * fcgiwrap read callback
74 */
75 static int read_cb(void *null, char *buf, int size)
76 {
77 return FCGX_GetStr(buf, size, req->in);
78 }
79
80 /**
81 * fcgiwrap writef callback
82 */
83 static int writef_cb(void *null, const char *format, va_list args)
84 {
85 FCGX_VFPrintF(req->out, format, args);
86 return 0;
87 }
88 /**
89 * fcgiwrap write callback
90 */
91 static int write_cb(void *null, const char *buf, int size)
92 {
93 return FCGX_PutStr(buf, size, req->out);
94 }
95
96 /**
97 * fcgiwrap getenv callback
98 */
99 static char *getenv_cb(void *null, const char *key)
100 {
101 char *value;
102
103 value = FCGX_GetParam(key, req->envp);
104 return value ? strdup(value) : NULL;
105 }
106
107 /**
108 * fcgiwrap getenv callback
109 */
110 static int putenv_cb(void *null, const char *key, const char *value)
111 {
112 /* not supported */
113 return 1;
114 }
115
116 /**
117 * fcgiwrap iterenv callback
118 */
119 static int iterenv_cb(void *null, int num, char **key, char **value)
120 {
121 *key = NULL;
122 *value = NULL;
123
124 if (num < req_env_len)
125 {
126 char *eq;
127
128 eq = strchr(req->envp[num], '=');
129 if (eq)
130 {
131 *key = strndup(req->envp[num], eq - req->envp[num]);
132 *value = strdup(eq + 1);
133 }
134 if (*key == NULL || *value == NULL)
135 {
136 free(*key);
137 free(*value);
138 return 1;
139 }
140 }
141 return 0;
142 }
143
144 /**
145 * Implementation of request_t.get_cookie.
146 */
147 static char* get_cookie(private_request_t *this, char *name)
148 {
149 return hdf_get_valuef(this->hdf, "Cookie.%s", name);
150 }
151
152 /**
153 * Implementation of request_t.get_path.
154 */
155 static char* get_path(private_request_t *this)
156 {
157 char * path = FCGX_GetParam("PATH_INFO", this->req->envp);
158 return path ? path : "";
159 }
160
161 /**
162 * Implementation of request_t.get_post_data.
163 */
164 static char* get_query_data(private_request_t *this, char *name)
165 {
166 return hdf_get_valuef(this->hdf, "Query.%s", name);
167 }
168
169 /**
170 * Implementation of request_t.add_cookie.
171 */
172 static void add_cookie(private_request_t *this, char *name, char *value)
173 {
174 cgi_cookie_set (this->cgi, name, value,
175 FCGX_GetParam("SCRIPT_NAME", this->req->envp),
176 NULL, NULL, 0, 0);
177 }
178
179 /**
180 * Implementation of request_t.redirect.
181 */
182 static void redirect(private_request_t *this, char *location)
183 {
184 FCGX_FPrintF(this->req->out, "Status: 303 See Other\n");
185 FCGX_FPrintF(this->req->out, "Location: %s%s%s\n\n",
186 FCGX_GetParam("SCRIPT_NAME", this->req->envp),
187 *location == '/' ? "" : "/", location);
188 }
189
190 /**
191 * Implementation of request_t.get_base.
192 */
193 static char* get_base(private_request_t *this)
194 {
195 return FCGX_GetParam("SCRIPT_NAME", this->req->envp);
196 }
197
198 /**
199 * Implementation of request_t.render.
200 */
201 static void render(private_request_t *this, char *template)
202 {
203 NEOERR* err;
204
205 err = cgi_display(this->cgi, template);
206 if (err)
207 {
208 cgi_neo_error(this->cgi, err);
209 nerr_log_error(err);
210 }
211 return;
212 }
213
214 /**
215 * Implementation of request_t.set.
216 */
217 static void set(private_request_t *this, char *key, char *value)
218 {
219 hdf_set_value(this->hdf, key, value);
220 }
221
222 /**
223 * Implementation of request_t.setf.
224 */
225 static void setf(private_request_t *this, char *format, ...)
226 {
227 va_list args;
228
229 va_start(args, format);
230 hdf_set_valuevf(this->hdf, format, args);
231 va_end(args);
232 }
233
234 /**
235 * Implementation of request_t.destroy
236 */
237 static void destroy(private_request_t *this)
238 {
239 cgi_destroy(&this->cgi);
240 free(this);
241 }
242
243 /*
244 * see header file
245 */
246 request_t *request_create(FCGX_Request *request, bool debug)
247 {
248 NEOERR* err;
249 static bool initialized = FALSE;
250 private_request_t *this = malloc_thing(private_request_t);
251
252 this->public.get_path = (char*(*)(request_t*))get_path;
253 this->public.get_base = (char*(*)(request_t*))get_base;
254 this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie;
255 this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie;
256 this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data;
257 this->public.redirect = (void(*)(request_t*, char *location))redirect;
258 this->public.render = (void(*)(request_t*,char*))render;
259 this->public.set = (void(*)(request_t*, char *, char*))set;
260 this->public.setf = (void(*)(request_t*, char *format, ...))setf;
261 this->public.destroy = (void(*)(request_t*))destroy;
262
263 if (!initialized)
264 {
265 cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb,
266 getenv_cb, putenv_cb, iterenv_cb);
267 initialized = TRUE;
268 }
269
270 this->req = request;
271 req = request;
272 req_env_len = 0;
273 while (req->envp[req_env_len] != NULL)
274 {
275 req_env_len++;
276 }
277
278 err = hdf_init(&this->hdf);
279 if (!err)
280 {
281 hdf_set_value(this->hdf, "base", get_base(this));
282 hdf_set_value(this->hdf, "Config.NoCache", "true");
283 if (!debug)
284 {
285 hdf_set_value(this->hdf, "Config.TimeFooter", "0");
286 hdf_set_value(this->hdf, "Config.CompressionEnabled", "1");
287 hdf_set_value(this->hdf, "Config.WhiteSpaceStrip", "2");
288 }
289
290 err = cgi_init(&this->cgi, this->hdf);
291 if (!err)
292 {
293 err = cgi_parse(this->cgi);
294 if (!err)
295 {
296 return &this->public;
297 }
298 cgi_destroy(&this->cgi);
299 }
300 }
301 nerr_log_error(err);
302 free(this);
303 return NULL;
304 }
305