refactored strongswan manager
authorMartin Willi <martin@strongswan.org>
Wed, 26 Sep 2007 14:02:21 +0000 (14:02 -0000)
committerMartin Willi <martin@strongswan.org>
Wed, 26 Sep 2007 14:02:21 +0000 (14:02 -0000)
  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

41 files changed:
src/charon/control/interfaces/stroke_interface.c
src/charon/control/interfaces/xml_interface.c
src/charon/control/interfaces/xml_interface.xml
src/charon/daemon.c
src/manager/Makefile.am
src/manager/controller/auth_controller.c
src/manager/controller/gateway_controller.c
src/manager/controller/status_controller.c
src/manager/gateway.c
src/manager/gateway.h
src/manager/lib/controller.h
src/manager/lib/dict.c [deleted file]
src/manager/lib/dict.h [deleted file]
src/manager/lib/dispatcher.c
src/manager/lib/dispatcher.h
src/manager/lib/request.c
src/manager/lib/request.h
src/manager/lib/response.c [deleted file]
src/manager/lib/response.h [deleted file]
src/manager/lib/session.c
src/manager/lib/session.h
src/manager/lib/template.c [deleted file]
src/manager/lib/template.h [deleted file]
src/manager/main.c
src/manager/manager.c
src/manager/manager.db [new file with mode: 0644]
src/manager/sqlite.db [deleted file]
src/manager/templates/error.cs [new file with mode: 0644]
src/manager/templates/static/client-left.png
src/manager/templates/static/client-right.png
src/manager/templates/static/gateway-left.png
src/manager/templates/static/gateway-right.png
src/manager/templates/static/nat.png [deleted file]
src/manager/templates/static/pipe-bad.png
src/manager/templates/static/pipe-good.png
src/manager/templates/static/pipe-thin-left.png [new file with mode: 0644]
src/manager/templates/static/pipe-thin-right.png [new file with mode: 0644]
src/manager/templates/static/pipe-thin.png [new file with mode: 0644]
src/manager/templates/static/pipe.png
src/manager/templates/static/router.png
src/manager/templates/status/ikesalist.cs

index 74bfa1a..3ab6b57 100755 (executable)
@@ -1698,7 +1698,7 @@ interface_t *interface_create()
                return NULL;
        }
        
-       old = umask(~S_IRWXU);
+       old = umask(~(S_IRWXU | S_IRWXG));
        if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
        {
                DBG1(DBG_CFG, "could not bind stroke socket: %s", strerror(errno));
@@ -1707,6 +1707,11 @@ interface_t *interface_create()
                return NULL;
        }
        umask(old);
+       if (chown(socket_addr.sun_path, IPSEC_UID, IPSEC_GID) != 0)
+       {
+               DBG1(DBG_CFG, "changing stroke socket permissions failed: %s",
+                        strerror(errno));
+       }
        
        if (listen(this->socket, 0) < 0)
        {
index 3946611..d376c01 100644 (file)
@@ -146,23 +146,28 @@ static void write_address(xmlTextWriterPtr writer, char *element, host_t *host)
 }
 
 /**
- * write a list of traffic_selector_t
+ * write a childEnd
  */
-static void write_ts(xmlTextWriterPtr writer, linked_list_t *list)
+static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool local)
 {
        iterator_t *iterator;
+       linked_list_t *list;
        traffic_selector_t *ts;
-       
+       xmlTextWriterWriteFormatElement(writer, "spi", "%lx", 
+                                                                       child->get_spi(child, local));
+       xmlTextWriterStartElement(writer, "networks");
+       list = child->get_traffic_selectors(child, local);
        iterator = list->create_iterator(list, TRUE);
        while (iterator->iterate(iterator, (void**)&ts))
        {
-               xmlTextWriterStartElement(writer, "net");
+               xmlTextWriterStartElement(writer, "network");
                xmlTextWriterWriteAttribute(writer, "type",
                                                ts->get_type(ts) == TS_IPV4_ADDR_RANGE ? "ipv4" : "ipv6");
                xmlTextWriterWriteFormatString(writer, "%R", ts);
                xmlTextWriterEndElement(writer);
        }
        iterator->destroy(iterator);
+       xmlTextWriterEndElement(writer);
 }
 
 /**
@@ -170,12 +175,26 @@ static void write_ts(xmlTextWriterPtr writer, linked_list_t *list)
  */
 static void write_child(xmlTextWriterPtr writer, child_sa_t *child)
 {
+       mode_t mode;
+       encryption_algorithm_t encr;
+       integrity_algorithm_t int_algo;
+       size_t encr_len, int_len;
+       u_int32_t rekey, use_in, use_out, use_fwd;
+       child_cfg_t *config;
+       
+       config = child->get_config(child);
+       child->get_stats(child, &mode, &encr, &encr_len, &int_algo, &int_len,
+                                        &rekey, &use_in, &use_out, &use_fwd);
+
        xmlTextWriterStartElement(writer, "childsa");
+       xmlTextWriterWriteFormatElement(writer, "reqid", "%d", child->get_reqid(child));
+       xmlTextWriterWriteFormatElement(writer, "childconfig", "%s", 
+                                                                       config->get_name(config));
        xmlTextWriterStartElement(writer, "local");
-       write_ts(writer, child->get_traffic_selectors(child, TRUE));
+       write_childend(writer, child, TRUE);
        xmlTextWriterEndElement(writer);
        xmlTextWriterStartElement(writer, "remote");
-       write_ts(writer, child->get_traffic_selectors(child, FALSE));
+       write_childend(writer, child, FALSE);
        xmlTextWriterEndElement(writer);
        xmlTextWriterEndElement(writer);
 }
@@ -421,7 +440,8 @@ static job_requeue_t dispatch(private_xml_interface_t *this)
        return JOB_REQUEUE_DIRECT;
 }
 
-struct sockaddr_un unix_addr = { AF_UNIX, "/var/run/charon.xml"};
+/** XML unix socket */
+struct sockaddr_un unix_addr = { AF_UNIX, IPSEC_PIDDIR "/charon.xml"};
 
 /**
  * Implementation of itnerface_t.destroy.
@@ -430,7 +450,7 @@ static void destroy(private_xml_interface_t *this)
 {
        this->job->cancel(this->job);
        close(this->socket);
-       //unlink(unix_addr.sun_path);
+       unlink(unix_addr.sun_path);
        free(this);
 }
 
@@ -440,42 +460,32 @@ static void destroy(private_xml_interface_t *this)
 interface_t *interface_create()
 {
        private_xml_interface_t *this = malloc_thing(private_xml_interface_t);
-       //mode_t old;
-       struct sockaddr_in tcp_addr;
+       mode_t old;
 
        this->public.interface.destroy = (void (*)(interface_t*))destroy;
        
        /* set up unix socket */
-       this->socket = socket(AF_INET, SOCK_STREAM, 0);//socket(AF_UNIX, SOCK_STREAM, 0);
+       this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
        if (this->socket == -1)
        {
                DBG1(DBG_CFG, "could not create XML socket");
                free(this);
                return NULL;
        }
-       
-       memset(&tcp_addr, 0, sizeof(tcp_addr));
-       tcp_addr.sin_family = AF_INET;
-       tcp_addr.sin_addr.s_addr = INADDR_ANY;
-       tcp_addr.sin_port = htons(4502);
-       if (bind(this->socket, (struct sockaddr*)&tcp_addr, sizeof(tcp_addr)) < 0)
+               
+       old = umask(~(S_IRWXU | S_IRWXG));
+       if (bind(this->socket, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) < 0)
        {
                DBG1(DBG_CFG, "could not bind XML socket: %s", strerror(errno));
                close(this->socket);
                free(this);
                return NULL;
        }
-       
-       /*
-       old = umask(~S_IRWXU);
-       if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
+       umask(old);
+       if (chown(unix_addr.sun_path, IPSEC_UID, IPSEC_GID) != 0)
        {
-               DBG1(DBG_CFG, "could not bind XML socket: %s", strerror(errno));
-               close(this->socket);
-               free(this);
-               return NULL;
+               DBG1(DBG_CFG, "changing XML socket permissions failed: %s", strerror(errno));
        }
-       umask(old);*/
        
        if (listen(this->socket, 5) < 0)
        {
index 82dff98..466d95f 100644 (file)
                                        <element name="peerconfig">
                                                <data type="string"/>
                                        </element>
+                                       <element name="lifetime">
+                                               <data type="integer"/>
+                                       </element>
+                                       <element name="rekeytime">
+                                               <data type="integer"/>
+                                       </element>
                                        <element name="local">
-                                               <ref name="endPoint"/>
+                                               <ref name="ikeEnd"/>
                                        </element>
                                        <element name="remote">
-                                               <ref name="endPoint"/>
+                                               <ref name="ikeEnd"/>
+                                       </element>
+                                       <element name="childsalist">
+                                               <zeroOrMore>
+                                                       <element name="childsa">
+                                                               <ref name="childsa"/>
+                                                       </element>
+                                               </zeroOrMore>
                                        </element>
                                </element>
                        </zeroOrMore>
                </element>
        </define>
-       <define name="endPoint">
+       <define name="ikeEnd">
                <element name="spi">
                        <data type="hexBinary" />
                </element>
                        </element>
                </optional>
        </define>
+       <define name="childsa">
+               <element name="reqid">
+                       <data type="nonNegativeInteger"/>
+               </element>
+               <element name="lifetime">
+                       <data type="integer"/>
+               </element>
+               <element name="rekeytime">
+                       <data type="integer"/>
+               </element>
+               <element name="local">
+                       <ref name="childEnd"/>
+               </element>
+               <element name="remote">
+                       <ref name="childEnd"/>
+               </element>
+       </define>
+       <define name="childEnd">
+               <element name="spi">
+               <element name="networks">
+                       <zeroOrMore>
+                               <element name="network">
+                                       <optional>
+                                               <attribute name="protocol"/>
+                                       </optional>
+                                       <optional>
+                                               <attribute name="port"/>
+                                       </optional>
+                               </element>
+                       </zeroOrMore>
+               </element>
+       </define>
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
        <!--                    identification and address                       -->
        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
index 9ef80a6..56b737a 100644 (file)
@@ -245,6 +245,8 @@ static void drop_capabilities(private_daemon_t *this, bool full)
                keep |= (1<<CAP_NET_RAW);
                /* CAP_DAC_READ_SEARCH to read ipsec.secrets */
                keep |= (1<<CAP_DAC_READ_SEARCH);
+               /* CAP_CHOWN to change file permissions (socket permissions) */
+               keep |= (1<<CAP_CHOWN);
        }
 
        hdr.version = _LINUX_CAPABILITY_VERSION;
@@ -552,6 +554,7 @@ int main(int argc, char *argv[])
        if (pid_file)
        {
                fprintf(pid_file, "%d\n", getpid());
+               fchown(fileno(pid_file), IPSEC_UID, IPSEC_GID);
                fclose(pid_file);
        }
        
index 432fad9..171bfa6 100644 (file)
@@ -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
index 68332da..fd4a3c7 100644 (file)
@@ -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;
index 1ebb511..bdc7792 100644 (file)
@@ -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;
index 7071176..bcdbd26 100644 (file)
@@ -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;
index b918da2..5f5a4b4 100644 (file)
 #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;
 }
 
index 7b5d910..d84f000 100644 (file)
@@ -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_ */
index fe61775..5b39f55 100644 (file)
@@ -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 (file)
index a5fdd52..0000000
+++ /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 (file)
index 9a9e903..0000000
+++ /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_ */
index db99110..5ce5523 100644 (file)
@@ -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;
 }
 
index f46e5f3..d047054 100644 (file)
@@ -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_ */
index 704b252..e029c0d 100644 (file)
 
 #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;
 }
 
index 852238a..e6fd71e 100644 (file)
@@ -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 (file)
index be93379..0000000
+++ /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**)&current))
-       {
-               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**)&current))
-       {
-               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 (file)
index 50d0eac..0000000
+++ /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_ */
index 7520c32..8ffbc72 100644 (file)
@@ -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**)&current) == 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;
 
index a66b1a8..d185458 100644 (file)
@@ -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 (file)
index 36a4d29..0000000
+++ /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 (file)
index 6e17177..0000000
+++ /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_ */
index abfc529..45e4b2f 100644 (file)
@@ -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);
index b09d8d3..39c8d99 100644 (file)
@@ -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
new file mode 100644 (file)
index 0000000..01c1f27
Binary files /dev/null and b/src/manager/manager.db differ
diff --git a/src/manager/sqlite.db b/src/manager/sqlite.db
deleted file mode 100644 (file)
index c079737..0000000
Binary files a/src/manager/sqlite.db and /dev/null differ
diff --git a/src/manager/templates/error.cs b/src/manager/templates/error.cs
new file mode 100644 (file)
index 0000000..be9b1a3
--- /dev/null
@@ -0,0 +1,3 @@
+<?cs include:"templates/header.cs" ?>
+<div><?cs var:error ?></div>
+<?cs include:"templates/footer.cs" ?>
index ee4247d..8a082ff 100644 (file)
Binary files a/src/manager/templates/static/client-left.png and b/src/manager/templates/static/client-left.png differ
index 792aef6..c841eeb 100644 (file)
Binary files a/src/manager/templates/static/client-right.png and b/src/manager/templates/static/client-right.png differ
index b584364..9ddd362 100644 (file)
Binary files a/src/manager/templates/static/gateway-left.png and b/src/manager/templates/static/gateway-left.png differ
index 4b370cb..0be4468 100644 (file)
Binary files a/src/manager/templates/static/gateway-right.png and b/src/manager/templates/static/gateway-right.png differ
diff --git a/src/manager/templates/static/nat.png b/src/manager/templates/static/nat.png
deleted file mode 100644 (file)
index f669b27..0000000
Binary files a/src/manager/templates/static/nat.png and /dev/null differ
index dede311..dce7e83 100644 (file)
Binary files a/src/manager/templates/static/pipe-bad.png and b/src/manager/templates/static/pipe-bad.png differ
index 9419fd3..1e25471 100644 (file)
Binary files a/src/manager/templates/static/pipe-good.png and b/src/manager/templates/static/pipe-good.png differ
diff --git a/src/manager/templates/static/pipe-thin-left.png b/src/manager/templates/static/pipe-thin-left.png
new file mode 100644 (file)
index 0000000..6ccc59a
Binary files /dev/null and b/src/manager/templates/static/pipe-thin-left.png differ
diff --git a/src/manager/templates/static/pipe-thin-right.png b/src/manager/templates/static/pipe-thin-right.png
new file mode 100644 (file)
index 0000000..1f582d2
Binary files /dev/null and b/src/manager/templates/static/pipe-thin-right.png differ
diff --git a/src/manager/templates/static/pipe-thin.png b/src/manager/templates/static/pipe-thin.png
new file mode 100644 (file)
index 0000000..d25f1b6
Binary files /dev/null and b/src/manager/templates/static/pipe-thin.png differ
index 931e170..1e25471 100644 (file)
Binary files a/src/manager/templates/static/pipe.png and b/src/manager/templates/static/pipe.png differ
index 53114d9..12a68fc 100644 (file)
Binary files a/src/manager/templates/static/router.png and b/src/manager/templates/static/router.png differ
index d329d07..05c3268 100644 (file)
@@ -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> &lt;-&gt; 
        <span><?cs var:ikesa.remote.identification ?></span>
   </h1> 
     <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 ?>
         </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>
           <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>