diff options
author | Martin Willi <martin@strongswan.org> | 2007-09-26 14:02:21 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2007-09-26 14:02:21 +0000 |
commit | c295d0eb4b11a024d1607f6a80275f372c345c08 (patch) | |
tree | ec3b578e771898bbf3ca35c1ae43e77ffdcea9d9 /src/manager | |
parent | a9522e16003dd9f9fc7dc998a9017dbb41a65273 (diff) | |
download | strongswan-c295d0eb4b11a024d1607f6a80275f372c345c08.tar.bz2 strongswan-c295d0eb4b11a024d1607f6a80275f372c345c08.tar.xz |
refactored strongswan manager
removed buggy request parsing code, use ClearSilvers CGI kit instead
fixed CHILD_SA listing in manager (needs better design)
using secure XML communication through unix sockets
removed images with questionable (non-GPL) license
Diffstat (limited to 'src/manager')
37 files changed, 629 insertions, 1189 deletions
diff --git a/src/manager/Makefile.am b/src/manager/Makefile.am index 432fad94b..171bfa688 100644 --- a/src/manager/Makefile.am +++ b/src/manager/Makefile.am @@ -13,20 +13,20 @@ manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3 lib_LTLIBRARIES = libappserv.la libappserv_la_SOURCES = \ -lib/context.h lib/dispatcher.c lib/request.h lib/response.h lib/session.h \ -lib/controller.h lib/dispatcher.h lib/request.c lib/response.c lib/session.c \ -lib/template.h lib/template.c lib/dict.h lib/dict.c lib/xml.h lib/xml.c lib/enumerator.h +lib/context.h lib/dispatcher.c lib/request.h lib/session.h \ +lib/controller.h lib/dispatcher.h lib/request.c lib/session.c \ +lib/xml.h lib/xml.c lib/enumerator.h -libappserv_la_LDFLAGS = -lstrongswan -lfcgi -lpthread -lneo_cs -lneo_utl ${xml_LIBS} +libappserv_la_LDFLAGS = -lstrongswan -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl ${xml_LIBS} INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/manager/lib -I/usr/include/ClearSilver ${xml_CFLAGS} AM_CFLAGS = -rdynamic -DIPSECDIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" -ipsec_DATA = sqlite.db +ipsec_DATA = manager.db # Don't forget to add templates to EXTRA_DIST !!! How to automate? ipsec_templatesdir = ${ipsecdir}/templates -ipsec_templates_DATA = templates/header.cs templates/footer.cs +ipsec_templates_DATA = templates/header.cs templates/footer.cs templates/error.cs ipsec_templates_authdir = ${ipsec_templatesdir}/auth ipsec_templates_auth_DATA = templates/auth/login.cs @@ -38,16 +38,16 @@ ipsec_templates_statusdir = ${ipsec_templatesdir}/status ipsec_templates_status_DATA = templates/status/ikesalist.cs ipsec_templates_staticdir = ${ipsec_templatesdir}/static -ipsec_templates_static_DATA = templates/static/style.css templates/static/script.js \ -templates/static/pipe.png templates/static/pipe-bad.png templates/static/jquery.js \ +ipsec_templates_static_DATA = templates/static/style.css templates/static/script.js templates/static/jquery.js \ +templates/static/pipe.png templates/static/pipe-good.png templates/static/pipe-bad.png \ +templates/static/pipe-thin.png templates/static/pipe-thin-left.png templates/static/pipe-thin-right.png \ templates/static/gateway-left.png templates/static/client-left.png templates/static/strongswan.png \ -templates/static/router.png templates/static/pipe-good.png templates/static/nat.png \ -templates/static/gateway-right.png templates/static/client-right.png +templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png -EXTRA_DIST = sqlite.db templates/header.cs templates/footer.cs \ +EXTRA_DIST = manager.db templates/header.cs templates/footer.cs templates/error.cs \ templates/auth/login.cs templates/gateway/list.cs templates/status/ikesalist.cs \ -templates/static/style.css templates/static/script.js \ -templates/static/pipe.png templates/static/pipe-bad.png templates/static/jquery.js \ +templates/static/style.css templates/static/script.js templates/static/jquery.js \ +templates/static/pipe.png templates/static/pipe-good.png templates/static/pipe-bad.png \ +templates/static/pipe-thin.png templates/static/pipe-thin-left.png templates/static/pipe-thin-right.png \ templates/static/gateway-left.png templates/static/client-left.png templates/static/strongswan.png \ -templates/static/router.png templates/static/pipe-good.png templates/static/nat.png \ -templates/static/gateway-right.png templates/static/client-right.png +templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png diff --git a/src/manager/controller/auth_controller.c b/src/manager/controller/auth_controller.c index 68332da46..fd4a3c7a5 100644 --- a/src/manager/controller/auth_controller.c +++ b/src/manager/controller/auth_controller.c @@ -23,8 +23,6 @@ #include "auth_controller.h" #include "../manager.h" -#include <template.h> - #include <library.h> @@ -46,39 +44,34 @@ struct private_auth_controller_t { manager_t *manager; }; -static void login(private_auth_controller_t *this, - request_t *request, response_t *response) +static void login(private_auth_controller_t *this, request_t *request) { - template_t *t = template_create("templates/auth/login.cs"); - t->set(t, "action", "check"); - t->set(t, "title", "Login"); - t->render(t, response); - t->destroy(t); + request->set(request, "action", "check"); + request->set(request, "title", "Login"); + request->render(request, "templates/auth/login.cs"); } -static void check(private_auth_controller_t *this, - request_t *request, response_t *response) +static void check(private_auth_controller_t *this, request_t *request) { char *username, *password; - username = request->get_post_data(request, "username"); - password = request->get_post_data(request, "password"); + username = request->get_query_data(request, "username"); + password = request->get_query_data(request, "password"); if (username && password && this->manager->login(this->manager, username, password)) { - response->redirect(response, "status/ikesalist"); + request->redirect(request, "status/ikesalist"); } else { - response->redirect(response, "auth/login"); + request->redirect(request, "auth/login"); } } -static void logout(private_auth_controller_t *this, - request_t *request, response_t *response) +static void logout(private_auth_controller_t *this, request_t *request) { this->manager->logout(this->manager); - response->redirect(response, "auth/login"); + request->redirect(request, "auth/login"); } /** @@ -93,24 +86,24 @@ static char* get_name(private_auth_controller_t *this) * Implementation of controller_t.handle */ static void handle(private_auth_controller_t *this, - request_t *request, response_t *response, char *action) + request_t *request, char *action) { if (action) { if (streq(action, "login")) { - return login(this, request, response); + return login(this, request); } else if (streq(action, "check")) { - return check(this, request, response); + return check(this, request); } else if (streq(action, "logout")) { - return logout(this, request, response); + return logout(this, request); } } - response->redirect(response, "auth/login"); + request->redirect(request, "auth/login"); } /** @@ -129,7 +122,7 @@ controller_t *auth_controller_create(context_t *context, void *param) private_auth_controller_t *this = malloc_thing(private_auth_controller_t); this->public.controller.get_name = (char*(*)(controller_t*))get_name; - this->public.controller.handle = (void(*)(controller_t*,request_t*,response_t*,char*,char*,char*,char*,char*))handle; + this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle; this->public.controller.destroy = (void(*)(controller_t*))destroy; this->manager = (manager_t*)context; diff --git a/src/manager/controller/gateway_controller.c b/src/manager/controller/gateway_controller.c index 1ebb51192..bdc779256 100644 --- a/src/manager/controller/gateway_controller.c +++ b/src/manager/controller/gateway_controller.c @@ -24,8 +24,6 @@ #include "../manager.h" #include "../gateway.h" -#include <template.h> - #include <library.h> @@ -48,50 +46,47 @@ struct private_gateway_controller_t { }; -static void list(private_gateway_controller_t *this, - request_t *request, response_t *response) +static void list(private_gateway_controller_t *this, request_t *request) { - template_t *t; enumerator_t *enumerator; char *name, *address; int id, port; - t = template_create("templates/gateway/list.cs"); enumerator = this->manager->create_gateway_enumerator(this->manager); while (enumerator->enumerate(enumerator, &id, &name, &port, &address)) { - t->setf(t, "gateways.%d.name=%s", id, name); + request->setf(request, "gateways.%d.name=%s", id, name); if (port) { - t->setf(t, "gateways.%d.address=tcp://%s:%d", id, address, port); + request->setf(request, "gateways.%d.address=tcp://%s:%d", + id, address, port); } else { - t->setf(t, "gateways.%d.address=unix://%s", id, address); + request->setf(request, "gateways.%d.address=unix://%s", + id, IPSEC_PIDDIR"/charon.xml"); } } enumerator->destroy(enumerator); - t->set(t, "action", "select"); - t->set(t, "title", "Choose gateway"); - t->render(t, response); - t->destroy(t); + request->set(request, "action", "select"); + request->set(request, "title", "Choose gateway"); + request->render(request, "templates/gateway/list.cs"); } -static void _select(private_gateway_controller_t *this, - request_t *request, response_t *response) +static void _select(private_gateway_controller_t *this, request_t *request) { char *id; - id = request->get_post_data(request, "gateway"); + id = request->get_query_data(request, "gateway"); if (id) { if (this->manager->select_gateway(this->manager, atoi(id))) { - response->redirect(response, "status/ikesalist"); + request->redirect(request, "status/ikesalist"); return; } } - response->printf(response, "selecting gateway failed: %s", id); + request->redirect(request, "gateway/list"); } /** @@ -106,24 +101,24 @@ static char* get_name(private_gateway_controller_t *this) * Implementation of controller_t.handle */ static void handle(private_gateway_controller_t *this, - request_t *request, response_t *response, char *action) + request_t *request, char *action) { if (!this->manager->logged_in(this->manager)) { - return response->redirect(response, "auth/login"); + return request->redirect(request, "auth/login"); } if (action) { if (streq(action, "list")) { - return list(this, request, response); + return list(this, request); } else if (streq(action, "select")) { - return _select(this, request, response); + return _select(this, request); } } - response->redirect(response, "gateway/list"); + request->redirect(request, "gateway/list"); } @@ -143,7 +138,7 @@ controller_t *gateway_controller_create(context_t *context, void *param) private_gateway_controller_t *this = malloc_thing(private_gateway_controller_t); this->public.controller.get_name = (char*(*)(controller_t*))get_name; - this->public.controller.handle = (void(*)(controller_t*,request_t*,response_t*,char*,char*,char*,char*,char*))handle; + this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle; this->public.controller.destroy = (void(*)(controller_t*))destroy; this->manager = (manager_t*)context; diff --git a/src/manager/controller/status_controller.c b/src/manager/controller/status_controller.c index 70711763a..bcdbd26ea 100644 --- a/src/manager/controller/status_controller.c +++ b/src/manager/controller/status_controller.c @@ -24,7 +24,6 @@ #include "../manager.h" #include "../gateway.h" -#include <template.h> #include <xml.h> #include <library.h> @@ -48,124 +47,137 @@ struct private_status_controller_t { manager_t *manager; }; -static void ikesalist(private_status_controller_t *this, - request_t *request, response_t *response) +/** + * read XML of a childsa element and fill template + */ +static void process_childsa(private_status_controller_t *this, char *id, + enumerator_t *e, request_t *r) { - char *str; - gateway_t *gateway; - xml_t *node; - enumerator_t *e1, *e2, *e3, *e4, *e5, *e6, *e7, *e8; - char *name, *value, *id = "", *section; - - gateway = this->manager->select_gateway(this->manager, 0); - str = gateway->request(gateway, "<message type=\"request\" id=\"1\">" - "<query>" - "<ikesalist/>" - "</query>" - "</message>"); - if (str == NULL) - { - response->printf(response, "gateway did not respond"); - return; - } + xml_t *xml; + enumerator_t *e1, *e2; + char *name, *value, *reqid = "", *section = ""; + int num = 0; - node = xml_create(str); - if (node == NULL) + while (e->enumerate(e, &xml, &name, &value)) { - response->printf(response, "parsing XML failed"); - return; - } - - template_t *t = template_create("templates/status/ikesalist.cs"); - - e1 = node->children(node); - while (e1->enumerate(e1, &node, &name, &value)) - { - if (streq(name, "message")) + if (streq(name, "reqid")) { - e2 = node->children(node); - while (e2->enumerate(e2, &node, &name, &value)) + reqid = value; + } + else if (streq(name, "local") || streq(name, "remote")) + { + section = name; + e1 = xml->children(xml); + while (e1->enumerate(e1, &xml, &name, &value)) { - if (streq(name, "query")) + if (streq(name, "networks")) { - e3 = node->children(node); - while (e3->enumerate(e3, &node, &name, &value)) + e2 = xml->children(xml); + while (e2->enumerate(e2, &xml, &name, &value)) { - if (streq(name, "ikesalist")) + if (streq(name, "network")) { - e4 = node->children(node); - while (e4->enumerate(e4, &node, &name, &value)) - { - if (streq(name, "ikesa")) - { - e5 = node->children(node); - while (e5->enumerate(e5, &node, &name, &value)) - { - if (streq(name, "id")) - { - id = value; - } - else if(streq(name, "local") || - streq(name, "remote")) - { - section = name; - e6 = node->children(node); - while (e6->enumerate(e6, &node, &name, &value)) - { - t->setf(t, "ikesas.%s.%s.%s=%s", id, section, name, value); - } - e6->destroy(e6); - } - else if (streq(name, "childsalist")) - { - e6 = node->children(node); - while (e6->enumerate(e6, &node, &name, &value)) - { - if (streq(name, "childsa")) - { - e7 = node->children(node); - while (e7->enumerate(e7, &node, &name, &value)) - { - if (streq(name, "local") || - streq(name, "remote")) - { - section = name; - e8 = node->children(node); - while (e8->enumerate(e8, &node, &name, &value)) - { - t->setf(t, "ikesas.%s.childsas.%s.%s=%s", id, section, name, value); - } - e8->destroy(e8); - } - } - e7->destroy(e7); - } - } - e6->destroy(e6); - } - else - { - t->setf(t, "ikesas.%s.%s=%s", id, name, value); - } - } - e5->destroy(e5); - } - } - e4->destroy(e4); + r->setf(r, "ikesas.%s.childsas.%s.%s.networks.%d=%s", + id, reqid, section, ++num, value); } } - e3->destroy(e3); + e2->destroy(e2); + } + else + { + r->setf(r, "ikesas.%s.childsas.%s.%s.%s=%s", + id, reqid, section, name, value); + } + } + e1->destroy(e1); + } + else + { + r->setf(r, "ikesas.%s.childsas.%s.%s=%s", + id, reqid, name, value); + } + } +} + +/** + * read XML of a ikesa element and fill template + */ +static void process_ikesa(private_status_controller_t *this, + enumerator_t *e, request_t *r) +{ + xml_t *xml; + enumerator_t *e1, *e2; + char *name, *value, *id = "", *section = ""; + + while (e->enumerate(e, &xml, &name, &value)) + { + if (streq(name, "id")) + { + id = value; + } + else if (streq(name, "local") || streq(name, "remote")) + { + section = name; + e1 = xml->children(xml); + while (e1->enumerate(e1, &xml, &name, &value)) + { + r->setf(r, "ikesas.%s.%s.%s=%s", id, section, name, value); + } + e1->destroy(e1); + } + else if (streq(name, "childsalist")) + { + e1 = xml->children(xml); + while (e1->enumerate(e1, &xml, &name, &value)) + { + if (streq(name, "childsa")) + { + e2 = xml->children(xml); + process_childsa(this, id, e2, r); + e2->destroy(e2); } } - e2->destroy(e2); + e1->destroy(e1); + } + else + { + r->setf(r, "ikesas.%s.%s=%s", id, name, value); } } - e1->destroy(e1); +} - t->set(t, "title", "IKE SA overview"); - t->render(t, response); - t->destroy(t); - free(str); +static void ikesalist(private_status_controller_t *this, request_t *r) +{ + gateway_t *gateway; + xml_t *xml; + enumerator_t *e1, *e2; + char *name, *value; + + gateway = this->manager->select_gateway(this->manager, 0); + e1 = gateway->query_ikesalist(gateway); + if (e1 == NULL) + { + r->set(r, "title", "Error"); + r->set(r, "error", "querying the gateway failed"); + r->render(r, "templates/error.cs"); + } + else + { + r->set(r, "title", "IKE SA overview"); + + while (e1->enumerate(e1, &xml, &name, &value)) + { + if (streq(name, "ikesa")) + { + e2 = xml->children(xml); + process_ikesa(this, e2, r); + e2->destroy(e2); + } + } + e1->destroy(e1); + + r->render(r, "templates/status/ikesalist.cs"); + } } /** @@ -180,24 +192,24 @@ static char* get_name(private_status_controller_t *this) * Implementation of controller_t.handle */ static void handle(private_status_controller_t *this, - request_t *request, response_t *response, char *action) + request_t *request, char *action) { if (!this->manager->logged_in(this->manager)) { - return response->redirect(response, "auth/login"); + return request->redirect(request, "auth/login"); } if (this->manager->select_gateway(this->manager, 0) == NULL) { - return response->redirect(response, "gateway/list"); + return request->redirect(request, "gateway/list"); } if (action) { if (streq(action, "ikesalist")) { - return ikesalist(this, request, response); + return ikesalist(this, request); } } - return response->redirect(response, "status/ikesalist"); + return request->redirect(request, "status/ikesalist"); } /** @@ -216,7 +228,7 @@ controller_t *status_controller_create(context_t *context, void *param) private_status_controller_t *this = malloc_thing(private_status_controller_t); this->public.controller.get_name = (char*(*)(controller_t*))get_name; - this->public.controller.handle = (void(*)(controller_t*,request_t*,response_t*,char*,char*,char*,char*,char*))handle; + this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle; this->public.controller.destroy = (void(*)(controller_t*))destroy; this->manager = (manager_t*)context; diff --git a/src/manager/gateway.c b/src/manager/gateway.c index b918da26d..5f5a4b477 100644 --- a/src/manager/gateway.c +++ b/src/manager/gateway.c @@ -26,6 +26,10 @@ #include <sys/socket.h> #include <unistd.h> #include <string.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <lib/xml.h> typedef struct private_gateway_t private_gateway_t; @@ -45,7 +49,7 @@ struct private_gateway_t { char *name; /** - * connection information + * host to connect using tcp */ host_t *host; @@ -55,22 +59,39 @@ struct private_gateway_t { int fd; }; +struct sockaddr_un unix_addr = { AF_UNIX, IPSEC_PIDDIR "/charon.xml"}; + /** * establish connection to gateway */ static bool connect_(private_gateway_t *this) { + int family, len; + struct sockaddr *addr; + if (this->fd >= 0) { close(this->fd); } - this->fd = socket(AF_INET, SOCK_STREAM, 0); + if (this->host) + { + family = AF_INET; + addr = this->host->get_sockaddr(this->host); + len = *this->host->get_sockaddr_len(this->host); + } + else + { + family = AF_UNIX; + addr = (struct sockaddr*)&unix_addr; + len = sizeof(unix_addr); + } + + this->fd = socket(family, SOCK_STREAM, 0); if (this->fd < 0) { return FALSE; } - if (connect(this->fd, this->host->get_sockaddr(this->host), - *this->host->get_sockaddr_len(this->host)) != 0) + if (connect(this->fd, addr, len) != 0) { close(this->fd); this->fd = -1; @@ -79,7 +100,6 @@ static bool connect_(private_gateway_t *this) return TRUE; } - /** * Implementation of gateway_t.request. */ @@ -119,7 +139,64 @@ static char* request(private_gateway_t *this, char *xml) return strdup(buf); } } + +/** + * Implementation of gateway_t.query_ikesalist. + */ +static enumerator_t* query_ikesalist(private_gateway_t *this) +{ + char *str, *name, *value; + xml_t *xml; + enumerator_t *e1, *e2, *e3, *e4 = NULL; + str = request(this, "<message type=\"request\" id=\"1\">" + "<query>" + "<ikesalist/>" + "</query>" + "</message>"); + if (str == NULL) + { + return NULL; + } + xml = xml_create(str); + if (xml == NULL) + { + return NULL; + } + + e1 = xml->children(xml); + free(str); + while (e1->enumerate(e1, &xml, &name, &value)) + { + if (streq(name, "message")) + { + e2 = xml->children(xml); + while (e2->enumerate(e2, &xml, &name, &value)) + { + if (streq(name, "query")) + { + e3 = xml->children(xml); + while (e3->enumerate(e3, &xml, &name, &value)) + { + if (streq(name, "ikesalist")) + { + e4 = xml->children(xml); + e1->destroy(e1); + e2->destroy(e2); + e3->destroy(e3); + return e4; + } + } + e3->destroy(e3); + } + } + e2->destroy(e2); + } + } + e1->destroy(e1); + return NULL; +} + /** * Implementation of gateway_t.destroy */ @@ -129,25 +206,48 @@ static void destroy(private_gateway_t *this) { close(this->fd); } - this->host->destroy(this->host); + if (this->host) this->host->destroy(this->host); free(this->name); free(this); } -/* - * see header file +/** + * generic constructor */ -gateway_t *gateway_create(char *name, host_t *host) +static private_gateway_t *gateway_create(char *name) { private_gateway_t *this = malloc_thing(private_gateway_t); this->public.request = (char*(*)(gateway_t*, char *xml))request; + this->public.query_ikesalist = (enumerator_t*(*)(gateway_t*))query_ikesalist; this->public.destroy = (void(*)(gateway_t*))destroy; this->name = strdup(name); - this->host = host; + this->host = NULL; this->fd = -1; + return this; +} + +/** + * see header + */ +gateway_t *gateway_create_tcp(char *name, host_t *host) +{ + private_gateway_t *this = gateway_create(name); + + this->host = host; + + return &this->public; +} + +/** + * see header + */ +gateway_t *gateway_create_unix(char *name) +{ + private_gateway_t *this = gateway_create(name); + return &this->public; } diff --git a/src/manager/gateway.h b/src/manager/gateway.h index 7b5d91045..d84f00038 100644 --- a/src/manager/gateway.h +++ b/src/manager/gateway.h @@ -24,6 +24,7 @@ #define GATEWAY_H_ #include <utils/host.h> +#include <enumerator.h> typedef struct gateway_t gateway_t; @@ -39,7 +40,14 @@ struct gateway_t { * @return allocated xml response string */ char* (*request)(gateway_t *this, char *xml); - + + /** + * @brief Query the list of IKE_SAs and all its children. + * + * @return enumerator over ikesa XML elements + */ + enumerator_t* (*query_ikesalist)(gateway_t *this); + /** * @brief Destroy a gateway instance. */ @@ -47,12 +55,20 @@ struct gateway_t { }; /** - * @brief Create a gateway instance. + * @brief Create a gateway instance using a TCP connection. * * @param name name of the gateway * @param host gateway connection endpoint * @param */ -gateway_t *gateway_create(char *name, host_t *host); +gateway_t *gateway_create_tcp(char *name, host_t *host); + +/** + * @brief Create a gateway instance using a UNIX socket. + * + * @param name name of the gateway + * @param + */ +gateway_t *gateway_create_unix(char *name); #endif /* GATEWAY_H_ */ diff --git a/src/manager/lib/controller.h b/src/manager/lib/controller.h index fe6177513..5b39f559c 100644 --- a/src/manager/lib/controller.h +++ b/src/manager/lib/controller.h @@ -24,7 +24,6 @@ #define CONTROLLER_H_ #include "request.h" -#include "response.h" #include "context.h" typedef struct controller_t controller_t; @@ -35,7 +34,7 @@ typedef struct controller_t controller_t; * @param request http request * @param response http response */ -typedef void *(*controller_handler_t)(controller_t *this, request_t *request, response_t *response); +typedef void *(*controller_handler_t)(controller_t *this, request_t *request); /** * @brief Constructor function for a controller @@ -66,7 +65,6 @@ struct controller_t { * parameter not found in the request URL is set to NULL. * * @param request HTTP request - * @param response HTTP response * @param p1 first parameter * @param p2 second parameter * @param p3 third parameter @@ -74,7 +72,7 @@ struct controller_t { * @param p5 fifth parameter * @return */ - void (*handle)(controller_t *this, request_t *request, response_t *response, + void (*handle)(controller_t *this, request_t *request, char *a1, char *a2, char *a3, char *a4, char *a5); /** diff --git a/src/manager/lib/dict.c b/src/manager/lib/dict.c deleted file mode 100644 index a5fdd52d5..000000000 --- a/src/manager/lib/dict.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file dict.c - * - * @brief Implementation of dict_t. - * - */ - -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include "dict.h" - -#include <utils/linked_list.h> - - -typedef struct private_dict_t private_dict_t; - -/** - * private data of dict - */ -struct private_dict_t { - - /** - * public functions - */ - dict_t public; - - /** - * baaah, we really should have a hashtable for this - */ - linked_list_t *list; - - /** - * key comparator function - */ - bool(*key_comparator)(void*,void*); - - /** - * destructor function for key - */ - void(*key_destructor)(void*); - - /** - * destructor function for value - */ - void(*value_destructor)(void*); -}; - -/** - * key value pair to store entries - */ -typedef struct { - void *key; - void *value; -} key_value_t; - -/** - * Implementation of dict_t.get. - */ -static void* get(private_dict_t *this, void *key) -{ - key_value_t *kv; - iterator_t *iterator; - void *value = NULL; - - iterator = this->list->create_iterator(this->list, TRUE); - while (iterator->iterate(iterator, (void**)&kv)) - { - if (this->key_comparator(kv->key, key)) - { - value = kv->value; - break; - } - } - iterator->destroy(iterator); - return value; -} -/** - * Implementation of dict_t.set. - */ -static void set(private_dict_t *this, void *key, void *value) -{ - /* we don't overwrite, just prepend */ - key_value_t *kv = malloc_thing(key_value_t); - kv->key = key; - kv->value = value; - this->list->insert_first(this->list, kv); -} - - -/** - * comparator for strings - */ -bool dict_streq(void *a, void *b) -{ - return streq(a, b); -} - -/** - * Implementation of dict_t.destroy - */ -static void destroy(private_dict_t *this) -{ - key_value_t *kv; - - while (this->list->remove_last(this->list, (void**)&kv) == SUCCESS) - { - if (this->key_destructor) - { - this->key_destructor(kv->key); - } - if (this->value_destructor) - { - this->value_destructor(kv->value); - } - free(kv); - } - this->list->destroy(this->list); - free(this); -} - -/* - * see header file - */ -dict_t *dict_create(bool(*key_comparator)(void*,void*), - void(*key_destructor)(void*), - void(*value_destructor)(void*)) -{ - private_dict_t *this = malloc_thing(private_dict_t); - - this->public.set = (void(*)(dict_t*, void *key, void *value))set; - this->public.get = (void*(*)(dict_t*, void *key))get; - this->public.destroy = (void(*)(dict_t*))destroy; - - this->list = linked_list_create(); - this->key_comparator = key_comparator; - this->key_destructor = key_destructor; - this->value_destructor = value_destructor; - - return &this->public; -} - diff --git a/src/manager/lib/dict.h b/src/manager/lib/dict.h deleted file mode 100644 index 9a9e9036b..000000000 --- a/src/manager/lib/dict.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file dict.h - * - * @brief Interface of dict_t. - * - */ - -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#ifndef DICT_H_ -#define DICT_H_ - -#include <library.h> - -typedef struct dict_t dict_t; - -/** - * @brief Dictionary type, key value stuff. - */ -struct dict_t { - - /** - * @brief Set a value in the dict. - * - * @param key key to set - * @param value value, NULL to unset key - * @return - */ - void (*set)(dict_t *this, void *key, void *value); - - /** - * @brief Get a value form the dict. - * - * @param key key to get value of - * @return assigned value, NULL if not found - */ - void* (*get)(dict_t *this, void *key); - - /** - * @brief Destroy a dict instance. - */ - void (*destroy)(dict_t *this); -}; - -/** - * @brief Key comparator function for strings - */ -bool dict_streq(void *a, void *b); - -/** - * @brief Create a dict instance. - * - * @param free_key TRUE to free() keys on destruction - * @param - */ -dict_t *dict_create(bool(*key_comparator)(void*,void*), - void(*key_destructor)(void*), - void(*value_destructor)(void*)); - -#endif /* DICT_H_ */ diff --git a/src/manager/lib/dispatcher.c b/src/manager/lib/dispatcher.c index db99110c3..5ce5523f8 100644 --- a/src/manager/lib/dispatcher.c +++ b/src/manager/lib/dispatcher.c @@ -28,6 +28,7 @@ #include <fcgiapp.h> #include <pthread.h> #include <signal.h> +#include <unistd.h> #include <utils/linked_list.h> @@ -183,7 +184,6 @@ static void dispatch(private_dispatcher_t *this) while (TRUE) { request_t *request; - response_t *response; session_entry_t *current, *found = NULL; iterator_t *iterator; time_t now; @@ -200,8 +200,11 @@ static void dispatch(private_dispatcher_t *this) } /* prepare */ - response = response_create(&fcgi_req); - request = request_create(&fcgi_req); + request = request_create(&fcgi_req, TRUE); + if (request == NULL) + { + continue; + } sid = request->get_cookie(request, "SID"); now = time(NULL); @@ -244,7 +247,7 @@ static void dispatch(private_dispatcher_t *this) } /* start processing */ - found->session->process(found->session, request, response); + found->session->process(found->session, request); found->used = time(NULL); /* release session */ @@ -255,7 +258,6 @@ static void dispatch(private_dispatcher_t *this) /* cleanup */ request->destroy(request); - response->destroy(response); /* FCGX_FPrintF(fcgi_req.out, "<ul>"); @@ -323,8 +325,8 @@ static void destroy(private_dispatcher_t *this) /* * see header file */ -dispatcher_t *dispatcher_create(int timeout, context_constructor_t constructor, - void *param) +dispatcher_t *dispatcher_create(char *socket, int timeout, + context_constructor_t constructor, void *param) { private_dispatcher_t *this = malloc_thing(private_dispatcher_t); @@ -343,11 +345,11 @@ dispatcher_t *dispatcher_create(int timeout, context_constructor_t constructor, FCGX_Init(); -#ifdef FCGI_SOCKET - unlink(FCGI_SOCKET); - this->fd = FCGX_OpenSocket(FCGI_SOCKET, 10); -#endif /* FCGI_SOCKET */ - + if (socket) + { + unlink(socket); + this->fd = FCGX_OpenSocket(socket, 10); + } return &this->public; } diff --git a/src/manager/lib/dispatcher.h b/src/manager/lib/dispatcher.h index f46e5f32d..d04705409 100644 --- a/src/manager/lib/dispatcher.h +++ b/src/manager/lib/dispatcher.h @@ -73,11 +73,12 @@ struct dispatcher_t { * The context constructor is invoked to create a session context for * each session. * + * @param socket FastCGI socket path, NULL for dynamic * @param timeout session timeout * @param constructor construction function for session context * @param param parameter to supply to context constructor */ -dispatcher_t *dispatcher_create(int timeout, +dispatcher_t *dispatcher_create(char *socket, int timeout, context_constructor_t constructor, void *param); #endif /* DISPATCHER_H_ */ diff --git a/src/manager/lib/request.c b/src/manager/lib/request.c index 704b25203..e029c0d09 100644 --- a/src/manager/lib/request.c +++ b/src/manager/lib/request.c @@ -24,9 +24,10 @@ #include "request.h" +#include <library.h> #include <stdlib.h> - -#include <dict.h> +#include <string.h> +#include <ClearSilver/ClearSilver.h> typedef struct private_request_t private_request_t; @@ -41,27 +42,111 @@ struct private_request_t { request_t public; /** - * the associated fcgi request + * FastCGI request object */ FCGX_Request *req; /** - * list of cookies + * ClearSilver CGI Kit context */ - dict_t *cookies; + CGI *cgi; /** - * list of post data + * ClearSilver HDF dataset for this request */ - dict_t *posts; + HDF *hdf; }; + +/** + * thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks. + * ClearSilver cgiwrap is not threadsave, so we use a private + * context for each thread. + */ +__thread FCGX_Request *req; + +/** + * length of param list in req->envp + */ +__thread int req_env_len; + +/** + * fcgiwrap read callback + */ +static int read_cb(void *null, char *buf, int size) +{ + return FCGX_GetStr(buf, size, req->in); +} + +/** + * fcgiwrap writef callback + */ +static int writef_cb(void *null, const char *format, va_list args) +{ + FCGX_VFPrintF(req->out, format, args); + return 0; +} +/** + * fcgiwrap write callback + */ +static int write_cb(void *null, const char *buf, int size) +{ + return FCGX_PutStr(buf, size, req->out); +} + +/** + * fcgiwrap getenv callback + */ +static char *getenv_cb(void *null, const char *key) +{ + char *value; + + value = FCGX_GetParam(key, req->envp); + return value ? strdup(value) : NULL; +} + +/** + * fcgiwrap getenv callback + */ +static int putenv_cb(void *null, const char *key, const char *value) +{ + /* not supported */ + return 1; +} + +/** + * fcgiwrap iterenv callback + */ +static int iterenv_cb(void *null, int num, char **key, char **value) +{ + *key = NULL; + *value = NULL; + + if (num > req_env_len) + { + char *eq; + + eq = strchr(req->envp[num], '='); + if (eq) + { + *key = strndup(req->envp[num], eq - req->envp[num]); + *value = strdup(eq + 1); + } + if (*key == NULL || *value == NULL) + { + free(*key); + free(*value); + return 1; + } + } + return 0; +} /** * Implementation of request_t.get_cookie. */ static char* get_cookie(private_request_t *this, char *name) { - return this->cookies->get(this->cookies, name); + return hdf_get_valuef(this->hdf, "Cookie.%s", name); } /** @@ -76,152 +161,74 @@ static char* get_path(private_request_t *this) /** * Implementation of request_t.get_post_data. */ -static char* get_post_data(private_request_t *this, char *name) +static char* get_query_data(private_request_t *this, char *name) { - return this->posts->get(this->posts, name); + return hdf_get_valuef(this->hdf, "Query.%s", name); } /** - * convert 2 digit hex string to a integer + * Implementation of request_t.add_cookie. */ -static char hex2char(char *hex) +static void add_cookie(private_request_t *this, char *name, char *value) { - static char hexdig[] = "00112233445566778899AaBbCcDdEeFf"; + cgi_cookie_set (this->cgi, name, value, + FCGX_GetParam("SCRIPT_NAME", this->req->envp), + NULL, NULL, 0, 0); +} - return (strchr(hexdig, hex[1]) - hexdig)/2 + - ((strchr(hexdig, hex[0]) - hexdig)/2 * 16); +/** + * Implementation of request_t.redirect. + */ +static void redirect(private_request_t *this, char *location) +{ + FCGX_FPrintF(this->req->out, "Status: 303 See Other\n"); + FCGX_FPrintF(this->req->out, "Location: %s%s%s\n\n", + FCGX_GetParam("SCRIPT_NAME", this->req->envp), + *location == '/' ? "" : "/", location); } /** - * unescape a string up to the delimiter, and return a clone + * Implementation of request_t.get_base. */ -static char *unescape(char **pos, char delimiter) +static char* get_base(private_request_t *this) { - char *ptr, *res, *end, code[3] = {'\0','\0','\0'}; - - if (**pos == '\0') - { - return NULL; - } - ptr = strchr(*pos, delimiter); - if (ptr) - { - res = strndup(*pos, ptr - *pos); - *pos = ptr + 1; - } - else - { - res = strdup(*pos); - *pos = ""; - } - end = res + strlen(res) + 1; - /* replace '+' with ' ' */ - ptr = res; - while ((ptr = strchr(ptr, '+'))) - { - *ptr = ' '; - } - /* replace %HH with its ascii value */ - ptr = res; - while ((ptr = strchr(ptr, '%'))) - { - if (ptr > end - 2) - { - break; - } - strncpy(code, ptr + 1, 2); - *ptr = hex2char(code); - memmove(ptr + 1, ptr + 3, end - (ptr + 3)); - } - return res; + return FCGX_GetParam("SCRIPT_NAME", this->req->envp); } /** - * parse the http POST data + * Implementation of request_t.render. */ -static void parse_post(private_request_t *this) +static void render(private_request_t *this, char *template) { - char buf[4096], *pos, *name, *value; - int len; - - if (!streq(FCGX_GetParam("REQUEST_METHOD", this->req->envp), "POST") || - !streq(FCGX_GetParam("CONTENT_TYPE", this->req->envp), - "application/x-www-form-urlencoded")) - { - return; - } + NEOERR* err; - len = FCGX_GetStr(buf, sizeof(buf) - 1, this->req->in); - if (len != atoi(FCGX_GetParam("CONTENT_LENGTH", this->req->envp))) + err = cgi_display(this->cgi, template); + if (err) { - return; - } - buf[len] = 0; - - pos = buf; - while (TRUE) - { - name = unescape(&pos, '='); - if (name) - { - value = unescape(&pos, '&'); - if (value) - { - this->posts->set(this->posts, name, value); - continue; - } - else - { - free(name); - } - } - break; + cgi_neo_error(this->cgi, err); + nerr_log_error(err); } + return; } /** - * parse the requests cookies + * Implementation of request_t.set. */ -static void parse_cookies(private_request_t *this) +static void set(private_request_t *this, char *key, char *value) { - char *str, *pos; - char *name, *value; - - str = FCGX_GetParam("HTTP_COOKIE", this->req->envp); - while (str) - { - if (*str == ' ') - { - str++; - continue; - } - pos = strchr(str, '='); - if (pos == NULL) - { - break; - } - name = strndup(str, pos - str); - value = NULL; - str = pos + 1; - if (str) - { - pos = strchr(str, ';'); - if (pos) - { - value = strndup(str, pos - str); - } - else - { - value = strdup(str); - } - } - this->cookies->set(this->cookies, name, value); - if (pos == NULL) - { - break; - } - str = pos + 1; - } + hdf_set_value(this->hdf, key, value); +} + +/** + * Implementation of request_t.setf. + */ +static void setf(private_request_t *this, char *format, ...) +{ + va_list args; + + va_start(args, format); + hdf_set_valuevf(this->hdf, format, args); + va_end(args); } /** @@ -229,30 +236,70 @@ static void parse_cookies(private_request_t *this) */ static void destroy(private_request_t *this) { - this->cookies->destroy(this->cookies); - this->posts->destroy(this->posts); + cgi_destroy(&this->cgi); free(this); } /* * see header file */ -request_t *request_create(FCGX_Request *request) +request_t *request_create(FCGX_Request *request, bool debug) { + NEOERR* err; + static bool initialized = FALSE; private_request_t *this = malloc_thing(private_request_t); this->public.get_path = (char*(*)(request_t*))get_path; + this->public.get_base = (char*(*)(request_t*))get_base; + this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie; this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie; - this->public.get_post_data = (char*(*)(request_t*, char *name))get_post_data; + this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data; + this->public.redirect = (void(*)(request_t*, char *location))redirect; + this->public.render = (void(*)(request_t*,char*))render; + this->public.set = (void(*)(request_t*, char *, char*))set; + this->public.setf = (void(*)(request_t*, char *format, ...))setf; this->public.destroy = (void(*)(request_t*))destroy; + if (!initialized) + { + cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb, + getenv_cb, putenv_cb, iterenv_cb); + initialized = TRUE; + } + this->req = request; - this->cookies = dict_create(dict_streq, free, free); - this->posts = dict_create(dict_streq, free, free); + req = request; + req_env_len = 0; + while (req->envp[req_env_len] != NULL) + { + req_env_len++; + } - parse_cookies(this); - parse_post(this); + err = hdf_init(&this->hdf); + if (!err) + { + hdf_set_value(this->hdf, "base", get_base(this)); + hdf_set_value(this->hdf, "Config.NoCache", "true"); + if (!debug) + { + hdf_set_value(this->hdf, "Config.TimeFooter", "0"); + hdf_set_value(this->hdf, "Config.CompressionEnabled", "1"); + hdf_set_value(this->hdf, "Config.WhiteSpaceStrip", "2"); + } - return &this->public; + err = cgi_init(&this->cgi, this->hdf); + if (!err) + { + err = cgi_parse(this->cgi); + if (!err) + { + return &this->public; + } + cgi_destroy(&this->cgi); + } + } + nerr_log_error(err); + free(this); + return NULL; } diff --git a/src/manager/lib/request.h b/src/manager/lib/request.h index 852238a1d..e6fd71e71 100644 --- a/src/manager/lib/request.h +++ b/src/manager/lib/request.h @@ -23,8 +23,8 @@ #ifndef REQUEST_H_ #define REQUEST_H_ - #include <fcgiapp.h> +#include <library.h> typedef struct request_t request_t; @@ -35,6 +35,14 @@ typedef struct request_t request_t; struct request_t { /** + * @brief Add a cookie to the reply (Set-Cookie header). + * + * @param name name of the cookie to set + * @param value value of the cookie + */ + void (*add_cookie)(request_t *this, char *name, char *value); + + /** * @brief Get a cookie the client sent in the request. * * @param name name of the cookie @@ -50,12 +58,57 @@ struct request_t { char* (*get_path)(request_t *this); /** - * @brief Get a post variable included in the request. + * @brief Get the base path of the application. + * + * @return base path + */ + char* (*get_base)(request_t *this); + + /** + * @brief Get a post/get variable included in the request. * - * @param name name of the POST variable + * @param name name of the POST/GET variable * @return value, NULL if not found */ - char* (*get_post_data)(request_t *this, char *name); + char* (*get_query_data)(request_t *this, char *name); + + /** + * @brief Redirect the client to another location. + * + * @param location location to redirect to + */ + void (*redirect)(request_t *this, char *location); + + /** + * @brief Set a template value. + * + * @param key key to set + * @param value value to set key to + */ + void (*set)(request_t *this, char *key, char *value); + + /** + * @brief Set a template value using format strings. + * + * Format string is in the form "key=value", where printf like format + * substitution occurs over the whole string. + * + * @param format printf like format string + * @param ... variable argument list + */ + void (*setf)(request_t *this, char *format, ...); + + /** + * @brief Render a template. + * + * The render() function additionally sets a HDF variable "base" + * which points to the root of the web application and allows to point to + * other targets without to worry about path location. + * + * @param template clearsilver template file location + * @return rendered template string + */ + void (*render)(request_t *this, char *template); /** * @brief Destroy the request_t. @@ -67,7 +120,8 @@ struct request_t { * @brief Create a request from the fastcgi struct. * * @param request the FCGI request + * @param debug no stripping, no compression, timing information */ -request_t *request_create(FCGX_Request *request); +request_t *request_create(FCGX_Request *request, bool debug); #endif /* REQUEST_H_ */ diff --git a/src/manager/lib/response.c b/src/manager/lib/response.c deleted file mode 100644 index be933792f..000000000 --- a/src/manager/lib/response.c +++ /dev/null @@ -1,233 +0,0 @@ -/** - * @file response.c - * - * @brief Implementation of response_t. - * - */ - -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include "response.h" - -#include <stdlib.h> -#include <stdarg.h> - -#include <utils/linked_list.h> - -typedef struct { - char *name; - char *value; -} name_value_t; - -/** - * create name value pair - */ -static name_value_t *name_value_create(char *name, char *value) -{ - name_value_t *this = malloc_thing(name_value_t); - - this->name = strdup(name); - this->value = strdup(value); - - return this; -} - -/** - * destroy a name value pair - */ -static void name_value_destroy(name_value_t *this) -{ - free(this->name); - free(this->value); - free(this); -} - -typedef struct private_response_t private_response_t; - -/** - * private data of the task manager - */ -struct private_response_t { - - /** - * public functions - */ - response_t public; - - /** - * the associated fcgi request - */ - FCGX_Request *req; - - /** - * Content type - */ - char *content_type; - - /** - * list of cookies (name_value_t) - */ - linked_list_t *cookies; - - /** - * list of custom headers (name_value_t) - */ - linked_list_t *headers; - - /** - * headers already written? - */ - bool started; -}; - -/** - * write the headers, if not already written - */ -static void write_headers(private_response_t *this) -{ - iterator_t *iterator; - name_value_t *current; - - FCGX_FPrintF(this->req->out, "Content-type: %s\n", this->content_type); - iterator = this->cookies->create_iterator(this->cookies, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - FCGX_FPrintF(this->req->out, "Set-Cookie: %s=%s; path=%s\n", - current->name, current->value, - FCGX_GetParam("SCRIPT_NAME", this->req->envp)); - } - iterator->destroy(iterator); - iterator = this->cookies->create_iterator(this->headers, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - FCGX_FPrintF(this->req->out, "%s: %s\n", - current->name, current->value); - } - iterator->destroy(iterator); - FCGX_PutChar('\n', this->req->out); - this->started = TRUE; -} - -/** - * Implementation of response_t.print. - */ -static void print_(private_response_t *this, char *str) -{ - if (!this->started) - { - write_headers(this); - } - FCGX_PutS(str, this->req->out); -} - -/** - * Implementation of response_t.printf. - */ -static void printf_(private_response_t *this, char *format, ...) -{ - va_list args; - - if (!this->started) - { - write_headers(this); - } - - va_start(args, format); - FCGX_VFPrintF(this->req->out, format, args); - va_end(args); -} - -/** - * Implementation of response_t.add_header. - */ -static void add_header(private_response_t *this, char *name, char *value) -{ - this->headers->insert_last(this->headers, name_value_create(name, value)); -} - -/** - * Implementation of response_t.set_content_type. - */ -static void set_content_type(private_response_t *this, char *type) -{ - free(this->content_type); - this->content_type = strdup(type); -} - -/** - * Implementation of response_t.add_cookie. - */ -static void add_cookie(private_response_t *this, char *name, char *value) -{ - this->cookies->insert_last(this->cookies, name_value_create(name, value)); -} - -/** - * Implementation of response_t.redirect. - */ -static void redirect(private_response_t *this, char *location) -{ - FCGX_FPrintF(this->req->out, "Status: 303 See Other\n"); - FCGX_FPrintF(this->req->out, "Location: %s%s%s\n\n", - FCGX_GetParam("SCRIPT_NAME", this->req->envp), - *location == '/' ? "" : "/", location); -} - - -/** - * Implementation of response_t.get_base. - */ -static char* get_base(private_response_t *this) -{ - return FCGX_GetParam("SCRIPT_NAME", this->req->envp); -} - -/** - * Implementation of response_t.destroy - */ -static void destroy(private_response_t *this) -{ - this->headers->destroy_function(this->headers, (void*)name_value_destroy); - this->cookies->destroy_function(this->cookies, (void*)name_value_destroy); - free(this->content_type); - free(this); -} - -/* - * see header file - */ -response_t *response_create(FCGX_Request *request) -{ - private_response_t *this = malloc_thing(private_response_t); - - this->public.print = (void(*)(response_t*, char *str))print_; - this->public.printf = (void(*)(response_t*, char *format, ...))printf_; - this->public.add_header = (void(*)(response_t*, char *name, char *value))add_header; - this->public.set_content_type = (void(*)(response_t*, char *type))set_content_type; - this->public.add_cookie = (void(*)(response_t*, char *name, char *value))add_cookie; - this->public.redirect = (void(*)(response_t*, char *location))redirect; - this->public.get_base = (char*(*)(response_t*))get_base; - this->public.destroy = (void(*)(response_t*))destroy; - - this->req = request; - this->headers = linked_list_create(); - this->cookies = linked_list_create(); - this->content_type = strdup("text/html"); - this->started = FALSE; - - return &this->public; -} - diff --git a/src/manager/lib/response.h b/src/manager/lib/response.h deleted file mode 100644 index 50d0eacc1..000000000 --- a/src/manager/lib/response.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file response.h - * - * @brief Interface of response_t. - * - */ - -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#ifndef RESPONSE_H_ -#define RESPONSE_H_ - - -#include <fcgiapp.h> - -typedef struct response_t response_t; - -/** - * @brief A HTTP response, wraps response functionality around FCGX_Request. - * - */ -struct response_t { - - /** - * @brief Write a string to the client. - * - * @param str string to write - */ - void (*print)(response_t *this, char *str); - - /** - * @brief Write a printf like format string to client. - * - * @param format printf like format string - * @param ... variable argument list - */ - void (*printf)(response_t *this, char *format, ...); - - /** - * @brief Add a custom header to the response. - * - * @param name name of the header - * @param value value of the header - */ - void (*add_header)(response_t *this, char *name, char *value); - - /** - * @brief Set the content type (Content-Type header). - * - * @param type content type (e.g. text/html) - */ - void (*set_content_type)(response_t *this, char *type); - - /** - * @brief Add a cookie to the response (Set-Cookie header). - * - * @param name name of the cookie to set - * @param value value of the cookie - */ - void (*add_cookie)(response_t *this, char *name, char *value); - - /** - * @brief Redirect the client to another location. - * - * @param location location to redirect to - */ - void (*redirect)(response_t *this, char *location); - - /** - * @brief Get the base path of the application. - * - * @return base path - */ - char* (*get_base)(response_t *this); - - /** - * @brief Destroy a response_t. - */ - void (*destroy) (response_t *this); -}; - -/** - * @brief Create a response. - * - * @param request the FCGI request structure - */ -response_t *response_create(FCGX_Request *request); - -#endif /* RESPONSE_H_ */ diff --git a/src/manager/lib/session.c b/src/manager/lib/session.c index 7520c3226..8ffbc7230 100644 --- a/src/manager/lib/session.c +++ b/src/manager/lib/session.c @@ -70,7 +70,7 @@ static void add_controller(private_session_t *this, controller_t *controller) /** * Create a session ID and a cookie */ -static void create_sid(private_session_t *this, response_t *response) +static void create_sid(private_session_t *this, request_t *request) { char buf[16]; chunk_t chunk = chunk_from_buf(buf); @@ -78,15 +78,14 @@ static void create_sid(private_session_t *this, response_t *response) randomizer->get_pseudo_random_bytes(randomizer, sizeof(buf), buf); asprintf(&this->sid, "%#B", &chunk); - response->add_cookie(response, "SID", this->sid); + request->add_cookie(request, "SID", this->sid); randomizer->destroy(randomizer); } /** * Implementation of session_t.process. */ -static void process(private_session_t *this, - request_t *request, response_t *response) +static void process(private_session_t *this, request_t *request) { char *pos, *path, *controller, *action; iterator_t *iterator; @@ -95,7 +94,7 @@ static void process(private_session_t *this, if (this->sid == NULL) { - create_sid(this, response); + create_sid(this, request); } path = request->get_path(request); @@ -125,7 +124,7 @@ static void process(private_session_t *this, { if (streq(current->get_name(current), controller)) { - current->handle(current, request, response, action, NULL, NULL, NULL, NULL); + current->handle(current, request, action, NULL, NULL, NULL, NULL); handled = TRUE; break; } @@ -138,11 +137,7 @@ static void process(private_session_t *this, if (this->controllers->get_first(this->controllers, (void**)¤t) == SUCCESS) { - response->redirect(response, current->get_name(current)); - } - else - { - response->printf(response, "No controllers loaded!\n"); + request->redirect(request, current->get_name(current)); } } } @@ -174,7 +169,7 @@ session_t *session_create(context_t *context) private_session_t *this = malloc_thing(private_session_t); this->public.add_controller = (void(*)(session_t*, controller_t*))add_controller; - this->public.process = (void(*)(session_t*, request_t*,response_t*))process; + this->public.process = (void(*)(session_t*,request_t*))process; this->public.get_sid = (char*(*)(session_t*))get_sid; this->public.destroy = (void(*)(session_t*))destroy; diff --git a/src/manager/lib/session.h b/src/manager/lib/session.h index a66b1a8e2..d18545876 100644 --- a/src/manager/lib/session.h +++ b/src/manager/lib/session.h @@ -24,7 +24,6 @@ #define SESSION_H_ #include "request.h" -#include "response.h" #include "controller.h" typedef struct session_t session_t; @@ -53,9 +52,8 @@ struct session_t { * @brief Process a request in this session. * * @param request request to process - * @param response response to send */ - void (*process)(session_t *this, request_t *request, response_t *response); + void (*process)(session_t *this, request_t *request); /** * @brief Destroy the session_t. diff --git a/src/manager/lib/template.c b/src/manager/lib/template.c deleted file mode 100644 index 36a4d294e..000000000 --- a/src/manager/lib/template.c +++ /dev/null @@ -1,138 +0,0 @@ -/** - * @file template.c - * - * @brief Implementation of template_t. - * - */ - -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include "template.h" - -#include <ClearSilver/ClearSilver.h> - -#include <library.h> - -typedef struct private_template_t private_template_t; - -/** - * private data of the task manager - */ -struct private_template_t { - - /** - * public functions - */ - template_t public; - - /** - * template file - */ - char *file; - - /** - * clearsilver HDF dataset - */ - HDF *hdf; -}; - -/** - * clearsilver cs_render callback function - */ -static NEOERR* render_cb(response_t *response, char *str) -{ - response->print(response, str); - return NULL; -} - -/** - * Implementation of template_t.render. - */ -static void render(private_template_t *this, response_t *response) -{ - NEOERR* err; - CSPARSE *parse; - - hdf_set_value(this->hdf, "base", response->get_base(response)); - - err = cs_init(&parse, this->hdf); - if (!err) - { - err = cs_parse_file(parse, this->file); - if (!err) - { - err = cs_render(parse, response, (CSOUTFUNC)render_cb); - if (!err) - { - cs_destroy(&parse); - return; - } - } - cs_destroy(&parse); - } - nerr_log_error(err); - return; -} - -/** - * Implementation of template_t.set. - */ -static void set(private_template_t *this, char *key, char *value) -{ - hdf_set_value(this->hdf, key, value); -} - -/** - * Implementation of template_t.setf. - */ -static void setf(private_template_t *this, char *format, ...) -{ - va_list args; - - va_start(args, format); - hdf_set_valuevf(this->hdf, format, args); - va_end(args); -} - -/** - * Implementation of template_t.destroy - */ -static void destroy(private_template_t *this) -{ - hdf_destroy(&this->hdf); - free(this->file); - free(this); -} - -/* - * see header file - */ -template_t *template_create(char *file) -{ - private_template_t *this = malloc_thing(private_template_t); - - this->public.render = (void(*)(template_t*,response_t*))render; - this->public.set = (void(*)(template_t*, char *, char*))set; - this->public.setf = (void(*)(template_t*, char *format, ...))setf; - this->public.destroy = (void(*)(template_t*))destroy; - - this->file = strdup(file); - this->hdf = NULL; - - hdf_init(&this->hdf); - return &this->public; -} - diff --git a/src/manager/lib/template.h b/src/manager/lib/template.h deleted file mode 100644 index 6e17177a1..000000000 --- a/src/manager/lib/template.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file template.h - * - * @brief Interface of template_t. - * - */ - -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#ifndef TEMPLATE_H_ -#define TEMPLATE_H_ - -#include "response.h" - -typedef struct template_t template_t; - -/** - * @brief Template engine based on ClearSilver. - * - */ -struct template_t { - - /** - * @brief Set a template value. - * - * @param key key to set - * @param value value to set key to - */ - void (*set)(template_t *this, char *key, char *value); - - /** - * @brief Set a template value using format strings. - * - * Format string is in the form "key=value", where printf like format - * substitution occurs over the whole string. - * - * @param format printf like format string - * @param ... variable argument list - */ - void (*setf)(template_t *this, char *format, ...); - - /** - * @brief Render a template to a response object. - * - * The render() function additionally sets a clearsilver variable "base" - * which points to the root of the web application and allows to point to - * other targets without to worry about path location. - * - * @param response response to render to - * @return rendered template string - */ - void (*render)(template_t *this, response_t *response); - - /** - * @brief Destroy the template_t. - */ - void (*destroy) (template_t *this); -}; - -/** - * @brief Create a template from a file. - * - * @param file template file - */ -template_t *template_create(char *file); - -#endif /* TEMPLATE_H_ */ diff --git a/src/manager/main.c b/src/manager/main.c index abfc52912..45e4b2fd9 100644 --- a/src/manager/main.c +++ b/src/manager/main.c @@ -29,7 +29,7 @@ #include "controller/status_controller.h" #include "controller/gateway_controller.h" -#define DBFILE IPSECDIR "/sqlite.db" +#define DBFILE IPSECDIR "/manager.db" #define SESSION_TIMEOUT 180 #define THREADS 10 @@ -37,6 +37,11 @@ int main (int arc, char *argv[]) { dispatcher_t *dispatcher; database_t *database; + char *socket = NULL; + +#ifdef FCGI_SOCKET + socket = FCGI_SOCKET; +#endif /* FCGI_SOCKET */ database = database_create(DBFILE); if (database == NULL) @@ -45,8 +50,8 @@ int main (int arc, char *argv[]) return 1; } - dispatcher = dispatcher_create(SESSION_TIMEOUT, - (context_constructor_t)manager_create, database); + dispatcher = dispatcher_create(socket, SESSION_TIMEOUT, + (context_constructor_t)manager_create, database); dispatcher->add_controller(dispatcher, status_controller_create, NULL); dispatcher->add_controller(dispatcher, gateway_controller_create, NULL); dispatcher->add_controller(dispatcher, auth_controller_create, NULL); diff --git a/src/manager/manager.c b/src/manager/manager.c index b09d8d339..39c8d995a 100644 --- a/src/manager/manager.c +++ b/src/manager/manager.c @@ -82,12 +82,16 @@ static gateway_t* select_gateway(private_manager_t *this, int select_id) { if (select_id == id) { - if (port != 0) + if (port == 0) + { + this->gateway = gateway_create_unix(name); + } + else { host = host_create_from_string(address, port); if (host) { - this->gateway = gateway_create(name, host); + this->gateway = gateway_create_tcp(name, host); } } break; diff --git a/src/manager/manager.db b/src/manager/manager.db Binary files differnew file mode 100644 index 000000000..01c1f2722 --- /dev/null +++ b/src/manager/manager.db diff --git a/src/manager/sqlite.db b/src/manager/sqlite.db Binary files differdeleted file mode 100644 index c07973790..000000000 --- a/src/manager/sqlite.db +++ /dev/null diff --git a/src/manager/templates/error.cs b/src/manager/templates/error.cs new file mode 100644 index 000000000..be9b1a3a1 --- /dev/null +++ b/src/manager/templates/error.cs @@ -0,0 +1,3 @@ +<?cs include:"templates/header.cs" ?> +<div><?cs var:error ?></div> +<?cs include:"templates/footer.cs" ?> diff --git a/src/manager/templates/static/client-left.png b/src/manager/templates/static/client-left.png Binary files differindex ee4247d9d..8a082ff9e 100644 --- a/src/manager/templates/static/client-left.png +++ b/src/manager/templates/static/client-left.png diff --git a/src/manager/templates/static/client-right.png b/src/manager/templates/static/client-right.png Binary files differindex 792aef69a..c841eebaf 100644 --- a/src/manager/templates/static/client-right.png +++ b/src/manager/templates/static/client-right.png diff --git a/src/manager/templates/static/gateway-left.png b/src/manager/templates/static/gateway-left.png Binary files differindex b58436406..9ddd3624d 100644 --- a/src/manager/templates/static/gateway-left.png +++ b/src/manager/templates/static/gateway-left.png diff --git a/src/manager/templates/static/gateway-right.png b/src/manager/templates/static/gateway-right.png Binary files differindex 4b370cbee..0be446827 100644 --- a/src/manager/templates/static/gateway-right.png +++ b/src/manager/templates/static/gateway-right.png diff --git a/src/manager/templates/static/nat.png b/src/manager/templates/static/nat.png Binary files differdeleted file mode 100644 index f669b27c2..000000000 --- a/src/manager/templates/static/nat.png +++ /dev/null diff --git a/src/manager/templates/static/pipe-bad.png b/src/manager/templates/static/pipe-bad.png Binary files differindex dede311de..dce7e836e 100644 --- a/src/manager/templates/static/pipe-bad.png +++ b/src/manager/templates/static/pipe-bad.png diff --git a/src/manager/templates/static/pipe-good.png b/src/manager/templates/static/pipe-good.png Binary files differindex 9419fd3f4..1e254711c 100644 --- a/src/manager/templates/static/pipe-good.png +++ b/src/manager/templates/static/pipe-good.png diff --git a/src/manager/templates/static/pipe-thin-left.png b/src/manager/templates/static/pipe-thin-left.png Binary files differnew file mode 100644 index 000000000..6ccc59a17 --- /dev/null +++ b/src/manager/templates/static/pipe-thin-left.png diff --git a/src/manager/templates/static/pipe-thin-right.png b/src/manager/templates/static/pipe-thin-right.png Binary files differnew file mode 100644 index 000000000..1f582d24b --- /dev/null +++ b/src/manager/templates/static/pipe-thin-right.png diff --git a/src/manager/templates/static/pipe-thin.png b/src/manager/templates/static/pipe-thin.png Binary files differnew file mode 100644 index 000000000..d25f1b625 --- /dev/null +++ b/src/manager/templates/static/pipe-thin.png diff --git a/src/manager/templates/static/pipe.png b/src/manager/templates/static/pipe.png Binary files differindex 931e1709e..1e254711c 100644 --- a/src/manager/templates/static/pipe.png +++ b/src/manager/templates/static/pipe.png diff --git a/src/manager/templates/static/router.png b/src/manager/templates/static/router.png Binary files differindex 53114d9e6..12a68fc90 100644 --- a/src/manager/templates/static/router.png +++ b/src/manager/templates/static/router.png diff --git a/src/manager/templates/status/ikesalist.cs b/src/manager/templates/status/ikesalist.cs index d329d070a..05c3268b6 100644 --- a/src/manager/templates/status/ikesalist.cs +++ b/src/manager/templates/status/ikesalist.cs @@ -2,7 +2,7 @@ <?cs each:ikesa = ikesas ?> <div class="expand" id="ikesa-<?cs name:ikesa ?>"> <h1> - <?cs name:ikesa ?> [<?cs var:ikesa.peerconfig ?>]: + IKE #<?cs name:ikesa ?> [<?cs var:ikesa.peerconfig ?>]: <span><?cs var:ikesa.local.identification ?></span> <-> <span><?cs var:ikesa.remote.identification ?></span> </h1> @@ -10,48 +10,30 @@ <hr/> <table class="drawing"> <tr> - <td> - </td> - <td class="left" colspan="2"> + <td class="left" colspan="3"> <?cs var:ikesa.local.identification ?> </td> <td> </td> - <td class="right" colspan="2"> + <td class="right" colspan="3"> <?cs var:ikesa.remote.identification ?> </td> - <td> - </td> - </tr> - <tr> - <td> - </td> - <td> - </td> - <td class="center" colspan="3"> - <?cs var:ikesa.local.spi ?> : <?cs var:ikesa.remote.spi ?> - </td> - <td> - </td> - <td> - </td> </tr> <tr class="images"> <td> - <?cs each:net = ikesa.childsas.local ?> - <p><?cs var:net ?></p> - <?cs /each ?> - </td> - <td> <?cs if:ikesa.role == "initiator" ?> <img title="Local host is the initiator" src="<?cs var:base ?>/static/client-left.png"></img> <?cs else ?> <img title="Local host is the responder" src="<?cs var:base ?>/static/gateway-left.png"></img> <?cs /if ?> </td> + <td style="background-image:url(<?cs var:base ?>/static/pipe.png)"> + <?cs var:ikesa.local.spi ?><br/><br/><br/> + <?cs var:ikesa.local.address ?> + </td> <td> <?cs if:ikesa.local.nat == "true" ?> - <img title="Local host is behind a NAT router" src="<?cs var:base ?>/static/router.png"></img> + <img title="Local host is behind NAT" src="<?cs var:base ?>/static/router.png"></img> <?cs else ?> <img title="Local host is not NATed" src="<?cs var:base ?>/static/pipe.png"></img> <?cs /if ?> @@ -65,11 +47,15 @@ </td> <td> <?cs if:ikesa.remote.nat == "true" ?> - <img title="Remote host is behind a NAT router" src="<?cs var:base ?>/static/router.png"></img> + <img title="Remote host is behind NAT" src="<?cs var:base ?>/static/router.png"></img> <?cs else ?> <img title="Remote host is not NATed" src="<?cs var:base ?>/static/pipe.png"></img> <?cs /if ?> </td> + <td class="right" style="background-image:url(<?cs var:base ?>/static/pipe.png)"> + <?cs var:ikesa.remote.spi ?><br/><br/><br/> + <?cs var:ikesa.remote.address ?> + </td> <td> <?cs if:ikesa.role == "responder" ?> <img title="Remote host is the initiator" src="<?cs var:base ?>/static/client-right.png"></img> @@ -77,26 +63,37 @@ <img title="Remote host is the responder" src="<?cs var:base ?>/static/gateway-right.png"></img> <?cs /if ?> </td> - <td> - <?cs each:net = ikesa.childsas.remote ?> - <p><?cs var:net ?></p> - <?cs /each ?> - </td> </tr> + <?cs each:childsa = ikesa.childsas ?> <tr> - <td> - </td> - <td class="left" colspan="2"> - <?cs var:ikesa.local.address ?>:<?cs var:ikesa.local.port ?> - </td> - <td> - </td> - <td class="right" colspan="2"> - <?cs var:ikesa.remote.address ?>:<?cs var:ikesa.remote.port ?> - </td> - <td> + <td colspan="7" class="expand"> + <h1>IPsec #<?cs name:childsa ?> [<?cs var:childsa.childconfig ?>]:</h1> </td> </tr> + <tr> + <td colspan="7"><hr/></td> + </tr> + <tr class="images"> + <td colspan="2"> + <?cs each:net = childsa.local.networks ?> + <p><?cs var:net ?></p> + <?cs /each ?> + </td> + <td style="background-image:url(<?cs var:base ?>/static/pipe-thin-left.png)"> + <?cs var:childsa.local.spi ?><br/><br/><br/> + </td> + <td style="background-image:url(<?cs var:base ?>/static/pipe-thin.png)"> + </td> + <td class="right" style="background-image:url(<?cs var:base ?>/static/pipe-thin-right.png)"> + <?cs var:childsa.remote.spi ?><br/><br/><br/> + </td> + <td class="right" colspan="2"> + <?cs each:net = childsa.remote.networks ?> + <p><?cs var:net ?></p> + <?cs /each ?> + </td> + </tr> + <?cs /each ?> </table> </div> </div> |