Management class for connection settings added, connections are stored in a simple GKeyFile.

This commit is contained in:
Tobias Brunner
2010-10-14 17:36:17 +02:00
parent 9a09e32b98
commit 01f7455640
5 changed files with 389 additions and 12 deletions
+2 -1
View 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)
+75 -11
View File
@@ -24,6 +24,7 @@
struct _StrongswanConnectionPrivate
{
gchar *orig_name;
gchar *name;
gchar *host;
gchar *cert;
@@ -113,15 +114,6 @@ strongswan_connection_init (StrongswanConnection *connection)
connection->priv = STRONGSWAN_CONNECTION_GET_PRIVATE (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)
{
@@ -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);
}
}
@@ -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__ */
@@ -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);
}
@@ -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__ */