]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libfast/fast_session.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libfast / fast_session.c
CommitLineData
965e99b5
MW
1/*
2 * Copyright (C) 2007 Martin Willi
19ef2aec
TB
3 *
4 * Copyright (C) secunet Security Networks AG
965e99b5
MW
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17#define _GNU_SOURCE
18
890f2098 19#include "fast_session.h"
965e99b5
MW
20
21#include <string.h>
22#include <fcgiapp.h>
23#include <stdio.h>
24
12642a68 25#include <collections/linked_list.h>
965e99b5 26
a6225e49
MW
27#define COOKIE_LEN 16
28
890f2098 29typedef struct private_fast_session_t private_fast_session_t;
965e99b5
MW
30
31/**
32 * private data of the task manager
33 */
890f2098 34struct private_fast_session_t {
965e99b5
MW
35
36 /**
37 * public functions
38 */
890f2098 39 fast_session_t public;
7daf5226 40
965e99b5
MW
41 /**
42 * session ID
43 */
a6225e49
MW
44 char sid[COOKIE_LEN * 2 + 1];
45
46 /**
47 * have we sent the session cookie?
48 */
49 bool cookie_sent;
7daf5226 50
965e99b5
MW
51 /**
52 * list of controller instances controller_t
53 */
54 linked_list_t *controllers;
7daf5226 55
552cc11b
MW
56 /**
57 * list of filter instances filter_t
58 */
59 linked_list_t *filters;
7daf5226 60
965e99b5
MW
61 /**
62 * user defined session context
63 */
890f2098 64 fast_context_t *context;
965e99b5
MW
65};
66
890f2098
MW
67METHOD(fast_session_t, add_controller, void,
68 private_fast_session_t *this, fast_controller_t *controller)
965e99b5
MW
69{
70 this->controllers->insert_last(this->controllers, controller);
71}
72
890f2098
MW
73METHOD(fast_session_t, add_filter, void,
74 private_fast_session_t *this, fast_filter_t *filter)
552cc11b
MW
75{
76 this->filters->insert_last(this->filters, filter);
77}
78
965e99b5
MW
79/**
80 * Create a session ID and a cookie
81 */
890f2098 82static bool create_sid(private_fast_session_t *this)
965e99b5 83{
a6225e49 84 char buf[COOKIE_LEN];
6a365f07 85 rng_t *rng;
7daf5226 86
6a365f07 87 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
9181784f 88 if (!rng)
6a365f07 89 {
76a98ee2
MW
90 return FALSE;
91 }
92 if (!rng->get_bytes(rng, sizeof(buf), buf))
93 {
6a365f07 94 rng->destroy(rng);
76a98ee2 95 return FALSE;
6a365f07 96 }
76a98ee2 97 rng->destroy(rng);
a6225e49 98 chunk_to_hex(chunk_create(buf, sizeof(buf)), this->sid, FALSE);
76a98ee2 99 return TRUE;
965e99b5
MW
100}
101
552cc11b
MW
102/**
103 * run all registered filters
104 */
890f2098
MW
105static bool run_filter(private_fast_session_t *this, fast_request_t *request,
106 char *p0, char *p1, char *p2, char *p3, char *p4, char *p5)
552cc11b 107{
69767897 108 enumerator_t *enumerator;
890f2098 109 fast_filter_t *filter;
7daf5226 110
69767897
MW
111 enumerator = this->filters->create_enumerator(this->filters);
112 while (enumerator->enumerate(enumerator, &filter))
552cc11b 113 {
69767897 114 if (!filter->run(filter, request, p0, p1, p2, p3, p4, p5))
552cc11b 115 {
69767897 116 enumerator->destroy(enumerator);
552cc11b
MW
117 return FALSE;
118 }
119 }
69767897 120 enumerator->destroy(enumerator);
552cc11b
MW
121 return TRUE;
122}
123
890f2098
MW
124METHOD(fast_session_t, process, void,
125 private_fast_session_t *this, fast_request_t *request)
965e99b5 126{
780050cb 127 char *pos, *start, *param[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
69767897 128 enumerator_t *enumerator;
965e99b5 129 bool handled = FALSE;
890f2098 130 fast_controller_t *current;
780050cb 131 int i = 0;
7daf5226 132
a6225e49 133 if (!this->cookie_sent)
965e99b5 134 {
a6225e49
MW
135 request->add_cookie(request, "SID", this->sid);
136 this->cookie_sent = TRUE;
965e99b5 137 }
7daf5226 138
780050cb
MW
139 start = request->get_path(request);
140 if (start)
965e99b5 141 {
69767897
MW
142 if (*start == '/')
143 {
144 start++;
145 }
780050cb 146 while ((pos = strchr(start, '/')) != NULL && i < 5)
965e99b5 147 {
69767897 148 param[i++] = strndupa(start, pos - start);
780050cb 149 start = pos + 1;
965e99b5 150 }
69767897 151 param[i] = strdupa(start);
7daf5226
MW
152
153 if (run_filter(this, request, param[0], param[1], param[2], param[3],
323f9f99 154 param[4], param[5]))
965e99b5 155 {
69767897
MW
156 enumerator = this->controllers->create_enumerator(this->controllers);
157 while (enumerator->enumerate(enumerator, &current))
158 {
159 if (streq(current->get_name(current), param[0]))
7daf5226 160 {
552cc11b
MW
161 current->handle(current, request, param[1], param[2],
162 param[3], param[4], param[5]);
163 handled = TRUE;
69767897 164 break;
552cc11b 165 }
780050cb 166 }
69767897 167 enumerator->destroy(enumerator);
965e99b5 168 }
69767897 169 else
780050cb 170 {
69767897 171 handled = TRUE;
965e99b5
MW
172 }
173 }
965e99b5
MW
174 if (!handled)
175 {
c01f7bf9
MW
176 if (this->controllers->get_first(this->controllers,
177 (void**)&current) == SUCCESS)
178 {
69e492f2
MW
179 request->streamf(request,
180 "Status: 301 Moved permanently\nLocation: %s/%s\n\n",
181 request->get_base(request), current->get_name(current));
c01f7bf9 182 }
965e99b5
MW
183 }
184}
185
890f2098
MW
186METHOD(fast_session_t, get_sid, char*,
187 private_fast_session_t *this)
965e99b5
MW
188{
189 return this->sid;
190}
191
890f2098
MW
192METHOD(fast_session_t, destroy, void,
193 private_fast_session_t *this)
965e99b5 194{
890f2098
MW
195 this->controllers->destroy_offset(this->controllers,
196 offsetof(fast_controller_t, destroy));
197 this->filters->destroy_offset(this->filters,
198 offsetof(fast_filter_t, destroy));
69767897 199 DESTROY_IF(this->context);
965e99b5
MW
200 free(this);
201}
202
203/*
204 * see header file
205 */
890f2098 206fast_session_t *fast_session_create(fast_context_t *context)
965e99b5 207{
890f2098 208 private_fast_session_t *this;
7804b7f4
MW
209
210 INIT(this,
211 .public = {
212 .add_controller = _add_controller,
213 .add_filter = _add_filter,
214 .process = _process,
215 .get_sid = _get_sid,
216 .destroy = _destroy,
217 },
218 .controllers = linked_list_create(),
219 .filters = linked_list_create(),
220 .context = context,
221 );
76a98ee2
MW
222 if (!create_sid(this))
223 {
224 destroy(this);
225 return NULL;
226 }
7daf5226 227
965e99b5
MW
228 return &this->public;
229}