summaryrefslogtreecommitdiff
path: root/src/charon/config
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2007-10-26 14:24:26 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2007-10-26 14:24:26 +0000
commit3168dc628f034e03bb4fab16e8a00da59a5c86e1 (patch)
tree663da4d1badc1373ec59d9bdc39f893af0cc8a75 /src/charon/config
parent1a144d57c8f2f08513b747078d185db688637859 (diff)
downloadvyos-strongswan-3168dc628f034e03bb4fab16e8a00da59a5c86e1.tar.gz
vyos-strongswan-3168dc628f034e03bb4fab16e8a00da59a5c86e1.zip
- Import new upstream release 4.1.8.
Diffstat (limited to 'src/charon/config')
-rw-r--r--src/charon/config/backend_manager.c17
-rw-r--r--src/charon/config/backend_manager.h9
-rw-r--r--src/charon/config/backends/backend.h9
-rw-r--r--src/charon/config/backends/local_backend.c48
-rw-r--r--src/charon/config/backends/sqlite_backend.c308
-rw-r--r--src/charon/config/backends/sqlite_backend.h58
-rw-r--r--src/charon/config/child_cfg.c22
-rw-r--r--src/charon/config/credentials/local_credential_store.c249
-rw-r--r--src/charon/config/ike_cfg.c18
-rw-r--r--src/charon/config/ike_cfg.h12
-rw-r--r--src/charon/config/peer_cfg.c116
-rw-r--r--src/charon/config/peer_cfg.h71
12 files changed, 848 insertions, 89 deletions
diff --git a/src/charon/config/backend_manager.c b/src/charon/config/backend_manager.c
index 6df68c700..b2104acea 100644
--- a/src/charon/config/backend_manager.c
+++ b/src/charon/config/backend_manager.c
@@ -96,6 +96,22 @@ static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this,
}
/**
+ * implements backend_manager_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(private_backend_manager_t *this, char *name)
+{
+ backend_t *backend;
+ peer_cfg_t *config = NULL;
+ iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
+ while (config == NULL && iterator->iterate(iterator, (void**)&backend))
+ {
+ config = backend->get_peer_cfg_by_name(backend, name);
+ }
+ iterator->destroy(iterator);
+ return config;
+}
+
+/**
* implements backend_manager_t.add_peer_cfg.
*/
static void add_peer_cfg(private_backend_manager_t *this, peer_cfg_t *config)
@@ -214,6 +230,7 @@ backend_manager_t *backend_manager_create()
this->public.get_ike_cfg = (ike_cfg_t* (*)(backend_manager_t*, host_t*, host_t*))get_ike_cfg;
this->public.get_peer_cfg = (peer_cfg_t* (*)(backend_manager_t*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
+ this->public.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_manager_t*,char*))get_peer_cfg_by_name;
this->public.add_peer_cfg = (void (*)(backend_manager_t*,peer_cfg_t*))add_peer_cfg;
this->public.create_iterator = (iterator_t* (*)(backend_manager_t*))create_iterator;
this->public.destroy = (void (*)(backend_manager_t*))destroy;
diff --git a/src/charon/config/backend_manager.h b/src/charon/config/backend_manager.h
index 22a19a218..7ca6d660e 100644
--- a/src/charon/config/backend_manager.h
+++ b/src/charon/config/backend_manager.h
@@ -88,6 +88,15 @@ struct backend_manager_t {
ca_info_t *other_ca_info);
/**
+ * @brief Get a peer_config identified by it's name.
+ *
+ * @param this calling object
+ * @param name name of the peer_config
+ * @return matching peer_config, or NULL if none found
+ */
+ peer_cfg_t* (*get_peer_cfg_by_name)(backend_manager_t *this, char *name);
+
+ /**
* @brief Add a peer_config to the first found writable backend.
*
* @param this calling object
diff --git a/src/charon/config/backends/backend.h b/src/charon/config/backends/backend.h
index acab660b6..592d1dd4c 100644
--- a/src/charon/config/backends/backend.h
+++ b/src/charon/config/backends/backend.h
@@ -71,6 +71,15 @@ struct backend_t {
ca_info_t *other_ca_info);
/**
+ * @brief Get a peer_cfg identified by it's name, or a name of its child.
+ *
+ * @param this calling object
+ * @param name
+ * @return matching peer_config, or NULL if none found
+ */
+ peer_cfg_t *(*get_peer_cfg_by_name)(backend_t *this, char *name);
+
+ /**
* @brief Check if a backend is writable and implements writable_backend_t.
*
* @param this calling object
diff --git a/src/charon/config/backends/local_backend.c b/src/charon/config/backends/local_backend.c
index 2e80cc870..e04c72ac1 100644
--- a/src/charon/config/backends/local_backend.c
+++ b/src/charon/config/backends/local_backend.c
@@ -146,6 +146,13 @@ static peer_cfg_t *get_peer_cfg(private_local_backend_t *this,
int prio = (wc1 + wc2) * (MAX_CA_PATH_LEN + 1);
int pathlen = 0;
identification_t *other_candidate_ca = current->get_other_ca(current);
+ linked_list_t *groups = current->get_groups(current);
+
+ /* is a group membership required? */
+ if (groups->get_count(groups) > 0)
+ {
+ DBG1(DBG_CFG, " group membership required");
+ }
/* are there any ca constraints? */
if (other_candidate_ca->get_type(other_candidate_ca) != ID_ANY)
@@ -218,6 +225,46 @@ static peer_cfg_t *get_peer_cfg(private_local_backend_t *this,
}
/**
+ * implements backend_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(private_local_backend_t *this, char *name)
+{
+ iterator_t *i1, *i2;
+ peer_cfg_t *current, *found = NULL;
+ child_cfg_t *child;
+
+ i1 = this->cfgs->create_iterator(this->cfgs, TRUE);
+ while (i1->iterate(i1, (void**)&current))
+ {
+ /* compare peer_cfgs name first */
+ if (streq(current->get_name(current), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ /* compare all child_cfg names otherwise */
+ i2 = current->create_child_cfg_iterator(current);
+ while (i2->iterate(i2, (void**)&child))
+ {
+ if (streq(child->get_name(child), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ }
+ i2->destroy(i2);
+ if (found)
+ {
+ break;
+ }
+ }
+ i1->destroy(i1);
+ return found;
+}
+
+/**
* Implementation of backend_t.is_writable.
*/
static bool is_writeable(private_local_backend_t *this)
@@ -261,6 +308,7 @@ backend_t *backend_create(void)
this->public.backend.backend.get_ike_cfg = (ike_cfg_t* (*)(backend_t*, host_t*, host_t*))get_ike_cfg;
this->public.backend.backend.get_peer_cfg = (peer_cfg_t* (*)(backend_t*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
+ this->public.backend.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
this->public.backend.backend.is_writeable = (bool(*) (backend_t*))is_writeable;
this->public.backend.backend.destroy = (void (*)(backend_t*))destroy;
this->public.backend.create_iterator = (iterator_t* (*)(writeable_backend_t*))create_iterator;
diff --git a/src/charon/config/backends/sqlite_backend.c b/src/charon/config/backends/sqlite_backend.c
new file mode 100644
index 000000000..33093a735
--- /dev/null
+++ b/src/charon/config/backends/sqlite_backend.c
@@ -0,0 +1,308 @@
+/**
+ * @file sqlite_backend.c
+ *
+ * @brief Implementation of sqlite_backend_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 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 <string.h>
+#include <sqlite3.h>
+
+#include "sqlite_backend.h"
+
+#include <daemon.h>
+
+
+typedef struct private_sqlite_backend_t private_sqlite_backend_t;
+
+/**
+ * Private data of an sqlite_backend_t object
+ */
+struct private_sqlite_backend_t {
+
+ /**
+ * Public part
+ */
+ sqlite_backend_t public;
+
+ /**
+ * SQLite database handle
+ */
+ sqlite3 *db;
+};
+
+/**
+ * implements backen_t.get_ike_cfg.
+ */
+static ike_cfg_t *get_ike_cfg(private_sqlite_backend_t *this,
+ host_t *my_host, host_t *other_host)
+{
+ return NULL;
+}
+
+/**
+ * add TS with child "id" to "child_cfg"
+ */
+static void add_ts(private_sqlite_backend_t *this, child_cfg_t *child_cfg, int id)
+{
+ sqlite3_stmt *stmt;
+
+ if (sqlite3_prepare_v2(this->db,
+ "SELECT type, protocol, start_addr, end_addr, start_port, end_port, kind "
+ "FROM traffic_selectors, child_config_traffic_selector "
+ "ON traffic_selectors.oid = child_config_traffic_selector.traffic_selector "
+ "WHERE child_config_traffic_selector.child_cfg = ?;",
+ -1, &stmt, NULL) == SQLITE_OK &&
+ sqlite3_bind_int(stmt, 1, id) == SQLITE_OK)
+ {
+ while (sqlite3_step(stmt) == SQLITE_ROW)
+ {
+ traffic_selector_t *ts;
+ bool local = FALSE;
+ enum {
+ TS_LOCAL = 0,
+ TS_REMOTE = 1,
+ TS_LOCAL_DYNAMIC = 2,
+ TS_REMOTE_DYNAMIC = 3,
+ } kind;
+
+ kind = sqlite3_column_int(stmt, 6);
+ switch (kind)
+ {
+ case TS_LOCAL:
+ local = TRUE;
+ /* FALL */
+ case TS_REMOTE:
+ ts = traffic_selector_create_from_string(
+ sqlite3_column_int(stmt, 1), /* protocol */
+ sqlite3_column_int(stmt, 0), /* type */
+ (char*)sqlite3_column_text(stmt, 2), /* from addr */
+ sqlite3_column_int(stmt, 4), /* from port */
+ (char*)sqlite3_column_text(stmt, 3), /* to addr */
+ sqlite3_column_int(stmt, 5)); /* to port */
+ break;
+ case TS_LOCAL_DYNAMIC:
+ local = TRUE;
+ /* FALL */
+ case TS_REMOTE_DYNAMIC:
+ ts = traffic_selector_create_dynamic(
+ sqlite3_column_int(stmt, 1), /* protocol */
+ sqlite3_column_int(stmt, 0), /* type */
+ sqlite3_column_int(stmt, 4), /* from port */
+ sqlite3_column_int(stmt, 5)); /* to port */
+ break;
+ default:
+ continue;
+ }
+ if (ts)
+ {
+ child_cfg->add_traffic_selector(child_cfg, local, ts);
+ }
+ }
+ }
+ sqlite3_finalize(stmt);
+}
+
+/**
+ * add childrens belonging to config with "id" to "peer_cfg"
+ */
+static void add_children(private_sqlite_backend_t *this, peer_cfg_t *peer_cfg, int id)
+{
+ sqlite3_stmt *stmt;
+ child_cfg_t *child_cfg;
+
+ if (sqlite3_prepare_v2(this->db,
+ "SELECT child_configs.oid, name, updown, hostaccess, mode, "
+ "lifetime, rekeytime, jitter "
+ "FROM child_configs, peer_config_child_config "
+ "ON child_configs.oid = peer_config_child_config.child_cfg "
+ "WHERE peer_config_child_config.peer_cfg = ?;",
+ -1, &stmt, NULL) == SQLITE_OK &&
+ sqlite3_bind_int(stmt, 1, id) == SQLITE_OK)
+ {
+ while (sqlite3_step(stmt) == SQLITE_ROW)
+ {
+ child_cfg = child_cfg_create(
+ (char*)sqlite3_column_text(stmt, 1), /* name */
+ sqlite3_column_int(stmt, 5), /* lifetime */
+ sqlite3_column_int(stmt, 6), /* rekeytime */
+ sqlite3_column_int(stmt, 7), /* jitter */
+ (char*)sqlite3_column_text(stmt, 2), /* updown */
+ sqlite3_column_int(stmt, 3), /* hostaccess */
+ sqlite3_column_int(stmt, 4)); /* mode */
+ add_ts(this, child_cfg, sqlite3_column_int(stmt, 0));
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ peer_cfg->add_child_cfg(peer_cfg, child_cfg);
+ }
+ }
+ sqlite3_finalize(stmt);
+}
+
+/**
+ * processing function for get_peer_cfg and get_peer_cfg_by_name
+ */
+static peer_cfg_t *process_peer_cfg_row(private_sqlite_backend_t *this,
+ sqlite3_stmt *stmt)
+{
+ host_t *local_host, *remote_host, *local_vip = NULL, *remote_vip = NULL;
+ identification_t *local_id, *remote_id;
+ peer_cfg_t *peer_cfg;
+ ike_cfg_t *ike_cfg;
+
+ local_host = host_create_from_string((char*)sqlite3_column_text(stmt, 17), IKEV2_UDP_PORT);
+ remote_host = host_create_from_string((char*)sqlite3_column_text(stmt, 18), IKEV2_UDP_PORT);
+ if (sqlite3_column_text(stmt, 15))
+ {
+ local_vip = host_create_from_string((char*)sqlite3_column_text(stmt, 15), 0);
+ }
+ if (sqlite3_column_text(stmt, 16))
+ {
+ remote_vip = host_create_from_string((char*)sqlite3_column_text(stmt, 16), 0);
+ }
+ local_id = identification_create_from_string((char*)sqlite3_column_text(stmt, 2));
+ remote_id = identification_create_from_string((char*)sqlite3_column_text(stmt, 3));
+ if (local_host && remote_host && local_id && remote_id)
+ {
+ ike_cfg = ike_cfg_create(sqlite3_column_int(stmt, 19), FALSE,
+ local_host, remote_host);
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ peer_cfg = peer_cfg_create(
+ (char*)sqlite3_column_text(stmt, 1), /* name */
+ 2, ike_cfg, local_id, remote_id, NULL, NULL, linked_list_create(),
+ sqlite3_column_int(stmt, 4), /* cert_policy */
+ sqlite3_column_int(stmt, 5), /* auth_method */
+ sqlite3_column_int(stmt, 6), /* eap_type */
+ sqlite3_column_int(stmt, 7), /* keyingtries */
+ sqlite3_column_int(stmt, 8), /* lifetime */
+ sqlite3_column_int(stmt, 9), /* rekeytime */
+ sqlite3_column_int(stmt, 10), /* jitter */
+ sqlite3_column_int(stmt, 13), /* reauth */
+ sqlite3_column_int(stmt, 14), /* mobike */
+ sqlite3_column_int(stmt, 11), /* dpd_delay */
+ sqlite3_column_int(stmt, 12), /* dpd_action */
+ local_vip, remote_vip, FALSE, NULL, NULL);
+ add_children(this, peer_cfg, sqlite3_column_int(stmt, 0));
+ return peer_cfg;
+ }
+
+ DESTROY_IF(local_host);
+ DESTROY_IF(remote_host);
+ DESTROY_IF(local_id);
+ DESTROY_IF(remote_id);
+ DESTROY_IF(local_vip);
+ DESTROY_IF(remote_vip);
+ return NULL;
+}
+
+/**
+ * implements backend_t.get_peer_cfg.
+ */
+static peer_cfg_t *get_peer_cfg(private_sqlite_backend_t *this,
+ identification_t *my_id, identification_t *other_id,
+ ca_info_t *other_ca_info)
+{
+ sqlite3_stmt *stmt;
+ char local[256], remote[256];
+ peer_cfg_t *peer_cfg = NULL;
+
+ snprintf(local, sizeof(local), "%D", my_id);
+ snprintf(remote, sizeof(remote), "%D", other_id);
+
+ if (sqlite3_prepare_v2(this->db,
+ "SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
+ "auth_method, eap_type, keyingtries, lifetime, rekeytime, jitter, "
+ "dpd_delay, dpd_action, reauth, mobike, local_vip, remote_vip, "
+ "local, remote, certreq "
+ "FROM peer_configs, ike_configs "
+ "ON peer_configs.ike_cfg = ike_configs.oid "
+ "WHERE local_id = ? and remote_id = ?;", -1, &stmt, NULL) == SQLITE_OK &&
+ sqlite3_bind_text(stmt, 1, local, -1, SQLITE_STATIC) == SQLITE_OK &&
+ sqlite3_bind_text(stmt, 2, remote, -1, SQLITE_STATIC) == SQLITE_OK &&
+ sqlite3_step(stmt) == SQLITE_ROW)
+ {
+ peer_cfg = process_peer_cfg_row(this, stmt);
+ }
+ sqlite3_finalize(stmt);
+ return peer_cfg;
+}
+
+/**
+ * implements backend_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(private_sqlite_backend_t *this, char *name)
+{
+ sqlite3_stmt *stmt;
+ peer_cfg_t *peer_cfg = NULL;
+
+ if (sqlite3_prepare_v2(this->db,
+ "SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
+ "auth_method, eap_type, keyingtries, lifetime, rekeytime, jitter, "
+ "dpd_delay, dpd_action, reauth, mobike, local_vip, remote_vip, "
+ "local, remote, certreq "
+ "FROM peer_configs, ike_configs "
+ "ON peer_configs.ike_cfg = ike_configs.oid "
+ "WHERE name = ? ;", -1, &stmt, NULL) == SQLITE_OK &&
+ sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC) == SQLITE_OK &&
+ sqlite3_step(stmt) == SQLITE_ROW)
+ {
+ peer_cfg = process_peer_cfg_row(this, stmt);
+ }
+ sqlite3_finalize(stmt);
+ return peer_cfg;
+}
+
+/**
+ * Implementation of backend_t.is_writable.
+ */
+static bool is_writeable(private_sqlite_backend_t *this)
+{
+ return FALSE;
+}
+
+/**
+ * Implementation of backend_t.destroy.
+ */
+static void destroy(private_sqlite_backend_t *this)
+{
+ sqlite3_close(this->db);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+backend_t *backend_create(void)
+{
+ private_sqlite_backend_t *this = malloc_thing(private_sqlite_backend_t);
+
+ this->public.backend.get_ike_cfg = (ike_cfg_t* (*)(backend_t*, host_t*, host_t*))get_ike_cfg;
+ this->public.backend.get_peer_cfg = (peer_cfg_t* (*)(backend_t*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
+ this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
+ this->public.backend.is_writeable = (bool(*) (backend_t*))is_writeable;
+ this->public.backend.destroy = (void (*)(backend_t*))destroy;
+
+ if (sqlite3_open(IPSEC_DIR "/manager.db", &this->db) != SQLITE_OK)
+ {
+ DBG1(DBG_CFG, "opening SQLite database '" IPSEC_DIR "/manager.db' failed.");
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public.backend;
+}
+
diff --git a/src/charon/config/backends/sqlite_backend.h b/src/charon/config/backends/sqlite_backend.h
new file mode 100644
index 000000000..4bc146583
--- /dev/null
+++ b/src/charon/config/backends/sqlite_backend.h
@@ -0,0 +1,58 @@
+/**
+ * @file sqlite_backend.h
+ *
+ * @brief Interface of sqlite_backend_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 SQLITE_BACKEND_H_
+#define SQLITE_BACKEND_H_
+
+typedef struct sqlite_backend_t sqlite_backend_t;
+
+#include <library.h>
+
+#include "backend.h"
+
+/**
+ * @brief An SQLite based configuration backend.
+ *
+ * @b Constructors:
+ * - sqlite_backend_create()
+ *
+ * @ingroup backends
+ */
+struct sqlite_backend_t {
+
+ /**
+ * Implements backend_t interface
+ */
+ backend_t backend;
+};
+
+/**
+ * @brief Create a backend_t instance implemented as sqlite backend.
+ *
+ * @return backend instance
+ *
+ * @ingroup backends
+ */
+backend_t *backend_create(void);
+
+#endif /* SQLITE_BACKEND_H_ */
+
diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c
index e9f0e5249..5827b4f61 100644
--- a/src/charon/config/child_cfg.c
+++ b/src/charon/config/child_cfg.c
@@ -239,21 +239,25 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
/* no list supplied, just fetch the stored traffic selectors */
if (supplied == NULL)
{
+ DBG2(DBG_CFG, "proposing traffic selectors for %s:",
+ local ? "us" : "other");
while (i1->iterate(i1, (void**)&ts1))
{
/* we make a copy of the TS, this allows us to update dynamic TS' */
- ts1 = ts1->clone(ts1);
+ selected = ts1->clone(ts1);
if (host)
{
- ts1->set_address(ts1, host);
+ selected->set_address(selected, host);
}
- result->insert_last(result, ts1);
+ DBG2(DBG_CFG, " %R (derived from %R)", selected, ts1);
+ result->insert_last(result, selected);
}
i1->destroy(i1);
}
else
{
- DBG2(DBG_CFG, "selecting traffic selectors");
+ DBG2(DBG_CFG, "selecting traffic selectors for %s:",
+ local ? "us" : "other");
i2 = supplied->create_iterator(supplied, TRUE);
/* iterate over all stored selectors */
while (i1->iterate(i1, (void**)&ts1))
@@ -269,13 +273,17 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
/* iterate over all supplied traffic selectors */
while (i2->iterate(i2, (void**)&ts2))
{
- DBG2(DBG_CFG, "stored %R <=> %R received", ts1, ts2);
selected = ts1->get_subset(ts1, ts2);
if (selected)
{
+ DBG2(DBG_CFG, " config: %R, received: %R => match: %R",
+ ts1, ts2, selected);
result->insert_last(result, selected);
- DBG2(DBG_CFG, "found traffic selector for %s: %R",
- local ? "us" : "other", selected);
+ }
+ else
+ {
+ DBG2(DBG_CFG, " config: %R, received: %R => no match",
+ ts1, ts2, selected);
}
}
ts1->destroy(ts1);
diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c
index 649fcbcfb..b71e9e9e2 100644
--- a/src/charon/config/credentials/local_credential_store.c
+++ b/src/charon/config/credentials/local_credential_store.c
@@ -66,7 +66,7 @@ struct shared_key_t {
static void shared_key_destroy(shared_key_t *this)
{
this->peers->destroy_offset(this->peers, offsetof(identification_t, destroy));
- chunk_free(&this->secret);
+ chunk_free_randomized(&this->secret);
free(this);
}
@@ -83,7 +83,7 @@ static shared_key_t *shared_key_create(chunk_t secret)
shared_key_t *this = malloc_thing(shared_key_t);
/* private data */
- this->secret = chunk_clone(secret);
+ this->secret = secret;
this->peers = linked_list_create();
return (this);
@@ -158,6 +158,11 @@ struct private_local_credential_store_t {
linked_list_t *private_keys;
/**
+ * mutex controls access to the linked lists of secret keys
+ */
+ pthread_mutex_t keys_mutex;
+
+ /**
* list of X.509 certificates with public keys
*/
linked_list_t *certs;
@@ -171,6 +176,16 @@ struct private_local_credential_store_t {
* list of X.509 CA information records
*/
linked_list_t *ca_infos;
+
+ /**
+ * list of X.509 attribute certificates
+ */
+ linked_list_t *acerts;
+
+ /**
+ * mutex controls access to the linked list of attribute certificates
+ */
+ pthread_mutex_t acerts_mutex;
};
@@ -191,8 +206,9 @@ static status_t get_key(linked_list_t *keys,
prio_t best_prio = PRIO_UNDEFINED;
chunk_t found = chunk_empty;
shared_key_t *shared_key;
+ iterator_t *iterator;
- iterator_t *iterator = keys->create_iterator(keys, TRUE);
+ iterator = keys->create_iterator(keys, TRUE);
while (iterator->iterate(iterator, (void**)&shared_key))
{
@@ -242,7 +258,6 @@ static status_t get_key(linked_list_t *keys,
}
}
-
/**
* Implementation of local_credential_store_t.get_shared_key.
*/
@@ -250,7 +265,12 @@ static status_t get_shared_key(private_local_credential_store_t *this,
identification_t *my_id,
identification_t *other_id, chunk_t *secret)
{
- return get_key(this->shared_keys, my_id, other_id, secret);
+ status_t status;
+
+ pthread_mutex_lock(&(this->keys_mutex));
+ status = get_key(this->shared_keys, my_id, other_id, secret);
+ pthread_mutex_unlock(&(this->keys_mutex));
+ return status;
}
/**
@@ -260,7 +280,12 @@ static status_t get_eap_key(private_local_credential_store_t *this,
identification_t *my_id,
identification_t *other_id, chunk_t *secret)
{
- return get_key(this->eap_keys, my_id, other_id, secret);
+ status_t status;
+
+ pthread_mutex_lock(&(this->keys_mutex));
+ status = get_key(this->eap_keys, my_id, other_id, secret);
+ pthread_mutex_unlock(&(this->keys_mutex));
+ return status;
}
/**
@@ -325,36 +350,16 @@ static ca_info_t* get_issuer(private_local_credential_store_t *this, x509_t *cer
}
/**
- * Implementation of local_credential_store_t.get_rsa_private_key.
- */
-static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *this,
- rsa_public_key_t *pubkey)
-{
- rsa_private_key_t *found = NULL, *current;
-
- iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current))
- {
- if (current->belongs_to(current, pubkey))
- {
- found = current->clone(current);
- break;
- }
- }
- iterator->destroy(iterator);
- return found;
-}
-
-/**
* Implementation of local_credential_store_t.has_rsa_private_key.
*/
static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey)
{
bool found = FALSE;
rsa_private_key_t *current;
+ iterator_t *iterator;
- iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
+ pthread_mutex_lock(&(this->keys_mutex));
+ iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
while (iterator->iterate(iterator, (void**)&current))
{
@@ -365,6 +370,7 @@ static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_publ
}
}
iterator->destroy(iterator);
+ pthread_mutex_unlock(&(this->keys_mutex));
return found;
}
@@ -725,10 +731,51 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
}
/**
+ * Implementation of local_credential_store_t.rsa_signature.
+ */
+static status_t rsa_signature(private_local_credential_store_t *this,
+ rsa_public_key_t *pubkey,
+ hash_algorithm_t hash_algorithm,
+ chunk_t data, chunk_t *signature)
+{
+ rsa_private_key_t *current, *key = NULL;
+ iterator_t *iterator;
+ status_t status;
+ chunk_t keyid = pubkey->get_keyid(pubkey);
+
+ DBG2(DBG_IKE, "looking for RSA private key with keyid %#B...", &keyid);
+ pthread_mutex_lock(&(this->keys_mutex));
+
+ iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
+ while (iterator->iterate(iterator, (void**)&current))
+ {
+ if (current->belongs_to(current, pubkey))
+ {
+ key = current;
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+
+ if (key)
+ {
+ DBG2(DBG_IKE, " matching RSA private key found");
+ status = key->build_emsa_pkcs1_signature(key, hash_algorithm, data, signature);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "no RSA private key found with keyid %#B", &keyid);
+ status = NOT_FOUND;
+ }
+ pthread_mutex_unlock(&(this->keys_mutex));
+ return status;
+}
+
+/**
* Implementation of local_credential_store_t.verify_signature.
*/
static status_t verify_signature(private_local_credential_store_t *this,
- chunk_t hash, chunk_t sig,
+ chunk_t hash, chunk_t signature,
identification_t *id, ca_info_t **issuer_p)
{
iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
@@ -785,7 +832,7 @@ static status_t verify_signature(private_local_credential_store_t *this,
}
*issuer_p = issuer;
}
- sig_status = public_key->verify_emsa_pkcs1_signature(public_key, hash, sig);
+ sig_status = public_key->verify_emsa_pkcs1_signature(public_key, HASH_UNKNOWN, hash, signature);
if (sig_status == SUCCESS)
{
DBG2(DBG_CFG, "candidate peer certificate has a matching RSA public key");
@@ -938,6 +985,14 @@ static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this
}
/**
+ * Implements local_credential_store_t.create_acert_iterator
+ */
+static iterator_t* create_acert_iterator(private_local_credential_store_t *this)
+{
+ return this->acerts->create_iterator_locked(this->acerts, &this->acerts_mutex);
+}
+
+/**
* Implements local_credential_store_t.load_auth_certificates
*/
static void load_auth_certificates(private_local_credential_store_t *this,
@@ -1053,7 +1108,39 @@ static void load_aa_certificates(private_local_credential_store_t *this)
*/
static void add_attr_certificate(private_local_credential_store_t *this, x509ac_t *cert)
{
- /* TODO add a new attribute certificate to the linked list */
+ iterator_t *iterator;
+ x509ac_t *current_cert;
+ bool found = FALSE;
+
+ pthread_mutex_lock(&(this->acerts_mutex));
+ iterator = this->acerts->create_iterator(this->acerts, TRUE);
+
+ while (iterator->iterate(iterator, (void **)&current_cert))
+ {
+ if (cert->equals_holder(cert, current_cert))
+ {
+ if (cert->is_newer(cert, current_cert))
+ {
+ iterator->replace(iterator, NULL, (void *)cert);
+ current_cert->destroy(current_cert);
+ DBG1(DBG_CFG, " this attr cert is newer - existing attr cert replaced");
+ }
+ else
+ {
+ cert->destroy(cert);
+ DBG1(DBG_CFG, " this attr cert is not newer - existing attr cert retained");
+ }
+ found = TRUE;
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+
+ if (!found)
+ {
+ this->acerts->insert_last(this->acerts, (void *)cert);
+ }
+ pthread_mutex_unlock(&(this->acerts_mutex));
}
/**
@@ -1230,21 +1317,26 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line)
}
if (quotes)
- { /* treat as an ASCII string */
- if (raw_secret.len > secret->len)
- return "secret larger than buffer";
- memcpy(secret->ptr, raw_secret.ptr, raw_secret.len);
- secret->len = raw_secret.len;
+ {
+ /* treat as an ASCII string */
+ *secret = chunk_clone(raw_secret);
}
else
- { /* convert from HEX or Base64 to binary */
+ {
size_t len;
- err_t ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
+ err_t ugh;
+
+ /* secret converted to binary form doesn't use more space than the raw_secret */
+ *secret = chunk_alloc(raw_secret.len);
+
+ /* convert from HEX or Base64 to binary */
+ ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
if (ugh != NULL)
+ {
+ chunk_free_randomized(secret);
return ugh;
- if (len > secret->len)
- return "secret larger than buffer";
+ }
secret->len = len;
}
return NULL;
@@ -1253,17 +1345,18 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line)
/**
* Implements local_credential_store_t.load_secrets
*/
-static void load_secrets(private_local_credential_store_t *this)
+static void load_secrets(private_local_credential_store_t *this, bool reload)
{
FILE *fd = fopen(SECRETS_FILE, "r");
if (fd)
{
- int bytes;
+ size_t bytes;
int line_nr = 0;
chunk_t chunk, src, line;
- DBG1(DBG_CFG, "loading secrets from \"%s\"", SECRETS_FILE);
+ DBG1(DBG_CFG, "%sloading secrets from \"%s\"",
+ reload? "re":"", SECRETS_FILE);
fseek(fd, 0, SEEK_END);
chunk.len = ftell(fd);
@@ -1271,9 +1364,25 @@ static void load_secrets(private_local_credential_store_t *this)
chunk.ptr = malloc(chunk.len);
bytes = fread(chunk.ptr, 1, chunk.len, fd);
fclose(fd);
-
src = chunk;
+ pthread_mutex_lock(&(this->keys_mutex));
+ if (reload)
+ {
+ DBG1(DBG_CFG, " forgetting old secrets");
+ this->private_keys->destroy_offset(this->private_keys,
+ offsetof(rsa_private_key_t, destroy));
+ this->private_keys = linked_list_create();
+
+ this->shared_keys->destroy_function(this->shared_keys,
+ (void*)shared_key_destroy);
+ this->shared_keys = linked_list_create();
+
+ this->eap_keys->destroy_function(this->eap_keys,
+ (void*)shared_key_destroy);
+ this->eap_keys = linked_list_create();
+ }
+
while (fetchline(&src, &line))
{
chunk_t ids, token;
@@ -1302,9 +1411,7 @@ static void load_secrets(private_local_credential_store_t *this)
{
char path[PATH_BUF];
chunk_t filename;
-
- char buf[BUF_LEN];
- chunk_t secret = { buf, BUF_LEN };
+ chunk_t secret = chunk_empty;
chunk_t *passphrase = NULL;
rsa_private_key_t *key;
@@ -1350,14 +1457,13 @@ static void load_secrets(private_local_credential_store_t *this)
{
this->private_keys->insert_last(this->private_keys, (void*)key);
}
+ chunk_free_randomized(&secret);
}
else if ( match("PSK", &token) ||
((match("EAP", &token) || match("XAUTH", &token)) && (is_eap = TRUE)))
{
shared_key_t *shared_key;
-
- char buf[BUF_LEN];
- chunk_t secret = { buf, BUF_LEN };
+ chunk_t secret = chunk_empty;
err_t ugh = extract_secret(&secret, &line);
if (ugh != NULL)
@@ -1373,16 +1479,13 @@ static void load_secrets(private_local_credential_store_t *this)
DBG4(DBG_CFG, " secret:", secret);
shared_key = shared_key_create(secret);
- if (shared_key)
+ if (is_eap)
{
- if (is_eap)
- {
- this->eap_keys->insert_last(this->eap_keys, (void*)shared_key);
- }
- else
- {
- this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
- }
+ this->eap_keys->insert_last(this->eap_keys, (void*)shared_key);
+ }
+ else
+ {
+ this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
}
while (ids.len > 0)
{
@@ -1430,7 +1533,8 @@ static void load_secrets(private_local_credential_store_t *this)
}
}
error:
- free(chunk.ptr);
+ chunk_free_randomized(&chunk);
+ pthread_mutex_unlock(&(this->keys_mutex));
}
else
{
@@ -1447,9 +1551,17 @@ static void destroy(private_local_credential_store_t *this)
this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
this->auth_certs->destroy_offset(this->auth_certs, offsetof(x509_t, destroy));
this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
+
+ pthread_mutex_lock(&(this->acerts_mutex));
+ this->acerts->destroy_offset(this->acerts, offsetof(x509ac_t, destroy));
+ pthread_mutex_unlock(&(this->acerts_mutex));
+
+ pthread_mutex_lock(&(this->keys_mutex));
this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
this->eap_keys->destroy_function(this->eap_keys, (void*)shared_key_destroy);
+ pthread_mutex_unlock(&(this->keys_mutex));
+
free(this);
}
@@ -1459,17 +1571,18 @@ static void destroy(private_local_credential_store_t *this)
local_credential_store_t * local_credential_store_create(void)
{
private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
-
+
+ /* public functions */
this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
this->public.credential_store.get_eap_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_eap_key;
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
- this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
this->public.credential_store.get_auth_certificate = (x509_t* (*) (credential_store_t*,u_int,identification_t*))get_auth_certificate;
this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid;
this->public.credential_store.get_issuer = (ca_info_t* (*) (credential_store_t*,x509_t*))get_issuer;
this->public.credential_store.is_trusted = (bool (*) (credential_store_t*,const char*,x509_t*))is_trusted;
+ this->public.credential_store.rsa_signature = (status_t (*) (credential_store_t*,rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t*))rsa_signature;
this->public.credential_store.verify_signature = (status_t (*) (credential_store_t*,chunk_t,chunk_t,identification_t*,ca_info_t**))verify_signature;
this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
@@ -1479,14 +1592,19 @@ local_credential_store_t * local_credential_store_create(void)
this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
this->public.credential_store.create_auth_cert_iterator = (iterator_t* (*) (credential_store_t*))create_auth_cert_iterator;
this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
+ this->public.credential_store.create_acert_iterator = (iterator_t* (*) (credential_store_t*))create_acert_iterator;
this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
this->public.credential_store.load_aa_certificates = (void (*) (credential_store_t*))load_aa_certificates;
this->public.credential_store.load_attr_certificates = (void (*) (credential_store_t*))load_attr_certificates;
this->public.credential_store.load_ocsp_certificates = (void (*) (credential_store_t*))load_ocsp_certificates;
this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
- this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets;
+ this->public.credential_store.load_secrets = (void (*) (credential_store_t*,bool))load_secrets;
this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
-
+
+ /* initialize the mutexes */
+ pthread_mutex_init(&(this->keys_mutex), NULL);
+ pthread_mutex_init(&(this->acerts_mutex), NULL);
+
/* private variables */
this->shared_keys = linked_list_create();
this->eap_keys = linked_list_create();
@@ -1494,6 +1612,7 @@ local_credential_store_t * local_credential_store_create(void)
this->certs = linked_list_create();
this->auth_certs = linked_list_create();
this->ca_infos = linked_list_create();
+ this->acerts = linked_list_create();
return (&this->public);
}
diff --git a/src/charon/config/ike_cfg.c b/src/charon/config/ike_cfg.c
index 35f46a6b7..abb300aab 100644
--- a/src/charon/config/ike_cfg.c
+++ b/src/charon/config/ike_cfg.c
@@ -59,6 +59,11 @@ struct private_ike_cfg_t {
bool certreq;
/**
+ * enforce UDP encapsulation
+ */
+ bool force_encap;
+
+ /**
* List of proposals to use
*/
linked_list_t *proposals;
@@ -71,6 +76,14 @@ static bool send_certreq(private_ike_cfg_t *this)
{
return this->certreq;
}
+
+/**
+ * Implementation of ike_cfg_t.force_encap.
+ */
+static bool force_encap_meth(private_ike_cfg_t *this)
+{
+ return this->force_encap;
+}
/**
* Implementation of ike_cfg_t.get_my_host.
@@ -201,12 +214,14 @@ static void destroy(private_ike_cfg_t *this)
/**
* Described in header.
*/
-ike_cfg_t *ike_cfg_create(bool certreq, host_t *my_host, host_t *other_host)
+ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
+ host_t *my_host, host_t *other_host)
{
private_ike_cfg_t *this = malloc_thing(private_ike_cfg_t);
/* public functions */
this->public.send_certreq = (bool(*)(ike_cfg_t*))send_certreq;
+ this->public.force_encap = (bool (*) (ike_cfg_t *))force_encap_meth;
this->public.get_my_host = (host_t*(*)(ike_cfg_t*))get_my_host;
this->public.get_other_host = (host_t*(*)(ike_cfg_t*))get_other_host;
this->public.add_proposal = (void(*)(ike_cfg_t*, proposal_t*)) add_proposal;
@@ -219,6 +234,7 @@ ike_cfg_t *ike_cfg_create(bool certreq, host_t *my_host, host_t *other_host)
/* private variables */
this->refcount = 1;
this->certreq = certreq;
+ this->force_encap = force_encap;
this->my_host = my_host;
this->other_host = other_host;
diff --git a/src/charon/config/ike_cfg.h b/src/charon/config/ike_cfg.h
index bcdc90d9e..5165d12a6 100644
--- a/src/charon/config/ike_cfg.h
+++ b/src/charon/config/ike_cfg.h
@@ -102,6 +102,14 @@ struct ike_cfg_t {
bool (*send_certreq) (ike_cfg_t *this);
/**
+ * @brief Enforce UDP encapsulation by faking NATD notifies?
+ *
+ * @param this calling object
+ * @return TRUE to enfoce UDP encapsulation
+ */
+ bool (*force_encap) (ike_cfg_t *this);
+
+ /**
* @brief Get the DH group to use for IKE_SA setup.
*
* @param this calling object
@@ -140,12 +148,14 @@ struct ike_cfg_t {
*
* @param name ike_cfg identifier
* @param certreq TRUE to send a certificate request
+ * @param force_encap enforce UDP encapsulation by faking NATD notify
* @param my_host host_t representing local address
* @param other_host host_t representing remote address
* @return ike_cfg_t object.
*
* @ingroup config
*/
-ike_cfg_t *ike_cfg_create(bool certreq, host_t *my_host, host_t *other_host);
+ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
+ host_t *my_host, host_t *other_host);
#endif /* IKE_CFG_H_ */
diff --git a/src/charon/config/peer_cfg.c b/src/charon/config/peer_cfg.c
index 1d9176e0d..d61ed9512 100644
--- a/src/charon/config/peer_cfg.c
+++ b/src/charon/config/peer_cfg.c
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -28,6 +29,7 @@
#include <utils/linked_list.h>
#include <utils/identification.h>
+#include <crypto/ietf_attr_list.h>
ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
"CERT_ALWAYS_SEND",
@@ -105,6 +107,11 @@ struct private_peer_cfg_t {
identification_t *other_ca;
/**
+ * we require the other end to belong to at least one group
+ */
+ linked_list_t *groups;
+
+ /**
* should we send a certificate
*/
cert_policy_t cert_policy;
@@ -130,6 +137,11 @@ struct private_peer_cfg_t {
bool use_reauth;
/**
+ * enable support for MOBIKE
+ */
+ bool use_mobike;
+
+ /**
* Time before an SA gets invalid
*/
u_int32_t lifetime;
@@ -164,6 +176,24 @@ struct private_peer_cfg_t {
* virtual IP to use remotly
*/
host_t *other_virtual_ip;
+
+#ifdef P2P
+ /**
+ * Is this a mediation connection?
+ */
+ bool p2p_mediation;
+
+ /**
+ * Name of the mediation connection to mediate through
+ */
+ peer_cfg_t *p2p_mediated_by;
+
+ /**
+ * ID of our peer at the mediation server (= leftid of the peer's conn with
+ * the mediation server)
+ */
+ identification_t *peer_id;
+#endif /* P2P */
};
/**
@@ -274,10 +304,21 @@ static identification_t *get_my_ca(private_peer_cfg_t *this)
return this->my_ca;
}
+/**
+ * Implementation of peer_cfg_t.get_other_ca
+ */
static identification_t *get_other_ca(private_peer_cfg_t *this)
{
return this->other_ca;
-}
+}
+
+/**
+ * Implementation of peer_cfg_t.get_groups
+ */
+static linked_list_t *get_groups(private_peer_cfg_t *this)
+{
+ return this->groups;
+}
/**
* Implementation of peer_cfg_t.get_cert_policy.
@@ -330,10 +371,18 @@ static u_int32_t get_lifetime(private_peer_cfg_t *this, bool rekey)
/**
* Implementation of peer_cfg_t.use_reauth.
*/
-static bool use_reauth(private_peer_cfg_t *this, bool rekey)
+static bool use_reauth(private_peer_cfg_t *this)
{
return this->use_reauth;
}
+
+/**
+ * Implementation of peer_cfg_t.use_mobike.
+ */
+static bool use_mobike(private_peer_cfg_t *this)
+{
+ return this->use_mobike;
+}
/**
* Implements peer_cfg_t.get_dpd_delay
@@ -383,6 +432,36 @@ static host_t* get_other_virtual_ip(private_peer_cfg_t *this, host_t *suggestion
return suggestion->clone(suggestion);
}
+#ifdef P2P
+/**
+ * Implementation of peer_cfg_t.is_mediation.
+ */
+static bool is_mediation(private_peer_cfg_t *this)
+{
+ return this->p2p_mediation;
+}
+
+/**
+ * Implementation of peer_cfg_t.get_mediated_by.
+ */
+static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this)
+{
+ if (this->p2p_mediated_by) {
+ this->p2p_mediated_by->get_ref(this->p2p_mediated_by);
+ return this->p2p_mediated_by;
+ }
+ return NULL;
+}
+
+/**
+ * Implementation of peer_cfg_t.get_peer_id.
+ */
+static identification_t* get_peer_id(private_peer_cfg_t *this)
+{
+ return this->peer_id;
+}
+#endif /* P2P */
+
/**
* Implements peer_cfg_t.get_ref.
*/
@@ -404,9 +483,13 @@ static void destroy(private_peer_cfg_t *this)
this->other_id->destroy(this->other_id);
DESTROY_IF(this->my_ca);
DESTROY_IF(this->other_ca);
-
DESTROY_IF(this->my_virtual_ip);
DESTROY_IF(this->other_virtual_ip);
+#ifdef P2P
+ DESTROY_IF(this->p2p_mediated_by);
+ DESTROY_IF(this->peer_id);
+#endif /* P2P */
+ ietfAttr_list_destroy(this->groups);
free(this->name);
free(this);
}
@@ -418,12 +501,15 @@ static void destroy(private_peer_cfg_t *this)
peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
identification_t *my_id, identification_t *other_id,
identification_t *my_ca, identification_t *other_ca,
- cert_policy_t cert_policy, auth_method_t auth_method,
- eap_type_t eap_type, u_int32_t keyingtries,
- u_int32_t lifetime, u_int32_t rekeytime,
- u_int32_t jitter, bool reauth,
+ linked_list_t *groups, cert_policy_t cert_policy,
+ auth_method_t auth_method, eap_type_t eap_type,
+ u_int32_t keyingtries, u_int32_t lifetime,
+ u_int32_t rekeytime, u_int32_t jitter,
+ bool reauth, bool mobike,
u_int32_t dpd_delay, dpd_action_t dpd_action,
- host_t *my_virtual_ip, host_t *other_virtual_ip)
+ host_t *my_virtual_ip, host_t *other_virtual_ip,
+ bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
+ identification_t *peer_id)
{
private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
@@ -438,18 +524,25 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->public.get_other_id = (identification_t* (*)(peer_cfg_t *))get_other_id;
this->public.get_my_ca = (identification_t* (*)(peer_cfg_t *))get_my_ca;
this->public.get_other_ca = (identification_t* (*)(peer_cfg_t *))get_other_ca;
+ this->public.get_groups = (linked_list_t* (*)(peer_cfg_t *))get_groups;
this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *))get_eap_type;
this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
this->public.get_lifetime = (u_int32_t (*) (peer_cfg_t *, bool rekey))get_lifetime;
this->public.use_reauth = (bool (*) (peer_cfg_t *))use_reauth;
+ this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
this->public.get_my_virtual_ip = (host_t* (*) (peer_cfg_t *))get_my_virtual_ip;
this->public.get_other_virtual_ip = (host_t* (*) (peer_cfg_t *, host_t *))get_other_virtual_ip;
this->public.get_ref = (void(*)(peer_cfg_t *))get_ref;
this->public.destroy = (void(*)(peer_cfg_t *))destroy;
+#ifdef P2P
+ this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation;
+ this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by;
+ this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id;
+#endif /* P2P */
/* apply init values */
this->name = strdup(name);
@@ -461,6 +554,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->other_id = other_id;
this->my_ca = my_ca;
this->other_ca = other_ca;
+ this->groups = groups;
this->cert_policy = cert_policy;
this->auth_method = auth_method;
this->eap_type = eap_type;
@@ -469,11 +563,17 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->rekeytime = rekeytime;
this->jitter = jitter;
this->use_reauth = reauth;
+ this->use_mobike = mobike;
this->dpd_delay = dpd_delay;
this->dpd_action = dpd_action;
this->my_virtual_ip = my_virtual_ip;
this->other_virtual_ip = other_virtual_ip;
this->refcount = 1;
+#ifdef P2P
+ this->p2p_mediation = p2p_mediation;
+ this->p2p_mediated_by = p2p_mediated_by;
+ this->peer_id = peer_id;
+#endif /* P2P */
return &this->public;
}
diff --git a/src/charon/config/peer_cfg.h b/src/charon/config/peer_cfg.h
index 63c87674c..3d238e6aa 100644
--- a/src/charon/config/peer_cfg.h
+++ b/src/charon/config/peer_cfg.h
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -30,6 +31,7 @@ typedef struct peer_cfg_t peer_cfg_t;
#include <library.h>
#include <utils/identification.h>
+#include <utils/linked_list.h>
#include <config/traffic_selector.h>
#include <config/proposal.h>
#include <config/ike_cfg.h>
@@ -194,7 +196,7 @@ struct peer_cfg_t {
identification_t* (*get_my_ca)(peer_cfg_t *this);
/**
- * @brief Get peers CA.
+ * @brief Get peer CA.
*
* @param this calling object
* @return other ca
@@ -202,6 +204,14 @@ struct peer_cfg_t {
identification_t* (*get_other_ca)(peer_cfg_t *this);
/**
+ * @brief Get list of group attributes.
+ *
+ * @param this calling object
+ * @return linked list of group attributes
+ */
+ linked_list_t* (*get_groups)(peer_cfg_t *this);
+
+ /**
* @brief Should be sent a certificate for this connection?
*
* @param this calling object
@@ -257,6 +267,14 @@ struct peer_cfg_t {
bool (*use_reauth) (peer_cfg_t *this);
/**
+ * @brief Use MOBIKE (RFC4555) if peer supports it?
+ *
+ * @param this calling object
+ * @return TRUE to enable MOBIKE support
+ */
+ bool (*use_mobike) (peer_cfg_t *this);
+
+ /**
* @brief Get the DPD check interval.
*
* @param this calling object
@@ -297,6 +315,37 @@ struct peer_cfg_t {
* @return clone of an IP to use
*/
host_t* (*get_other_virtual_ip) (peer_cfg_t *this, host_t *suggestion);
+
+#ifdef P2P
+ /**
+ * @brief Is this a mediation connection?
+ *
+ * @param this peer_cfg
+ * @return TRUE, if this is a mediation connection
+ */
+ bool (*is_mediation) (peer_cfg_t *this);
+
+ /**
+ * @brief Get peer_cfg of the connection this one is mediated through.
+ *
+ * @param this peer_cfg
+ * @return reference to peer_cfg of the mediation connection
+ */
+ peer_cfg_t* (*get_mediated_by) (peer_cfg_t *this);
+
+ /**
+ * @brief Get the id of the other peer at the mediation server.
+ *
+ * This is the leftid of the peer's connection with the mediation server.
+ *
+ * If it is not configured, it is assumed to be the same as the right id
+ * of this connection.
+ *
+ * @param this peer_cfg
+ * @return the id of the other peer
+ */
+ identification_t* (*get_peer_id) (peer_cfg_t *this);
+#endif /* P2P */
/**
* @brief Get a new reference.
@@ -339,6 +388,7 @@ struct peer_cfg_t {
* @param other_id identification_t for the remote guy
* @param my_ca CA to use for us
* @param other_ca CA to use for other
+ * @param groups list of group memberships
* @param cert_policy should we send a certificate payload?
* @param auth_method auth method to use to authenticate us
* @param eap_type EAP type to use for peer authentication
@@ -346,11 +396,15 @@ struct peer_cfg_t {
* @param lifetime lifetime before deleting an SA
* @param rekeytime lifetime before rekeying an SA
* @param jitter range of random to substract from rekeytime
- * @param use_reauth sould be done reauthentication instead of rekeying?
+ * @param reauth sould be done reauthentication instead of rekeying?
+ * @param mobike use MOBIKE (RFC4555) if peer supports it
* @param dpd_delay after how many seconds of inactivity to check DPD
* @param dpd_action what to do with CHILD_SAs when detected a dead peer
* @param my_virtual_ip virtual IP for local host, or NULL
* @param other_virtual_ip virtual IP for remote host, or NULL
+ * @param p2p_mediation TRUE if this is a mediation connection
+ * @param p2p_mediated_by name of the mediation connection to mediate through
+ * @param peer_id ID that identifies our peer at the mediation server
* @return peer_cfg_t object
*
* @ingroup config
@@ -358,11 +412,14 @@ struct peer_cfg_t {
peer_cfg_t *peer_cfg_create(char *name, u_int ikev_version, ike_cfg_t *ike_cfg,
identification_t *my_id, identification_t *other_id,
identification_t *my_ca, identification_t *other_ca,
- cert_policy_t cert_policy, auth_method_t auth_method,
- eap_type_t eap_type, u_int32_t keyingtries,
- u_int32_t lifetime, u_int32_t rekeytime,
- u_int32_t jitter, bool use_reauth,
+ linked_list_t *groups, cert_policy_t cert_policy,
+ auth_method_t auth_method, eap_type_t eap_type,
+ u_int32_t keyingtries, u_int32_t lifetime,
+ u_int32_t rekeytime, u_int32_t jitter,
+ bool reauth, bool mobike,
u_int32_t dpd_delay, dpd_action_t dpd_action,
- host_t *my_virtual_ip, host_t *other_virtual_ip);
+ host_t *my_virtual_ip, host_t *other_virtual_ip,
+ bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
+ identification_t *peer_id);
#endif /* PEER_CFG_H_ */