manager can query and list IKE_SA status (no layout yet)
authorMartin Willi <martin@strongswan.org>
Thu, 13 Sep 2007 07:45:04 +0000 (07:45 -0000)
committerMartin Willi <martin@strongswan.org>
Thu, 13 Sep 2007 07:45:04 +0000 (07:45 -0000)
16 files changed:
configure.in
src/Makefile.am
src/charon/control/interfaces/xml_interface.c
src/manager/Makefile.am
src/manager/controller/status_controller.c
src/manager/database.c
src/manager/lib/dict.c [new file with mode: 0644]
src/manager/lib/dict.h [new file with mode: 0644]
src/manager/lib/enumerator.h
src/manager/lib/request.c
src/manager/lib/template.c
src/manager/lib/xml.c [new file with mode: 0644]
src/manager/lib/xml.h [new file with mode: 0644]
src/manager/manager.c
src/manager/sqlite.db [new file with mode: 0644]
src/manager/templates/status/ikesalist.cs

index d4bc3a0..ccc1bf1 100644 (file)
@@ -255,6 +255,15 @@ AC_ARG_ENABLE(
 AM_CONDITIONAL(USE_UML, test x$uml = xtrue)
 
 AC_ARG_ENABLE(
+    [manager],
+    AS_HELP_STRING([--enable-manager],[build web management console (default is NO).]),
+    [if test x$enableval = xyes; then
+        manager=true
+    fi]
+)
+AM_CONDITIONAL(USE_MANAGER, test x$manager = xtrue)
+
+AC_ARG_ENABLE(
     [integrity-test],
     AS_HELP_STRING([--enable-integrity-test],[enable the integrity test of the crypto library (default is NO).]),
     [if test x$enableval = xyes; then
@@ -371,5 +380,6 @@ AC_OUTPUT(
        src/openac/Makefile
        src/scepclient/Makefile
        src/dumm/Makefile
+       src/manager/Makefile
        testing/Makefile
 )
index 4f57695..4d41ea9 100644 (file)
@@ -4,3 +4,7 @@ if USE_UML
   SUBDIRS += dumm
 endif
 
+if USE_MANAGER
+  SUBDIRS += manager
+endif
+
index 389aeed..b295ec2 100644 (file)
@@ -189,6 +189,7 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
                {
                        write_bool(writer, "nat", ike_sa->has_condition(ike_sa, COND_NAT_HERE));
                }
+               xmlTextWriterEndElement(writer);
                /* </local> */
                
                /* <remote> */
@@ -205,6 +206,7 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
                {
                        write_bool(writer, "nat", ike_sa->has_condition(ike_sa, COND_NAT_THERE));
                }
+               xmlTextWriterEndElement(writer);
                /* </remote> */         
                
                /* <childsalist> */
@@ -286,8 +288,6 @@ static void request(xmlTextReaderPtr reader, char *id, int fd)
        /*   </message> and close document */
        xmlTextWriterEndDocument(writer);
        xmlFreeTextWriter(writer);
-       /* write a newline to indicate end of xml */
-       write(fd, "\n", 1);
 }
 
 /**
@@ -312,6 +312,7 @@ static job_requeue_t process(int *fdp)
                DBG2(DBG_CFG, "SMP XML connection closed");
                return JOB_REQUEUE_NONE;
        }
+       DBG1(DBG_CFG, "got XML request: %b", buffer, len);
        
        reader = xmlReaderForMemory(buffer, len, NULL, NULL, 0);
        if (reader == NULL)
index d86110e..633423f 100644 (file)
@@ -1,13 +1,13 @@
-ipsec_PROGRAMS = manager
+ipsec_PROGRAMS = manager.fcgi
 
-manager_SOURCES = \
+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/static_controller.c controller/static_controller.h \
 controller/status_controller.c controller/status_controller.h \
 controller/gateway_controller.c controller/gateway_controller.h
 
-manager_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
+manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
 
 
 
@@ -16,18 +16,23 @@ 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/template.h lib/template.c lib/dict.h lib/dict.c lib/xml.h lib/xml.c
 
-libappserv_la_LDFLAGS = -lstrongswan -lfcgi -lpthread -lneo_cs -lneo_utl
+libappserv_la_LDFLAGS = -lstrongswan -lfcgi -lpthread -lneo_cs -lneo_utl ${xml_LIBS}
 
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/manager/lib -I/usr/include/ClearSilver
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/manager/lib -I/usr/include/ClearSilver ${xml_CFLAGS}
 
 
+ipsec_DATA = sqlite.db
+
 ipsec_templatesdir = ${ipsecdir}/templates
 ipsec_templates_DATA = templates/header.cs templates/footer.cs
 
 ipsec_templates_authdir = ${ipsec_templatesdir}/auth
 ipsec_templates_auth_DATA = templates/auth/login.cs templates/auth/logout.cs
 
-ipsec_templates_staticdir = ${ipsec_templatesdir}/static
-ipsec_templates_static_DATA = templates/static/style.css
+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
index eac4b67..e3abda0 100644 (file)
@@ -25,6 +25,7 @@
 #include "../gateway.h"
 
 #include <template.h>
+#include <xml.h>
 
 #include <library.h>
 
@@ -45,9 +46,6 @@ struct private_status_controller_t {
         * manager instance
         */
        manager_t *manager;
-       
-       int count;
-       
 };
 
 static void ikesalist(private_status_controller_t *this,
@@ -55,6 +53,9 @@ static void ikesalist(private_status_controller_t *this,
 {
        char *str;
        gateway_t *gateway;
+       xml_t *doc, *node;
+       enumerator_t *e1, *e2, *e3, *e4, *e5, *e6;
+       char *name, *value, *id, *section;
 
        gateway = this->manager->select_gateway(this->manager, 0);
        str = gateway->request(gateway, "<message type=\"request\" id=\"1\">"
@@ -62,13 +63,80 @@ static void ikesalist(private_status_controller_t *this,
                                                                                        "<ikesalist/>"
                                                                                "</query>"
                                                                        "</message>");
-
-       response->set_content_type(response, "text/xml");
+       if (str == NULL)
+       {
+               response->printf(response, "gateway did not respond");
+               return;
+       }
+       
+       doc = xml_create(str);
+       if (doc == NULL)
+       {
+               response->printf(response, "parsing XML failed");
+               return;
+       }
+       
        template_t *t = template_create("templates/status/ikesalist.cs");
-       t->set(t, "xml", str);
+
+       e1 = doc->children(doc);
+       while (e1->enumerate(e1, &node, &name, &value))
+       {
+               if (streq(name, "message"))
+               {
+                       e2 = node->children(node);
+                       while (e2->enumerate(e2, &node, &name, &value))
+                       {
+                               if (streq(name, "query"))
+                               {
+                                       e3 = node->children(node);
+                                       while (e3->enumerate(e3, &node, &name, &value))
+                                       {
+                                               if (streq(name, "ikesalist"))
+                                               {
+                                                       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
+                                                                               {
+                                                                                       t->setf(t, "ikesas.%s.%s=%s", id, name, value);
+                                                                               }
+                                                                       }
+                                                                       e5->destroy(e5);
+                                                               }
+                                                       }
+                                                       e4->destroy(e4);
+                                               }
+                                       }
+                                       e3->destroy(e3);
+                               }
+                       }
+                       e2->destroy(e2);
+               }
+       }
+       e1->destroy(e1);
+
        t->render(t, response);
-       t->destroy(t);
-       
+       t->destroy(t); 
        free(str);
 }
 
@@ -128,7 +196,6 @@ controller_t *status_controller_create(context_t *context, void *param)
        this->public.controller.get_handler = (controller_handler_t(*)(controller_t*,char*))get_handler;
        this->public.controller.destroy = (void(*)(controller_t*))destroy;
        
-       this->count = 0;
        this->manager = (manager_t*)context;
        
        return &this->public.controller;
index 5e8eb78..46ac5a6 100644 (file)
@@ -65,7 +65,7 @@ static void db_enumerator_destroy(db_enumerator_t* this)
 /**
  * create a database enumerator
  */
-static enumerator_t *db_enumerator_create(bool(*enumerate)(db_enumerator_t*,...),
+static enumerator_t *db_enumerator_create(bool(*enumerate)(db_enumerator_t*,void*,...),
                                                                                         sqlite3_stmt *stmt)
 {
        db_enumerator_t *this = malloc_thing(db_enumerator_t);
@@ -78,7 +78,7 @@ static enumerator_t *db_enumerator_create(bool(*enumerate)(db_enumerator_t*,...)
 /**
  * enumerator function for empty enumerator
  */
-static bool empty_enumerate(enumerator_t *enumerator, ...)
+static bool empty_enumerate(enumerator_t *enumerator, void *item, ...)
 {
        return FALSE;
 }
@@ -120,19 +120,9 @@ static int login(private_database_t *this, char *username, char *password)
 /**
  * enumerate function for gateway enumrator
  */
-static bool gateway_enumerate(db_enumerator_t* e, ...)
+static bool gateway_enumerate(db_enumerator_t* e, int *id, const char **name,
+                                                         int *port, const char **address)
 {
-       va_list args;
-       int *id, *port;
-       const char **name, **address;
-       
-       va_start(args, e);
-       id = va_arg(args, typeof(id));
-       name = va_arg(args, typeof(name));
-       port = va_arg(args, typeof(port));
-       address = va_arg(args, typeof(address));
-       va_end(args);
-       
        if (sqlite3_step(e->stmt) == SQLITE_ROW)
        {
                *id = sqlite3_column_int(e->stmt, 0);
diff --git a/src/manager/lib/dict.c b/src/manager/lib/dict.c
new file mode 100644 (file)
index 0000000..a5fdd52
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * @file dict.c
+ *
+ * @brief Implementation of dict_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "dict.h"
+
+#include <utils/linked_list.h>
+
+
+typedef struct private_dict_t private_dict_t;
+
+/**
+ * private data of dict
+ */
+struct private_dict_t {
+
+       /**
+        * public functions
+        */
+       dict_t public;
+       
+       /**
+        * baaah, we really should have a hashtable for this
+        */
+       linked_list_t *list;
+       
+       /**
+        * key comparator function
+        */
+       bool(*key_comparator)(void*,void*);
+       
+       /**
+        * destructor function for key
+        */
+        void(*key_destructor)(void*);
+        
+        /**
+         * destructor function for value
+         */
+        void(*value_destructor)(void*);
+};
+
+/**
+ * key value pair to store entries
+ */
+typedef struct {
+       void *key;
+       void *value;
+} key_value_t;
+
+/**
+ * Implementation of dict_t.get.
+ */
+static void* get(private_dict_t *this, void *key)
+{
+       key_value_t *kv;
+       iterator_t *iterator;
+       void *value = NULL;
+       
+       iterator = this->list->create_iterator(this->list, TRUE);
+       while (iterator->iterate(iterator, (void**)&kv))
+       {
+               if (this->key_comparator(kv->key, key))
+               {
+                       value = kv->value;
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+       return value;
+}
+/**
+ * Implementation of dict_t.set.
+ */
+static void set(private_dict_t *this, void *key, void *value)
+{
+       /* we don't overwrite, just prepend */
+       key_value_t *kv = malloc_thing(key_value_t);
+       kv->key = key;
+       kv->value = value;
+       this->list->insert_first(this->list, kv);
+}
+
+
+/**
+ * comparator for strings
+ */
+bool dict_streq(void *a, void *b)
+{
+       return streq(a, b);
+}
+
+/**
+ * Implementation of dict_t.destroy
+ */
+static void destroy(private_dict_t *this)
+{
+       key_value_t *kv;
+
+       while (this->list->remove_last(this->list, (void**)&kv) == SUCCESS)
+       {
+               if (this->key_destructor)
+               {
+                       this->key_destructor(kv->key);
+               }
+               if (this->value_destructor)
+               {
+                       this->value_destructor(kv->value);
+               }
+               free(kv);
+       }
+       this->list->destroy(this->list);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+dict_t *dict_create(bool(*key_comparator)(void*,void*),
+                                       void(*key_destructor)(void*),
+                                       void(*value_destructor)(void*))
+{
+       private_dict_t *this = malloc_thing(private_dict_t);
+       
+       this->public.set = (void(*)(dict_t*, void *key, void *value))set;
+       this->public.get = (void*(*)(dict_t*, void *key))get;
+       this->public.destroy = (void(*)(dict_t*))destroy;
+       
+       this->list = linked_list_create();
+       this->key_comparator = key_comparator;
+       this->key_destructor = key_destructor;
+       this->value_destructor = value_destructor;
+       
+       return &this->public;
+}
+
diff --git a/src/manager/lib/dict.h b/src/manager/lib/dict.h
new file mode 100644 (file)
index 0000000..9a9e903
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * @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_ */
index de272f9..7321e21 100644 (file)
@@ -35,10 +35,11 @@ struct enumerator_t {
        /**
         * @brief Enumerate collection.
         *
-        * @param ...           variable argument list of pointers, NULL terminated
+        * @param item          first enumerated item
+        * @param ...           additional items enumerated, depending in implementation
         * @return                      TRUE if pointers returned
         */
-       bool (*enumerate)(enumerator_t *this, ...);
+       bool (*enumerate)(enumerator_t *this, void *item, ...);
                
        /**
      * @brief Destroy a enumerator instance.
index 2e12d36..704b252 100644 (file)
 
 #include <stdlib.h>
 
-#include <utils/linked_list.h>
-
-typedef struct {
-       char *name;
-       char *value;
-} name_value_t;
-
-/**
- * destroy a name value pair
- */
-static void name_value_destroy(name_value_t *this)
-{
-       free(this->name);
-       free(this->value);
-       free(this);
-}
+#include <dict.h>
 
 typedef struct private_request_t private_request_t;
 
@@ -61,14 +46,14 @@ struct private_request_t {
        FCGX_Request *req;
        
        /**
-        * list of cookies (name_value_t)
+        * list of cookies
         */
-       linked_list_t *cookies;
+       dict_t *cookies;
        
        /**
-        * list of post data (name_value_t)
+        * list of post data
         */
-       linked_list_t *posts;
+       dict_t *posts;
 };
        
 /**
@@ -76,21 +61,7 @@ struct private_request_t {
  */
 static char* get_cookie(private_request_t *this, char *name)
 {
-       char *value = NULL;
-       name_value_t *cookie;
-       iterator_t *iterator;
-       
-       iterator = this->cookies->create_iterator(this->cookies, TRUE);
-       while (iterator->iterate(iterator, (void**)&cookie))
-       {
-               if (streq(cookie->name, name))
-               {
-                       value = cookie->value;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       return value;
+       return this->cookies->get(this->cookies, name);
 }
        
 /**
@@ -107,21 +78,7 @@ static char* get_path(private_request_t *this)
  */
 static char* get_post_data(private_request_t *this, char *name)
 {
-       char *value = NULL;
-       name_value_t *data;
-       iterator_t *iterator;
-       
-       iterator = this->posts->create_iterator(this->posts, TRUE);
-       while (iterator->iterate(iterator, (void**)&data))
-       {
-               if (streq(data->name, name))
-               {
-                       value = data->value;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       return value;
+       return this->posts->get(this->posts, name);
 }
 
 /**
@@ -185,7 +142,6 @@ static char *unescape(char **pos, char delimiter)
 static void parse_post(private_request_t *this)
 {
        char buf[4096], *pos, *name, *value;
-       name_value_t *data;
        int len;
 
        if (!streq(FCGX_GetParam("REQUEST_METHOD", this->req->envp), "POST") ||
@@ -211,10 +167,7 @@ static void parse_post(private_request_t *this)
                        value = unescape(&pos, '&');
                        if (value)
                        {
-                               data = malloc_thing(name_value_t);
-                               data->name = name;
-                               data->value = value;
-                               this->posts->insert_last(this->posts, data);
+                               this->posts->set(this->posts, name, value);
                                continue;
                        }
                        else
@@ -232,7 +185,7 @@ static void parse_post(private_request_t *this)
 static void parse_cookies(private_request_t *this)
 {
        char *str, *pos;
-       name_value_t *cookie;
+       char *name, *value;
        
        str = FCGX_GetParam("HTTP_COOKIE", this->req->envp);
        while (str)
@@ -247,23 +200,22 @@ static void parse_cookies(private_request_t *this)
                {
                        break;
                }
-               cookie = malloc_thing(name_value_t);
-               cookie->name = strndup(str, pos - str);
-               cookie->value = NULL;
+               name = strndup(str, pos - str);
+               value = NULL;
                str = pos + 1;
                if (str)
                {
                        pos = strchr(str, ';');
                        if (pos)
                        {
-                               cookie->value = strndup(str, pos - str);
+                               value = strndup(str, pos - str);
                        }
                        else
                        {
-                               cookie->value = strdup(str);
+                               value = strdup(str);
                        }
                }
-               this->cookies->insert_last(this->cookies, cookie);
+               this->cookies->set(this->cookies, name, value);
                if (pos == NULL)
                {
                        break;
@@ -277,8 +229,8 @@ static void parse_cookies(private_request_t *this)
  */
 static void destroy(private_request_t *this)
 {
-       this->cookies->destroy_function(this->cookies, (void*)name_value_destroy);
-       this->posts->destroy_function(this->posts, (void*)name_value_destroy);
+       this->cookies->destroy(this->cookies);
+       this->posts->destroy(this->posts);
        free(this);
 }
 
@@ -295,8 +247,8 @@ request_t *request_create(FCGX_Request *request)
        this->public.destroy = (void(*)(request_t*))destroy;
        
        this->req = request;
-       this->cookies = linked_list_create();
-       this->posts = linked_list_create();
+       this->cookies = dict_create(dict_streq, free, free);
+       this->posts = dict_create(dict_streq, free, free);
        
        parse_cookies(this);
        parse_post(this);
index f168f9a..3ae7c87 100644 (file)
@@ -66,8 +66,6 @@ static void render(private_template_t *this, response_t *response)
        NEOERR* err;
        CSPARSE *parse;
        
-       hdf_remove_tree(this->hdf, "");
-       
        err = cs_init(&parse, this->hdf);
        if (!err)
        {
diff --git a/src/manager/lib/xml.c b/src/manager/lib/xml.c
new file mode 100644 (file)
index 0000000..008235b
--- /dev/null
@@ -0,0 +1,169 @@
+/**
+ * @file xml.c
+ *
+ * @brief Implementation of xml_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 "xml.h"
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+
+typedef struct private_xml_t private_xml_t;
+
+/**
+ * private data of xml
+ */
+struct private_xml_t {
+
+       /**
+        * public functions
+        */
+       xml_t public;
+       
+       /**
+        * root node of this xml (part)
+        */
+       xmlNode *node;
+       
+       /**
+        * document, only for root xml_t
+        */
+       xmlDoc *doc;
+       
+       /**
+        * Root xml_t*
+        */
+       private_xml_t *root;
+       
+       /**
+        * number of enumerator instances
+        */
+       int enums;
+};
+
+/**
+ * child element enumerator
+ */
+typedef struct {
+       /** enumerator interface */
+       enumerator_t e;
+       /** current child context (returned to enumerate() caller) */
+       private_xml_t child;
+       /** currently processing node */
+       xmlNode *node;
+} child_enum_t;
+
+/**
+ * Implementation of xml_t.children().enumerate().
+ */
+static bool child_enumerate(child_enum_t *e, private_xml_t **child,
+                                                       char **name, char **value)
+{
+       while (e->node && e->node->type != XML_ELEMENT_NODE)
+       {
+               e->node = e->node->next;
+       }
+       if (e->node)
+       {
+               xmlNode *text;
+               
+               text = e->node->children;
+               *value = NULL;
+               
+               while (text && text->type != XML_TEXT_NODE)
+               {
+                       text = text->next;
+               }
+               if (text)
+               {
+                       *value = text->content;
+               }
+               *name = (char*)e->node->name;
+               *child = &e->child;
+               e->child.node = e->node->children;
+               e->node = e->node->next;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * Implementation of xml_t.get_attribute.
+ */
+static char* get_attribute(private_xml_t *this, char *name)
+{
+       return NULL;
+}
+
+/**
+ * destroy enumerator, and complete tree if this was the last enumerator 
+ */
+static void child_destroy(child_enum_t *this)
+{
+       if (--this->child.root->enums == 0)
+       {
+               xmlFreeDoc(this->child.root->doc);
+               free(this->child.root);
+       }
+       free(this);
+}
+
+/**
+ * Implementation of xml_t.children.
+ */
+static enumerator_t* children(private_xml_t *this)
+{
+       child_enum_t *ce = malloc_thing(child_enum_t);
+       ce->e.enumerate = (void*)child_enumerate;
+       ce->e.destroy = (void*)child_destroy;
+       ce->node = this->node;
+       ce->child.public.children = (void*)children;
+       ce->child.public.get_attribute = (void*)get_attribute;
+       ce->child.node = NULL;
+       ce->child.doc = this->doc;
+       ce->child.root = this->root;
+       this->root->enums++;
+       return &ce->e;
+}
+
+/*
+ * see header file
+ */
+xml_t *xml_create(char *xml)
+{
+       private_xml_t *this = malloc_thing(private_xml_t);
+       
+       this->public.get_attribute = (char*(*)(xml_t*,char*))get_attribute;
+       this->public.children = (enumerator_t*(*)(xml_t*))children;
+       
+       this->doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0);
+       if (this->doc == NULL)
+       {
+               free(this);
+               return NULL;
+       }
+       this->node = xmlDocGetRootElement(this->doc);
+       this->root = this;
+       this->enums = 0;
+       
+       return &this->public;
+}
+
diff --git a/src/manager/lib/xml.h b/src/manager/lib/xml.h
new file mode 100644 (file)
index 0000000..b73ddf0
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * @file xml.h
+ * 
+ * @brief Interface of xml_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 XML_H_
+#define XML_H_
+
+#include <enumerator.h>
+
+typedef struct xml_t xml_t;
+
+/**
+ * @brief Simple enumerator based XML parser.
+ *
+ * An xml_t is a single node of the XML tree, but also serves as root node
+ * and therefore the document.
+ * This object has no destructor, the tree gets destroyed when all enumerator
+ * instances get destroyed.
+ */
+struct xml_t {
+
+       /**
+        * @brief Create an enumerator over all children.
+        *
+        * Enumerated values must not be manipulated or freed.
+        *
+        * @return                      enumerator over (xml_t* child, char *name, char *value)
+        */
+       enumerator_t* (*children)(xml_t *this);
+       
+       /**
+        * @brief Get an attribute value by its name.
+        *
+        * @param name          name of the attribute
+        * @return                      attribute value, NULL if not found
+        */
+       char *(*get_attribute)(xml_t *this, char *name);
+};
+
+/**
+ * @brief Create a xml instance.
+ */
+xml_t *xml_create(char *xml);
+
+#endif /* XML_H_ */
index dc27f86..b09d8d3 100644 (file)
@@ -123,9 +123,12 @@ static bool login(private_manager_t *this, char *username, char *password)
  */
 static void logout(private_manager_t *this)
 {
+       if (this->gateway)
+       {
+               this->gateway->destroy(this->gateway);
+               this->gateway = NULL;
+       }
        this->user = 0;
-       this->gateway->destroy(this->gateway);
-       this->gateway = NULL;
 }
 
 /**
diff --git a/src/manager/sqlite.db b/src/manager/sqlite.db
new file mode 100644 (file)
index 0000000..c079737
Binary files /dev/null and b/src/manager/sqlite.db differ
index f9becf8..239e622 100644 (file)
@@ -1 +1,35 @@
-<?cs var:xml ?>
+<?cs include:"templates/header.cs" ?>
+<h1>List of IKE SA's</h1>
+<table>
+  <tr>
+    <td>ID</td>
+    <td>Status</td>
+    <td>Role</td>
+    <td>Config</td>
+    <td colspan="3">Local</td>
+    <td colspan="3">Remote</td>
+  <tr>
+  <tr>
+    <td colspan="4"></td>
+    <td>ID</td>
+    <td>Address</td>
+    <td>SPI</td>
+    <td>ID</td>
+    <td>Address</td>
+    <td>SPI</td>
+  <tr>
+  <?cs each:ikesa = ikesas ?>
+    <td><?cs name:ikesa ?></td>
+    <td><?cs var:ikesa.status ?></td>
+    <td><?cs var:ikesa.role ?></td>
+    <td><?cs var:ikesa.peerconfig ?></td>
+    <td><?cs var:ikesa.local.identification ?></td>
+    <td><?cs var:ikesa.local.address ?>:<?cs var:ikesa.local.port ?></td>
+    <td><?cs var:ikesa.local.spi ?></td>
+    <td><?cs var:ikesa.remote.identification ?></td>
+    <td><?cs var:ikesa.remote.address ?>:<?cs var:ikesa.remote.port ?></td>
+    <td><?cs var:ikesa.remote.spi ?></td>
+  <?cs /each ?>
+  </tr>
+</table>
+<?cs include:"templates/footer.cs" ?>