diff options
Diffstat (limited to 'src/libcharon/plugins/xauth_generic')
5 files changed, 413 insertions, 0 deletions
diff --git a/src/libcharon/plugins/xauth_generic/Makefile.am b/src/libcharon/plugins/xauth_generic/Makefile.am new file mode 100644 index 000000000..0f25e74a2 --- /dev/null +++ b/src/libcharon/plugins/xauth_generic/Makefile.am @@ -0,0 +1,17 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-xauth-generic.la +else +plugin_LTLIBRARIES = libstrongswan-xauth-generic.la +endif + +libstrongswan_xauth_generic_la_SOURCES = \ + xauth_generic_plugin.h xauth_generic_plugin.c \ + xauth_generic.h xauth_generic.c + +libstrongswan_xauth_generic_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic.c b/src/libcharon/plugins/xauth_generic/xauth_generic.c new file mode 100644 index 000000000..f0e675ac0 --- /dev/null +++ b/src/libcharon/plugins/xauth_generic/xauth_generic.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 "xauth_generic.h" + +#include <daemon.h> +#include <library.h> + +typedef struct private_xauth_generic_t private_xauth_generic_t; + +/** + * Private data of an xauth_generic_t object. + */ +struct private_xauth_generic_t { + + /** + * Public interface. + */ + xauth_generic_t public; + + /** + * ID of the server + */ + identification_t *server; + + /** + * ID of the peer + */ + identification_t *peer; + +}; + +METHOD(xauth_method_t, initiate_peer, status_t, + private_xauth_generic_t *this, cp_payload_t **out) +{ + /* peer never initiates */ + return FAILED; +} + +METHOD(xauth_method_t, process_peer, status_t, + private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out) +{ + shared_key_t *shared; + cp_payload_t *cp; + chunk_t user, pass; + + shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, this->peer, + this->server); + if (!shared) + { + DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'", this->peer, + this->server); + return FAILED; + } + + user = this->peer->get_encoding(this->peer); + pass = shared->get_key(shared); + + cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REPLY); + cp->add_attribute(cp, configuration_attribute_create_chunk( + CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, user)); + cp->add_attribute(cp, configuration_attribute_create_chunk( + CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, pass)); + shared->destroy(shared); + *out = cp; + return NEED_MORE; +} + +METHOD(xauth_method_t, initiate_server, status_t, + private_xauth_generic_t *this, cp_payload_t **out) +{ + cp_payload_t *cp; + + cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST); + cp->add_attribute(cp, configuration_attribute_create_chunk( + CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, chunk_empty)); + cp->add_attribute(cp, configuration_attribute_create_chunk( + CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, chunk_empty)); + *out = cp; + return NEED_MORE; +} + +METHOD(xauth_method_t, process_server, status_t, + private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out) +{ + configuration_attribute_t *attr; + enumerator_t *enumerator; + shared_key_t *shared; + identification_t *id; + chunk_t user = chunk_empty, pass = chunk_empty; + status_t status = FAILED; + int tried = 0; + + enumerator = in->create_attribute_enumerator(in); + while (enumerator->enumerate(enumerator, &attr)) + { + switch (attr->get_type(attr)) + { + case XAUTH_USER_NAME: + user = attr->get_chunk(attr); + break; + case XAUTH_USER_PASSWORD: + pass = attr->get_chunk(attr); + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + if (!user.ptr || !pass.ptr) + { + DBG1(DBG_IKE, "peer did not respond to our XAuth request"); + return FAILED; + } + if (user.len) + { + id = identification_create_from_data(user); + if (!id) + { + DBG1(DBG_IKE, "failed to parse provided XAuth username"); + return FAILED; + } + this->peer->destroy(this->peer); + this->peer = id; + } + if (pass.len && pass.ptr[pass.len - 1] == 0) + { /* fix null-terminated passwords (Android etc.) */ + pass.len -= 1; + } + + enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, + SHARED_EAP, this->server, this->peer); + while (enumerator->enumerate(enumerator, &shared, NULL, NULL)) + { + if (chunk_equals(shared->get_key(shared), pass)) + { + status = SUCCESS; + break; + } + tried++; + } + enumerator->destroy(enumerator); + if (status != SUCCESS) + { + if (!tried) + { + DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'", + this->server, this->peer); + } + else + { + DBG1(DBG_IKE, "none of %d found XAuth secrets for '%Y' - '%Y' " + "matched", tried, this->server, this->peer); + } + } + return status; +} + +METHOD(xauth_method_t, get_identity, identification_t*, + private_xauth_generic_t *this) +{ + return this->peer; +} + +METHOD(xauth_method_t, destroy, void, + private_xauth_generic_t *this) +{ + this->server->destroy(this->server); + this->peer->destroy(this->peer); + free(this); +} + +/* + * Described in header. + */ +xauth_generic_t *xauth_generic_create_peer(identification_t *server, + identification_t *peer) +{ + private_xauth_generic_t *this; + + INIT(this, + .public = { + .xauth_method = { + .initiate = _initiate_peer, + .process = _process_peer, + .get_identity = _get_identity, + .destroy = _destroy, + }, + }, + .server = server->clone(server), + .peer = peer->clone(peer), + ); + + return &this->public; +} + +/* + * Described in header. + */ +xauth_generic_t *xauth_generic_create_server(identification_t *server, + identification_t *peer) +{ + private_xauth_generic_t *this; + + INIT(this, + .public = { + .xauth_method = { + .initiate = _initiate_server, + .process = _process_server, + .get_identity = _get_identity, + .destroy = _destroy, + }, + }, + .server = server->clone(server), + .peer = peer->clone(peer), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic.h b/src/libcharon/plugins/xauth_generic/xauth_generic.h new file mode 100644 index 000000000..5773589cb --- /dev/null +++ b/src/libcharon/plugins/xauth_generic/xauth_generic.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 xauth_generic_i xauth_generic + * @{ @ingroup xauth_generic + */ + +#ifndef XAUTH_GENERIC_H_ +#define XAUTH_GENERIC_H_ + +typedef struct xauth_generic_t xauth_generic_t; + +#include <sa/xauth/xauth_method.h> + +/** + * Implementation of the xauth_method_t interface using cleartext secrets + * from any credential set. + */ +struct xauth_generic_t { + + /** + * Implemented xauth_method_t interface. + */ + xauth_method_t xauth_method; +}; + +/** + * Creates the generic XAuth method, acting as server. + * + * @param server ID of the XAuth server + * @param peer ID of the XAuth client + * @return xauth_generic_t object + */ +xauth_generic_t *xauth_generic_create_server(identification_t *server, + identification_t *peer); + +/** + * Creates the generic XAuth method, acting as peer. + * + * @param server ID of the XAuth server + * @param peer ID of the XAuth client + * @return xauth_generic_t object + */ +xauth_generic_t *xauth_generic_create_peer(identification_t *server, + identification_t *peer); + +#endif /** XAUTH_GENERIC_H_ @}*/ diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic_plugin.c b/src/libcharon/plugins/xauth_generic/xauth_generic_plugin.c new file mode 100644 index 000000000..a87084e20 --- /dev/null +++ b/src/libcharon/plugins/xauth_generic/xauth_generic_plugin.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 "xauth_generic_plugin.h" +#include "xauth_generic.h" + +#include <daemon.h> + +METHOD(plugin_t, get_name, char*, + xauth_generic_plugin_t *this) +{ + return "xauth-generic"; +} + +METHOD(plugin_t, get_features, int, + xauth_generic_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(xauth_method_register, xauth_generic_create_server), + PLUGIN_PROVIDE(XAUTH_SERVER, "generic"), + PLUGIN_CALLBACK(xauth_method_register, xauth_generic_create_peer), + PLUGIN_PROVIDE(XAUTH_PEER, "generic"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + xauth_generic_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *xauth_generic_plugin_create() +{ + xauth_generic_plugin_t *this; + + INIT(this, + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + ); + + return &this->plugin; +} diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic_plugin.h b/src/libcharon/plugins/xauth_generic/xauth_generic_plugin.h new file mode 100644 index 000000000..426f806a7 --- /dev/null +++ b/src/libcharon/plugins/xauth_generic/xauth_generic_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 xauth_generic xauth_generic + * @ingroup cplugins + * + * @defgroup xauth_generic_plugin xauth_generic_plugin + * @{ @ingroup xauth_generic + */ + +#ifndef XAUTH_GENERIC_PLUGIN_H_ +#define XAUTH_GENERIC_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct xauth_generic_plugin_t xauth_generic_plugin_t; + +/** + * XAuth generic plugin using secrets defined in ipsec.secrets. + */ +struct xauth_generic_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** XAUTH_GENERIC_PLUGIN_H_ @}*/ |