Annotation of embedaddon/strongswan/src/libfast/fast_session.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2007 Martin Willi
3: * HSR 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: #define _GNU_SOURCE
17:
18: #include "fast_session.h"
19:
20: #include <string.h>
21: #include <fcgiapp.h>
22: #include <stdio.h>
23:
24: #include <collections/linked_list.h>
25:
26: #define COOKIE_LEN 16
27:
28: typedef struct private_fast_session_t private_fast_session_t;
29:
30: /**
31: * private data of the task manager
32: */
33: struct private_fast_session_t {
34:
35: /**
36: * public functions
37: */
38: fast_session_t public;
39:
40: /**
41: * session ID
42: */
43: char sid[COOKIE_LEN * 2 + 1];
44:
45: /**
46: * have we sent the session cookie?
47: */
48: bool cookie_sent;
49:
50: /**
51: * list of controller instances controller_t
52: */
53: linked_list_t *controllers;
54:
55: /**
56: * list of filter instances filter_t
57: */
58: linked_list_t *filters;
59:
60: /**
61: * user defined session context
62: */
63: fast_context_t *context;
64: };
65:
66: METHOD(fast_session_t, add_controller, void,
67: private_fast_session_t *this, fast_controller_t *controller)
68: {
69: this->controllers->insert_last(this->controllers, controller);
70: }
71:
72: METHOD(fast_session_t, add_filter, void,
73: private_fast_session_t *this, fast_filter_t *filter)
74: {
75: this->filters->insert_last(this->filters, filter);
76: }
77:
78: /**
79: * Create a session ID and a cookie
80: */
81: static bool create_sid(private_fast_session_t *this)
82: {
83: char buf[COOKIE_LEN];
84: rng_t *rng;
85:
86: rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
87: if (!rng)
88: {
89: return FALSE;
90: }
91: if (!rng->get_bytes(rng, sizeof(buf), buf))
92: {
93: rng->destroy(rng);
94: return FALSE;
95: }
96: rng->destroy(rng);
97: chunk_to_hex(chunk_create(buf, sizeof(buf)), this->sid, FALSE);
98: return TRUE;
99: }
100:
101: /**
102: * run all registered filters
103: */
104: static bool run_filter(private_fast_session_t *this, fast_request_t *request,
105: char *p0, char *p1, char *p2, char *p3, char *p4, char *p5)
106: {
107: enumerator_t *enumerator;
108: fast_filter_t *filter;
109:
110: enumerator = this->filters->create_enumerator(this->filters);
111: while (enumerator->enumerate(enumerator, &filter))
112: {
113: if (!filter->run(filter, request, p0, p1, p2, p3, p4, p5))
114: {
115: enumerator->destroy(enumerator);
116: return FALSE;
117: }
118: }
119: enumerator->destroy(enumerator);
120: return TRUE;
121: }
122:
123: METHOD(fast_session_t, process, void,
124: private_fast_session_t *this, fast_request_t *request)
125: {
126: char *pos, *start, *param[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
127: enumerator_t *enumerator;
128: bool handled = FALSE;
129: fast_controller_t *current;
130: int i = 0;
131:
132: if (!this->cookie_sent)
133: {
134: request->add_cookie(request, "SID", this->sid);
135: this->cookie_sent = TRUE;
136: }
137:
138: start = request->get_path(request);
139: if (start)
140: {
141: if (*start == '/')
142: {
143: start++;
144: }
145: while ((pos = strchr(start, '/')) != NULL && i < 5)
146: {
147: param[i++] = strndupa(start, pos - start);
148: start = pos + 1;
149: }
150: param[i] = strdupa(start);
151:
152: if (run_filter(this, request, param[0], param[1], param[2], param[3],
153: param[4], param[5]))
154: {
155: enumerator = this->controllers->create_enumerator(this->controllers);
156: while (enumerator->enumerate(enumerator, ¤t))
157: {
158: if (streq(current->get_name(current), param[0]))
159: {
160: current->handle(current, request, param[1], param[2],
161: param[3], param[4], param[5]);
162: handled = TRUE;
163: break;
164: }
165: }
166: enumerator->destroy(enumerator);
167: }
168: else
169: {
170: handled = TRUE;
171: }
172: }
173: if (!handled)
174: {
175: if (this->controllers->get_first(this->controllers,
176: (void**)¤t) == SUCCESS)
177: {
178: request->streamf(request,
179: "Status: 301 Moved permanently\nLocation: %s/%s\n\n",
180: request->get_base(request), current->get_name(current));
181: }
182: }
183: }
184:
185: METHOD(fast_session_t, get_sid, char*,
186: private_fast_session_t *this)
187: {
188: return this->sid;
189: }
190:
191: METHOD(fast_session_t, destroy, void,
192: private_fast_session_t *this)
193: {
194: this->controllers->destroy_offset(this->controllers,
195: offsetof(fast_controller_t, destroy));
196: this->filters->destroy_offset(this->filters,
197: offsetof(fast_filter_t, destroy));
198: DESTROY_IF(this->context);
199: free(this);
200: }
201:
202: /*
203: * see header file
204: */
205: fast_session_t *fast_session_create(fast_context_t *context)
206: {
207: private_fast_session_t *this;
208:
209: INIT(this,
210: .public = {
211: .add_controller = _add_controller,
212: .add_filter = _add_filter,
213: .process = _process,
214: .get_sid = _get_sid,
215: .destroy = _destroy,
216: },
217: .controllers = linked_list_create(),
218: .filters = linked_list_create(),
219: .context = context,
220: );
221: if (!create_sid(this))
222: {
223: destroy(this);
224: return NULL;
225: }
226:
227: return &this->public;
228: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>