diff --git a/configure.in b/configure.in index cfc90ab19..6611330ee 100644 --- a/configure.in +++ b/configure.in @@ -322,6 +322,14 @@ AC_ARG_ENABLE( fi] ) +AC_ARG_ENABLE( + [medcli], + AS_HELP_STRING([--enable-medcli],[enable mediation client configuration database plugin (default is NO).]), + [if test x$enableval = xyes; then + medcli=true + fi] +) + AC_ARG_ENABLE( [smp], AS_HELP_STRING([--enable-smp],[enable SMP configuration and control interface (default is NO). Requires libxml.]), @@ -569,6 +577,14 @@ if test x$manager = xtrue; then fast=true fi +if test x$medsrv = xtrue; then + me=true +fi + +if test x$medcli = xtrue; then + me=true +fi + dnl ========================================== dnl check required libraries and header files dnl ========================================== @@ -678,6 +694,7 @@ AM_CONDITIONAL(USE_MYSQL, test x$mysql = xtrue) AM_CONDITIONAL(USE_SQLITE, test x$sqlite = xtrue) AM_CONDITIONAL(USE_STROKE, test x$stroke = xtrue) AM_CONDITIONAL(USE_MEDSRV, test x$medsrv = xtrue) +AM_CONDITIONAL(USE_MEDCLI, test x$medcli = xtrue) AM_CONDITIONAL(USE_SMP, test x$smp = xtrue) AM_CONDITIONAL(USE_SQL, test x$sql = xtrue) AM_CONDITIONAL(USE_SMARTCARD, test x$smartcard = xtrue) @@ -753,6 +770,7 @@ AC_OUTPUT( src/charon/plugins/smp/Makefile src/charon/plugins/sql/Makefile src/charon/plugins/medsrv/Makefile + src/charon/plugins/medcli/Makefile src/charon/plugins/stroke/Makefile src/charon/plugins/unit_tester/Makefile src/stroke/Makefile diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index c1306ce53..0f17c9642 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -166,3 +166,7 @@ if USE_MEDSRV SUBDIRS += plugins/medsrv endif +if USE_MEDCLI + SUBDIRS += plugins/medcli +endif + diff --git a/src/charon/plugins/medcli/Makefile.am b/src/charon/plugins/medcli/Makefile.am new file mode 100644 index 000000000..6581f5a4d --- /dev/null +++ b/src/charon/plugins/medcli/Makefile.am @@ -0,0 +1,11 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libcharon-medcli.la +libcharon_medcli_la_SOURCES = medcli_plugin.h medcli_plugin.c \ + medcli_creds.h medcli_creds.c \ + medcli_config.h medcli_config.c +libcharon_medcli_la_LDFLAGS = -module + diff --git a/src/charon/plugins/medcli/medcli_config.c b/src/charon/plugins/medcli/medcli_config.c new file mode 100644 index 000000000..dff6c3dec --- /dev/null +++ b/src/charon/plugins/medcli/medcli_config.c @@ -0,0 +1,322 @@ +/* + * 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 . + * + * 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$ + */ + +#define _GNU_SOURCE +#include + +#include "medcli_config.h" + +#include + +typedef struct private_medcli_config_t private_medcli_config_t; + +/** + * Private data of an medcli_config_t object + */ +struct private_medcli_config_t { + + /** + * Public part + */ + medcli_config_t public; + + /** + * database connection + */ + database_t *db; + + /** + * rekey time + */ + int rekey; + + /** + * dpd delay + */ + int dpd; + + /** + * default ike config + */ + ike_cfg_t *ike; +}; + +/** + * create a traffic selector from a CIDR notation string + */ +static traffic_selector_t *ts_from_string(char *str) +{ + if (str) + { + int netbits = 32; + host_t *net; + char *pos; + + str = strdupa(str); + pos = strchr(str, '/'); + if (pos) + { + *pos++ = '\0'; + netbits = atoi(pos); + } + else + { + if (strchr(str, ':')) + { + netbits = 128; + } + } + net = host_create_from_string(str, 0); + if (net) + { + return traffic_selector_create_from_subnet(net, netbits, 0, 0); + } + } + return traffic_selector_create_dynamic(0, 0, 65535); +} + +/** + * implements backend_t.get_peer_cfg_by_name. + */ +static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *name) +{ + enumerator_t *e; + peer_cfg_t *peer_cfg, *med_cfg; + ike_cfg_t *ike_cfg; + child_cfg_t *child_cfg; + chunk_t me, other; + char *address, *local_net, *remote_net; + host_t *med; + + /* query mediation server config: + * - build ike_cfg/peer_cfg for mediation connection on-the-fly + */ + e = this->db->query(this->db, + "SELECT Address, ClientConfig.KeyId, MediationServerConfig.KeyId " + "FROM MediationServerConfig JOIN ClientConfig", + DB_TEXT, DB_BLOB, DB_BLOB); + if (!e || !e->enumerate(e, &address, &me, &other)) + { + DESTROY_IF(e); + return NULL; + } + med = host_create_from_string(address, 500); + if (!med) + { + e->destroy(e); + return NULL; + } + ike_cfg = ike_cfg_create(FALSE, FALSE, + host_create_from_string("0.0.0.0", 500), med); + ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); + DBG1(DBG_CFG, "mediation server id: %B", &other); + med_cfg = peer_cfg_create( + "mediation", 2, ike_cfg, + identification_create_from_encoding(ID_KEY_ID, me), + identification_create_from_encoding(ID_KEY_ID, other), + CERT_NEVER_SEND, UNIQUE_REPLACE, AUTH_RSA, + 0, 0, /* EAP method, vendor */ + 1, this->rekey*60, 0, /* keytries, rekey, reauth */ + this->rekey*5, this->rekey*3, /* jitter, overtime */ + TRUE, this->dpd, /* mobike, dpddelay */ + NULL, NULL, /* vip, pool */ + TRUE, NULL, NULL); /* mediation, med by, peer id */ + e->destroy(e); + + /* query mediated config: + * - use any-any ike_cfg + * - build peer_cfg on-the-fly using med_cfg + * - add a child_cfg + */ + e = this->db->query(this->db, + "SELECT ClientConfig.KeyId, Connection.KeyId, " + "Connection.LocalSubnet, Connection.RemoteSubnet " + "FROM ClientConfig JOIN Connection " + "WHERE Active AND Alias = ?", DB_TEXT, name, + DB_BLOB, DB_BLOB, DB_TEXT, DB_TEXT); + if (!e || !e->enumerate(e, &me, &other, &local_net, &remote_net)) + { + DESTROY_IF(e); + return NULL; + } + peer_cfg = peer_cfg_create( + name, 2, this->ike->get_ref(this->ike), + identification_create_from_encoding(ID_KEY_ID, me), + identification_create_from_encoding(ID_KEY_ID, other), + CERT_NEVER_SEND, UNIQUE_REPLACE, AUTH_RSA, + 0, 0, /* EAP method, vendor */ + 1, this->rekey*60, 0, /* keytries, rekey, reauth */ + this->rekey*5, this->rekey*3, /* jitter, overtime */ + TRUE, this->dpd, /* mobike, dpddelay */ + NULL, NULL, /* vip, pool */ + FALSE, med_cfg, /* mediation, med by */ + identification_create_from_encoding(ID_KEY_ID, other)); + + child_cfg = child_cfg_create(name, this->rekey*60 + this->rekey, + this->rekey*60, this->rekey, NULL, TRUE, + MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE); + child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP)); + child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net)); + child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net)); + peer_cfg->add_child_cfg(peer_cfg, child_cfg); + e->destroy(e); + return peer_cfg; +} + +/** + * Implementation of backend_t.create_ike_cfg_enumerator. + */ +static enumerator_t* create_ike_cfg_enumerator(private_medcli_config_t *this, + host_t *me, host_t *other) +{ + return enumerator_create_single(this->ike, NULL); +} + +typedef struct { + /** implements enumerator */ + enumerator_t public; + /** inner SQL enumerator */ + enumerator_t *inner; + /** currently enumerated peer config */ + peer_cfg_t *current; + /** ike cfg to use in peer cfg */ + ike_cfg_t *ike; + /** rekey time */ + int rekey; + /** dpd time */ + int dpd; +} peer_enumerator_t; + +/** + * Implementation of peer_enumerator_t.public.enumerate + */ +static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) +{ + char *name, *local_net, *remote_net; + chunk_t me, other; + child_cfg_t *child_cfg; + + DESTROY_IF(this->current); + if (!this->inner->enumerate(this->inner, &name, &me, &other, + &local_net, &remote_net)) + { + this->current = NULL; + return FALSE; + } + this->current = peer_cfg_create( + name, 2, this->ike->get_ref(this->ike), + identification_create_from_encoding(ID_KEY_ID, me), + identification_create_from_encoding(ID_KEY_ID, other), + CERT_NEVER_SEND, UNIQUE_REPLACE, AUTH_RSA, + 0, 0, /* EAP method, vendor */ + 1, this->rekey*60, 0, /* keytries, rekey, reauth */ + this->rekey*5, this->rekey*3, /* jitter, overtime */ + TRUE, this->dpd, /* mobike, dpddelay */ + NULL, NULL, /* vip, pool */ + FALSE, NULL, NULL); /* mediation, med by, peer id */ + child_cfg = child_cfg_create( + name, this->rekey*60 + this->rekey, + this->rekey*60, this->rekey, NULL, TRUE, + MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE); + child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP)); + child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net)); + child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net)); + this->current->add_child_cfg(this->current, child_cfg); + *cfg = this->current; + return TRUE; +} + +/** + * 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_medcli_config_t *this, + identification_t *me, + identification_t *other) +{ + peer_enumerator_t *e = malloc_thing(peer_enumerator_t); + + e->current = NULL; + e->ike = this->ike; + e->rekey = this->rekey; + e->dpd = this->dpd; + e->public.enumerate = (void*)peer_enumerator_enumerate; + e->public.destroy = (void*)peer_enumerator_destroy; + + /* filter on IDs: NULL or ANY or matching KEY_ID */ + e->inner = this->db->query(this->db, + "SELECT Alias, ClientConfig.KeyId, Connection.KeyId, " + "Connection.LocalSubnet, Connection.RemoteSubnet " + "FROM ClientConfig JOIN Connection " + "WHERE Active AND " + "(? OR ClientConfig.KeyId = ?) AND (? OR Connection.KeyId = ?)", + DB_INT, me == NULL || me->get_type(me) == ID_ANY, + DB_BLOB, me && me->get_type(me) == ID_KEY_ID ? + me->get_encoding(me) : chunk_empty, + DB_INT, other == NULL || other->get_type(other) == ID_ANY, + DB_BLOB, other && other->get_type(other) == ID_KEY_ID ? + other->get_encoding(other) : chunk_empty, + DB_TEXT, DB_BLOB, DB_BLOB, DB_TEXT, DB_TEXT); + if (!e->inner) + { + free(e); + return NULL; + } + return &e->public; +} + +/** + * Implementation of medcli_config_t.destroy. + */ +static void destroy(private_medcli_config_t *this) +{ + this->ike->destroy(this->ike); + free(this); +} + +/** + * Described in header. + */ +medcli_config_t *medcli_config_create(database_t *db) +{ + private_medcli_config_t *this = malloc_thing(private_medcli_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(*)(medcli_config_t*))destroy; + + this->db = db; + this->rekey = lib->settings->get_int(lib->settings, + "medclient.rekey", 20) * 60; + this->dpd = lib->settings->get_int(lib->settings, "medclient.dpd", 300); + this->ike = ike_cfg_create(FALSE, FALSE, host_create_any(AF_INET), + host_create_any(AF_INET)); + this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE)); + + return &this->public; +} + diff --git a/src/charon/plugins/medcli/medcli_config.h b/src/charon/plugins/medcli/medcli_config.h new file mode 100644 index 000000000..789a73243 --- /dev/null +++ b/src/charon/plugins/medcli/medcli_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 . + * + * 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 medcli_config_i medcli_config + * @{ @ingroup medcli + */ + +#ifndef MEDCLI_CONFIG_H_ +#define MEDCLI_CONFIG_H_ + +#include +#include + +typedef struct medcli_config_t medcli_config_t; + +/** + * Mediation client configuration backend. + */ +struct medcli_config_t { + + /** + * Implements backend_t interface + */ + backend_t backend; + + /** + * Destroy the backend. + */ + void (*destroy)(medcli_config_t *this); +}; + +/** + * Create a medcli_config backend instance. + * + * @param db underlying database + * @return backend instance + */ +medcli_config_t *medcli_config_create(database_t *db); + +#endif /* MEDCLI_CONFIG_H_ @}*/ diff --git a/src/charon/plugins/medcli/medcli_creds.c b/src/charon/plugins/medcli/medcli_creds.c new file mode 100644 index 000000000..685f34271 --- /dev/null +++ b/src/charon/plugins/medcli/medcli_creds.c @@ -0,0 +1,242 @@ +/* + * 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 . + * + * 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 "medcli_creds.h" + +#include +#include +#include + +typedef struct private_medcli_creds_t private_medcli_creds_t; + +/** + * Private data of an medcli_creds_t object + */ +struct private_medcli_creds_t { + + /** + * Public part + */ + medcli_creds_t public; + + /** + * underlying database handle + */ + database_t *db; +}; + +/** + * enumerator over private keys + */ +typedef struct { + /** implements enumerator */ + enumerator_t public; + /** inner SQL enumerator */ + enumerator_t *inner; + /** currently enumerated private key */ + private_key_t *current; +} private_enumerator_t; + +/** + * Implementation of private_enumerator_t.public.enumerate + */ +static bool private_enumerator_enumerate(private_enumerator_t *this, + private_key_t **key) +{ + chunk_t chunk; + + DESTROY_IF(this->current); + while (this->inner->enumerate(this->inner, &chunk)) + { + this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + BUILD_BLOB_ASN1_DER, chunk_clone(chunk), + BUILD_END); + if (this->current) + { + *key = this->current; + return TRUE; + } + } + this->current = NULL; + return FALSE; +} + +/** + * Implementation of private_enumerator_t.public.destroy + */ +static void private_enumerator_destroy(private_enumerator_t *this) +{ + DESTROY_IF(this->current); + this->inner->destroy(this->inner); + free(this); +} + +/** + * Implementation of credential_set_t.create_private_enumerator. + */ +static enumerator_t* create_private_enumerator(private_medcli_creds_t *this, + key_type_t type, identification_t *id) +{ + private_enumerator_t *e; + + if ((type != KEY_RSA && type != KEY_ANY) || + id == NULL || id->get_type(id) != ID_KEY_ID) + { + DBG1(DBG_CFG, "%N - %D", key_type_names, type, id); + return NULL; + } + + e = malloc_thing(private_enumerator_t); + e->current = NULL; + e->public.enumerate = (void*)private_enumerator_enumerate; + e->public.destroy = (void*)private_enumerator_destroy; + e->inner = this->db->query(this->db, + "SELECT PrivateKey FROM ClientConfig WHERE KeyId = ?", + DB_BLOB, id->get_encoding(id), + DB_BLOB); + if (!e->inner) + { + free(e); + return NULL; + } + return &e->public; +} + +/** + * enumerator over certificates + */ +typedef struct { + /** implements enumerator */ + enumerator_t public; + /** inner SQL enumerator */ + enumerator_t *inner; + /** currently enumerated cert */ + certificate_t *current; + /** type of requested key */ + key_type_t type; +} cert_enumerator_t; + +/** + * Implementation of cert_enumerator_t.public.enumerate + */ +static bool cert_enumerator_enumerate(cert_enumerator_t *this, + certificate_t **cert) +{ + public_key_t *public; + chunk_t chunk; + + DESTROY_IF(this->current); + while (this->inner->enumerate(this->inner, &chunk)) + { + public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, + BUILD_BLOB_ASN1_DER, chunk_clone(chunk), + BUILD_END); + if (public) + { + if (this->type == KEY_ANY || this->type == public->get_type(public)) + { + this->current = lib->creds->create(lib->creds, + CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY, + BUILD_PUBLIC_KEY, public, BUILD_END); + if (this->current) + { + *cert = this->current; + return TRUE; + } + continue; + } + public->destroy(public); + } + } + this->current = NULL; + return FALSE; +} + +/** + * Implementation of cert_enumerator_t.public.destroy + */ +static void cert_enumerator_destroy(cert_enumerator_t *this) +{ + DESTROY_IF(this->current); + this->inner->destroy(this->inner); + free(this); +} + +/** + * Implementation of credential_set_t.create_cert_enumerator. + */ +static enumerator_t* create_cert_enumerator(private_medcli_creds_t *this, + certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) +{ + cert_enumerator_t *e; + + if ((cert != CERT_TRUSTED_PUBKEY && cert != CERT_ANY) || + id == NULL || id->get_type(id) != ID_KEY_ID) + { + return NULL; + } + + e = malloc_thing(cert_enumerator_t); + e->current = NULL; + e->type = key; + e->public.enumerate = (void*)cert_enumerator_enumerate; + e->public.destroy = (void*)cert_enumerator_destroy; + e->inner = this->db->query(this->db, + "SELECT PublicKey FROM ClientConfig WHERE KeyId = ? UNION " + "SELECT PublicKey FROM MediationServerConfig WHERE KeyId = ? UNION " + "SELECT PublicKey FROM Connection WHERE KeyId = ?", + DB_BLOB, id->get_encoding(id), + DB_BLOB, id->get_encoding(id), + DB_BLOB, id->get_encoding(id), + DB_BLOB); + if (!e->inner) + { + free(e); + return NULL; + } + return &e->public; +} + +/** + * Implementation of backend_t.destroy. + */ +static void destroy(private_medcli_creds_t *this) +{ + free(this); +} + +/** + * Described in header. + */ +medcli_creds_t *medcli_creds_create(database_t *db) +{ + private_medcli_creds_t *this = malloc_thing(private_medcli_creds_t); + + this->public.set.create_private_enumerator = (void*)create_private_enumerator; + this->public.set.create_cert_enumerator = (void*)create_cert_enumerator; + this->public.set.create_shared_enumerator = (void*)return_null; + this->public.set.create_cdp_enumerator = (void*)return_null; + this->public.set.cache_cert = (void*)nop; + + this->public.destroy = (void (*)(medcli_creds_t*))destroy; + + this->db = db; + + return &this->public; +} + diff --git a/src/charon/plugins/medcli/medcli_creds.h b/src/charon/plugins/medcli/medcli_creds.h new file mode 100644 index 000000000..5a81edaf2 --- /dev/null +++ b/src/charon/plugins/medcli/medcli_creds.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 . + * + * 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 medcli_creds_i medcli_creds + * @{ @ingroup medcli + */ + +#ifndef MEDCLI_CREDS_H_ +#define MEDCLI_CREDS_H_ + +#include +#include + +typedef struct medcli_creds_t medcli_creds_t; + +/** + * Mediation client credentials database. + */ +struct medcli_creds_t { + + /** + * Implements credential_set_t interface + */ + credential_set_t set; + + /** + * Destroy the credentials databse. + */ + void (*destroy)(medcli_creds_t *this); +}; + +/** + * Create the medcli credential set. + * + * @param database underlying database + * @return credential set implementation on that database + */ +medcli_creds_t *medcli_creds_create(database_t *database); + +#endif /* MEDCLI_CREDS_H_ @}*/ diff --git a/src/charon/plugins/medcli/medcli_plugin.c b/src/charon/plugins/medcli/medcli_plugin.c new file mode 100644 index 000000000..016a2d6a3 --- /dev/null +++ b/src/charon/plugins/medcli/medcli_plugin.c @@ -0,0 +1,101 @@ +/* + * 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 . + * + * 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 "medcli_plugin.h" + +#include "medcli_creds.h" +#include "medcli_config.h" + +#include + +typedef struct private_medcli_plugin_t private_medcli_plugin_t; + +/** + * private data of medcli plugin + */ +struct private_medcli_plugin_t { + + /** + * implements plugin interface + */ + medcli_plugin_t public; + + /** + * database connection instance + */ + database_t *db; + + /** + * medcli credential set instance + */ + medcli_creds_t *creds; + + /** + * medcli config database + */ + medcli_config_t *config; +}; + +/** + * Implementation of plugin_t.destroy + */ +static void destroy(private_medcli_plugin_t *this) +{ + charon->backends->remove_backend(charon->backends, &this->config->backend); + charon->credentials->remove_set(charon->credentials, &this->creds->set); + this->config->destroy(this->config); + this->creds->destroy(this->creds); + this->db->destroy(this->db); + free(this); +} + +/* + * see header file + */ +plugin_t *plugin_create() +{ + char *uri; + private_medcli_plugin_t *this = malloc_thing(private_medcli_plugin_t); + + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; + + uri = lib->settings->get_str(lib->settings, + "medclient.database", NULL); + if (!uri) + { + DBG1(DBG_CFG, "mediation client database URI not defined, skipped"); + free(this); + return NULL; + } + + this->db = lib->db->create(lib->db, uri); + if (this->db == NULL) + { + DBG1(DBG_CFG, "opening mediation client database failed"); + free(this); + return NULL; + } + + this->creds = medcli_creds_create(this->db); + this->config = medcli_config_create(this->db); + + charon->credentials->add_set(charon->credentials, &this->creds->set); + charon->backends->add_backend(charon->backends, &this->config->backend); + + return &this->public.plugin; +} + diff --git a/src/charon/plugins/medcli/medcli_plugin.h b/src/charon/plugins/medcli/medcli_plugin.h new file mode 100644 index 000000000..1a8c5b5e7 --- /dev/null +++ b/src/charon/plugins/medcli/medcli_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 . + * + * 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 medcli medcli + * @ingroup cplugins + * + * @defgroup medcli_plugin medcli_plugin + * @{ @ingroup medcli + */ + +#ifndef MEDCLI_PLUGIN_H_ +#define MEDCLI_PLUGIN_H_ + +#include + +typedef struct medcli_plugin_t medcli_plugin_t; + +/** + * Mediation client database plugin. + */ +struct medcli_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +/** + * Create a medcli_plugin instance. + */ +plugin_t *plugin_create(); + +#endif /* MEDCLI_PLUGIN_H_ @}*/ diff --git a/src/charon/plugins/medcli/mysql.sql b/src/charon/plugins/medcli/mysql.sql new file mode 100644 index 000000000..0107ad35a --- /dev/null +++ b/src/charon/plugins/medcli/mysql.sql @@ -0,0 +1,32 @@ + +CREATE TABLE `ClientConfig` ( + `IdClientConfig` int(11) NOT NULL, + `KeyId` varbinary(20) NOT NULL, + `PublicKey` blob NOT NULL, + `PrivateKey` blob NOT NULL, + PRIMARY KEY (`IdClientConfig`) +); + + +CREATE TABLE `MediationServerConfig` ( + `IdMediationServerConfig` int(11) NOT NULL, + `Address` varchar(200) NOT NULL, + `KeyId` varbinary(20) NOT NULL, + `PublicKey` blob NOT NULL, + PRIMARY KEY (`IdMediationServerConfig`) +); + + +CREATE TABLE `Connection` ( + `IdConnection` int(11) NOT NULL auto_increment, + `Active` tinyint(1) NOT NULL, + `Alias` varchar(50) NOT NULL, + `KeyId` varbinary(20) NOT NULL, + `PublicKey` blob NOT NULL, + `LocalSubnet` varchar(20), + `RemoteSubnet` varchar(20), + `Status` int(11) NOT NULL, + PRIMARY KEY (`IdConnection`), + UNIQUE (`Alias`), + UNIQUE (`KeyId`) +);