Management class for connection settings added, connections are stored in a simple...
authorTobias Brunner <tobias@strongswan.org>
Fri, 17 Sep 2010 15:43:00 +0000 (17:43 +0200)
committerTobias Brunner <tobias@strongswan.org>
Thu, 14 Oct 2010 15:36:17 +0000 (17:36 +0200)
src/frontends/maemo/src/Makefile.am
src/frontends/maemo/src/strongswan-connection.c
src/frontends/maemo/src/strongswan-connection.h
src/frontends/maemo/src/strongswan-connections.c [new file with mode: 0644]
src/frontends/maemo/src/strongswan-connections.h [new file with mode: 0644]

index 1dbf937..446ba39 100644 (file)
@@ -1,7 +1,8 @@
 pluginlib_LTLIBRARIES = libstrongswan-settings.la
 libstrongswan_settings_la_SOURCES = \
        strongswan-settings.c \
-       strongswan-connection.c strongswan-connection.h
+       strongswan-connection.c strongswan-connection.h \
+       strongswan-connections.c strongswan-connections.h
 
 libstrongswan_settings_la_LIBADD = $(HILDON_LIBS)
 libstrongswan_settings_la_CFLAGS = $(HILDON_CFLAGS)
index 0120f59..a861dfa 100644 (file)
@@ -24,6 +24,7 @@
 
 struct _StrongswanConnectionPrivate
 {
+       gchar *orig_name;
        gchar *name;
        gchar *host;
        gchar *cert;
@@ -114,15 +115,6 @@ strongswan_connection_init (StrongswanConnection *connection)
 }
 
 static void
-strongswan_connection_constructed (GObject *object)
-{
-       if (G_OBJECT_CLASS (strongswan_connection_parent_class)->constructed)
-       {
-               G_OBJECT_CLASS (strongswan_connection_parent_class)->constructed (object);
-       }
-}
-
-static void
 strongswan_connection_dispose (GObject *object)
 {
        G_OBJECT_CLASS (strongswan_connection_parent_class)->dispose (object);
@@ -132,6 +124,7 @@ static void
 strongswan_connection_finalize (GObject *object)
 {
        StrongswanConnectionPrivate *priv = STRONGSWAN_CONNECTION (object)->priv;
+       g_free (priv->orig_name);
        g_free (priv->name);
        g_free (priv->host);
        g_free (priv->cert);
@@ -145,7 +138,6 @@ strongswan_connection_class_init (StrongswanConnectionClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-       object_class->constructed = strongswan_connection_constructed;
        object_class->get_property = strongswan_connection_get_property;
        object_class->set_property = strongswan_connection_set_property;
        object_class->dispose = strongswan_connection_dispose;
@@ -166,7 +158,6 @@ strongswan_connection_class_init (StrongswanConnectionClass *klass)
        g_object_class_install_property (object_class, PROP_CERT,
                        g_param_spec_string ("cert", "Gateway or CA certificate",
                                                                 "The certificate of the gateway or the CA",
-
                                                                 NULL,
                                                                 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
@@ -185,6 +176,37 @@ strongswan_connection_class_init (StrongswanConnectionClass *klass)
        g_type_class_add_private (klass, sizeof (StrongswanConnectionPrivate));
 }
 
+static inline gchar *
+get_string_from_key_file (GKeyFile *key_file,
+                                                 const gchar *name,
+                                                 const gchar *key)
+{
+       GError *error = NULL;
+       gchar *value;
+       value = g_key_file_get_string (key_file, name, key, &error);
+       if (error)
+       {
+               g_warning ("Failed to read %s/%s from key file: %s",
+                                  name, key, error->message);
+               g_error_free (error);
+       }
+       return value;
+}
+
+static void
+strongswan_connection_update_from_key_file (GKeyFile *key_file,
+                                                                                       StrongswanConnection *connection)
+{
+       StrongswanConnectionPrivate *priv = connection->priv;
+       gchar *name = priv->name;
+
+       priv->orig_name = g_strdup (name);
+       priv->host = get_string_from_key_file (key_file, name, "host");
+       priv->cert = get_string_from_key_file (key_file, name, "cert");
+       priv->user = get_string_from_key_file (key_file, name, "user");
+       priv->pass = get_string_from_key_file (key_file, name, "pass");
+}
+
 StrongswanConnection *
 strongswan_connection_new (const gchar *name)
 {
@@ -196,3 +218,45 @@ strongswan_connection_new (const gchar *name)
        return conn;
 }
 
+StrongswanConnection *
+strongswan_connection_new_from_key_file (GKeyFile *key_file,
+                                                                                const gchar *name)
+{
+       StrongswanConnection *conn = strongswan_connection_new (name);
+       g_return_val_if_fail (conn != NULL, NULL);
+       strongswan_connection_update_from_key_file (key_file, conn);
+       return conn;
+}
+
+void
+strongswan_connection_save_to_key_file (GKeyFile *key_file,
+                                                                               StrongswanConnection *connection)
+{
+       StrongswanConnectionPrivate *priv = connection->priv;
+       gchar *name = priv->name;
+
+       if (priv->orig_name && strcmp (name, priv->orig_name))
+       {
+               g_key_file_remove_group (key_file, priv->orig_name, NULL);
+               g_free (priv->orig_name);
+               priv->orig_name = g_strdup (name);
+       }
+
+       if (priv->host)
+       {
+               g_key_file_set_string (key_file, name, "host", priv->host);
+       }
+       if (priv->cert)
+       {
+               g_key_file_set_string (key_file, name, "cert", priv->cert);
+       }
+       if (priv->user)
+       {
+               g_key_file_set_string (key_file, name, "user", priv->user);
+       }
+       if (priv->pass)
+       {
+               g_key_file_set_string (key_file, name, "pass", priv->pass);
+       }
+}
+
index dd94326..e80a162 100644 (file)
@@ -48,6 +48,9 @@ GType strongswan_connection_get_type (void);
 
 StrongswanConnection *strongswan_connection_new (const gchar *name);
 
+StrongswanConnection *strongswan_connection_new_from_key_file(GKeyFile *key_file, const gchar *name);
+void strongswan_connection_save_to_key_file (GKeyFile *key_file, StrongswanConnection *connection);
+
 G_END_DECLS
 
 #endif /* __STRONGSWAN_CONNECTION_H__ */
diff --git a/src/frontends/maemo/src/strongswan-connections.c b/src/frontends/maemo/src/strongswan-connections.c
new file mode 100644 (file)
index 0000000..9378101
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * 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 <glib.h>
+#include <libgnomevfs/gnome-vfs.h>
+
+#include "strongswan-connections.h"
+
+/* connections are stored in ~/.config/strongswan/connections */
+#define CONFIG_DIR_NAME "strongswan"
+#define CONFIG_FILE_NAME "connections"
+
+#define STRONGSWAN_CONNECTIONS_GET_PRIVATE(object) \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((object), STRONGSWAN_TYPE_CONNECTIONS, StrongswanConnectionsPrivate))
+
+struct _StrongswanConnectionsPrivate
+{
+       GKeyFile *key_file;
+       gchar *path;
+       GnomeVFSMonitorHandle *monitor;
+       GHashTable *connections;
+};
+
+G_DEFINE_TYPE (StrongswanConnections, strongswan_connections, G_TYPE_OBJECT);
+
+static void
+strongswan_connections_load_connections (StrongswanConnections *connections)
+{
+       StrongswanConnectionsPrivate *priv = connections->priv;
+       gchar **groups;
+       guint i;
+
+       g_hash_table_remove_all (priv->connections);
+       groups = g_key_file_get_groups (priv->key_file, NULL);
+       for (i = 0; groups[i]; i++)
+       {
+               StrongswanConnection *conn;
+               conn = strongswan_connection_new_from_key_file(priv->key_file,
+                                                                                                          groups[i]);
+               if (conn != NULL)
+               {
+                       g_hash_table_insert (priv->connections,
+                                                                g_strdup(groups[i]),
+                                                                conn);
+               }
+       }
+       g_strfreev (groups);
+}
+
+static void
+strongswan_connections_load_config (StrongswanConnections *connections)
+{
+       StrongswanConnectionsPrivate *priv = connections->priv;
+       GError *error = NULL;
+
+       if (priv->key_file)
+       {
+               g_key_file_free (priv->key_file);
+       }
+
+       priv->key_file = g_key_file_new ();
+       if (!g_key_file_load_from_file (priv->key_file,
+                                                                       priv->path,
+                                                                       G_KEY_FILE_KEEP_COMMENTS,
+                                                                       &error))
+       {
+               if (g_error_matches (error,
+                                                         G_KEY_FILE_ERROR,
+                                                         G_KEY_FILE_ERROR_PARSE))
+               {
+                       g_debug ("Failed to parse config file '%s', treated as empty: %s",
+                                        priv->path, error->message);
+                       g_error_free (error);
+               }
+               else
+               {
+                       g_debug ("Could not read config file '%s': %s",
+                                        priv->path, error->message);
+                       g_error_free (error);
+               }
+       }
+
+       strongswan_connections_load_connections (connections);
+}
+
+static void
+strongswan_connections_file_changed (GnomeVFSMonitorHandle             *handle,
+                                                                        const gchar                            *monitor_uri,
+                                                                        const gchar                            *info_uri,
+                                                                        GnomeVFSMonitorEventType        event_type,
+                                                                        StrongswanConnections          *connections)
+{
+       strongswan_connections_load_config (connections);
+}
+
+
+static void
+strongswan_connections_init (StrongswanConnections *connections)
+{
+       StrongswanConnectionsPrivate *priv;
+       connections->priv = STRONGSWAN_CONNECTIONS_GET_PRIVATE (connections);
+       priv = connections->priv;
+
+       priv->path = g_build_filename (g_get_user_config_dir (),
+                                                                  CONFIG_DIR_NAME,
+                                                                  CONFIG_FILE_NAME,
+                                                                  NULL);
+
+       priv->connections = g_hash_table_new_full (g_str_hash,
+                                                                                          g_str_equal,
+                                                                                          g_free,
+                                                                                          g_object_unref);
+
+}
+
+static void
+strongswan_connections_constructed (GObject *object)
+{
+       StrongswanConnectionsPrivate *priv;
+       GnomeVFSResult result;
+
+       if (G_OBJECT_CLASS (strongswan_connections_parent_class)->constructed)
+       {
+               G_OBJECT_CLASS (strongswan_connections_parent_class)->constructed (object);
+       }
+
+       g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
+       priv = STRONGSWAN_CONNECTIONS (object)->priv;
+
+       result = gnome_vfs_monitor_add (&priv->monitor,
+                                                                       priv->path,
+                                                                       GNOME_VFS_MONITOR_FILE,
+                                                                       (GnomeVFSMonitorCallback) strongswan_connections_file_changed,
+                                                                       object);
+       if (result != GNOME_VFS_OK)
+       {
+               g_warning ("Could not monitor '%s': %s",
+                                  priv->path,
+                                  gnome_vfs_result_to_string (result));
+       }
+
+       strongswan_connections_load_config (STRONGSWAN_CONNECTIONS (object));
+}
+
+static void
+strongswan_connections_dispose (GObject *object)
+{
+       StrongswanConnectionsPrivate *priv;
+
+       g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
+       priv = STRONGSWAN_CONNECTIONS (object)->priv;
+
+       G_OBJECT_CLASS (strongswan_connections_parent_class)->dispose (object);
+}
+
+static void
+strongswan_connections_finalize (GObject *object)
+{
+       StrongswanConnectionsPrivate *priv;
+
+       g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
+       priv = STRONGSWAN_CONNECTIONS (object)->priv;
+
+       priv->path = (g_free (priv->path), NULL);
+       priv->monitor = (gnome_vfs_monitor_cancel (priv->monitor), NULL);
+       priv->key_file = (g_key_file_free (priv->key_file), NULL);
+       priv->connections = (g_hash_table_destroy (priv->connections), NULL);
+
+       G_OBJECT_CLASS (strongswan_connections_parent_class)->finalize (object);
+}
+
+static void
+strongswan_connections_class_init (StrongswanConnectionsClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->constructed = strongswan_connections_constructed;
+       object_class->dispose = strongswan_connections_dispose;
+       object_class->finalize = strongswan_connections_finalize;
+
+       g_type_class_add_private (klass, sizeof (StrongswanConnectionsPrivate));
+}
+
+StrongswanConnections *
+strongswan_connections_new (void)
+{
+       StrongswanConnections *connections;
+       connections = g_object_new (STRONGSWAN_TYPE_CONNECTIONS,
+                                                               NULL);
+       return connections;
+}
+
+StrongswanConnection *
+strongswan_connections_get_connection (StrongswanConnections *self,
+                                                                          const gchar *name)
+{
+       StrongswanConnectionsPrivate *priv = self->priv;
+       g_return_val_if_fail (name != NULL, NULL);
+       return g_hash_table_lookup (priv->connections, name);
+}
+
+static void
+strongswan_connections_save_connections (StrongswanConnections *self)
+{
+       StrongswanConnectionsPrivate *priv = self->priv;
+       gchar *data;
+       gsize size;
+       GError *error = NULL;
+
+       data = g_key_file_to_data (priv->key_file, &size, NULL);
+       if (!g_file_set_contents (priv->path, data, size, &error))
+       {
+               g_warning ("Failed to save connections to '%s': %s",
+                                  priv->path, error->message);
+               g_error_free (error);
+       }
+       g_free (data);
+}
+
+void
+strongswan_connections_save_connection (StrongswanConnections *self,
+                                                                               StrongswanConnection *conn)
+{
+       StrongswanConnectionsPrivate *priv = self->priv;
+
+       strongswan_connection_save_to_key_file (priv->key_file, conn);
+
+       strongswan_connections_save_connections (self);
+}
+
+void
+strongswan_connections_remove_connection (StrongswanConnections *self,
+                                                                                 const gchar *name)
+{
+       StrongswanConnectionsPrivate *priv = self->priv;
+
+       g_key_file_remove_group (priv->key_file, name, NULL);
+
+       strongswan_connections_save_connections (self);
+}
+
diff --git a/src/frontends/maemo/src/strongswan-connections.h b/src/frontends/maemo/src/strongswan-connections.h
new file mode 100644 (file)
index 0000000..6a9f557
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * 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 __STRONGSWAN_CONNECTIONS_H__
+#define __STRONGSWAN_CONNECTIONS_H__
+
+#include "strongswan-connection.h"
+
+G_BEGIN_DECLS
+
+#define STRONGSWAN_TYPE_CONNECTIONS                            (strongswan_connections_get_type ())
+#define STRONGSWAN_CONNECTIONS(obj)                            (G_TYPE_CHECK_INSTANCE_CAST ((obj), STRONGSWAN_TYPE_CONNECTIONS, StrongswanConnections))
+#define STRONGSWAN_CONNECTIONS_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass),  STRONGSWAN_TYPE_CONNECTIONS, StrongswanConnectionsClass))
+#define STRONGSWAN_IS_CONNECTIONS(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STRONGSWAN_TYPE_CONNECTIONS))
+#define STRONGSWAN_IS_CONNECTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  STRONGSWAN_TYPE_CONNECTIONS))
+#define STRONGSWAN_CONNECTIONS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  STRONGSWAN_TYPE_CONNECTIONS, StrongswanConnectionsClass))
+
+typedef struct _StrongswanConnections                  StrongswanConnections;
+typedef struct _StrongswanConnectionsClass             StrongswanConnectionsClass;
+typedef struct _StrongswanConnectionsPrivate   StrongswanConnectionsPrivate;
+
+struct _StrongswanConnections
+{
+       GObject gobject;
+
+       StrongswanConnectionsPrivate *priv;
+};
+
+struct _StrongswanConnectionsClass
+{
+       GObjectClass parent_class;
+};
+
+GType strongswan_connections_get_type (void);
+
+StrongswanConnections *strongswan_connections_new (void);
+
+StrongswanConnection *strongswan_connections_get_connection (StrongswanConnections *self, const gchar *name);
+void strongswan_connections_save_connection (StrongswanConnections *self, StrongswanConnection *conn);
+void strongswan_connections_remove_connection (StrongswanConnections *self, const gchar *name);
+
+G_END_DECLS
+
+#endif /* __STRONGSWAN_CONNECTIONS_H__ */