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, &current))
                    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**)&current) == 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>