implemented IKE_SA initiation in manager
authorMartin Willi <martin@strongswan.org>
Tue, 13 Nov 2007 11:58:28 +0000 (11:58 -0000)
committerMartin Willi <martin@strongswan.org>
Tue, 13 Nov 2007 11:58:28 +0000 (11:58 -0000)
19 files changed:
src/manager/Makefile.am
src/manager/controller/auth_controller.c
src/manager/controller/config_controller.c
src/manager/controller/control_controller.c
src/manager/controller/gateway_controller.c
src/manager/controller/ikesa_controller.c [new file with mode: 0644]
src/manager/controller/ikesa_controller.h [new file with mode: 0644]
src/manager/controller/status_controller.c [deleted file]
src/manager/controller/status_controller.h [deleted file]
src/manager/gateway.c
src/manager/gateway.h
src/manager/main.c
src/manager/templates/config/list.cs
src/manager/templates/control/result.cs [new file with mode: 0644]
src/manager/templates/header.cs
src/manager/templates/ikesa/list.cs [new file with mode: 0644]
src/manager/templates/static/script.js
src/manager/templates/static/style.css
src/manager/templates/status/ikesalist.cs [deleted file]

index c210c73..9409a9c 100644 (file)
@@ -3,7 +3,7 @@ ipsec_PROGRAMS = manager.fcgi
 manager_fcgi_SOURCES = \
 main.c manager.c manager.h gateway.h gateway.c database.h database.c \
 controller/auth_controller.c controller/auth_controller.h \
-controller/status_controller.c controller/status_controller.h \
+controller/ikesa_controller.c controller/ikesa_controller.h \
 controller/control_controller.c controller/control_controller.h \
 controller/config_controller.c controller/config_controller.h \
 controller/gateway_controller.c controller/gateway_controller.h
@@ -36,8 +36,11 @@ ipsec_templates_auth_DATA = templates/auth/login.cs
 ipsec_templates_gatewaydir = ${ipsec_templatesdir}/gateway
 ipsec_templates_gateway_DATA = templates/gateway/list.cs
 
-ipsec_templates_statusdir = ${ipsec_templatesdir}/status
-ipsec_templates_status_DATA = templates/status/ikesalist.cs
+ipsec_templates_ikesadir = ${ipsec_templatesdir}/ikesa
+ipsec_templates_ikesa_DATA = templates/ikesa/list.cs
+
+ipsec_templates_controldir = ${ipsec_templatesdir}/control
+ipsec_templates_control_DATA = templates/control/result.cs
 
 ipsec_templates_configdir = ${ipsec_templatesdir}/config
 ipsec_templates_config_DATA = templates/config/list.cs
@@ -51,8 +54,8 @@ templates/static/router.png templates/static/gateway-right.png templates/static/
 templates/static/close.png templates/static/initiate.png
 
 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/config/list.cs \
+templates/auth/login.cs templates/gateway/list.cs templates/ikesa/list.cs \
+templates/config/list.cs templates/control/result.cs \
 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 \
index fd4a3c7..e9b8694 100644 (file)
@@ -60,7 +60,7 @@ static void check(private_auth_controller_t *this, request_t *request)
        if (username && password &&
                this->manager->login(this->manager, username, password))
        {
-               request->redirect(request, "status/ikesalist");
+               request->redirect(request, "ikesa/list");
        }
        else
        {
index 7d14984..c5c96a0 100644 (file)
@@ -55,7 +55,7 @@ static void process_peerconfig(private_config_controller_t *this,
 {
        xml_t *xml;
        enumerator_t *e1, *e2, *e3;
-       char *name, *value, *config = "", *child = "";
+       char *name, *value, *config = "", *child = "", *section = "";
 
        while (e->enumerate(e, &xml, &name, &value))
        {
@@ -80,7 +80,7 @@ static void process_peerconfig(private_config_controller_t *this,
                        e1 = xml->children(xml);
                        while (e1->enumerate(e1, &xml, &name, &value))
                        {
-                               if (streq(name, "childcfg"))
+                               if (streq(name, "childconfig"))
                                {
                                        int num = 0;
                                        
@@ -93,13 +93,14 @@ static void process_peerconfig(private_config_controller_t *this,
                                                }
                                                else if (streq(name, "local") || streq(name, "remote"))
                                                {
+                                                       section = name;
                                                        e3 = xml->children(xml);
                                                        while (e3->enumerate(e3, &xml, &name, &value))
                                                        {
                                                                if (streq(name, "network"))
                                                                {
-                                                                       r->setf(r, "peercfgs.%s.childcfgs.%s.%s.%d=%s",
-                                                                                       config, child, name, ++num, value);
+                                                                       r->setf(r, "peercfgs.%s.childcfgs.%s.%s.networks.%d=%s",
+                                                                                       config, child, section, ++num, value);
                                                                }
                                                        }
                                                        e3->destroy(e3);
index 9d0789d..12cb5e9 100644 (file)
@@ -48,17 +48,46 @@ struct private_control_controller_t {
 };
 
 /**
- * terminate a IKE or CHILD SA
+ * handle the result of a control operation
  */
-static void terminate(private_control_controller_t *this, request_t *r,
-                                         bool ike, u_int32_t id)
+static void handle_result(private_control_controller_t *this, request_t *r,
+                                                 enumerator_t *e)
 {
-       gateway_t *gateway;
-
-       gateway = this->manager->select_gateway(this->manager, 0);
-       if (gateway->terminate(gateway, ike, id))
+       enumerator_t *e1;
+       xml_t *xml;
+       char *name, *value;
+       int num = 0;
+       
+       if (e)
        {
-               r->redirect(r, "status/ikesalist");
+               while (e->enumerate(e, &xml, &name, &value))
+               {
+                       if (streq(name, "status"))
+                       {
+                               if (value && atoi(value) == 0)
+                               {
+                                       r->set(r, "result", "Operation executed successfully:");
+                               }
+                               else
+                               {
+                                       r->set(r, "result", "Operation failed:");
+                               }
+                       }
+                       else if (streq(name, "log"))
+                       {
+                               e1 = xml->children(xml);
+                               while (e1->enumerate(e1, &xml, &name, &value))
+                               {
+                                       if (streq(name, "item"))
+                                       {
+                                               r->setf(r, "log.%d=%s", ++num, value);
+                                       }
+                               }
+                               e1->destroy(e1);
+                       }
+               }
+               e->destroy(e);
+               r->render(r, "templates/control/result.cs");
        }
        else
        {
@@ -69,6 +98,36 @@ static void terminate(private_control_controller_t *this, request_t *r,
 }
 
 /**
+ * initiate an IKE or CHILD SA
+ */
+static void initiate(private_control_controller_t *this, request_t *r,
+                                        bool ike, char *config)
+{
+       gateway_t *gateway;
+       enumerator_t *e;
+
+       r->setf(r, "title=Establishing %s SA %s", ike ? "IKE" : "CHILD", config);
+       gateway = this->manager->select_gateway(this->manager, 0);
+       e = gateway->initiate(gateway, ike, config);
+       handle_result(this, r, e);
+}
+
+/**
+ * terminate an IKE or CHILD SA
+ */
+static void terminate(private_control_controller_t *this, request_t *r,
+                                         bool ike, u_int32_t id)
+{
+       gateway_t *gateway;
+       enumerator_t *e;
+       
+       r->setf(r, "title=Terminate %s SA %d", ike ? "IKE" : "CHILD", id);
+       gateway = this->manager->select_gateway(this->manager, 0);
+       e = gateway->terminate(gateway, ike, id);
+       handle_result(this, r, e);
+}
+
+/**
  * Implementation of controller_t.get_name
  */
 static char* get_name(private_control_controller_t *this)
@@ -80,7 +139,7 @@ static char* get_name(private_control_controller_t *this)
  * Implementation of controller_t.handle
  */
 static void handle(private_control_controller_t *this,
-                                  request_t *request, char *action, char *strid)
+                                  request_t *request, char *action, char *str)
 {
        if (!this->manager->logged_in(this->manager))
        {
@@ -96,20 +155,34 @@ static void handle(private_control_controller_t *this,
        
                if (streq(action, "terminateike"))
                {
-                       if (strid && (id = atoi(strid)))
+                       if (str && (id = atoi(str)))
                        {
                                return terminate(this, request, TRUE, id);
                        }
                }
                if (streq(action, "terminatechild"))
                {
-                       if (strid && (id = atoi(strid)))
+                       if (str && (id = atoi(str)))
                        {
                                return terminate(this, request, FALSE, id);
                        }
                }
+               if (streq(action, "initiateike"))
+               {
+                       if (str)
+                       {
+                               return initiate(this, request, TRUE, str);
+                       }
+               }
+               if (streq(action, "initiatechild"))
+               {
+                       if (str)
+                       {
+                               return initiate(this, request, FALSE, str);
+                       }
+               }
        }
-       return request->redirect(request, "status/ikesalist");
+       return request->redirect(request, "ikesa/list");
 }
 
 /**
index bdc7792..dff1cf3 100644 (file)
@@ -82,7 +82,7 @@ static void _select(private_gateway_controller_t *this, request_t *request)
        {
                if (this->manager->select_gateway(this->manager, atoi(id)))
                {
-                       request->redirect(request, "status/ikesalist");
+                       request->redirect(request, "ikesa/list");
                        return;
                }
        }
diff --git a/src/manager/controller/ikesa_controller.c b/src/manager/controller/ikesa_controller.c
new file mode 100644 (file)
index 0000000..2b282b7
--- /dev/null
@@ -0,0 +1,238 @@
+/**
+ * @file ikesa_controller.c
+ *
+ * @brief Implementation of ikesa_controller_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 "ikesa_controller.h"
+#include "../manager.h"
+#include "../gateway.h"
+
+#include <xml.h>
+
+#include <library.h>
+
+
+typedef struct private_ikesa_controller_t private_ikesa_controller_t;
+
+/**
+ * private data of the task manager
+ */
+struct private_ikesa_controller_t {
+
+       /**
+        * public functions
+        */
+       ikesa_controller_t public;
+       
+       /**
+        * manager instance
+        */
+       manager_t *manager;
+};
+
+/**
+ * read XML of a childsa element and fill template
+ */
+static void process_childsa(private_ikesa_controller_t *this, char *id,
+                                                       enumerator_t *e, request_t *r)
+{
+       xml_t *xml;
+       enumerator_t *e1, *e2;
+       char *name, *value, *reqid = "", *section = "";
+       int num = 0;
+       
+       while (e->enumerate(e, &xml, &name, &value))
+       {
+               if (streq(name, "reqid"))
+               {
+                       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, "networks"))
+                               {
+                                       e2 = xml->children(xml);
+                                       while (e2->enumerate(e2, &xml, &name, &value))
+                                       {
+                                               if (streq(name, "network"))
+                                               {
+                                                       r->setf(r, "ikesas.%s.childsas.%s.%s.networks.%d=%s",
+                                                                       id, reqid, section, ++num, value);
+                                               }
+                                       }
+                                       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_ikesa_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 list(private_ikesa_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/ikesa/list.cs");
+       }
+}
+
+/**
+ * Implementation of controller_t.get_name
+ */
+static char* get_name(private_ikesa_controller_t *this)
+{
+       return "ikesa";
+}
+
+/**
+ * Implementation of controller_t.handle
+ */
+static void handle(private_ikesa_controller_t *this,
+                                  request_t *request, char *action)
+{
+       if (!this->manager->logged_in(this->manager))
+       {
+               return request->redirect(request, "auth/login");
+       }
+       if (this->manager->select_gateway(this->manager, 0) == NULL)
+       {
+               return request->redirect(request, "gateway/list");
+       }
+       if (action)
+       {
+               if (streq(action, "list"))
+               {
+                       return list(this, request);
+               }
+       }
+       return request->redirect(request, "ikesa/list");
+}
+
+/**
+ * Implementation of controller_t.destroy
+ */
+static void destroy(private_ikesa_controller_t *this)
+{
+       free(this);
+}
+
+/*
+ * see header file
+ */
+controller_t *ikesa_controller_create(context_t *context, void *param)
+{
+       private_ikesa_controller_t *this = malloc_thing(private_ikesa_controller_t);
+
+       this->public.controller.get_name = (char*(*)(controller_t*))get_name;
+       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;
+       
+       return &this->public.controller;
+}
+
diff --git a/src/manager/controller/ikesa_controller.h b/src/manager/controller/ikesa_controller.h
new file mode 100644 (file)
index 0000000..753ccca
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * @file ikesa_controller.h
+ * 
+ * @brief Interface of ikesa_controller_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 IKESA_CONTROLLER_H_
+#define IKESA_CONTROLLER_H_
+
+
+#include <controller.h>
+
+typedef struct ikesa_controller_t ikesa_controller_t;
+
+/**
+ * @brief Status controller.
+ */
+struct ikesa_controller_t {
+
+       /**
+        * Implements controller_t interface.
+        */
+       controller_t controller;
+};
+
+/**
+ * @brief Create a ikesa_controller controller instance.
+ */
+controller_t *ikesa_controller_create(context_t *context, void *param);
+
+#endif /* IKESA_CONTROLLER_H_ */
diff --git a/src/manager/controller/status_controller.c b/src/manager/controller/status_controller.c
deleted file mode 100644 (file)
index bcdbd26..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * @file status_controller.c
- *
- * @brief Implementation of status_controller_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 "status_controller.h"
-#include "../manager.h"
-#include "../gateway.h"
-
-#include <xml.h>
-
-#include <library.h>
-
-
-typedef struct private_status_controller_t private_status_controller_t;
-
-/**
- * private data of the task manager
- */
-struct private_status_controller_t {
-
-       /**
-        * public functions
-        */
-       status_controller_t public;
-       
-       /**
-        * manager instance
-        */
-       manager_t *manager;
-};
-
-/**
- * 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)
-{
-       xml_t *xml;
-       enumerator_t *e1, *e2;
-       char *name, *value, *reqid = "", *section = "";
-       int num = 0;
-       
-       while (e->enumerate(e, &xml, &name, &value))
-       {
-               if (streq(name, "reqid"))
-               {
-                       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, "networks"))
-                               {
-                                       e2 = xml->children(xml);
-                                       while (e2->enumerate(e2, &xml, &name, &value))
-                                       {
-                                               if (streq(name, "network"))
-                                               {
-                                                       r->setf(r, "ikesas.%s.childsas.%s.%s.networks.%d=%s",
-                                                                       id, reqid, section, ++num, value);
-                                               }
-                                       }
-                                       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);
-                               }
-                       }
-                       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");
-       }
-}
-
-/**
- * Implementation of controller_t.get_name
- */
-static char* get_name(private_status_controller_t *this)
-{
-       return "status";
-}
-
-/**
- * Implementation of controller_t.handle
- */
-static void handle(private_status_controller_t *this,
-                                  request_t *request, char *action)
-{
-       if (!this->manager->logged_in(this->manager))
-       {
-               return request->redirect(request, "auth/login");
-       }
-       if (this->manager->select_gateway(this->manager, 0) == NULL)
-       {
-               return request->redirect(request, "gateway/list");
-       }
-       if (action)
-       {
-               if (streq(action, "ikesalist"))
-               {
-                       return ikesalist(this, request);
-               }
-       }
-       return request->redirect(request, "status/ikesalist");
-}
-
-/**
- * Implementation of controller_t.destroy
- */
-static void destroy(private_status_controller_t *this)
-{
-       free(this);
-}
-
-/*
- * see header file
- */
-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*,char*,char*,char*,char*,char*))handle;
-       this->public.controller.destroy = (void(*)(controller_t*))destroy;
-       
-       this->manager = (manager_t*)context;
-       
-       return &this->public.controller;
-}
-
diff --git a/src/manager/controller/status_controller.h b/src/manager/controller/status_controller.h
deleted file mode 100644 (file)
index a736dda..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * @file status_controller.h
- * 
- * @brief Interface of status_controller_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 STATUS_CONTROLLER_H_
-#define STATUS_CONTROLLER_H_
-
-
-#include <controller.h>
-
-typedef struct status_controller_t status_controller_t;
-
-/**
- * @brief Status controller.
- */
-struct status_controller_t {
-
-       /**
-        * Implements controller_t interface.
-        */
-       controller_t controller;
-};
-
-/**
- * @brief Create a status_controller controller instance.
- */
-controller_t *status_controller_create(context_t *context, void *param);
-
-#endif /* STATUS_CONTROLLER_H_ */
index d7e395a..d4eb527 100644 (file)
@@ -57,6 +57,11 @@ struct private_gateway_t {
         * socket file descriptor, > 0 if connected
         */
        int fd;
+       
+       /**
+        * unique id assigned to each xml message
+        */
+       int xmlid;
 };
 
 struct sockaddr_un unix_addr = { AF_UNIX, IPSEC_PIDDIR "/charon.xml"};
@@ -127,14 +132,14 @@ static char* request(private_gateway_t *this, char *xml, ...)
                }
                if (send(this->fd, buf, len, 0) != len)
                {
-                       return NULL;
+                       if (!connect_(this))
+                       {
+                               return NULL;
+                       }
+                       continue;
                }
                len = recv(this->fd, buf, sizeof(buf) - 1, 0);
-               if (len < 0)
-               {
-                       return NULL;
-               }
-               if (len == 0)
+               if (len <= 0)
                {
                        if (!connect_(this))
                        {
@@ -156,11 +161,11 @@ static enumerator_t* query_ikesalist(private_gateway_t *this)
        xml_t *xml;
        enumerator_t *e1, *e2, *e3, *e4 = NULL;
        
-       str = request(this,     "<message type=\"request\" id=\"1\">"
+       str = request(this,     "<message type=\"request\" id=\"%d\">"
                                                        "<query>"
                                                                "<ikesalist/>"
                                                        "</query>"
-                                               "</message>");
+                                               "</message>", this->xmlid++);
        if (str == NULL)
        {
                return NULL;
@@ -214,11 +219,11 @@ static enumerator_t* query_configlist(private_gateway_t *this)
        xml_t *xml;
        enumerator_t *e1, *e2, *e3, *e4 = NULL;
        
-       str = request(this,     "<message type=\"request\" id=\"1\">"
+       str = request(this,     "<message type=\"request\" id=\"%d\">"
                                                        "<query>"
                                                                "<configlist/>"
                                                        "</query>"
-                                               "</message>");
+                                               "</message>", this->xmlid++);
        if (str == NULL)
        {
                return NULL;
@@ -262,11 +267,52 @@ static enumerator_t* query_configlist(private_gateway_t *this)
        return NULL;
 }
 
+/**
+ * create enumerator over control elements children of a control response
+ */
+static enumerator_t* read_result(private_gateway_t *this, char *res)
+{
+       char *name, *value;
+       xml_t *xml;
+       enumerator_t *e1, *e2, *e3;
+
+       if (res == NULL)
+       {
+               return NULL;
+       }
+       xml = xml_create(res);
+       if (xml == NULL)
+       {
+               return NULL;
+       }
+       e1 = xml->children(xml);
+       free(res);
+       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, "control"))
+                               {
+                                       e3 = xml->children(xml);
+                                       e1->destroy(e1);
+                                       e2->destroy(e2);
+                                       return e3;
+                               }
+                       }
+                       e2->destroy(e2);
+               }
+       }
+       e1->destroy(e1);
+       return NULL;
+}
 
 /**
- * Implementation of gateway_t.terminate.
+ * Implementation of gateway_t.initiate.
  */
-static bool terminate(private_gateway_t *this, bool ike, u_int32_t id)
+static enumerator_t* initiate(private_gateway_t *this, bool ike, char *name)
 {
        char *str, *kind;
        
@@ -278,18 +324,35 @@ static bool terminate(private_gateway_t *this, bool ike, u_int32_t id)
        {
                kind = "child";
        }
-       
-       str = request(this,     "<message type=\"request\" id=\"1\">"
+       str = request(this,     "<message type=\"request\" id=\"%d\">"
                                                        "<control>"
-                                                               "<%ssaterminate><id>%d</id></%ssaterminate>"
+                                                               "<%ssainitiate>%s</%ssainitiate>"
                                                        "</control>"
-                                               "</message>", kind, id, kind);
-       if (str == NULL)
+                                               "</message>", this->xmlid++, kind, name, kind);
+       return read_result(this, str);
+}
+
+/**
+ * Implementation of gateway_t.terminate.
+ */
+static enumerator_t* terminate(private_gateway_t *this, bool ike, u_int32_t id)
+{
+       char *str, *kind;
+       
+       if (ike)
        {
-               return FALSE;
+               kind = "ike";
        }
-       free(str);
-       return TRUE;
+       else
+       {
+               kind = "child";
+       }
+       str = request(this,     "<message type=\"request\" id=\"%d\">"
+                                                       "<control>"
+                                                               "<%ssaterminate>%d</%ssaterminate>"
+                                                       "</control>"
+                                               "</message>", this->xmlid++, kind, id, kind);
+       return read_result(this, str);
 }
 
 /**
@@ -316,12 +379,14 @@ static private_gateway_t *gateway_create(char *name)
        this->public.request = (char*(*)(gateway_t*, char *xml))request;
        this->public.query_ikesalist = (enumerator_t*(*)(gateway_t*))query_ikesalist;
        this->public.query_configlist = (enumerator_t*(*)(gateway_t*))query_configlist;
-       this->public.terminate = (bool(*)(gateway_t*, bool ike, u_int32_t id))terminate;
+       this->public.initiate = (enumerator_t*(*)(gateway_t*, bool ike, char *name))initiate;
+       this->public.terminate = (enumerator_t*(*)(gateway_t*, bool ike, u_int32_t id))terminate;
        this->public.destroy = (void(*)(gateway_t*))destroy;
        
        this->name = strdup(name);
        this->host = NULL;
        this->fd = -1;
+       this->xmlid = 1;
        
        return this;
 }
index 54dab86..81d8b9c 100644 (file)
@@ -59,9 +59,19 @@ struct gateway_t {
         * @brief Terminate an IKE or a CHILD SA.
         *
         * @param ike           TRUE for IKE-, FALSE for a CHILD-SA
-        * @return                      TRUE if successful
+        * @param id            ID of the SA to terminate
+        * @return                      enumerator over control response XML children
         */
-       bool (*terminate)(gateway_t *this, bool ike, u_int32_t id);
+       enumerator_t* (*terminate)(gateway_t *this, bool ike, u_int32_t id);
+       
+       /**
+        * @brief Initiate an IKE or a CHILD SA.
+        *
+        * @param ike           TRUE for IKE-, FALSE for CHILD-SA
+        * @param name          name of the peer/child config
+        * @return                      enumerator over control response XML children
+        */
+       enumerator_t* (*initiate)(gateway_t *this, bool ike, char *name);
        
        /**
      * @brief Destroy a gateway instance.
index 011598b..b5b26ff 100644 (file)
@@ -26,7 +26,7 @@
 #include "manager.h"
 #include "database.h"
 #include "controller/auth_controller.h"
-#include "controller/status_controller.h"
+#include "controller/ikesa_controller.h"
 #include "controller/gateway_controller.h"
 #include "controller/control_controller.h"
 #include "controller/config_controller.h"
@@ -54,7 +54,7 @@ int main (int arc, char *argv[])
        
        dispatcher = dispatcher_create(socket, SESSION_TIMEOUT,
                                                (context_constructor_t)manager_create, database);
-       dispatcher->add_controller(dispatcher, status_controller_create, NULL);
+       dispatcher->add_controller(dispatcher, ikesa_controller_create, NULL);
        dispatcher->add_controller(dispatcher, gateway_controller_create, NULL);
        dispatcher->add_controller(dispatcher, auth_controller_create, NULL);
        dispatcher->add_controller(dispatcher, control_controller_create, NULL);
index 1a5af0d..79fda64 100644 (file)
@@ -1,39 +1,43 @@
 <?cs include:"templates/header.cs" ?>
 <?cs each:peercfg = peercfgs ?>
   <div class="expand" id="peercfg-<?cs name:peercfg ?>">
-  <h1><?cs name:peercfg ?></h1>
+  <h1><?cs name:peercfg ?>:
+       <span><?cs var:peercfg.local ?></span> &lt;-&gt; 
+       <span><?cs var:peercfg.remote ?></span>
+  </h1>
   <div class="controls">
-    <a title="initiate SA" href="<?cs var:base ?>/control/initiate/<?cs name:peercfg ?>">
+    <a title="initiate SA" href="<?cs var:base ?>/control/initiateike/<?cs name:peercfg ?>">
       <img src="<?cs var:base ?>/static/initiate.png"/>
     </a>
   </div>
   <div class="expander">
     <hr/>
-    <?cs var:peercfg.local ?> - <?cs var:peercfg.remote ?>
-    <hr/>
     <?cs each:childcfg = peercfg.childcfgs ?>
-    helo
+    <div class="expand">
+    <h1><?cs name:childcfg ?>:</h1>
+  <div class="controls">
+    <a title="initiate SA" href="<?cs var:base ?>/control/initiatechild/<?cs name:childcfg ?>">
+      <img src="<?cs var:base ?>/static/initiate.png"/>
+    </a>
+  </div>
+    <div class="expander">
     <table>
-      <tr>
-        <td colspan="2"><?cs name:childcfg ?></td>
-      </tr>
-      <tr>
-       <td>Local</td>
-       <td>Remote</td>
+      <tr class="images">
+       <td>
+          <?cs each:net = childcfg.local.networks ?>
+           <p><?cs var:net ?></p>
+          <?cs /each ?>
+       </td>
+       <td>&lt;-&gt;</td>
+       <td class="right">
+          <?cs each:net = childcfg.remote.networks ?>
+           <p><?cs var:net ?></p>
+          <?cs /each ?>
+       </td>
       </tr>
-      <tr>
-        <td>
-                 <?cs each:net = childcfg.local.networks ?>
-                   <p><?cs var:net ?></p>
-                 <?cs /each ?>
-               </td>
-        <td>
-                 <?cs each:net = childcfg.remote.networks ?>
-                   <p><?cs var:net ?></p>
-                 <?cs /each ?>
-               </td>
-         </tr>
-       </table>
+    </table>
+       </div>
+       </div>
     <?cs /each ?>
   </div>
   </div>
diff --git a/src/manager/templates/control/result.cs b/src/manager/templates/control/result.cs
new file mode 100644 (file)
index 0000000..1d59df6
--- /dev/null
@@ -0,0 +1,14 @@
+<?cs include:"templates/header.cs" ?>
+<div class="expand">
+  <h1><?cs var:result ?></h1>
+  <div class="controls">&nbsp;</div>
+  <div class="expander">
+  <hr/>
+  <ul>
+  <?cs each:item = log ?>
+    <li><?cs var:item ?></li>
+  <?cs /each ?>
+  </ul>
+  </div>
+</div>
+<?cs include:"templates/footer.cs" ?>
index 095b9f4..bacd833 100644 (file)
@@ -9,14 +9,14 @@
   </head>
   <body>
        <div class="fleft">
-      <a href="<?cs var:base ?>/status/ikesalist">
+      <a href="<?cs var:base ?>/ikesa/list">
         <img class="fleft" src="<?cs var:base ?>/static/strongswan.png"/>
       </a>
       <h1>strongSwan Manager</h1>
          <h2><?cs var:title ?></h2>
     </div>
     <div class="menu">
-      | <a href="<?cs var:base ?>/status/ikesalist">IKE SAs</a>
+      | <a href="<?cs var:base ?>/ikesa/list">IKE SAs</a>
       | <a href="<?cs var:base ?>/config/list">Config</a>
       | <a href="<?cs var:base ?>/gateway/list">Select Gateway</a>
       | <a href="<?cs var:base ?>/auth/logout">Logout</a>
diff --git a/src/manager/templates/ikesa/list.cs b/src/manager/templates/ikesa/list.cs
new file mode 100644 (file)
index 0000000..15fe407
--- /dev/null
@@ -0,0 +1,111 @@
+<?cs include:"templates/header.cs" ?>
+<?cs each:ikesa = ikesas ?>
+  <div class="expand" id="ikesa-<?cs name:ikesa ?>">
+  <h1>
+       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>
+  <div class="controls">
+    <a title="close IKE_SA" href="<?cs var:base ?>/control/terminateike/<?cs name:ikesa ?>">
+      <img src="<?cs var:base ?>/static/close.png"/>
+    </a>
+  </div>
+  <div class="expander">
+    <hr/>
+    <table class="drawing">
+      <tr>
+        <td class="left" colspan="3">
+          <?cs var:ikesa.local.identification ?>
+        </td>
+        <td>
+        </td>
+        <td class="right" colspan="3">
+          <?cs var:ikesa.remote.identification ?>
+        </td>
+      </tr>
+      <tr class="images">
+        <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 NAT" src="<?cs var:base ?>/static/router.png"></img>
+          <?cs else ?>
+          <img title="Local host is not NATed" src="<?cs var:base ?>/static/pipe.png"></img>
+          <?cs /if ?>
+        </td>
+        <td>
+          <?cs if:ikesa.status == "established" ?>
+          <img title="IKE connection <?cs var:ikesa.status ?>" src="<?cs var:base ?>/static/pipe-good.png"></img>
+          <?cs else ?>
+          <img title="IKE connection in state <?cs var:ikesa.status ?>" src="<?cs var:base ?>/static/pipe-bad.png"></img>
+          <?cs /if ?>
+        </td>
+        <td>
+          <?cs if:ikesa.remote.nat == "true" ?>
+          <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>
+          <?cs else ?>
+          <img title="Remote host is the responder" src="<?cs var:base ?>/static/gateway-right.png"></img>
+          <?cs /if ?>
+        </td>
+      </tr>
+      <?cs each:childsa = ikesa.childsas ?>
+      <tr>
+       <td colspan="6" class="expand">
+         <h1>IPsec #<?cs name:childsa ?> [<?cs var:childsa.childconfig ?>]:</h1>
+        </td>
+       <td class="controls">
+                 <a title="close CHILD_SA" href="<?cs var:base ?>/control/terminatechild/<?cs name:childsa ?>">  
+            <img src="<?cs var:base ?>/static/close.png"/>
+          </a>
+        </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 ?> &lt;-<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)">
+          -&gt; <?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>
+<?cs /each ?>
+<?cs include:"templates/footer.cs" ?>
index ba6f622..c9105c3 100644 (file)
@@ -1,8 +1,7 @@
 
 $(function(){
-  $(".expander").hide();
   $(".expand > h1").toggle(
-    function(){$(this).parent(".expand").find(".expander").slideDown('fast');},
-    function(){$(this).parent(".expand").find(".expander").slideUp('fast');}
+    function(){$(this).parent(".expand").find(".expander").slideUp('fast');},
+    function(){$(this).parent(".expand").find(".expander").slideDown('fast');}
   );
 });
index 22c0805..9550b82 100644 (file)
@@ -58,6 +58,7 @@ a img {
     cursor: pointer;
     margin: 0;
     float: left;
+    padding-top: 3px;
 }
 
 .expand h1 span {
diff --git a/src/manager/templates/status/ikesalist.cs b/src/manager/templates/status/ikesalist.cs
deleted file mode 100644 (file)
index 15fe407..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-<?cs include:"templates/header.cs" ?>
-<?cs each:ikesa = ikesas ?>
-  <div class="expand" id="ikesa-<?cs name:ikesa ?>">
-  <h1>
-       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>
-  <div class="controls">
-    <a title="close IKE_SA" href="<?cs var:base ?>/control/terminateike/<?cs name:ikesa ?>">
-      <img src="<?cs var:base ?>/static/close.png"/>
-    </a>
-  </div>
-  <div class="expander">
-    <hr/>
-    <table class="drawing">
-      <tr>
-        <td class="left" colspan="3">
-          <?cs var:ikesa.local.identification ?>
-        </td>
-        <td>
-        </td>
-        <td class="right" colspan="3">
-          <?cs var:ikesa.remote.identification ?>
-        </td>
-      </tr>
-      <tr class="images">
-        <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 NAT" src="<?cs var:base ?>/static/router.png"></img>
-          <?cs else ?>
-          <img title="Local host is not NATed" src="<?cs var:base ?>/static/pipe.png"></img>
-          <?cs /if ?>
-        </td>
-        <td>
-          <?cs if:ikesa.status == "established" ?>
-          <img title="IKE connection <?cs var:ikesa.status ?>" src="<?cs var:base ?>/static/pipe-good.png"></img>
-          <?cs else ?>
-          <img title="IKE connection in state <?cs var:ikesa.status ?>" src="<?cs var:base ?>/static/pipe-bad.png"></img>
-          <?cs /if ?>
-        </td>
-        <td>
-          <?cs if:ikesa.remote.nat == "true" ?>
-          <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>
-          <?cs else ?>
-          <img title="Remote host is the responder" src="<?cs var:base ?>/static/gateway-right.png"></img>
-          <?cs /if ?>
-        </td>
-      </tr>
-      <?cs each:childsa = ikesa.childsas ?>
-      <tr>
-       <td colspan="6" class="expand">
-         <h1>IPsec #<?cs name:childsa ?> [<?cs var:childsa.childconfig ?>]:</h1>
-        </td>
-       <td class="controls">
-                 <a title="close CHILD_SA" href="<?cs var:base ?>/control/terminatechild/<?cs name:childsa ?>">  
-            <img src="<?cs var:base ?>/static/close.png"/>
-          </a>
-        </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 ?> &lt;-<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)">
-          -&gt; <?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>
-<?cs /each ?>
-<?cs include:"templates/footer.cs" ?>