configuration query for manager (WIP)
authorMartin Willi <martin@strongswan.org>
Mon, 12 Nov 2007 18:34:50 +0000 (18:34 -0000)
committerMartin Willi <martin@strongswan.org>
Mon, 12 Nov 2007 18:34:50 +0000 (18:34 -0000)
src/manager/Makefile.am
src/manager/controller/config_controller.c [new file with mode: 0644]
src/manager/controller/config_controller.h [new file with mode: 0644]
src/manager/gateway.c
src/manager/gateway.h
src/manager/main.c
src/manager/templates/config/list.cs [new file with mode: 0644]
src/manager/templates/header.cs
src/manager/templates/static/initiate.png [new file with mode: 0644]

index d141f37..c210c73 100644 (file)
@@ -5,6 +5,7 @@ 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/control_controller.c controller/control_controller.h \
+controller/config_controller.c controller/config_controller.h \
 controller/gateway_controller.c controller/gateway_controller.h
 
 manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
@@ -38,19 +39,23 @@ ipsec_templates_gateway_DATA = templates/gateway/list.cs
 ipsec_templates_statusdir = ${ipsec_templatesdir}/status
 ipsec_templates_status_DATA = templates/status/ikesalist.cs
 
+ipsec_templates_configdir = ${ipsec_templatesdir}/config
+ipsec_templates_config_DATA = templates/config/list.cs
+
 ipsec_templates_staticdir = ${ipsec_templatesdir}/static
 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/gateway-right.png templates/static/client-right.png \
-templates/static/close.png
+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/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/gateway-right.png templates/static/client-right.png \
-templates/static/close.png
+templates/static/close.png templates/static/initiate.png
diff --git a/src/manager/controller/config_controller.c b/src/manager/controller/config_controller.c
new file mode 100644 (file)
index 0000000..7d14984
--- /dev/null
@@ -0,0 +1,209 @@
+/**
+ * @file config_controller.c
+ *
+ * @brief Implementation of config_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 "config_controller.h"
+#include "../manager.h"
+#include "../gateway.h"
+
+#include <xml.h>
+
+#include <library.h>
+
+
+typedef struct private_config_controller_t private_config_controller_t;
+
+/**
+ * private data of the task manager
+ */
+struct private_config_controller_t {
+
+       /**
+        * public functions
+        */
+       config_controller_t public;
+       
+       /**
+        * manager instance
+        */
+       manager_t *manager;
+};
+
+/**
+ * read XML of a peerconfig element and fill template
+ */
+static void process_peerconfig(private_config_controller_t *this,
+                                                          enumerator_t *e, request_t *r)
+{
+       xml_t *xml;
+       enumerator_t *e1, *e2, *e3;
+       char *name, *value, *config = "", *child = "";
+
+       while (e->enumerate(e, &xml, &name, &value))
+       {
+               if (streq(name, "name"))
+               {
+                       config = value; 
+               }
+               else if (streq(name, "ikeconfig"))
+               {
+                       e1 = xml->children(xml);
+                       while (e1->enumerate(e1, &xml, &name, &value))
+                       {
+                               if (streq(name, "local") || streq(name, "remote"))
+                               {
+                                       r->setf(r, "peercfgs.%s.ikecfg.%s=%s", config, name, value);
+                               }
+                       }
+                       e1->destroy(e1);
+               }
+               else if (streq(name, "childconfiglist"))
+               {
+                       e1 = xml->children(xml);
+                       while (e1->enumerate(e1, &xml, &name, &value))
+                       {
+                               if (streq(name, "childcfg"))
+                               {
+                                       int num = 0;
+                                       
+                                       e2 = xml->children(xml);
+                                       while (e2->enumerate(e2, &xml, &name, &value))
+                                       {
+                                               if (streq(name, "name"))
+                                               {
+                                                       child = value;
+                                               }
+                                               else if (streq(name, "local") || streq(name, "remote"))
+                                               {
+                                                       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);
+                                                               }
+                                                       }
+                                                       e3->destroy(e3);
+                                               }
+                                       }
+                                       e2->destroy(e2);
+                               }
+                       }
+                       e1->destroy(e1);
+               }
+               else
+               {
+                       r->setf(r, "peercfgs.%s.%s=%s", config, name, value);
+               }
+       }
+}
+
+static void list(private_config_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_configlist(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", "Configuration overview");
+
+               while (e1->enumerate(e1, &xml, &name, &value))
+               {
+                       if (streq(name, "peerconfig"))
+                       {
+                               e2 = xml->children(xml);
+                               process_peerconfig(this, e2, r);
+                               e2->destroy(e2);
+                       }
+               }
+               e1->destroy(e1);
+
+               r->render(r, "templates/config/list.cs");
+       }
+}
+
+/**
+ * Implementation of controller_t.get_name
+ */
+static char* get_name(private_config_controller_t *this)
+{
+       return "config";
+}
+
+/**
+ * Implementation of controller_t.handle
+ */
+static void handle(private_config_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, "config/list");
+}
+
+/**
+ * Implementation of controller_t.destroy
+ */
+static void destroy(private_config_controller_t *this)
+{
+       free(this);
+}
+
+/*
+ * see header file
+ */
+controller_t *config_controller_create(context_t *context, void *param)
+{
+       private_config_controller_t *this = malloc_thing(private_config_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/config_controller.h b/src/manager/controller/config_controller.h
new file mode 100644 (file)
index 0000000..fcf5f5c
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * @file config_controller.h
+ * 
+ * @brief Interface of config_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 CONFIG_CONTROLLER_H_
+#define CONFIG_CONTROLLER_H_
+
+
+#include <controller.h>
+
+typedef struct config_controller_t config_controller_t;
+
+/**
+ * @brief Status controller.
+ */
+struct config_controller_t {
+
+       /**
+        * Implements controller_t interface.
+        */
+       controller_t controller;
+};
+
+/**
+ * @brief Create a config_controller controller instance.
+ */
+controller_t *config_controller_create(context_t *context, void *param);
+
+#endif /* CONFIG_CONTROLLER_H_ */
index 011025b..d7e395a 100644 (file)
@@ -204,13 +204,71 @@ static enumerator_t* query_ikesalist(private_gateway_t *this)
        return NULL;
 }
 
+       
+/**
+ * Implementation of gateway_t.query_configlist.
+ */
+static enumerator_t* query_configlist(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>"
+                                                               "<configlist/>"
+                                                       "</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, "configlist"))
+                                               {
+                                                       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.terminate.
  */
 static bool terminate(private_gateway_t *this, bool ike, u_int32_t id)
 {
        char *str, *kind;
-       xml_t *xml;
        
        if (ike)
        {
@@ -257,6 +315,7 @@ 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.destroy = (void(*)(gateway_t*))destroy;
        
index 060a97a..54dab86 100644 (file)
@@ -49,6 +49,13 @@ struct gateway_t {
        enumerator_t* (*query_ikesalist)(gateway_t *this);
        
        /**
+        * @brief Query the list of peer configs and its subconfigs.
+        *
+        * @return                      enumerator over peerconfig XML elements
+        */
+       enumerator_t* (*query_configlist)(gateway_t *this);
+       
+       /**
         * @brief Terminate an IKE or a CHILD SA.
         *
         * @param ike           TRUE for IKE-, FALSE for a CHILD-SA
index 7af957d..011598b 100644 (file)
@@ -29,6 +29,7 @@
 #include "controller/status_controller.h"
 #include "controller/gateway_controller.h"
 #include "controller/control_controller.h"
+#include "controller/config_controller.h"
 
 #define DBFILE IPSECDIR "/manager.db"
 #define SESSION_TIMEOUT 180
@@ -57,6 +58,7 @@ int main (int arc, char *argv[])
        dispatcher->add_controller(dispatcher, gateway_controller_create, NULL);
        dispatcher->add_controller(dispatcher, auth_controller_create, NULL);
        dispatcher->add_controller(dispatcher, control_controller_create, NULL);
+       dispatcher->add_controller(dispatcher, config_controller_create, NULL);
        
        dispatcher->run(dispatcher, THREADS, NULL, NULL, NULL, NULL);
        
diff --git a/src/manager/templates/config/list.cs b/src/manager/templates/config/list.cs
new file mode 100644 (file)
index 0000000..1a5af0d
--- /dev/null
@@ -0,0 +1,41 @@
+<?cs include:"templates/header.cs" ?>
+<?cs each:peercfg = peercfgs ?>
+  <div class="expand" id="peercfg-<?cs name:peercfg ?>">
+  <h1><?cs name:peercfg ?></h1>
+  <div class="controls">
+    <a title="initiate SA" href="<?cs var:base ?>/control/initiate/<?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
+    <table>
+      <tr>
+        <td colspan="2"><?cs name:childcfg ?></td>
+      </tr>
+      <tr>
+       <td>Local</td>
+       <td>Remote</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>
+    <?cs /each ?>
+  </div>
+  </div>
+<?cs /each ?>
+<?cs include:"templates/footer.cs" ?>
index 64a859a..095b9f4 100644 (file)
@@ -16,6 +16,8 @@
          <h2><?cs var:title ?></h2>
     </div>
     <div class="menu">
+      | <a href="<?cs var:base ?>/status/ikesalist">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>
     </div>
diff --git a/src/manager/templates/static/initiate.png b/src/manager/templates/static/initiate.png
new file mode 100644 (file)
index 0000000..4463e3b
Binary files /dev/null and b/src/manager/templates/static/initiate.png differ