From: Martin Willi Date: Fri, 30 Jan 2015 14:37:48 +0000 (+0100) Subject: narrowid: Add a plugin narrowing remote TS to authenticated IKE IPv4/IPv6 IDs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57a9fec3d1c4ff551b6176ed201b9e18e3c8b897;p=thirdparty%2Fstrongswan.git narrowid: Add a plugin narrowing remote TS to authenticated IKE IPv4/IPv6 IDs --- diff --git a/conf/Makefile.am b/conf/Makefile.am index 1d0cfde777..221b2a48cc 100644 --- a/conf/Makefile.am +++ b/conf/Makefile.am @@ -67,6 +67,7 @@ plugins = \ plugins/kernel-pfroute.opt \ plugins/load-tester.opt \ plugins/lookip.opt \ + plugins/narrowid.opt \ plugins/ntru.opt \ plugins/openssl.opt \ plugins/pkcs11.opt \ diff --git a/conf/plugins/narrowid.opt b/conf/plugins/narrowid.opt new file mode 100644 index 0000000000..967ac3e058 --- /dev/null +++ b/conf/plugins/narrowid.opt @@ -0,0 +1,7 @@ +charon.plugins.narrowid.configs = + Space separated list of CHILD_SA configurations to do narrowing for. + + For matching CHILD_SA configuration names, the plugin narrows the remote + traffic selectors to any succesfully authenticated IPv4 or IPv6 IKE + identity. Multiple configurations can be separated by spaces, no narrowing + is done if the option is not set. diff --git a/configure.ac b/configure.ac index 2d77652d11..cd732df6e1 100644 --- a/configure.ac +++ b/configure.ac @@ -194,6 +194,7 @@ ARG_ENABL_SET([eap-dynamic], [enable dynamic EAP proxy module.]) ARG_ENABL_SET([eap-radius], [enable RADIUS proxy authentication module.]) ARG_ENABL_SET([ext-auth], [enable plugin calling an external authorization script.]) ARG_ENABL_SET([ipseckey], [enable IPSECKEY authentication plugin.]) +ARG_ENABL_SET([narrowid], [enables plugin narrowing remote traffic selectors to authenticated IDs.]) ARG_ENABL_SET([keychain], [enables OS X Keychain Services credential set.]) ARG_ENABL_SET([pkcs11], [enables the PKCS11 token support plugin.]) ARG_DISBL_SET([revocation], [disable X509 CRL/OCSP revocation check plugin.]) @@ -1336,6 +1337,7 @@ ADD_PLUGIN([radattr], [c charon]) ADD_PLUGIN([maemo], [c charon]) ADD_PLUGIN([uci], [c charon]) ADD_PLUGIN([addrblock], [c charon]) +ADD_PLUGIN([narrowid], [c charon]) ADD_PLUGIN([unity], [c charon]) AC_SUBST(charon_plugins) @@ -1492,6 +1494,7 @@ AM_CONDITIONAL(USE_CONNMARK, test x$connmark = xtrue) AM_CONDITIONAL(USE_FORECAST, test x$forecast = xtrue) AM_CONDITIONAL(USE_FARP, test x$farp = xtrue) AM_CONDITIONAL(USE_ADDRBLOCK, test x$addrblock = xtrue) +AM_CONDITIONAL(USE_NARROWID, test x$narrowid = xtrue) AM_CONDITIONAL(USE_UNITY, test x$unity = xtrue) AM_CONDITIONAL(USE_RESOLVE, test x$resolve = xtrue) AM_CONDITIONAL(USE_ATTR, test x$attr = xtrue) @@ -1735,6 +1738,7 @@ AC_CONFIG_FILES([ src/libcharon/plugins/medsrv/Makefile src/libcharon/plugins/medcli/Makefile src/libcharon/plugins/addrblock/Makefile + src/libcharon/plugins/narrowid/Makefile src/libcharon/plugins/unity/Makefile src/libcharon/plugins/uci/Makefile src/libcharon/plugins/ha/Makefile diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index 7d6e86bd54..89075788dc 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -608,6 +608,13 @@ if MONOLITHIC endif endif +if USE_NARROWID + SUBDIRS += plugins/narrowid +if MONOLITHIC + libcharon_la_LIBADD += plugins/narrowid/libstrongswan-narrowid.la +endif +endif + if USE_UNITY SUBDIRS += plugins/unity if MONOLITHIC diff --git a/src/libcharon/plugins/narrowid/Makefile.am b/src/libcharon/plugins/narrowid/Makefile.am new file mode 100644 index 0000000000..b8d478978e --- /dev/null +++ b/src/libcharon/plugins/narrowid/Makefile.am @@ -0,0 +1,19 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-narrowid.la +else +plugin_LTLIBRARIES = libstrongswan-narrowid.la +endif + +libstrongswan_narrowid_la_SOURCES = \ + narrowid_narrow.h narrowid_narrow.c \ + narrowid_plugin.h narrowid_plugin.c + +libstrongswan_narrowid_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/narrowid/narrowid_narrow.c b/src/libcharon/plugins/narrowid/narrowid_narrow.c new file mode 100644 index 0000000000..3efb66a611 --- /dev/null +++ b/src/libcharon/plugins/narrowid/narrowid_narrow.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2015 Martin Willi + * Copyright (C) 2015 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 . + * + * 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 "narrowid_narrow.h" + +#include + +typedef struct private_narrowid_narrow_t private_narrowid_narrow_t; + +/** + * Private data of an narrowid_narrow_t object. + */ +struct private_narrowid_narrow_t { + + /** + * Public narrowid_narrow_t interface. + */ + narrowid_narrow_t public; + + /** + * Space separated list of configs we do narrowing for + */ + char *configs; +}; + +/** + * Narrow list of traffic selectors to authenticated remote identities + */ +static void narrow_to_ids(private_narrowid_narrow_t *this, + ike_sa_t *ike_sa, linked_list_t *list) +{ + traffic_selector_t *current, *ts, *subset; + enumerator_t *enumerator; + identification_t *id; + linked_list_t *orig; + auth_cfg_t *auth; + ts_type_t type; + + orig = linked_list_create(); + + while (list->remove_first(list, (void**)¤t) == SUCCESS) + { + orig->insert_last(orig, current); + } + + while (orig->remove_first(orig, (void**)¤t) == SUCCESS) + { + enumerator = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE); + while (enumerator->enumerate(enumerator, &auth)) + { + id = auth->get(auth, AUTH_RULE_IDENTITY); + if (id) + { + switch (id->get_type(id)) + { + case ID_IPV4_ADDR: + type = TS_IPV4_ADDR_RANGE; + break; + case ID_IPV6_ADDR: + type = TS_IPV6_ADDR_RANGE; + break; + default: + continue; + } + ts = traffic_selector_create_from_bytes(0, type, + id->get_encoding(id), 0, id->get_encoding(id), 65535); + if (ts) + { + subset = current->get_subset(current, ts); + if (subset) + { + list->insert_last(list, subset); + } + ts->destroy(ts); + } + } + } + enumerator->destroy(enumerator); + + current->destroy(current); + } + + orig->destroy(orig); + + if (list->get_count(list)) + { + DBG1(DBG_CFG, "narrowed selectors to peer identities: %#R", list); + } + else + { + DBG1(DBG_CFG, "narrowing selectors to peer identites gives empty set"); + } +} + +/** + * Check if we should do narrowing for the given CHILD_SA config + */ +static bool do_narrowing_for(private_narrowid_narrow_t *this, char *config) +{ + enumerator_t *enumerator; + char *token; + bool found = FALSE; + + if (!this->configs) + { /* none by default */ + return FALSE; + } + + enumerator = enumerator_create_token(this->configs, " ", ""); + while (enumerator->enumerate(enumerator, &token)) + { + if (streq(token, config)) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + return found; +} + +METHOD(listener_t, narrow, bool, + private_narrowid_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) +{ + switch (type) + { + case NARROW_RESPONDER: + case NARROW_INITIATOR_POST_AUTH: + case NARROW_INITIATOR_POST_NOAUTH: + if (do_narrowing_for(this, child_sa->get_name(child_sa))) + { + narrow_to_ids(this, ike_sa, remote); + } + break; + default: + break; + } + return TRUE; +} + +METHOD(narrowid_narrow_t, destroy, void, + private_narrowid_narrow_t *this) +{ + free(this); +} + +/** + * See header + */ +narrowid_narrow_t *narrowid_narrow_create() +{ + private_narrowid_narrow_t *this; + + INIT(this, + .public = { + .listener = { + .narrow = _narrow, + }, + .destroy = _destroy, + }, + .configs = lib->settings->get_str(lib->settings, + "%s.plugins.narrowid.configs", NULL, lib->ns), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/narrowid/narrowid_narrow.h b/src/libcharon/plugins/narrowid/narrowid_narrow.h new file mode 100644 index 0000000000..9ac11956b6 --- /dev/null +++ b/src/libcharon/plugins/narrowid/narrowid_narrow.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 Martin Willi + * Copyright (C) 2015 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 . + * + * 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 narrowid_narrow narrowid_narrow + * @{ @ingroup narrowid + */ + +#ifndef NARROWID_NARROW_H_ +#define NARROWID_NARROW_H_ + +#include + +typedef struct narrowid_narrow_t narrowid_narrow_t; + +/** + * Listener narrowing remote traffic selectors to authenticated IKE IDs. + */ +struct narrowid_narrow_t { + + /** + * Implements listener_t. + */ + listener_t listener; + + /** + * Destroy a narrowid_narrow_t. + */ + void (*destroy)(narrowid_narrow_t *this); +}; + +/** + * Create a narrowid_narrow instance. + */ +narrowid_narrow_t *narrowid_narrow_create(); + +#endif /** NARROWID_NARROW_H_ @}*/ diff --git a/src/libcharon/plugins/narrowid/narrowid_plugin.c b/src/libcharon/plugins/narrowid/narrowid_plugin.c new file mode 100644 index 0000000000..14d120766f --- /dev/null +++ b/src/libcharon/plugins/narrowid/narrowid_plugin.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2015 Martin Willi + * Copyright (C) 2015 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 . + * + * 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 "narrowid_plugin.h" +#include "narrowid_narrow.h" + +#include + +typedef struct private_narrowid_plugin_t private_narrowid_plugin_t; + +/** + * private data of narrowid_plugin + */ +struct private_narrowid_plugin_t { + + /** + * public functions + */ + narrowid_plugin_t public; + + /** + * Listener to narrow TS list + */ + narrowid_narrow_t *narrower; +}; + +METHOD(plugin_t, get_name, char*, + private_narrowid_plugin_t *this) +{ + return "narrowid"; +} + +/** + * Register listener + */ +static bool plugin_cb(private_narrowid_plugin_t *this, + plugin_feature_t *feature, bool reg, void *cb_data) +{ + if (reg) + { + charon->bus->add_listener(charon->bus, &this->narrower->listener); + } + else + { + charon->bus->remove_listener(charon->bus, &this->narrower->listener); + } + return TRUE; +} + +METHOD(plugin_t, get_features, int, + private_narrowid_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL), + PLUGIN_PROVIDE(CUSTOM, "narrowid"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_narrowid_plugin_t *this) +{ + this->narrower->destroy(this->narrower); + free(this); +} + +/* + * see header file + */ +plugin_t *narrowid_plugin_create() +{ + private_narrowid_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + .narrower = narrowid_narrow_create(), + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/narrowid/narrowid_plugin.h b/src/libcharon/plugins/narrowid/narrowid_plugin.h new file mode 100644 index 0000000000..380d8e4c21 --- /dev/null +++ b/src/libcharon/plugins/narrowid/narrowid_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 Martin Willi + * Copyright (C) 2015 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 . + * + * 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 narrowid narrowid + * @ingroup cplugins + * + * @defgroup narrowid_plugin narrowid_plugin + * @{ @ingroup narrowid + */ + +#ifndef NARROWID_PLUGIN_H_ +#define NARROWID_PLUGIN_H_ + +#include + +typedef struct narrowid_plugin_t narrowid_plugin_t; + +/** + * Plugin narrowing remote traffic selectors to its authenticated IKE IDs. + */ +struct narrowid_plugin_t { + + /** + * Implements plugin_t. interface. + */ + plugin_t plugin; +}; + +#endif /** NARROWID_PLUGIN_H_ @}*/