diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-07-13 14:27:41 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-08-08 15:41:03 +0200 |
commit | 7000cf11b1b4e3b2c504951812b48396258e55e2 (patch) | |
tree | 11d80c206437c8acc72c1b4199701353e43953f7 /src | |
parent | 3b8276b405868c176a936e34579d908dcabd61df (diff) | |
download | strongswan-7000cf11b1b4e3b2c504951812b48396258e55e2.tar.bz2 strongswan-7000cf11b1b4e3b2c504951812b48396258e55e2.tar.xz |
IPsec policy manager added
This version only provides the very simplest management functions.
Diffstat (limited to 'src')
-rw-r--r-- | src/libipsec/Android.mk | 1 | ||||
-rw-r--r-- | src/libipsec/Makefile.am | 1 | ||||
-rw-r--r-- | src/libipsec/ipsec.c | 2 | ||||
-rw-r--r-- | src/libipsec/ipsec.h | 6 | ||||
-rw-r--r-- | src/libipsec/ipsec_policy_mgr.c | 162 | ||||
-rw-r--r-- | src/libipsec/ipsec_policy_mgr.h | 106 |
6 files changed, 278 insertions, 0 deletions
diff --git a/src/libipsec/Android.mk b/src/libipsec/Android.mk index f18fc73f0..269f39b3a 100644 --- a/src/libipsec/Android.mk +++ b/src/libipsec/Android.mk @@ -9,6 +9,7 @@ esp_packet.c esp_packet.h \ ipsec_event_listener.h \ ipsec_event_relay.c ipsec_event_relay.h \ ipsec_policy.c ipsec_policy.h \ +ipsec_policy_mgr.c ipsec_policy_mgr.h \ ipsec_sa.c ipsec_sa.h \ ipsec_sa_mgr.c ipsec_sa_mgr.h diff --git a/src/libipsec/Makefile.am b/src/libipsec/Makefile.am index 4b81d4563..ec5745a83 100644 --- a/src/libipsec/Makefile.am +++ b/src/libipsec/Makefile.am @@ -7,6 +7,7 @@ esp_packet.c esp_packet.h \ ipsec_event_listener.h \ ipsec_event_relay.c ipsec_event_relay.h \ ipsec_policy.c ipsec_policy.h \ +ipsec_policy_mgr.c ipsec_policy_mgr.h \ ipsec_sa.c ipsec_sa.h \ ipsec_sa_mgr.c ipsec_sa_mgr.h diff --git a/src/libipsec/ipsec.c b/src/libipsec/ipsec.c index 49773abc9..5453430a3 100644 --- a/src/libipsec/ipsec.c +++ b/src/libipsec/ipsec.c @@ -44,6 +44,7 @@ void libipsec_deinit() { private_ipsec_t *this = (private_ipsec_t*)ipsec; DESTROY_IF(this->public.events); + DESTROY_IF(this->public.policies); DESTROY_IF(this->public.sas); free(this); ipsec = NULL; @@ -67,6 +68,7 @@ bool libipsec_init() } this->public.sas = ipsec_sa_mgr_create(); + this->public.policies = ipsec_policy_mgr_create(); this->public.events = ipsec_event_relay_create(); return TRUE; } diff --git a/src/libipsec/ipsec.h b/src/libipsec/ipsec.h index 304738170..e8e828d25 100644 --- a/src/libipsec/ipsec.h +++ b/src/libipsec/ipsec.h @@ -26,6 +26,7 @@ #define IPSEC_H_ #include "ipsec_sa_mgr.h" +#include "ipsec_policy_mgr.h" #include "ipsec_event_relay.h" #include <library.h> @@ -43,6 +44,11 @@ struct ipsec_t { ipsec_sa_mgr_t *sas; /** + * IPsec policy manager instance + */ + ipsec_policy_mgr_t *policies; + + /** * Event relay instance */ ipsec_event_relay_t *events; diff --git a/src/libipsec/ipsec_policy_mgr.c b/src/libipsec/ipsec_policy_mgr.c new file mode 100644 index 000000000..40e69894d --- /dev/null +++ b/src/libipsec/ipsec_policy_mgr.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012 Giuliano Grassi + * Copyright (C) 2012 Ralf Sager + * 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 "ipsec_policy_mgr.h" +#include "ipsec_policy.h" + +#include <debug.h> +#include <library.h> +#include <ipsec/ipsec_types.h> +#include <selectors/traffic_selector.h> +#include <threading/rwlock.h> +#include <utils/host.h> +#include <utils/linked_list.h> + +typedef struct private_ipsec_policy_mgr_t private_ipsec_policy_mgr_t; + +/** + * Private additions to ipsec_policy_mgr_t. + */ +struct private_ipsec_policy_mgr_t { + + /** + * Public members of ipsec_policy_mgr_t. + */ + ipsec_policy_mgr_t public; + + /** + * Installed policies + */ + linked_list_t *policies; + + /** + * Lock to safely access policies + */ + rwlock_t *lock; + +}; + +static bool match_policy(ipsec_policy_t *policy, ipsec_policy_t *other_policy) +{ + return policy->match(policy, other_policy->get_source_ts(other_policy), + other_policy->get_destination_ts(other_policy), + other_policy->get_direction(other_policy), + other_policy->get_reqid(other_policy), + (mark_t){ .value = 0, }, + other_policy->get_priority(other_policy)); +} + +METHOD(ipsec_policy_mgr_t, add_policy, status_t, + private_ipsec_policy_mgr_t *this, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, mark_t mark, + policy_priority_t priority) +{ + ipsec_policy_t *policy; + + policy = ipsec_policy_create(src, dst, src_ts, dst_ts, direction, type, sa, + mark, priority); + this->lock->write_lock(this->lock); + if (this->policies->find_first(this->policies, (void*)match_policy, + NULL, policy) != SUCCESS) + { + this->policies->insert_last(this->policies, policy); + } + else + { + policy->destroy(policy); + } + this->lock->unlock(this->lock); + return SUCCESS; +} + +METHOD(ipsec_policy_mgr_t, del_policy, status_t, + private_ipsec_policy_mgr_t *this, traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid, + mark_t mark, policy_priority_t priority) +{ + enumerator_t *enumerator; + ipsec_policy_t *current, *found = NULL; + + this->lock->write_lock(this->lock); + enumerator = this->policies->create_enumerator(this->policies); + while (enumerator->enumerate(enumerator, (void**)¤t)) + { + if (current->match(current, src_ts, dst_ts, direction, reqid, + mark, priority)) + { + this->policies->remove_at(this->policies, enumerator); + found = current; + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + if (found) + { + found->destroy(found); + return SUCCESS; + } + return FAILED; +} + +METHOD(ipsec_policy_mgr_t, flush_policies, status_t, + private_ipsec_policy_mgr_t *this) +{ + ipsec_policy_t *policy; + + DBG2(DBG_ESP, "flushing policies"); + + this->lock->write_lock(this->lock); + while (this->policies->remove_last(this->policies, + (void**)&policy) == SUCCESS) + { + policy->destroy(policy); + } + this->lock->unlock(this->lock); + return SUCCESS; +} + +METHOD(ipsec_policy_mgr_t, destroy, void, + private_ipsec_policy_mgr_t *this) +{ + flush_policies(this); + this->policies->destroy(this->policies); + this->lock->destroy(this->lock); + free(this); +} + +/** + * Described in header. + */ +ipsec_policy_mgr_t *ipsec_policy_mgr_create() +{ + private_ipsec_policy_mgr_t *this; + + INIT(this, + .public = { + .add_policy = _add_policy, + .del_policy = _del_policy, + .flush_policies = _flush_policies, + .destroy = _destroy, + }, + .policies = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); + + return &this->public; +} diff --git a/src/libipsec/ipsec_policy_mgr.h b/src/libipsec/ipsec_policy_mgr.h new file mode 100644 index 000000000..0a2f63239 --- /dev/null +++ b/src/libipsec/ipsec_policy_mgr.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012 Giuliano Grassi + * Copyright (C) 2012 Ralf Sager + * 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. + */ + +/** + * @defgroup ipsec_policy_mgr ipsec_policy_mgr + * @{ @ingroup libipsec + */ + +#ifndef IPSEC_POLICY_MGR_H_ +#define IPSEC_POLICY_MGR_H_ + +#include <library.h> +#include <utils/host.h> +#include <utils/linked_list.h> +#include <ipsec/ipsec_types.h> +#include <selectors/traffic_selector.h> + +typedef struct ipsec_policy_mgr_t ipsec_policy_mgr_t; + +/** + * IPsec policy manager + * + * The first methods are modeled after those in kernel_ipsec_t. + * + * @note Only policies of type POLICY_IPSEC are currently used, also policies + * with direction POLICY_FWD are ignored. Any packets that do not match an + * installed policy will be dropped. + */ +struct ipsec_policy_mgr_t { + + /** + * Add a policy + * + * A policy is always associated to an SA. Traffic which matches a + * policy is handled by the SA with the same reqid. + * + * @param src source address of SA + * @param dst dest address of SA + * @param src_ts traffic selector to match traffic source + * @param dst_ts traffic selector to match traffic dest + * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param type type of policy, POLICY_(IPSEC|PASS|DROP) + * @param sa details about the SA(s) tied to this policy + * @param mark mark for this policy + * @param priority priority of this policy + * @return SUCCESS if operation completed + */ + status_t (*add_policy)(ipsec_policy_mgr_t *this, + host_t *src, host_t *dst, traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, policy_dir_t direction, + policy_type_t type, ipsec_sa_cfg_t *sa, mark_t mark, + policy_priority_t priority); + + /** + * Remove a policy + * + * @param src_ts traffic selector to match traffic source + * @param dst_ts traffic selector to match traffic dest + * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param reqid unique ID of the associated SA + * @param mark optional mark + * @param priority priority of the policy + * @return SUCCESS if operation completed + */ + status_t (*del_policy)(ipsec_policy_mgr_t *this, + traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, + policy_dir_t direction, u_int32_t reqid, mark_t mark, + policy_priority_t priority); + + /** + * Flush all policies + * + * @return SUCCESS if operation completed + */ + status_t (*flush_policies)(ipsec_policy_mgr_t *this); + + /** + * Destroy an ipsec_policy_mgr_t + */ + void (*destroy)(ipsec_policy_mgr_t *this); + +}; + +/** + * Create an ipsec_policy_mgr instance + * + * @return ipsec_policy_mgr + */ +ipsec_policy_mgr_t *ipsec_policy_mgr_create(); + +#endif /** IPSEC_POLICY_MGR_H_ @}*/ |