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