Merge branch 'unity'
Add Cisco Unity extension support implemented in a dedicated plugin.
This commit is contained in:
@@ -23,6 +23,13 @@ strongswan-5.0.1
|
|||||||
PAM directly anymore, but can use any XAuth backend to verify credentials,
|
PAM directly anymore, but can use any XAuth backend to verify credentials,
|
||||||
including xauth-pam.
|
including xauth-pam.
|
||||||
|
|
||||||
|
- The new unity plugin brings support for some parts of the IKEv1 Cisco Unity
|
||||||
|
Extension. As client, charon narrows traffic selectors to the received
|
||||||
|
Split-Include attributes and automatically installs IPsec bypass policies
|
||||||
|
for received Local-LAN attributes. As server, charon sends Split-Include
|
||||||
|
attributes for leftsubnet definitions containing multiple subnets to Unity-
|
||||||
|
aware clients.
|
||||||
|
|
||||||
- An EAP-Nak payload is returned by clients if the gateway requests an EAP
|
- An EAP-Nak payload is returned by clients if the gateway requests an EAP
|
||||||
method that the client does not support. Clients can also request a specific
|
method that the client does not support. Clients can also request a specific
|
||||||
EAP method by configuring that method with leftauth.
|
EAP method by configuring that method with leftauth.
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ ARG_ENABL_SET([ctr], [enables the Counter Mode wrapper crypto plugin.
|
|||||||
ARG_ENABL_SET([ccm], [enables the CCM AEAD wrapper crypto plugin.])
|
ARG_ENABL_SET([ccm], [enables the CCM AEAD wrapper crypto plugin.])
|
||||||
ARG_ENABL_SET([gcm], [enables the GCM AEAD wrapper crypto plugin.])
|
ARG_ENABL_SET([gcm], [enables the GCM AEAD wrapper crypto plugin.])
|
||||||
ARG_ENABL_SET([addrblock], [enables RFC 3779 address block constraint support.])
|
ARG_ENABL_SET([addrblock], [enables RFC 3779 address block constraint support.])
|
||||||
|
ARG_ENABL_SET([unity], [enables Cisco Unity extension plugin.])
|
||||||
ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.])
|
ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.])
|
||||||
ARG_ENABL_SET([android], [enable Android specific plugin.])
|
ARG_ENABL_SET([android], [enable Android specific plugin.])
|
||||||
ARG_ENABL_SET([android-log], [enable Android specific logger plugin.])
|
ARG_ENABL_SET([android-log], [enable Android specific logger plugin.])
|
||||||
@@ -953,6 +954,7 @@ ADD_PLUGIN([radattr], [c charon])
|
|||||||
ADD_PLUGIN([maemo], [c charon])
|
ADD_PLUGIN([maemo], [c charon])
|
||||||
ADD_PLUGIN([uci], [c charon])
|
ADD_PLUGIN([uci], [c charon])
|
||||||
ADD_PLUGIN([addrblock], [c charon])
|
ADD_PLUGIN([addrblock], [c charon])
|
||||||
|
ADD_PLUGIN([unity], [c charon])
|
||||||
ADD_PLUGIN([unit-tester], [c charon])
|
ADD_PLUGIN([unit-tester], [c charon])
|
||||||
|
|
||||||
AC_SUBST(charon_plugins)
|
AC_SUBST(charon_plugins)
|
||||||
@@ -1078,6 +1080,7 @@ AM_CONDITIONAL(USE_SOCKET_DEFAULT, test x$socket_default = xtrue)
|
|||||||
AM_CONDITIONAL(USE_SOCKET_DYNAMIC, test x$socket_dynamic = xtrue)
|
AM_CONDITIONAL(USE_SOCKET_DYNAMIC, test x$socket_dynamic = xtrue)
|
||||||
AM_CONDITIONAL(USE_FARP, test x$farp = xtrue)
|
AM_CONDITIONAL(USE_FARP, test x$farp = xtrue)
|
||||||
AM_CONDITIONAL(USE_ADDRBLOCK, test x$addrblock = xtrue)
|
AM_CONDITIONAL(USE_ADDRBLOCK, test x$addrblock = xtrue)
|
||||||
|
AM_CONDITIONAL(USE_UNITY, test x$unity = xtrue)
|
||||||
|
|
||||||
dnl hydra plugins
|
dnl hydra plugins
|
||||||
dnl =============
|
dnl =============
|
||||||
@@ -1257,6 +1260,7 @@ AC_OUTPUT(
|
|||||||
src/libcharon/plugins/medsrv/Makefile
|
src/libcharon/plugins/medsrv/Makefile
|
||||||
src/libcharon/plugins/medcli/Makefile
|
src/libcharon/plugins/medcli/Makefile
|
||||||
src/libcharon/plugins/addrblock/Makefile
|
src/libcharon/plugins/addrblock/Makefile
|
||||||
|
src/libcharon/plugins/unity/Makefile
|
||||||
src/libcharon/plugins/uci/Makefile
|
src/libcharon/plugins/uci/Makefile
|
||||||
src/libcharon/plugins/ha/Makefile
|
src/libcharon/plugins/ha/Makefile
|
||||||
src/libcharon/plugins/whitelist/Makefile
|
src/libcharon/plugins/whitelist/Makefile
|
||||||
|
|||||||
+3
-2
@@ -756,8 +756,9 @@ signifying that the left end of the connection goes to the left participant
|
|||||||
only. Configured subnets of the peers may differ, the protocol narrows it to
|
only. Configured subnets of the peers may differ, the protocol narrows it to
|
||||||
the greatest common subnet. In IKEv1, this may lead to problems with other
|
the greatest common subnet. In IKEv1, this may lead to problems with other
|
||||||
implementations, make sure to configure identical subnets in such
|
implementations, make sure to configure identical subnets in such
|
||||||
configurations. IKEv2 supports multiple subnets separated by commas, IKEv1 only
|
configurations. IKEv2 supports multiple subnets separated by commas. IKEv1 only
|
||||||
interprets the first subnet of such a definition.
|
interprets the first subnet of such a definition, unless the Cisco Unity
|
||||||
|
extension plugin is enabled.
|
||||||
.TP
|
.TP
|
||||||
.BR leftupdown " = <path>"
|
.BR leftupdown " = <path>"
|
||||||
what ``updown'' script to run to adjust routing and/or firewalling
|
what ``updown'' script to run to adjust routing and/or firewalling
|
||||||
|
|||||||
@@ -533,6 +533,13 @@ if MONOLITHIC
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if USE_UNITY
|
||||||
|
SUBDIRS += plugins/unity
|
||||||
|
if MONOLITHIC
|
||||||
|
libcharon_la_LIBADD += plugins/unity/libstrongswan-unity.la
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
if USE_UNIT_TESTS
|
if USE_UNIT_TESTS
|
||||||
SUBDIRS += plugins/unit_tester
|
SUBDIRS += plugins/unit_tester
|
||||||
if MONOLITHIC
|
if MONOLITHIC
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
|
||||||
|
-I$(top_srcdir)/src/libcharon
|
||||||
|
|
||||||
|
AM_CFLAGS = -rdynamic
|
||||||
|
|
||||||
|
if MONOLITHIC
|
||||||
|
noinst_LTLIBRARIES = libstrongswan-unity.la
|
||||||
|
else
|
||||||
|
plugin_LTLIBRARIES = libstrongswan-unity.la
|
||||||
|
endif
|
||||||
|
|
||||||
|
libstrongswan_unity_la_SOURCES = \
|
||||||
|
unity_plugin.h unity_plugin.c \
|
||||||
|
unity_handler.h unity_handler.c \
|
||||||
|
unity_narrow.h unity_narrow.c \
|
||||||
|
unity_provider.h unity_provider.c
|
||||||
|
|
||||||
|
libstrongswan_unity_la_LDFLAGS = -module -avoid-version
|
||||||
@@ -0,0 +1,433 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 revosec AG
|
||||||
|
*
|
||||||
|
* 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 "unity_handler.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
#include <threading/mutex.h>
|
||||||
|
#include <utils/linked_list.h>
|
||||||
|
#include <processing/jobs/callback_job.h>
|
||||||
|
|
||||||
|
typedef struct private_unity_handler_t private_unity_handler_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of an unity_handler_t object.
|
||||||
|
*/
|
||||||
|
struct private_unity_handler_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public unity_handler_t interface.
|
||||||
|
*/
|
||||||
|
unity_handler_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of subnets to include, as entry_t
|
||||||
|
*/
|
||||||
|
linked_list_t *include;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex for concurrent access to lists
|
||||||
|
*/
|
||||||
|
mutex_t *mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traffic selector entry for networks to include under a given IKE_SA
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** associated IKE_SA, unique ID */
|
||||||
|
u_int32_t sa;
|
||||||
|
/** traffic selector to include/exclude */
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
} entry_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up an entry
|
||||||
|
*/
|
||||||
|
static void entry_destroy(entry_t *this)
|
||||||
|
{
|
||||||
|
this->ts->destroy(this->ts);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a traffic selector from a unity subnet definition
|
||||||
|
*/
|
||||||
|
static traffic_selector_t *create_ts(chunk_t subnet)
|
||||||
|
{
|
||||||
|
chunk_t net, mask;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (subnet.len != 8)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
net = chunk_create(subnet.ptr, 4);
|
||||||
|
mask = chunk_clonea(chunk_skip(subnet, 4));
|
||||||
|
for (i = 0; i < net.len; i++)
|
||||||
|
{
|
||||||
|
mask.ptr[i] = (mask.ptr[i] ^ 0xFF) | net.ptr[i];
|
||||||
|
}
|
||||||
|
return traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
|
||||||
|
net, 0, mask, 65535);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a subnet to include in tunnels under this IKE_SA
|
||||||
|
*/
|
||||||
|
static bool add_include(private_unity_handler_t *this, chunk_t subnet)
|
||||||
|
{
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
entry_t *entry;
|
||||||
|
|
||||||
|
ike_sa = charon->bus->get_sa(charon->bus);
|
||||||
|
if (!ike_sa)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ts = create_ts(subnet);
|
||||||
|
if (!ts)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
INIT(entry,
|
||||||
|
.sa = ike_sa->get_unique_id(ike_sa),
|
||||||
|
.ts = ts,
|
||||||
|
);
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
|
this->include->insert_last(this->include, entry);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rempve a subnet from the inclusion list for this IKE_SA
|
||||||
|
*/
|
||||||
|
static bool remove_include(private_unity_handler_t *this, chunk_t subnet)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
entry_t *entry;
|
||||||
|
|
||||||
|
ike_sa = charon->bus->get_sa(charon->bus);
|
||||||
|
if (!ike_sa)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ts = create_ts(subnet);
|
||||||
|
if (!ts)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
|
enumerator = this->include->create_enumerator(this->include);
|
||||||
|
while (enumerator->enumerate(enumerator, &entry))
|
||||||
|
{
|
||||||
|
if (entry->sa == ike_sa->get_unique_id(ike_sa) &&
|
||||||
|
ts->equals(ts, entry->ts))
|
||||||
|
{
|
||||||
|
this->include->remove_at(this->include, enumerator);
|
||||||
|
entry_destroy(entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
ts->destroy(ts);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a unique shunt name for a bypass policy
|
||||||
|
*/
|
||||||
|
static void create_shunt_name(ike_sa_t *ike_sa, traffic_selector_t *ts,
|
||||||
|
char *buf, size_t len)
|
||||||
|
{
|
||||||
|
snprintf(buf, len, "Unity (%s[%u]: %R)", ike_sa->get_name(ike_sa),
|
||||||
|
ike_sa->get_unique_id(ike_sa), ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install entry as a shunt policy
|
||||||
|
*/
|
||||||
|
static job_requeue_t add_exclude_async(entry_t *entry)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
child_cfg_t *child_cfg;
|
||||||
|
lifetime_cfg_t lft = {};
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
char name[128];
|
||||||
|
host_t *host;
|
||||||
|
bool has_vip = FALSE;
|
||||||
|
|
||||||
|
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
|
||||||
|
entry->sa, FALSE);
|
||||||
|
if (ike_sa)
|
||||||
|
{
|
||||||
|
create_shunt_name(ike_sa, entry->ts, name, sizeof(name));
|
||||||
|
|
||||||
|
child_cfg = child_cfg_create(name, &lft, NULL, TRUE, MODE_PASS,
|
||||||
|
ACTION_NONE, ACTION_NONE, ACTION_NONE,
|
||||||
|
FALSE, 0, 0, NULL, NULL, FALSE);
|
||||||
|
child_cfg->add_traffic_selector(child_cfg, FALSE,
|
||||||
|
entry->ts->clone(entry->ts));
|
||||||
|
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
|
||||||
|
while (enumerator->enumerate(enumerator, &host))
|
||||||
|
{
|
||||||
|
has_vip = TRUE;
|
||||||
|
child_cfg->add_traffic_selector(child_cfg, TRUE,
|
||||||
|
traffic_selector_create_from_subnet(host->clone(host), 32, 0, 0));
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
if (!has_vip)
|
||||||
|
{
|
||||||
|
host = ike_sa->get_my_host(ike_sa);
|
||||||
|
child_cfg->add_traffic_selector(child_cfg, TRUE,
|
||||||
|
traffic_selector_create_from_subnet(host->clone(host), 32, 0, 0));
|
||||||
|
}
|
||||||
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||||
|
|
||||||
|
charon->shunts->install(charon->shunts, child_cfg);
|
||||||
|
child_cfg->destroy(child_cfg);
|
||||||
|
|
||||||
|
DBG1(DBG_IKE, "installed %N bypass policy for %R",
|
||||||
|
configuration_attribute_type_names, UNITY_LOCAL_LAN, entry->ts);
|
||||||
|
}
|
||||||
|
return JOB_REQUEUE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a bypass policy for a given subnet
|
||||||
|
*/
|
||||||
|
static bool add_exclude(private_unity_handler_t *this, chunk_t subnet)
|
||||||
|
{
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
entry_t *entry;
|
||||||
|
|
||||||
|
ike_sa = charon->bus->get_sa(charon->bus);
|
||||||
|
if (!ike_sa)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ts = create_ts(subnet);
|
||||||
|
if (!ts)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
INIT(entry,
|
||||||
|
.sa = ike_sa->get_unique_id(ike_sa),
|
||||||
|
.ts = ts,
|
||||||
|
);
|
||||||
|
|
||||||
|
/* we can't install the shunt policy yet, as we don't know the virtual IP.
|
||||||
|
* Defer installation using an async callback. */
|
||||||
|
lib->processor->queue_job(lib->processor, (job_t*)
|
||||||
|
callback_job_create((void*)add_exclude_async, entry,
|
||||||
|
(void*)entry_destroy, NULL));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a bypass policy for a given subnet
|
||||||
|
*/
|
||||||
|
static bool remove_exclude(private_unity_handler_t *this, chunk_t subnet)
|
||||||
|
{
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
char name[128];
|
||||||
|
|
||||||
|
ike_sa = charon->bus->get_sa(charon->bus);
|
||||||
|
if (!ike_sa)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ts = create_ts(subnet);
|
||||||
|
if (!ts)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
create_shunt_name(ike_sa, ts, name, sizeof(name));
|
||||||
|
DBG1(DBG_IKE, "uninstalling %N bypass policy for %R",
|
||||||
|
configuration_attribute_type_names, UNITY_LOCAL_LAN, ts);
|
||||||
|
ts->destroy(ts);
|
||||||
|
return charon->shunts->uninstall(charon->shunts, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(attribute_handler_t, handle, bool,
|
||||||
|
private_unity_handler_t *this, identification_t *id,
|
||||||
|
configuration_attribute_type_t type, chunk_t data)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case UNITY_SPLIT_INCLUDE:
|
||||||
|
return add_include(this, data);
|
||||||
|
case UNITY_LOCAL_LAN:
|
||||||
|
return add_exclude(this, data);
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(attribute_handler_t, release, void,
|
||||||
|
private_unity_handler_t *this, identification_t *server,
|
||||||
|
configuration_attribute_type_t type, chunk_t data)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case UNITY_SPLIT_INCLUDE:
|
||||||
|
remove_include(this, data);
|
||||||
|
break;
|
||||||
|
case UNITY_LOCAL_LAN:
|
||||||
|
remove_exclude(this, data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration attributes to request
|
||||||
|
*/
|
||||||
|
static configuration_attribute_type_t attributes[] = {
|
||||||
|
UNITY_SPLIT_INCLUDE,
|
||||||
|
UNITY_LOCAL_LAN,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute enumerator implementation
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** implements enumerator_t */
|
||||||
|
enumerator_t public;
|
||||||
|
/** position in attributes[] */
|
||||||
|
int i;
|
||||||
|
} attribute_enumerator_t;
|
||||||
|
|
||||||
|
METHOD(enumerator_t, enumerate_attributes, bool,
|
||||||
|
attribute_enumerator_t *this, configuration_attribute_type_t *type,
|
||||||
|
chunk_t *data)
|
||||||
|
{
|
||||||
|
if (this->i < countof(attributes))
|
||||||
|
{
|
||||||
|
*type = attributes[this->i++];
|
||||||
|
*data = chunk_empty;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
||||||
|
unity_handler_t *this, identification_t *id, linked_list_t *vips)
|
||||||
|
{
|
||||||
|
attribute_enumerator_t *enumerator;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
|
||||||
|
ike_sa = charon->bus->get_sa(charon->bus);
|
||||||
|
if (!ike_sa || ike_sa->get_version(ike_sa) != IKEV1 ||
|
||||||
|
!ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY))
|
||||||
|
{
|
||||||
|
return enumerator_create_empty();
|
||||||
|
}
|
||||||
|
INIT(enumerator,
|
||||||
|
.public = {
|
||||||
|
.enumerate = (void*)_enumerate_attributes,
|
||||||
|
.destroy = (void*)free,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return &enumerator->public;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/** mutex to unlock */
|
||||||
|
mutex_t *mutex;
|
||||||
|
/** IKE_SA ID to filter for */
|
||||||
|
u_int32_t id;
|
||||||
|
} include_filter_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include enumerator filter function
|
||||||
|
*/
|
||||||
|
static bool include_filter(include_filter_t *data,
|
||||||
|
entry_t **entry, traffic_selector_t **ts)
|
||||||
|
{
|
||||||
|
if ((*entry)->sa == data->id)
|
||||||
|
{
|
||||||
|
*ts = (*entry)->ts;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy include filter data, unlock mutex
|
||||||
|
*/
|
||||||
|
static void destroy_filter(include_filter_t *data)
|
||||||
|
{
|
||||||
|
data->mutex->unlock(data->mutex);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(unity_handler_t, create_include_enumerator, enumerator_t*,
|
||||||
|
private_unity_handler_t *this, u_int32_t id)
|
||||||
|
{
|
||||||
|
include_filter_t *data;
|
||||||
|
|
||||||
|
INIT(data,
|
||||||
|
.mutex = this->mutex,
|
||||||
|
.id = id,
|
||||||
|
);
|
||||||
|
data->mutex->lock(data->mutex);
|
||||||
|
return enumerator_create_filter(
|
||||||
|
this->include->create_enumerator(this->include),
|
||||||
|
(void*)include_filter, data, (void*)destroy_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(unity_handler_t, destroy, void,
|
||||||
|
private_unity_handler_t *this)
|
||||||
|
{
|
||||||
|
this->include->destroy(this->include);
|
||||||
|
this->mutex->destroy(this->mutex);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
unity_handler_t *unity_handler_create()
|
||||||
|
{
|
||||||
|
private_unity_handler_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.handler = {
|
||||||
|
.handle = _handle,
|
||||||
|
.release = _release,
|
||||||
|
.create_attribute_enumerator = _create_attribute_enumerator,
|
||||||
|
},
|
||||||
|
.create_include_enumerator = _create_include_enumerator,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.include = linked_list_create(),
|
||||||
|
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 revosec AG
|
||||||
|
*
|
||||||
|
* 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 unity_handler unity_handler
|
||||||
|
* @{ @ingroup unity
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UNITY_HANDLER_H_
|
||||||
|
#define UNITY_HANDLER_H_
|
||||||
|
|
||||||
|
#include <attributes/attribute_handler.h>
|
||||||
|
|
||||||
|
typedef struct unity_handler_t unity_handler_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cisco Unity attribute handling.
|
||||||
|
*/
|
||||||
|
struct unity_handler_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements attribute_handler_t.
|
||||||
|
*/
|
||||||
|
attribute_handler_t handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an enumerator over Split-Include attributes received for an IKE_SA.
|
||||||
|
*
|
||||||
|
* @param id IKE_SA unique ID to get Split-Includes for
|
||||||
|
* @return enumerator over traffic_selector_t*
|
||||||
|
*/
|
||||||
|
enumerator_t* (*create_include_enumerator)(unity_handler_t *this,
|
||||||
|
u_int32_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a unity_handler_t.
|
||||||
|
*/
|
||||||
|
void (*destroy)(unity_handler_t *this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a unity_handler instance.
|
||||||
|
*/
|
||||||
|
unity_handler_t *unity_handler_create();
|
||||||
|
|
||||||
|
#endif /** UNITY_HANDLER_H_ @}*/
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 revosec AG
|
||||||
|
*
|
||||||
|
* 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 "unity_narrow.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
|
||||||
|
typedef struct private_unity_narrow_t private_unity_narrow_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of an unity_narrow_t object.
|
||||||
|
*/
|
||||||
|
struct private_unity_narrow_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public unity_narrow_t interface.
|
||||||
|
*/
|
||||||
|
unity_narrow_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unity attribute handler
|
||||||
|
*/
|
||||||
|
unity_handler_t *handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrow TS as initiator to Unity Split-Include/Local-LAN
|
||||||
|
*/
|
||||||
|
static void narrow_initiator(private_unity_narrow_t *this, ike_sa_t *ike_sa,
|
||||||
|
child_cfg_t *cfg, linked_list_t *remote)
|
||||||
|
{
|
||||||
|
traffic_selector_t *current, *orig = NULL;
|
||||||
|
linked_list_t *received, *selected;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
|
enumerator = this->handler->create_include_enumerator(this->handler,
|
||||||
|
ike_sa->get_unique_id(ike_sa));
|
||||||
|
while (enumerator->enumerate(enumerator, ¤t))
|
||||||
|
{
|
||||||
|
if (orig == NULL)
|
||||||
|
{ /* got one, replace original TS */
|
||||||
|
if (remote->remove_first(remote, (void**)&orig) != SUCCESS)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* narrow received Unity TS with the child configuration */
|
||||||
|
received = linked_list_create();
|
||||||
|
received->insert_last(received, current);
|
||||||
|
selected = cfg->get_traffic_selectors(cfg, FALSE, received, NULL);
|
||||||
|
while (selected->remove_first(selected, (void**)¤t) == SUCCESS)
|
||||||
|
{
|
||||||
|
remote->insert_last(remote, current);
|
||||||
|
}
|
||||||
|
selected->destroy(selected);
|
||||||
|
received->destroy(received);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
if (orig)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "narrowed CHILD_SA to %N %#R",
|
||||||
|
configuration_attribute_type_names,
|
||||||
|
UNITY_SPLIT_INCLUDE, remote);
|
||||||
|
orig->destroy(orig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As initiator, bump up TS to 0.0.0.0/0 for on-the-wire bits
|
||||||
|
*/
|
||||||
|
static void narrow_initiator_pre(linked_list_t *list)
|
||||||
|
{
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
|
||||||
|
while (list->remove_first(list, (void**)&ts) == SUCCESS)
|
||||||
|
{
|
||||||
|
ts->destroy(ts);
|
||||||
|
}
|
||||||
|
ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
|
||||||
|
"0.0.0.0", 0,
|
||||||
|
"255.255.255.255", 65535);
|
||||||
|
if (ts)
|
||||||
|
{
|
||||||
|
list->insert_last(list, ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As responder, narrow down TS to configuration for installation
|
||||||
|
*/
|
||||||
|
static void narrow_responder_post(child_cfg_t *child_cfg, linked_list_t *local)
|
||||||
|
{
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
linked_list_t *configured;
|
||||||
|
|
||||||
|
while (local->remove_first(local, (void**)&ts) == SUCCESS)
|
||||||
|
{
|
||||||
|
ts->destroy(ts);
|
||||||
|
}
|
||||||
|
configured = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
|
||||||
|
|
||||||
|
while (configured->remove_first(configured, (void**)&ts) == SUCCESS)
|
||||||
|
{
|
||||||
|
local->insert_last(local, ts);
|
||||||
|
}
|
||||||
|
configured->destroy(configured);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(listener_t, narrow, bool,
|
||||||
|
private_unity_narrow_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
||||||
|
narrow_hook_t type, linked_list_t *local, linked_list_t *remote)
|
||||||
|
{
|
||||||
|
if (ike_sa->get_version(ike_sa) == IKEV1 &&
|
||||||
|
ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY))
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case NARROW_INITIATOR_PRE_AUTH:
|
||||||
|
narrow_initiator_pre(remote);
|
||||||
|
break;
|
||||||
|
case NARROW_INITIATOR_POST_AUTH:
|
||||||
|
narrow_initiator(this, ike_sa,
|
||||||
|
child_sa->get_config(child_sa), remote);
|
||||||
|
break;
|
||||||
|
case NARROW_RESPONDER_POST:
|
||||||
|
narrow_responder_post(child_sa->get_config(child_sa), local);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(unity_narrow_t, destroy, void,
|
||||||
|
private_unity_narrow_t *this)
|
||||||
|
{
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
unity_narrow_t *unity_narrow_create(unity_handler_t *handler)
|
||||||
|
{
|
||||||
|
private_unity_narrow_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.listener = {
|
||||||
|
.narrow = _narrow,
|
||||||
|
},
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.handler = handler,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 revosec AG
|
||||||
|
*
|
||||||
|
* 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 unity_narrow unity_narrow
|
||||||
|
* @{ @ingroup unity
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UNITY_NARROW_H_
|
||||||
|
#define UNITY_NARROW_H_
|
||||||
|
|
||||||
|
#include <bus/listeners/listener.h>
|
||||||
|
|
||||||
|
#include "unity_handler.h"
|
||||||
|
|
||||||
|
typedef struct unity_narrow_t unity_narrow_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener that narrows Quick Modes to the Unity Split-Include subnets.
|
||||||
|
*/
|
||||||
|
struct unity_narrow_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements listener_t.
|
||||||
|
*/
|
||||||
|
listener_t listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a unity_narrow_t.
|
||||||
|
*/
|
||||||
|
void (*destroy)(unity_narrow_t *this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a unity_narrow instance.
|
||||||
|
*/
|
||||||
|
unity_narrow_t *unity_narrow_create(unity_handler_t *handler);
|
||||||
|
|
||||||
|
#endif /** UNITY_NARROW_H_ @}*/
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 revosec AG
|
||||||
|
*
|
||||||
|
* 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 "unity_plugin.h"
|
||||||
|
#include "unity_handler.h"
|
||||||
|
#include "unity_narrow.h"
|
||||||
|
#include "unity_provider.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
#include <hydra.h>
|
||||||
|
|
||||||
|
typedef struct private_unity_plugin_t private_unity_plugin_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private data of unity_plugin
|
||||||
|
*/
|
||||||
|
struct private_unity_plugin_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public functions
|
||||||
|
*/
|
||||||
|
unity_plugin_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for UNITY configuration attributes
|
||||||
|
*/
|
||||||
|
unity_handler_t *handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responder Unity configuration attribute provider
|
||||||
|
*/
|
||||||
|
unity_provider_t *provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traffic selector narrower, for Unity Split-Includes
|
||||||
|
*/
|
||||||
|
unity_narrow_t *narrower;
|
||||||
|
};
|
||||||
|
|
||||||
|
METHOD(plugin_t, get_name, char*,
|
||||||
|
private_unity_plugin_t *this)
|
||||||
|
{
|
||||||
|
return "unity";
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(plugin_t, destroy, void,
|
||||||
|
private_unity_plugin_t *this)
|
||||||
|
{
|
||||||
|
charon->bus->remove_listener(charon->bus, &this->narrower->listener);
|
||||||
|
this->narrower->destroy(this->narrower);
|
||||||
|
hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
|
||||||
|
hydra->attributes->remove_provider(hydra->attributes,
|
||||||
|
&this->provider->provider);
|
||||||
|
this->handler->destroy(this->handler);
|
||||||
|
this->provider->destroy(this->provider);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* see header file
|
||||||
|
*/
|
||||||
|
plugin_t *unity_plugin_create()
|
||||||
|
{
|
||||||
|
private_unity_plugin_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.plugin = {
|
||||||
|
.get_name = _get_name,
|
||||||
|
.reload = (void*)return_false,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.handler = unity_handler_create(),
|
||||||
|
.provider = unity_provider_create(),
|
||||||
|
);
|
||||||
|
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
|
||||||
|
hydra->attributes->add_provider(hydra->attributes, &this->provider->provider);
|
||||||
|
|
||||||
|
this->narrower = unity_narrow_create(this->handler),
|
||||||
|
charon->bus->add_listener(charon->bus, &this->narrower->listener);
|
||||||
|
|
||||||
|
return &this->public.plugin;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 revosec AG
|
||||||
|
*
|
||||||
|
* 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 unity unity
|
||||||
|
* @ingroup cplugins
|
||||||
|
*
|
||||||
|
* @defgroup unity_plugin unity_plugin
|
||||||
|
* @{ @ingroup unity
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UNITY_PLUGIN_H_
|
||||||
|
#define UNITY_PLUGIN_H_
|
||||||
|
|
||||||
|
#include <plugins/plugin.h>
|
||||||
|
|
||||||
|
typedef struct unity_plugin_t unity_plugin_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IKEv1 Cisco Unity extension support.
|
||||||
|
*/
|
||||||
|
struct unity_plugin_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements plugin_t. interface.
|
||||||
|
*/
|
||||||
|
plugin_t plugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /** UNITY_PLUGIN_H_ @}*/
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 revosec AG
|
||||||
|
*
|
||||||
|
* 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 "unity_provider.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
|
||||||
|
typedef struct private_unity_provider_t private_unity_provider_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of an unity_provider_t object.
|
||||||
|
*/
|
||||||
|
struct private_unity_provider_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public unity_provider_t interface.
|
||||||
|
*/
|
||||||
|
unity_provider_t public;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute enumerator for traffic selector list
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** Implements enumerator_t */
|
||||||
|
enumerator_t public;
|
||||||
|
/** list of traffic selectors to enumerate */
|
||||||
|
linked_list_t *list;
|
||||||
|
/** currently enumerating subnet */
|
||||||
|
u_char subnet[4];
|
||||||
|
/** currently enumerating subnet mask */
|
||||||
|
u_char mask[4];
|
||||||
|
} attribute_enumerator_t;
|
||||||
|
|
||||||
|
METHOD(enumerator_t, attribute_enumerate, bool,
|
||||||
|
attribute_enumerator_t *this, configuration_attribute_type_t *type,
|
||||||
|
chunk_t *attr)
|
||||||
|
{
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
u_int8_t i, mask;
|
||||||
|
host_t *net;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (this->list->remove_first(this->list, (void**)&ts) != SUCCESS)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE &&
|
||||||
|
ts->to_subnet(ts, &net, &mask))
|
||||||
|
{
|
||||||
|
ts->destroy(ts);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ts->destroy(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(this->mask, 0, sizeof(this->mask));
|
||||||
|
for (i = 0; i < sizeof(this->mask); i++)
|
||||||
|
{
|
||||||
|
if (mask < 8)
|
||||||
|
{
|
||||||
|
this->mask[i] = 0xFF << (8 - mask);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->mask[i] = 0xFF;
|
||||||
|
mask -= 8;
|
||||||
|
}
|
||||||
|
memcpy(this->subnet, net->get_address(net).ptr, sizeof(this->subnet));
|
||||||
|
net->destroy(net);
|
||||||
|
|
||||||
|
*type = UNITY_SPLIT_INCLUDE;
|
||||||
|
*attr = chunk_create(this->subnet, sizeof(this->subnet) + sizeof(this->mask));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(enumerator_t, attribute_destroy, void,
|
||||||
|
attribute_enumerator_t *this)
|
||||||
|
{
|
||||||
|
this->list->destroy_offset(this->list, offsetof(traffic_selector_t, destroy));
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||||
|
private_unity_provider_t *this, linked_list_t *pools, identification_t *id,
|
||||||
|
linked_list_t *vips)
|
||||||
|
{
|
||||||
|
attribute_enumerator_t *attr_enum;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
linked_list_t *list, *current;
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
peer_cfg_t *peer_cfg;
|
||||||
|
child_cfg_t *child_cfg;
|
||||||
|
|
||||||
|
ike_sa = charon->bus->get_sa(charon->bus);
|
||||||
|
if (!ike_sa || ike_sa->get_version(ike_sa) != IKEV1 ||
|
||||||
|
!ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY) ||
|
||||||
|
!vips->get_count(vips))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = linked_list_create();
|
||||||
|
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
|
||||||
|
enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
|
||||||
|
while (enumerator->enumerate(enumerator, &child_cfg))
|
||||||
|
{
|
||||||
|
current = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
|
||||||
|
while (current->remove_first(current, (void**)&ts) == SUCCESS)
|
||||||
|
{
|
||||||
|
list->insert_last(list, ts);
|
||||||
|
}
|
||||||
|
current->destroy(current);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
if (list->get_count(list) == 0)
|
||||||
|
{
|
||||||
|
list->destroy(list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DBG1(DBG_CFG, "sending %N: %#R",
|
||||||
|
configuration_attribute_type_names, UNITY_SPLIT_INCLUDE, list);
|
||||||
|
|
||||||
|
INIT(attr_enum,
|
||||||
|
.public = {
|
||||||
|
.enumerate = (void*)_attribute_enumerate,
|
||||||
|
.destroy = _attribute_destroy,
|
||||||
|
},
|
||||||
|
.list = list,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &attr_enum->public;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(unity_provider_t, destroy, void,
|
||||||
|
private_unity_provider_t *this)
|
||||||
|
{
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
unity_provider_t *unity_provider_create()
|
||||||
|
{
|
||||||
|
private_unity_provider_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.provider = {
|
||||||
|
.acquire_address = (void*)return_null,
|
||||||
|
.release_address = (void*)return_false,
|
||||||
|
.create_attribute_enumerator = _create_attribute_enumerator,
|
||||||
|
},
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 revosec AG
|
||||||
|
*
|
||||||
|
* 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 unity_provider unity_provider
|
||||||
|
* @{ @ingroup unity
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UNITY_PROVIDER_H_
|
||||||
|
#define UNITY_PROVIDER_H_
|
||||||
|
|
||||||
|
typedef struct unity_provider_t unity_provider_t;
|
||||||
|
|
||||||
|
#include <attributes/attribute_provider.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cisco Unity extension attribute provider.
|
||||||
|
*/
|
||||||
|
struct unity_provider_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements attribute_provier_t interface.
|
||||||
|
*/
|
||||||
|
attribute_provider_t provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a unity_provider_t.
|
||||||
|
*/
|
||||||
|
void (*destroy)(unity_provider_t *this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a unity_provider instance.
|
||||||
|
*/
|
||||||
|
unity_provider_t *unity_provider_create();
|
||||||
|
|
||||||
|
#endif /** UNITY_PROVIDER_H_ @}*/
|
||||||
@@ -460,11 +460,6 @@ static traffic_selector_t* select_ts(private_quick_mode_t *this, bool local,
|
|||||||
hosts->destroy(hosts);
|
hosts->destroy(hosts);
|
||||||
if (list->get_first(list, (void**)&ts) == SUCCESS)
|
if (list->get_first(list, (void**)&ts) == SUCCESS)
|
||||||
{
|
{
|
||||||
if (this->initiator && list->get_count(list) > 1)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "configuration has more than one %s traffic selector,"
|
|
||||||
" using first only", local ? "local" : "remote");
|
|
||||||
}
|
|
||||||
ts = ts->clone(ts);
|
ts = ts->clone(ts);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -392,6 +392,11 @@ then
|
|||||||
echo -n " --enable-cisco-quirks" >> $INSTALLSHELL
|
echo -n " --enable-cisco-quirks" >> $INSTALLSHELL
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$USE_UNITY" = "yes" ]
|
||||||
|
then
|
||||||
|
echo -n " --enable-unity" >> $INSTALLSHELL
|
||||||
|
fi
|
||||||
|
|
||||||
echo "" >> $INSTALLSHELL
|
echo "" >> $INSTALLSHELL
|
||||||
echo "make -j" >> $INSTALLSHELL
|
echo "make -j" >> $INSTALLSHELL
|
||||||
echo "make install" >> $INSTALLSHELL
|
echo "make install" >> $INSTALLSHELL
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ USE_XAUTH_EAP="yes"
|
|||||||
USE_PKCS8="yes"
|
USE_PKCS8="yes"
|
||||||
USE_IFMAP="no"
|
USE_IFMAP="no"
|
||||||
USE_CISCO_QUIRKS="no"
|
USE_CISCO_QUIRKS="no"
|
||||||
|
USE_UNITY="yes"
|
||||||
|
|
||||||
# Gentoo linux root filesystem
|
# Gentoo linux root filesystem
|
||||||
ROOTFS=$UMLTESTDIR/gentoo-fs-20111212.tar.bz2
|
ROOTFS=$UMLTESTDIR/gentoo-fs-20111212.tar.bz2
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
The roadwarrior <b>carol</b> sets up a connection to gateway <b>moon</b>.
|
||||||
|
The authentication is based on <b>X.509 certificates</b>. <b>carol</b>
|
||||||
|
requests a virtual IP using <b>leftsourceip=%config</b> and indicates
|
||||||
|
support for the Cisco Unity extension. Gateway <b>moon</b> responds with
|
||||||
|
two Split-Include subnets configured in the <b>leftsubnet</b> definition and a
|
||||||
|
global Local-LAN exclude option defined in strongswan.conf.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*[email protected].*moon.strongswan.org::YES
|
||||||
|
moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*[email protected]::YES
|
||||||
|
carol::ipsec status 2> /dev/null::10.2.1.1/32 === 192.168.0.0/24 PASS::YES
|
||||||
|
carol::ipsec status 2> /dev/null::home.*10.2.1.1/32 === 10.1.0.0/16 10.2.1.0/24::YES
|
||||||
|
moon:: ipsec status 2> /dev/null::rw[{]1}.*10.1.0.0/16 10.2.1.0/24 === 10.2.1.1/32::YES
|
||||||
|
carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
|
||||||
|
moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
|
||||||
|
moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# /etc/ipsec.conf - strongSwan IPsec configuration file
|
||||||
|
|
||||||
|
config setup
|
||||||
|
|
||||||
|
conn %default
|
||||||
|
ikelifetime=60m
|
||||||
|
keylife=20m
|
||||||
|
rekeymargin=3m
|
||||||
|
keyingtries=1
|
||||||
|
keyexchange=ikev1
|
||||||
|
|
||||||
|
conn home
|
||||||
|
left=PH_IP_CAROL
|
||||||
|
leftcert=carolCert.pem
|
||||||
|
[email protected]
|
||||||
|
leftsourceip=%config
|
||||||
|
right=PH_IP_MOON
|
||||||
|
[email protected]
|
||||||
|
rightsubnet=0.0.0.0/0
|
||||||
|
auto=add
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
charon {
|
||||||
|
load = curl test-vectors aes des sha1 sha2 md5 pem pkcs1 pkcs8 gmp random nonce x509 revocation hmac xcbc ctr ccm gcm stroke kernel-netlink socket-default unity
|
||||||
|
cisco_unity = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
libstrongswan {
|
||||||
|
dh_exponent_ansi_x9_42 = no
|
||||||
|
integrity_test = yes
|
||||||
|
crypto_test {
|
||||||
|
on_add = yes
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# /etc/ipsec.conf - strongSwan IPsec configuration file
|
||||||
|
|
||||||
|
config setup
|
||||||
|
|
||||||
|
conn %default
|
||||||
|
ikelifetime=60m
|
||||||
|
keylife=20m
|
||||||
|
rekeymargin=3m
|
||||||
|
keyingtries=1
|
||||||
|
keyexchange=ikev1
|
||||||
|
|
||||||
|
conn rw
|
||||||
|
left=PH_IP_MOON
|
||||||
|
leftcert=moonCert.pem
|
||||||
|
[email protected]
|
||||||
|
leftsubnet=10.1.0.0/16,10.2.1.0/24
|
||||||
|
right=%any
|
||||||
|
rightsourceip=10.2.1.0/24
|
||||||
|
auto=add
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
charon {
|
||||||
|
load = curl test-vectors aes des sha1 sha2 md5 pem pkcs1 pkcs8 gmp random nonce x509 revocation hmac xcbc ctr ccm gcm stroke kernel-netlink socket-default attr unity
|
||||||
|
cisco_unity = yes
|
||||||
|
plugins {
|
||||||
|
attr {
|
||||||
|
split-exclude = 192.168.0.0/24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libstrongswan {
|
||||||
|
dh_exponent_ansi_x9_42 = no
|
||||||
|
integrity_test = yes
|
||||||
|
crypto_test {
|
||||||
|
on_add = yes
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
moon::ipsec stop
|
||||||
|
carol::ipsec stop
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
moon::ipsec start
|
||||||
|
carol::ipsec start
|
||||||
|
carol::sleep 1
|
||||||
|
carol::ipsec up home
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This configuration file provides information on the
|
||||||
|
# UML instances used for this test
|
||||||
|
|
||||||
|
# All UML instances that are required for this test
|
||||||
|
#
|
||||||
|
UMLHOSTS="alice moon carol winnetou"
|
||||||
|
|
||||||
|
# Corresponding block diagram
|
||||||
|
#
|
||||||
|
DIAGRAM="a-m-c.png"
|
||||||
|
|
||||||
|
# UML instances on which tcpdump is to be started
|
||||||
|
#
|
||||||
|
TCPDUMPHOSTS="moon"
|
||||||
|
|
||||||
|
# UML instances on which IPsec is started
|
||||||
|
# Used for IPsec logging purposes
|
||||||
|
#
|
||||||
|
IPSECHOSTS="moon carol"
|
||||||
Reference in New Issue
Block a user