diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2007-10-26 14:24:26 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2007-10-26 14:24:26 +0000 |
commit | 3168dc628f034e03bb4fab16e8a00da59a5c86e1 (patch) | |
tree | 663da4d1badc1373ec59d9bdc39f893af0cc8a75 /src/charon/config | |
parent | 1a144d57c8f2f08513b747078d185db688637859 (diff) | |
download | vyos-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.c | 17 | ||||
-rw-r--r-- | src/charon/config/backend_manager.h | 9 | ||||
-rw-r--r-- | src/charon/config/backends/backend.h | 9 | ||||
-rw-r--r-- | src/charon/config/backends/local_backend.c | 48 | ||||
-rw-r--r-- | src/charon/config/backends/sqlite_backend.c | 308 | ||||
-rw-r--r-- | src/charon/config/backends/sqlite_backend.h | 58 | ||||
-rw-r--r-- | src/charon/config/child_cfg.c | 22 | ||||
-rw-r--r-- | src/charon/config/credentials/local_credential_store.c | 249 | ||||
-rw-r--r-- | src/charon/config/ike_cfg.c | 18 | ||||
-rw-r--r-- | src/charon/config/ike_cfg.h | 12 | ||||
-rw-r--r-- | src/charon/config/peer_cfg.c | 116 | ||||
-rw-r--r-- | src/charon/config/peer_cfg.h | 71 |
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**)¤t)) + { + /* 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**)¤t)) - { - 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**)¤t)) { @@ -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**)¤t)) + { + 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 **)¤t_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_ */ |