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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -100,17 +100,30 @@
|
||||
<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>
|
||||
@@ -131,6 +144,38 @@
|
||||
</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 -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
e2->destroy(e2);
|
||||
e1->destroy(e1);
|
||||
}
|
||||
else
|
||||
{
|
||||
r->setf(r, "ikesas.%s.childsas.%s.%s=%s",
|
||||
id, reqid, name, value);
|
||||
}
|
||||
}
|
||||
e1->destroy(e1);
|
||||
}
|
||||
|
||||
t->set(t, "title", "IKE SA overview");
|
||||
t->render(t, response);
|
||||
t->destroy(t);
|
||||
free(str);
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
e1->destroy(e1);
|
||||
}
|
||||
else
|
||||
{
|
||||
r->setf(r, "ikesas.%s.%s=%s", id, name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#ifndef REQUEST_H_
|
||||
#define REQUEST_H_
|
||||
|
||||
|
||||
#include <fcgiapp.h>
|
||||
#include <library.h>
|
||||
|
||||
typedef struct request_t request_t;
|
||||
|
||||
@@ -34,6 +34,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.
|
||||
*
|
||||
@@ -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.
|
||||
*
|
||||
* @param name name of the POST variable
|
||||
* @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/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_ */
|
||||
|
||||
@@ -1,233 +0,0 @@
|
||||
/**
|
||||
* @file response.c
|
||||
*
|
||||
* @brief Implementation of response_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "response.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *value;
|
||||
} name_value_t;
|
||||
|
||||
/**
|
||||
* create name value pair
|
||||
*/
|
||||
static name_value_t *name_value_create(char *name, char *value)
|
||||
{
|
||||
name_value_t *this = malloc_thing(name_value_t);
|
||||
|
||||
this->name = strdup(name);
|
||||
this->value = strdup(value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy a name value pair
|
||||
*/
|
||||
static void name_value_destroy(name_value_t *this)
|
||||
{
|
||||
free(this->name);
|
||||
free(this->value);
|
||||
free(this);
|
||||
}
|
||||
|
||||
typedef struct private_response_t private_response_t;
|
||||
|
||||
/**
|
||||
* private data of the task manager
|
||||
*/
|
||||
struct private_response_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
response_t public;
|
||||
|
||||
/**
|
||||
* the associated fcgi request
|
||||
*/
|
||||
FCGX_Request *req;
|
||||
|
||||
/**
|
||||
* Content type
|
||||
*/
|
||||
char *content_type;
|
||||
|
||||
/**
|
||||
* list of cookies (name_value_t)
|
||||
*/
|
||||
linked_list_t *cookies;
|
||||
|
||||
/**
|
||||
* list of custom headers (name_value_t)
|
||||
*/
|
||||
linked_list_t *headers;
|
||||
|
||||
/**
|
||||
* headers already written?
|
||||
*/
|
||||
bool started;
|
||||
};
|
||||
|
||||
/**
|
||||
* write the headers, if not already written
|
||||
*/
|
||||
static void write_headers(private_response_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
name_value_t *current;
|
||||
|
||||
FCGX_FPrintF(this->req->out, "Content-type: %s\n", this->content_type);
|
||||
iterator = this->cookies->create_iterator(this->cookies, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)¤t))
|
||||
{
|
||||
FCGX_FPrintF(this->req->out, "Set-Cookie: %s=%s; path=%s\n",
|
||||
current->name, current->value,
|
||||
FCGX_GetParam("SCRIPT_NAME", this->req->envp));
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
iterator = this->cookies->create_iterator(this->headers, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)¤t))
|
||||
{
|
||||
FCGX_FPrintF(this->req->out, "%s: %s\n",
|
||||
current->name, current->value);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
FCGX_PutChar('\n', this->req->out);
|
||||
this->started = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of response_t.print.
|
||||
*/
|
||||
static void print_(private_response_t *this, char *str)
|
||||
{
|
||||
if (!this->started)
|
||||
{
|
||||
write_headers(this);
|
||||
}
|
||||
FCGX_PutS(str, this->req->out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of response_t.printf.
|
||||
*/
|
||||
static void printf_(private_response_t *this, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!this->started)
|
||||
{
|
||||
write_headers(this);
|
||||
}
|
||||
|
||||
va_start(args, format);
|
||||
FCGX_VFPrintF(this->req->out, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of response_t.add_header.
|
||||
*/
|
||||
static void add_header(private_response_t *this, char *name, char *value)
|
||||
{
|
||||
this->headers->insert_last(this->headers, name_value_create(name, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of response_t.set_content_type.
|
||||
*/
|
||||
static void set_content_type(private_response_t *this, char *type)
|
||||
{
|
||||
free(this->content_type);
|
||||
this->content_type = strdup(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of response_t.add_cookie.
|
||||
*/
|
||||
static void add_cookie(private_response_t *this, char *name, char *value)
|
||||
{
|
||||
this->cookies->insert_last(this->cookies, name_value_create(name, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of response_t.redirect.
|
||||
*/
|
||||
static void redirect(private_response_t *this, char *location)
|
||||
{
|
||||
FCGX_FPrintF(this->req->out, "Status: 303 See Other\n");
|
||||
FCGX_FPrintF(this->req->out, "Location: %s%s%s\n\n",
|
||||
FCGX_GetParam("SCRIPT_NAME", this->req->envp),
|
||||
*location == '/' ? "" : "/", location);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of response_t.get_base.
|
||||
*/
|
||||
static char* get_base(private_response_t *this)
|
||||
{
|
||||
return FCGX_GetParam("SCRIPT_NAME", this->req->envp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of response_t.destroy
|
||||
*/
|
||||
static void destroy(private_response_t *this)
|
||||
{
|
||||
this->headers->destroy_function(this->headers, (void*)name_value_destroy);
|
||||
this->cookies->destroy_function(this->cookies, (void*)name_value_destroy);
|
||||
free(this->content_type);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
response_t *response_create(FCGX_Request *request)
|
||||
{
|
||||
private_response_t *this = malloc_thing(private_response_t);
|
||||
|
||||
this->public.print = (void(*)(response_t*, char *str))print_;
|
||||
this->public.printf = (void(*)(response_t*, char *format, ...))printf_;
|
||||
this->public.add_header = (void(*)(response_t*, char *name, char *value))add_header;
|
||||
this->public.set_content_type = (void(*)(response_t*, char *type))set_content_type;
|
||||
this->public.add_cookie = (void(*)(response_t*, char *name, char *value))add_cookie;
|
||||
this->public.redirect = (void(*)(response_t*, char *location))redirect;
|
||||
this->public.get_base = (char*(*)(response_t*))get_base;
|
||||
this->public.destroy = (void(*)(response_t*))destroy;
|
||||
|
||||
this->req = request;
|
||||
this->headers = linked_list_create();
|
||||
this->cookies = linked_list_create();
|
||||
this->content_type = strdup("text/html");
|
||||
this->started = FALSE;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
@@ -70,7 +70,7 @@ static void add_controller(private_session_t *this, controller_t *controller)
|
||||
/**
|
||||
* Create a session ID and a cookie
|
||||
*/
|
||||
static void create_sid(private_session_t *this, response_t *response)
|
||||
static void create_sid(private_session_t *this, request_t *request)
|
||||
{
|
||||
char buf[16];
|
||||
chunk_t chunk = chunk_from_buf(buf);
|
||||
@@ -78,15 +78,14 @@ static void create_sid(private_session_t *this, response_t *response)
|
||||
|
||||
randomizer->get_pseudo_random_bytes(randomizer, sizeof(buf), buf);
|
||||
asprintf(&this->sid, "%#B", &chunk);
|
||||
response->add_cookie(response, "SID", this->sid);
|
||||
request->add_cookie(request, "SID", this->sid);
|
||||
randomizer->destroy(randomizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of session_t.process.
|
||||
*/
|
||||
static void process(private_session_t *this,
|
||||
request_t *request, response_t *response)
|
||||
static void process(private_session_t *this, request_t *request)
|
||||
{
|
||||
char *pos, *path, *controller, *action;
|
||||
iterator_t *iterator;
|
||||
@@ -95,7 +94,7 @@ static void process(private_session_t *this,
|
||||
|
||||
if (this->sid == NULL)
|
||||
{
|
||||
create_sid(this, response);
|
||||
create_sid(this, request);
|
||||
}
|
||||
|
||||
path = request->get_path(request);
|
||||
@@ -125,7 +124,7 @@ static void process(private_session_t *this,
|
||||
{
|
||||
if (streq(current->get_name(current), controller))
|
||||
{
|
||||
current->handle(current, request, response, action, NULL, NULL, NULL, NULL);
|
||||
current->handle(current, request, action, NULL, NULL, NULL, NULL);
|
||||
handled = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -138,11 +137,7 @@ static void process(private_session_t *this,
|
||||
if (this->controllers->get_first(this->controllers,
|
||||
(void**)¤t) == SUCCESS)
|
||||
{
|
||||
response->redirect(response, current->get_name(current));
|
||||
}
|
||||
else
|
||||
{
|
||||
response->printf(response, "No controllers loaded!\n");
|
||||
request->redirect(request, current->get_name(current));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,7 +169,7 @@ session_t *session_create(context_t *context)
|
||||
private_session_t *this = malloc_thing(private_session_t);
|
||||
|
||||
this->public.add_controller = (void(*)(session_t*, controller_t*))add_controller;
|
||||
this->public.process = (void(*)(session_t*, request_t*,response_t*))process;
|
||||
this->public.process = (void(*)(session_t*,request_t*))process;
|
||||
this->public.get_sid = (char*(*)(session_t*))get_sid;
|
||||
this->public.destroy = (void(*)(session_t*))destroy;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<?cs include:"templates/header.cs" ?>
|
||||
<div><?cs var:error ?></div>
|
||||
<?cs include:"templates/footer.cs" ?>
|
||||
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 322 B |
|
After Width: | Height: | Size: 345 B |
|
After Width: | Height: | Size: 357 B |
|
After Width: | Height: | Size: 256 B |
|
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 322 B |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.2 KiB |
@@ -2,7 +2,7 @@
|
||||
<?cs each:ikesa = ikesas ?>
|
||||
<div class="expand" id="ikesa-<?cs name:ikesa ?>">
|
||||
<h1>
|
||||
<?cs name:ikesa ?> [<?cs var:ikesa.peerconfig ?>]:
|
||||
IKE #<?cs name:ikesa ?> [<?cs var:ikesa.peerconfig ?>]:
|
||||
<span><?cs var:ikesa.local.identification ?></span> <->
|
||||
<span><?cs var:ikesa.remote.identification ?></span>
|
||||
</h1>
|
||||
@@ -10,38 +10,16 @@
|
||||
<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>
|
||||
@@ -49,9 +27,13 @@
|
||||
<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 ?>
|
||||
</tr>
|
||||
<?cs each:childsa = ikesa.childsas ?>
|
||||
<tr>
|
||||
<td colspan="7" class="expand">
|
||||
<h1>IPsec #<?cs name:childsa ?> [<?cs var:childsa.childconfig ?>]:</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<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>
|
||||
<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>
|
||||
|
||||