implemented IKE/CHILD_SA close through manager
authorMartin Willi <martin@strongswan.org>
Mon, 12 Nov 2007 15:09:11 +0000 (15:09 -0000)
committerMartin Willi <martin@strongswan.org>
Mon, 12 Nov 2007 15:09:11 +0000 (15:09 -0000)
src/manager/Makefile.am
src/manager/controller/control_controller.c [new file with mode: 0644]
src/manager/controller/control_controller.h [new file with mode: 0644]
src/manager/gateway.c
src/manager/gateway.h
src/manager/main.c
src/manager/templates/static/close.png [new file with mode: 0644]
src/manager/templates/static/script.js
src/manager/templates/static/style.css
src/manager/templates/status/ikesalist.cs

index 17eecdb..d141f37 100644 (file)
@@ -4,6 +4,7 @@ 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/control_controller.c controller/control_controller.h \
 controller/gateway_controller.c controller/gateway_controller.h
 
 manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
@@ -42,7 +43,8 @@ ipsec_templates_static_DATA = templates/static/style.css templates/static/script
 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/router.png templates/static/gateway-right.png templates/static/client-right.png \
+templates/static/close.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 \
@@ -50,4 +52,5 @@ 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/router.png templates/static/gateway-right.png templates/static/client-right.png \
+templates/static/close.png
diff --git a/src/manager/controller/control_controller.c b/src/manager/controller/control_controller.c
new file mode 100644 (file)
index 0000000..9d0789d
--- /dev/null
@@ -0,0 +1,138 @@
+/**
+ * @file control_controller.c
+ *
+ * @brief Implementation of control_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 "control_controller.h"
+#include "../manager.h"
+#include "../gateway.h"
+
+#include <xml.h>
+
+#include <library.h>
+
+
+typedef struct private_control_controller_t private_control_controller_t;
+
+/**
+ * private data of the task manager
+ */
+struct private_control_controller_t {
+
+       /**
+        * public functions
+        */
+       control_controller_t public;
+       
+       /**
+        * manager instance
+        */
+       manager_t *manager;
+};
+
+/**
+ * terminate a IKE or CHILD SA
+ */
+static void terminate(private_control_controller_t *this, request_t *r,
+                                         bool ike, u_int32_t id)
+{
+       gateway_t *gateway;
+
+       gateway = this->manager->select_gateway(this->manager, 0);
+       if (gateway->terminate(gateway, ike, id))
+       {
+               r->redirect(r, "status/ikesalist");
+       }
+       else
+       {
+               r->set(r, "title", "Error");
+               r->set(r, "error", "controlling the gateway failed");
+               r->render(r, "templates/error.cs");
+       }
+}
+
+/**
+ * Implementation of controller_t.get_name
+ */
+static char* get_name(private_control_controller_t *this)
+{
+       return "control";
+}
+
+/**
+ * Implementation of controller_t.handle
+ */
+static void handle(private_control_controller_t *this,
+                                  request_t *request, char *action, char *strid)
+{
+       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)
+       {
+               u_int32_t id;
+       
+               if (streq(action, "terminateike"))
+               {
+                       if (strid && (id = atoi(strid)))
+                       {
+                               return terminate(this, request, TRUE, id);
+                       }
+               }
+               if (streq(action, "terminatechild"))
+               {
+                       if (strid && (id = atoi(strid)))
+                       {
+                               return terminate(this, request, FALSE, id);
+                       }
+               }
+       }
+       return request->redirect(request, "status/ikesalist");
+}
+
+/**
+ * Implementation of controller_t.destroy
+ */
+static void destroy(private_control_controller_t *this)
+{
+       free(this);
+}
+
+/*
+ * see header file
+ */
+controller_t *control_controller_create(context_t *context, void *param)
+{
+       private_control_controller_t *this = malloc_thing(private_control_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/control_controller.h b/src/manager/controller/control_controller.h
new file mode 100644 (file)
index 0000000..6a55170
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * @file control_controller.h
+ * 
+ * @brief Interface of control_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 CONTROL_CONTROLLER_H_
+#define CONTROL_CONTROLLER_H_
+
+
+#include <controller.h>
+
+typedef struct control_controller_t control_controller_t;
+
+/**
+ * @brief Status controller.
+ */
+struct control_controller_t {
+
+       /**
+        * Implements controller_t interface.
+        */
+       controller_t controller;
+};
+
+/**
+ * @brief Create a control_controller controller instance.
+ */
+controller_t *control_controller_create(context_t *context, void *param);
+
+#endif /* CONTROL_CONTROLLER_H_ */
index 5f5a4b4..011025b 100644 (file)
@@ -103,7 +103,7 @@ static bool connect_(private_gateway_t *this)
 /**
  * Implementation of gateway_t.request.
  */
-static char* request(private_gateway_t *this, char *xml)
+static char* request(private_gateway_t *this, char *xml, ...)
 {
        if (this->fd < 0)
        {
@@ -116,9 +116,16 @@ static char* request(private_gateway_t *this, char *xml)
        {
                char buf[8096];
                ssize_t len;
+               va_list args;
                
-               len = strlen(xml);
-               if (send(this->fd, xml, len, 0) != len)
+               va_start(args, xml);
+               len = vsnprintf(buf, sizeof(buf), xml, args);
+               va_end(args);
+               if (len < 0 || len >= sizeof(buf))
+               {
+                       return NULL;
+               }
+               if (send(this->fd, buf, len, 0) != len)
                {
                        return NULL;
                }
@@ -198,6 +205,36 @@ static enumerator_t* query_ikesalist(private_gateway_t *this)
 }
 
 /**
+ * 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)
+       {
+               kind = "ike";
+       }
+       else
+       {
+               kind = "child";
+       }
+       
+       str = request(this,     "<message type=\"request\" id=\"1\">"
+                                                       "<control>"
+                                                               "<%ssaterminate><id>%d</id></%ssaterminate>"
+                                                       "</control>"
+                                               "</message>", kind, id, kind);
+       if (str == NULL)
+       {
+               return FALSE;
+       }
+       free(str);
+       return TRUE;
+}
+
+/**
  * Implementation of gateway_t.destroy
  */
 static void destroy(private_gateway_t *this)
@@ -220,6 +257,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.terminate = (bool(*)(gateway_t*, bool ike, u_int32_t id))terminate;
        this->public.destroy = (void(*)(gateway_t*))destroy;
        
        this->name = strdup(name);
index 1fe2aef..060a97a 100644 (file)
@@ -49,6 +49,14 @@ struct gateway_t {
        enumerator_t* (*query_ikesalist)(gateway_t *this);
        
        /**
+        * @brief Terminate an IKE or a CHILD SA.
+        *
+        * @param ike           TRUE for IKE-, FALSE for a CHILD-SA
+        * @return                      TRUE if successful
+        */
+       bool (*terminate)(gateway_t *this, bool ike, u_int32_t id);
+       
+       /**
      * @brief Destroy a gateway instance.
      */
     void (*destroy)(gateway_t *this);
index bbe07cb..7af957d 100644 (file)
@@ -28,6 +28,7 @@
 #include "controller/auth_controller.h"
 #include "controller/status_controller.h"
 #include "controller/gateway_controller.h"
+#include "controller/control_controller.h"
 
 #define DBFILE IPSECDIR "/manager.db"
 #define SESSION_TIMEOUT 180
@@ -55,6 +56,7 @@ int main (int arc, char *argv[])
        dispatcher->add_controller(dispatcher, status_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);
        
        dispatcher->run(dispatcher, THREADS, NULL, NULL, NULL, NULL);
        
diff --git a/src/manager/templates/static/close.png b/src/manager/templates/static/close.png
new file mode 100644 (file)
index 0000000..7cb058d
Binary files /dev/null and b/src/manager/templates/static/close.png differ
index 7b2a582..ba6f622 100644 (file)
@@ -1,8 +1,8 @@
 
 $(function(){
-  $(".expand > div").hide();
+  $(".expander").hide();
   $(".expand > h1").toggle(
-    function(){$(this).parent(".expand").find("div").slideDown('fast');},
-    function(){$(this).parent(".expand").find("div").slideUp('fast');}
+    function(){$(this).parent(".expand").find(".expander").slideDown('fast');},
+    function(){$(this).parent(".expand").find(".expander").slideUp('fast');}
   );
 });
index 8a7f496..22c0805 100644 (file)
@@ -57,6 +57,7 @@ a img {
     font-size: 1em;
     cursor: pointer;
     margin: 0;
+    float: left;
 }
 
 .expand h1 span {
@@ -64,6 +65,15 @@ a img {
        margin-right: 2em;
 }
 
+.expander {
+       clear:left;
+}
+
+.controls {
+       margin-top: 3px;
+       text-align: right;
+}
+
 .center {
        text-align: center;
 }
index 2238aaf..15fe407 100644 (file)
@@ -5,8 +5,13 @@
        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>
+  </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>
       </tr>
       <?cs each:childsa = ikesa.childsas ?>
       <tr>
-       <td colspan="7" class="expand">
+       <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>