aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/plugins/sql
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2008-03-13 14:14:44 +0000
committerMartin Willi <martin@strongswan.org>2008-03-13 14:14:44 +0000
commit552cc11b1f017ce4962fca741f567d098f768574 (patch)
tree2835ae64c435191e04b5a265b1509c40a2e6766a /src/charon/plugins/sql
parent2df655134ca29f7a0b7d90ef4783f85eff1ddfd3 (diff)
downloadstrongswan-552cc11b1f017ce4962fca741f567d098f768574.tar.bz2
strongswan-552cc11b1f017ce4962fca741f567d098f768574.tar.xz
merged the modularization branch (credentials) back to trunk
Diffstat (limited to 'src/charon/plugins/sql')
-rw-r--r--src/charon/plugins/sql/Makefile.am10
-rw-r--r--src/charon/plugins/sql/config.sql73
-rw-r--r--src/charon/plugins/sql/cred.sql24
-rw-r--r--src/charon/plugins/sql/sql_config.c538
-rw-r--r--src/charon/plugins/sql/sql_config.h55
-rw-r--r--src/charon/plugins/sql/sql_plugin.c89
-rw-r--r--src/charon/plugins/sql/sql_plugin.h49
-rw-r--r--src/charon/plugins/sql/test.sql47
8 files changed, 885 insertions, 0 deletions
diff --git a/src/charon/plugins/sql/Makefile.am b/src/charon/plugins/sql/Makefile.am
new file mode 100644
index 000000000..813c601eb
--- /dev/null
+++ b/src/charon/plugins/sql/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libcharon-sql.la
+libcharon_sql_la_SOURCES = sql_plugin.h sql_plugin.c \
+ sql_config.h sql_config.c
+libcharon_sql_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/sql/config.sql b/src/charon/plugins/sql/config.sql
new file mode 100644
index 000000000..64aaea7d7
--- /dev/null
+++ b/src/charon/plugins/sql/config.sql
@@ -0,0 +1,73 @@
+
+DROP TABLE IF EXISTS ike_configs;
+CREATE TABLE ike_configs (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ certreq INTEGER,
+ force_encap INTEGER,
+ local TEXT,
+ remote TEXT
+);
+
+DROP TABLE IF EXISTS child_configs;
+CREATE TABLE child_configs (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT,
+ lifetime INTEGER,
+ rekeytime INTEGER,
+ jitter INTEGER,
+ updown TEXT,
+ hostaccess INTEGER,
+ mode INTEGER
+);
+
+DROP TABLE IF EXISTS peer_config_child_config;
+CREATE TABLE peer_config_child_config (
+ peer_cfg INTEGER,
+ child_cfg INTEGER
+);
+
+DROP TABLE IF EXISTS traffic_selectors;
+CREATE TABLE traffic_selectors (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ type INTEGER,
+ protocol INTEGER,
+ start_addr TEXT,
+ end_addr TEXT,
+ start_port INTEGER,
+ end_port INTEGER
+);
+
+DROP TABLE IF EXISTS child_config_traffic_selector;
+CREATE TABLE child_config_traffic_selector (
+ child_cfg INTEGER,
+ traffic_selector INTEGER,
+ kind INTEGER
+);
+
+DROP TABLE IF EXISTS peer_configs;
+CREATE TABLE peer_configs (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT,
+ ike_version INTEGER,
+ ike_cfg INTEGER,
+ local_id TEXT,
+ remote_id TEXT,
+ cert_policy INTEGER,
+ auth_method INTEGER,
+ eap_type INTEGER,
+ eap_vendor INTEGER,
+ keyingtries INTEGER,
+ rekeytime INTEGER,
+ reauthtime INTEGER,
+ jitter INTEGER,
+ overtime INTEGER,
+ mobike INTEGER,
+ dpd_delay INTEGER,
+ dpd_action INTEGER,
+ local_vip TEXT,
+ remote_vip TEXT,
+ mediation INTEGER,
+ mediated_by INTEGER,
+ peer_id TEXT
+);
+
diff --git a/src/charon/plugins/sql/cred.sql b/src/charon/plugins/sql/cred.sql
new file mode 100644
index 000000000..4b53e4e4b
--- /dev/null
+++ b/src/charon/plugins/sql/cred.sql
@@ -0,0 +1,24 @@
+
+DROP TABLE IF EXISTS shared_secrets;
+CREATE TABLE shared_secrets (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ type INTEGER,
+ local TEXT,
+ remote TEXT
+);
+
+DROP TABLE IF EXISTS certificates;
+CREATE TABLE certificates (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ type INTEGER,
+ subject TEXT,
+ data BLOB,
+);
+
+DROP TABLE IF EXISTS private_keys;
+CREATE TABLE private_keys (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ type INTEGER,
+ keyid BLOB,
+ data BLOB,
+);
diff --git a/src/charon/plugins/sql/sql_config.c b/src/charon/plugins/sql/sql_config.c
new file mode 100644
index 000000000..eaa9da5ef
--- /dev/null
+++ b/src/charon/plugins/sql/sql_config.c
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2006-2008 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.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+
+#include "sql_config.h"
+
+#include <daemon.h>
+
+typedef struct private_sql_config_t private_sql_config_t;
+
+/**
+ * Private data of an sql_config_t object
+ */
+struct private_sql_config_t {
+
+ /**
+ * Public part
+ */
+ sql_config_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+};
+
+/**
+ * forward declaration
+ */
+static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
+ identification_t *me, identification_t *other);
+
+/**
+ * build a traffic selector from a SQL query
+ */
+static traffic_selector_t *build_traffic_selector(private_sql_config_t *this,
+ enumerator_t *e, bool *local)
+{
+ int type, protocol, start_port, end_port;
+ char *start_addr, *end_addr;
+ traffic_selector_t *ts;
+ enum {
+ TS_LOCAL = 0,
+ TS_REMOTE = 1,
+ TS_LOCAL_DYNAMIC = 2,
+ TS_REMOTE_DYNAMIC = 3,
+ } kind;
+
+ while (e->enumerate(e, &kind, &type, &protocol,
+ &start_addr, &end_addr, &start_port, &end_port))
+ {
+ *local = FALSE;
+ switch (kind)
+ {
+ case TS_LOCAL:
+ *local = TRUE;
+ /* FALL */
+ case TS_REMOTE:
+ ts = traffic_selector_create_from_string(protocol, type,
+ start_addr, start_port, end_addr, end_port);
+ break;
+ case TS_LOCAL_DYNAMIC:
+ *local = TRUE;
+ /* FALL */
+ case TS_REMOTE_DYNAMIC:
+ ts = traffic_selector_create_dynamic(protocol, type,
+ start_port, end_port);
+ break;
+ default:
+ continue;
+ }
+ if (ts)
+ {
+ return ts;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Add traffic selectors to a child config
+ */
+static void add_traffic_selectors(private_sql_config_t *this,
+ child_cfg_t *child, int id)
+{
+ enumerator_t *e;
+ traffic_selector_t *ts;
+ bool local;
+
+ e = this->db->query(this->db,
+ "SELECT kind, type, protocol, "
+ "start_addr, end_addr, start_port, end_port "
+ "FROM traffic_selectors JOIN child_config_traffic_selector "
+ "ON id = traffic_selector WHERE child_cfg = ?",
+ DB_INT, id,
+ DB_INT, DB_INT, DB_INT,
+ DB_TEXT, DB_TEXT, DB_INT, DB_INT);
+ if (e)
+ {
+ while ((ts = build_traffic_selector(this, e, &local)))
+ {
+ child->add_traffic_selector(child, local, ts);
+ }
+ e->destroy(e);
+ }
+}
+
+/**
+ * build a Child configuration from a SQL query
+ */
+static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
+{
+ int id, lifetime, rekeytime, jitter, hostaccess, mode;
+ char *name, *updown;
+ child_cfg_t *child_cfg;
+
+ if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter,
+ &updown, &hostaccess, &mode))
+ {
+ child_cfg = child_cfg_create(name, lifetime, rekeytime, jitter,
+ updown, hostaccess, mode);
+ /* TODO: read proposal from db */
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ add_traffic_selectors(this, child_cfg, id);
+ return child_cfg;
+ }
+ return NULL;
+}
+
+/**
+ * Add child configs to peer config
+ */
+static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
+{
+ enumerator_t *e;
+ child_cfg_t *child_cfg;
+
+ e = this->db->query(this->db,
+ "SELECT id, name, lifetime, rekeytime, jitter, "
+ "updown, hostaccess, mode "
+ "FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
+ "WHERE peer_cfg = ?",
+ DB_INT, id,
+ DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT,
+ DB_TEXT, DB_INT, DB_INT);
+ if (e)
+ {
+ while ((child_cfg = build_child_cfg(this, e)))
+ {
+ peer->add_child_cfg(peer, child_cfg);
+ }
+ e->destroy(e);
+ }
+}
+
+/**
+ * build a ike configuration from a SQL query
+ */
+static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
+ host_t *my_host, host_t *other_host)
+{
+ int certreq, force_encap;
+ char *local, *remote;
+
+ while (e->enumerate(e, &certreq, &force_encap, &local, &remote))
+ {
+ host_t *me, *other;
+ ike_cfg_t *ike_cfg;
+
+ me = host_create_from_string(local, 500);
+ if (!me)
+ {
+ continue;
+ }
+ if (my_host && !me->is_anyaddr(me) &&
+ !me->ip_equals(me, my_host))
+ {
+ me->destroy(me);
+ continue;
+ }
+ other = host_create_from_string(remote, 500);
+ if (!other)
+ {
+ me->destroy(me);
+ continue;
+ }
+ if (other_host && !other->is_anyaddr(other) &&
+ !other->ip_equals(other, other_host))
+ {
+ me->destroy(me);
+ other->destroy(other);
+ continue;
+ }
+ ike_cfg = ike_cfg_create(certreq, force_encap, me, other);
+ /* TODO: read proposal from db */
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ return ike_cfg;
+ }
+ return NULL;
+}
+
+/**
+ * Query a IKE config by its id
+ */
+static ike_cfg_t* get_ike_cfg_by_id(private_sql_config_t *this, int id)
+{
+ enumerator_t *e;
+ ike_cfg_t *ike_cfg = NULL;
+
+ e = this->db->query(this->db,
+ "SELECT certreq, force_encap, local, remote "
+ "FROM ike_configs WHERE id = ?",
+ DB_INT, id,
+ DB_INT, DB_INT, DB_TEXT, DB_TEXT);
+ if (e)
+ {
+ ike_cfg = build_ike_cfg(this, e, NULL, NULL);
+ e->destroy(e);
+ }
+ return ike_cfg;
+}
+
+/**
+ * Query a peer config by its id
+ */
+static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
+{
+ enumerator_t *e;
+ peer_cfg_t *peer_cfg = NULL;
+
+ e = this->db->query(this->db,
+ "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
+ "auth_method, eap_type, eap_vendor, keyingtries, "
+ "rekeytime, reauthtime, jitter, overtime, mobike, "
+ "dpd_delay, dpd_action, local_vip, remote_vip, "
+ "mediation, mediated_by, peer_id "
+ "FROM peer_configs WHERE id = ?",
+ DB_INT, id,
+ DB_INT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_TEXT, DB_TEXT,
+ DB_INT, DB_INT, DB_TEXT);
+ if (e)
+ {
+ peer_cfg = build_peer_cfg(this, e, NULL, NULL);
+ e->destroy(e);
+ }
+ return peer_cfg;
+}
+
+/**
+ * build a peer configuration from a SQL query
+ */
+static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
+ identification_t *me, identification_t *other)
+{
+ int id, ike_cfg, cert_policy, auth_method, eap_type, eap_vendor,
+ keyingtries, rekeytime, reauthtime, jitter, overtime, mobike,
+ dpd_delay, dpd_action, mediation, mediated_by;
+ char *local_id, *remote_id, *local_vip, *remote_vip, *peer_id, *name;
+
+ while (e->enumerate(e, &id, &name, &ike_cfg, &local_id, &remote_id, &cert_policy,
+ &auth_method, &eap_type, &eap_vendor, &keyingtries,
+ &rekeytime, &reauthtime, &jitter, &overtime, &mobike,
+ &dpd_delay, &dpd_action, &local_vip, &remote_vip,
+ &mediation, &mediated_by, &peer_id))
+ {
+ ike_cfg_t *ike;
+ peer_cfg_t *peer_cfg, *mediated_cfg;
+ identification_t *my_id, *other_id, *peer;
+ host_t *my_vip, *other_vip;
+
+ my_id = identification_create_from_string(local_id);
+ if (!my_id)
+ {
+ continue;
+ }
+ if (me && !me->matches(me, my_id))
+ {
+ my_id->destroy(my_id);
+ continue;
+ }
+ other_id = identification_create_from_string(remote_id);
+ if (!other_id)
+ {
+ my_id->destroy(my_id);
+ continue;
+ }
+ if (other && !other->matches(other, other_id))
+ {
+ other_id->destroy(other_id);
+ my_id->destroy(my_id);
+ continue;
+ }
+ ike = get_ike_cfg_by_id(this, ike_cfg);
+ mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by) : NULL;
+ peer = peer_id ? identification_create_from_string(peer_id) : NULL;
+ my_vip = local_vip ? host_create_from_string(local_vip, 0) : NULL;
+ other_vip = remote_vip ? host_create_from_string(remote_vip, 0) : NULL;
+
+ if (ike)
+ {
+ peer_cfg = peer_cfg_create(
+ name, 2, ike, my_id, other_id, cert_policy,
+ auth_method, eap_type, eap_vendor, keyingtries,
+ rekeytime, reauthtime, jitter, overtime, mobike,
+ dpd_delay, dpd_action, my_vip, other_vip,
+ mediation, mediated_cfg, peer);
+ add_child_cfgs(this, peer_cfg, id);
+ return peer_cfg;
+ }
+ DESTROY_IF(ike);
+ DESTROY_IF(mediated_cfg);
+ DESTROY_IF(peer);
+ DESTROY_IF(my_vip);
+ DESTROY_IF(other_vip);
+ DESTROY_IF(my_id);
+ DESTROY_IF(other_id);
+ }
+ return NULL;
+}
+
+/**
+ * implements backend_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(private_sql_config_t *this, char *name)
+{
+ enumerator_t *e;
+ peer_cfg_t *peer_cfg = NULL;
+
+ e = this->db->query(this->db,
+ "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
+ "auth_method, eap_type, eap_vendor, keyingtries, "
+ "rekeytime, reauthtime, jitter, overtime, mobike, "
+ "dpd_delay, dpd_action, local_vip, remote_vip, "
+ "mediation, mediated_by, peer_id "
+ "FROM peer_configs WHERE ike_version = ? AND name = ?",
+ DB_INT, 2, DB_TEXT, name,
+ DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_TEXT, DB_TEXT,
+ DB_INT, DB_INT, DB_TEXT);
+ if (e)
+ {
+ peer_cfg = build_peer_cfg(this, e, NULL, NULL);
+ e->destroy(e);
+ }
+ return peer_cfg;
+}
+
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** reference to context */
+ private_sql_config_t *this;
+ /** filtering own host */
+ host_t *me;
+ /** filtering remote host */
+ host_t *other;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated peer config */
+ ike_cfg_t *current;
+} ike_enumerator_t;
+
+/**
+ * Implementation of ike_enumerator_t.public.enumerate
+ */
+static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg)
+{
+ DESTROY_IF(this->current);
+ this->current = build_ike_cfg(this->this, this->inner, this->me, this->other);
+ if (this->current)
+ {
+ *cfg = this->current;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of ike_enumerator_t.public.destroy
+ */
+static void ike_enumerator_destroy(ike_enumerator_t *this)
+{
+ DESTROY_IF(this->current);
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * Implementation of backend_t.create_ike_cfg_enumerator.
+ */
+static enumerator_t* create_ike_cfg_enumerator(private_sql_config_t *this,
+ host_t *me, host_t *other)
+{
+ ike_enumerator_t *e = malloc_thing(ike_enumerator_t);
+
+ e->this = this;
+ e->me = me;
+ e->other = other;
+ e->current = NULL;
+ e->public.enumerate = (void*)ike_enumerator_enumerate;
+ e->public.destroy = (void*)ike_enumerator_destroy;
+
+ e->inner = this->db->query(this->db,
+ "SELECT certreq, force_encap, local, remote "
+ "FROM ike_configs",
+ DB_INT, DB_INT, DB_TEXT, DB_TEXT);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** reference to context */
+ private_sql_config_t *this;
+ /** filtering own identity */
+ identification_t *me;
+ /** filtering remote identity */
+ identification_t *other;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated peer config */
+ peer_cfg_t *current;
+} peer_enumerator_t;
+
+/**
+ * Implementation of peer_enumerator_t.public.enumerate
+ */
+static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
+{
+ DESTROY_IF(this->current);
+ this->current = build_peer_cfg(this->this, this->inner, this->me, this->other);
+ if (this->current)
+ {
+ *cfg = this->current;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of peer_enumerator_t.public.destroy
+ */
+static void peer_enumerator_destroy(peer_enumerator_t *this)
+{
+ DESTROY_IF(this->current);
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * Implementation of backend_t.create_peer_cfg_enumerator.
+ */
+static enumerator_t* create_peer_cfg_enumerator(private_sql_config_t *this,
+ identification_t *me,
+ identification_t *other)
+{
+ peer_enumerator_t *e = malloc_thing(peer_enumerator_t);
+
+ e->this = this;
+ e->me = me;
+ e->other = other;
+ e->current = NULL;
+ e->public.enumerate = (void*)peer_enumerator_enumerate;
+ e->public.destroy = (void*)peer_enumerator_destroy;
+
+ /* TODO: only get configs whose IDs match exactly or contain wildcards */
+ e->inner = this->db->query(this->db,
+ "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
+ "auth_method, eap_type, eap_vendor, keyingtries, "
+ "rekeytime, reauthtime, jitter, overtime, mobike, "
+ "dpd_delay, dpd_action, local_vip, remote_vip, "
+ "mediation, mediated_by, peer_id "
+ "FROM peer_configs WHERE ike_version = ? ",
+ DB_INT, 2,
+ DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_TEXT, DB_TEXT,
+ DB_INT, DB_INT, DB_TEXT);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * Implementation of sql_config_t.destroy.
+ */
+static void destroy(private_sql_config_t *this)
+{
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+sql_config_t *sql_config_create(database_t *db)
+{
+ private_sql_config_t *this = malloc_thing(private_sql_config_t);
+
+ this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
+ this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
+ this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
+ this->public.destroy = (void(*)(sql_config_t*))destroy;
+
+ this->db = db;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/sql/sql_config.h b/src/charon/plugins/sql/sql_config.h
new file mode 100644
index 000000000..829d80da8
--- /dev/null
+++ b/src/charon/plugins/sql/sql_config.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup sql_config_i sql_config
+ * @{ @ingroup sql_config
+ */
+
+#ifndef SQL_CONFIG_H_
+#define SQL_CONFIG_H_
+
+#include <config/backend.h>
+#include <database/database.h>
+
+typedef struct sql_config_t sql_config_t;
+
+/**
+ * SQL database configuration backend.
+ */
+struct sql_config_t {
+
+ /**
+ * Implements backend_t interface
+ */
+ backend_t backend;
+
+ /**
+ * Destry the backend.
+ */
+ void (*destroy)(sql_config_t *this);
+};
+
+/**
+ * Create a sql_config backend instance.
+ *
+ * @param db underlying database
+ * @return backend instance
+ */
+sql_config_t *sql_config_create(database_t *db);
+
+#endif /* SQL_CONFIG_H_ @}*/
diff --git a/src/charon/plugins/sql/sql_plugin.c b/src/charon/plugins/sql/sql_plugin.c
new file mode 100644
index 000000000..8ee6400ba
--- /dev/null
+++ b/src/charon/plugins/sql/sql_plugin.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include "sql_plugin.h"
+
+#include <daemon.h>
+#include "sql_config.h"
+
+typedef struct private_sql_plugin_t private_sql_plugin_t;
+
+/**
+ * private data of sql plugin
+ */
+struct private_sql_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ sql_plugin_t public;
+
+ /**
+ * database connection instance
+ */
+ database_t *db;
+
+ /**
+ * configuration backend
+ */
+ sql_config_t *config;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_sql_plugin_t *this)
+{
+ charon->backends->remove_backend(charon->backends, &this->config->backend);
+ this->config->destroy(this->config);
+ this->db->destroy(this->db);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ char *uri;
+ private_sql_plugin_t *this;
+
+ uri = lib->settings->get_str(lib->settings, "charon.plugins.sql.database", NULL);
+ if (!uri)
+ {
+ DBG1(DBG_CFG, "SQL plugin database URI not set");
+ return NULL;
+ }
+
+ this = malloc_thing(private_sql_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ this->db = lib->db->create(lib->db, uri);
+ if (!this->db)
+ {
+ DBG1(DBG_CFG, "SQL plugin failed to connect to database");
+ free(this);
+ return NULL;
+ }
+ this->config = sql_config_create(this->db);
+
+ charon->backends->add_backend(charon->backends, &this->config->backend);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/sql/sql_plugin.h b/src/charon/plugins/sql/sql_plugin.h
new file mode 100644
index 000000000..978df3744
--- /dev/null
+++ b/src/charon/plugins/sql/sql_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup sql sql
+ * @ingroup cplugins
+ *
+ * @defgroup sql_plugin sql_plugin
+ * @{ @ingroup sql
+ */
+
+#ifndef SQL_PLUGIN_H_
+#define SQL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sql_plugin_t sql_plugin_t;
+
+/**
+ * SQL database configuration plugin
+ */
+struct sql_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a sql_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SQL_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/sql/test.sql b/src/charon/plugins/sql/test.sql
new file mode 100644
index 000000000..ec5b401c5
--- /dev/null
+++ b/src/charon/plugins/sql/test.sql
@@ -0,0 +1,47 @@
+
+INSERT INTO ike_configs (
+ certreq, force_encap, local, remote
+) VALUES (
+ 0, 0, '0.0.0.0', '152.96.52.150'
+);
+
+INSERT INTO child_configs (
+ name, lifetime, rekeytime, jitter, updown, hostaccess, mode
+) VALUES (
+ 'sqltest', 500, 400, 50, NULL, 1, 1
+);
+
+INSERT INTO peer_config_child_config (
+ peer_cfg, child_cfg
+) VALUES (
+ 1, 1
+);
+
+INSERT INTO traffic_selectors (
+ type, protocol
+) values (
+ 7, 0
+);
+
+INSERT INTO child_config_traffic_selector (
+ child_cfg, traffic_selector, kind
+) VALUES (
+ 1, 1, 2
+);
+
+INSERT INTO child_config_traffic_selector (
+ child_cfg, traffic_selector, kind
+) VALUES (
+ 1, 1, 3
+);
+
+INSERT INTO peer_configs (
+ name, ike_version, ike_cfg, local_id, remote_id, cert_policy, auth_method,
+ eap_type, eap_vendor, keyingtries, rekeytime, reauthtime, jitter, overtime,
+ mobike, dpd_delay, dpd_action, local_vip, remote_vip,
+ mediation, mediated_by, peer_id
+) VALUES (
+ 'sqltest', 2, 1, 'C=CH, O=Linux strongSwan, CN=martin', 'sidv0150.hsr.ch', 0, 0,
+ 0, 0, 0, 500, 2000, 20, 20,
+ 1, 120, 0, NULL, NULL, 0, 0, NULL
+);