diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2010-09-08 11:01:47 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2010-09-08 11:01:53 +0200 |
commit | d2b1d4378e298b76e87ee9165923d675412935ab (patch) | |
tree | 00b0da8c200ad69c64ebaf3728f1c2a6051b7f98 /src/libcharon | |
parent | 7b3c01845f639b3c845dbcb5607eef15e43036c8 (diff) | |
download | strongswan-d2b1d4378e298b76e87ee9165923d675412935ab.tar.bz2 strongswan-d2b1d4378e298b76e87ee9165923d675412935ab.tar.xz |
generalized tls_eap_t to support EAP_TNC wrapping the TNC_IF_TNCCS protocol
Diffstat (limited to 'src/libcharon')
-rw-r--r-- | src/libcharon/plugins/eap_tls/eap_tls.c | 10 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_tnc/Makefile.am | 6 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_tnc/eap_tnc.c | 156 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_tnc/tnc_if_tnccs.c | 125 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_tnc/tnc_if_tnccs.h | 37 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_ttls/eap_ttls.c | 10 |
6 files changed, 250 insertions, 94 deletions
diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c index 09b46ffd9..2980d74b2 100644 --- a/src/libcharon/plugins/eap_tls/eap_tls.c +++ b/src/libcharon/plugins/eap_tls/eap_tls.c @@ -123,6 +123,7 @@ static eap_tls_t *eap_tls_create(identification_t *server, { private_eap_tls_t *this; size_t frag_size; + tls_t *tls; INIT(this, .public = { @@ -139,8 +140,13 @@ static eap_tls_t *eap_tls_create(identification_t *server, frag_size = lib->settings->get_int(lib->settings, "charon.plugins.eap-tls.fragment_size", MAX_FRAGMENT_LEN); - this->tls_eap = tls_eap_create(EAP_TLS, is_server, server, peer, - NULL, frag_size); + tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL); + if (!tls) + { + free(this); + return NULL; + } + this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size); if (!this->tls_eap) { free(this); diff --git a/src/libcharon/plugins/eap_tnc/Makefile.am b/src/libcharon/plugins/eap_tnc/Makefile.am index ad77155b0..004a3eb6b 100644 --- a/src/libcharon/plugins/eap_tnc/Makefile.am +++ b/src/libcharon/plugins/eap_tnc/Makefile.am @@ -1,6 +1,6 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls AM_CFLAGS = -rdynamic @@ -8,9 +8,11 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-tnc.la else plugin_LTLIBRARIES = libstrongswan-eap-tnc.la +libstrongswan_eap_tnc_la_LIBADD = $(top_builddir)/src/libtls/libtls.la endif libstrongswan_eap_tnc_la_SOURCES = \ - eap_tnc_plugin.h eap_tnc_plugin.c eap_tnc.h eap_tnc.c + eap_tnc_plugin.h eap_tnc_plugin.c eap_tnc.h eap_tnc.c \ + tnc_if_tnccs.h tnc_if_tnccs.c libstrongswan_eap_tnc_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c index 6208774ff..432d5efbd 100644 --- a/src/libcharon/plugins/eap_tnc/eap_tnc.c +++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c @@ -14,6 +14,9 @@ */ #include "eap_tnc.h" +#include "tnc_if_tnccs.h" + +#include <tls_eap.h> #include <daemon.h> #include <library.h> @@ -31,84 +34,56 @@ struct private_eap_tnc_t { eap_tnc_t public; /** - * ID of the server + * Number of EAP-TNC messages processed so far */ - identification_t *server; + int processed; /** - * ID of the peer + * TLS stack, wrapped by EAP helper */ - identification_t *peer; + tls_eap_t *tls_eap; }; -/** - * Flags of an EAP-TNC message - */ -typedef enum { - EAP_TNC_LENGTH = (1<<7), - EAP_TNC_MORE_FRAGS = (1<<6), - EAP_TNC_START = (1<<5), - EAP_TNC_DH = (1<<4), - EAP_TNC_VERSION = 0x07 -} eap_tnc_flags_t; -/** - * EAP-TNC packet format - */ -typedef struct __attribute__((packed)) { - u_int8_t code; - u_int8_t identifier; - u_int16_t length; - u_int8_t type; - u_int8_t flags; -} eap_tnc_packet_t; - -METHOD(eap_method_t, initiate_peer, status_t, - private_eap_tnc_t *this, eap_payload_t **out) -{ - /* peer never initiates */ - return FAILED; -} +/** Maximum number of EAP-TNC messages/fragments allowed */ +#define MAX_MESSAGE_COUNT 2 +/** Default size of a EAP-TNC fragment */ +#define MAX_FRAGMENT_LEN 50000 -METHOD(eap_method_t, initiate_server, status_t, +METHOD(eap_method_t, initiate, status_t, private_eap_tnc_t *this, eap_payload_t **out) { - return NEED_MORE; -} - -METHOD(eap_method_t, process_peer, status_t, - private_eap_tnc_t *this, eap_payload_t *in, eap_payload_t **out) -{ - eap_tnc_packet_t *pkt; chunk_t data; - data = in->get_data(in); - - pkt = (eap_tnc_packet_t*)data.ptr; - if (data.len < sizeof(eap_tnc_packet_t) || - untoh16(&pkt->length) != data.len) + if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE) { - DBG1(DBG_IKE, "invalid EAP-TNC packet length"); - return FAILED; + *out = eap_payload_create_data(data); + free(data.ptr); + return NEED_MORE; } - if (pkt->flags & EAP_TNC_START) - { - DBG1(DBG_IKE, "EAP-TNC version is v%u", pkt->flags & EAP_TNC_VERSION); - } - *out = eap_payload_create_nak(in->get_identifier(in)); - - return NEED_MORE; + return FAILED; } -METHOD(eap_method_t, process_server, status_t, +METHOD(eap_method_t, process, status_t, private_eap_tnc_t *this, eap_payload_t *in, eap_payload_t **out) { + status_t status; chunk_t data; + if (++this->processed > MAX_MESSAGE_COUNT) + { + DBG1(DBG_IKE, "EAP-TNC packet count exceeded (%d > %d)", + this->processed, MAX_MESSAGE_COUNT); + return FAILED; + } data = in->get_data(in); - DBG2(DBG_IKE, "received EAP-TNC data: %B", &data); - - return SUCCESS; + status = this->tls_eap->process(this->tls_eap, data, &data); + if (status == NEED_MORE) + { + *out = eap_payload_create_data(data); + free(data.ptr); + } + return status; } METHOD(eap_method_t, get_type, eap_type_t, @@ -121,6 +96,11 @@ METHOD(eap_method_t, get_type, eap_type_t, METHOD(eap_method_t, get_msk, status_t, private_eap_tnc_t *this, chunk_t *msk) { + *msk = this->tls_eap->get_msk(this->tls_eap); + if (msk->len) + { + return SUCCESS; + } return FAILED; } @@ -133,58 +113,58 @@ METHOD(eap_method_t, is_mutual, bool, METHOD(eap_method_t, destroy, void, private_eap_tnc_t *this) { - this->peer->destroy(this->peer); - this->server->destroy(this->server); + this->tls_eap->destroy(this->tls_eap); free(this); } -/* - * See header +/** + * Generic private constructor */ -eap_tnc_t *eap_tnc_create_server(identification_t *server, identification_t *peer) +static eap_tnc_t *eap_tnc_create(identification_t *server, + identification_t *peer, bool is_server) { private_eap_tnc_t *this; + size_t frag_size; + tls_t *tnc_if_tnccs; INIT(this, .public = { .eap_method = { - .initiate = _initiate_server, - .process = _process_server, + .initiate = _initiate, + .process = _process, .get_type = _get_type, .is_mutual = _is_mutual, .get_msk = _get_msk, .destroy = _destroy, }, }, - .peer = peer->clone(peer), - .server = server->clone(server), ); + frag_size = lib->settings->get_int(lib->settings, + "charon.plugins.eap-tnc.fragment_size", MAX_FRAGMENT_LEN); + tnc_if_tnccs = tnc_if_tnccs_create(is_server, TLS_PURPOSE_EAP_TNC); + if (!tnc_if_tnccs) + { + free(this); + return NULL; + } + this->tls_eap = tls_eap_create(EAP_TNC, tnc_if_tnccs, frag_size); + if (!this->tls_eap) + { + free(this); + return NULL; + } return &this->public; } -/* - * See header - */ -eap_tnc_t *eap_tnc_create_peer(identification_t *server, identification_t *peer) +eap_tnc_t *eap_tnc_create_server(identification_t *server, + identification_t *peer) { - private_eap_tnc_t *this; - - INIT(this, - .public = { - .eap_method = { - .initiate = _initiate_peer, - .process = _process_peer, - .get_type = _get_type, - .is_mutual = _is_mutual, - .get_msk = _get_msk, - .destroy = _destroy, - }, - }, - .peer = peer->clone(peer), - .server = server->clone(server), - ); - - return &this->public; + return eap_tnc_create(server, peer, TRUE); } +eap_tnc_t *eap_tnc_create_peer(identification_t *server, + identification_t *peer) +{ + return eap_tnc_create(server, peer, FALSE); +} diff --git a/src/libcharon/plugins/eap_tnc/tnc_if_tnccs.c b/src/libcharon/plugins/eap_tnc/tnc_if_tnccs.c new file mode 100644 index 000000000..fc3500c7b --- /dev/null +++ b/src/libcharon/plugins/eap_tnc/tnc_if_tnccs.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 HSR 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 "tnc_if_tnccs.h" + +#include <debug.h> + +typedef struct private_tnc_if_tnccs_t private_tnc_if_tnccs_t; + +/** + * Private data of a tnc_if_tnccs_t object. + */ +struct private_tnc_if_tnccs_t { + + /** + * Public tls_t interface. + */ + tls_t public; + + /** + * Role this TNC IF-TNCCS stack acts as. + */ + bool is_server; + + /** + * TLS stack purpose, as given to constructor + */ + tls_purpose_t purpose; +}; + +METHOD(tls_t, process, status_t, + private_tnc_if_tnccs_t *this, void *buf, size_t buflen) +{ + /* TODO */ + return NEED_MORE; +} + +METHOD(tls_t, build, status_t, + private_tnc_if_tnccs_t *this, void *buf, size_t *buflen, size_t *msglen) +{ + char output[] = "Hello World"; + size_t len = strlen(output); + + /* TODO */ + *buflen = len; + *msglen = len; + memcpy(buf, output, len); + + return ALREADY_DONE; +} + +METHOD(tls_t, is_server, bool, + private_tnc_if_tnccs_t *this) +{ + return this->is_server; +} + +METHOD(tls_t, get_purpose, tls_purpose_t, + private_tnc_if_tnccs_t *this) +{ + return this->purpose; +} + +METHOD(tls_t, is_complete, bool, + private_tnc_if_tnccs_t *this) +{ + /* TODO */ + return TRUE; +} + +METHOD(tls_t, get_eap_msk, chunk_t, + private_tnc_if_tnccs_t *this) +{ + return chunk_empty; +} + +METHOD(tls_t, destroy, void, + private_tnc_if_tnccs_t *this) +{ + free(this); +} + +/** + * See header + */ +tls_t *tnc_if_tnccs_create(bool is_server, tls_purpose_t purpose) +{ + private_tnc_if_tnccs_t *this; + + switch (purpose) + { + case TLS_PURPOSE_EAP_TNC: + break; + default: + return NULL; + } + + INIT(this, + .public = { + .process = _process, + .build = _build, + .is_server = _is_server, + .get_purpose = _get_purpose, + .is_complete = _is_complete, + .get_eap_msk = _get_eap_msk, + .destroy = _destroy, + }, + .is_server = is_server, + .purpose = purpose, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/eap_tnc/tnc_if_tnccs.h b/src/libcharon/plugins/eap_tnc/tnc_if_tnccs.h new file mode 100644 index 000000000..5c0d51c9a --- /dev/null +++ b/src/libcharon/plugins/eap_tnc/tnc_if_tnccs.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * 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 tnc_if_tnccs tnc_if_tnccs + * @{ @ingroup tnc_if_tnccs + */ + +#ifndef TNC_IF_TNCCS_H_ +#define TNC_IF_TNCCS_H_ + +#include <library.h> + +#include <tls.h> + +/** + * Create an instance of the TNC IF-TNCCS 1.1 protocol handler. + * + * @param is_server TRUE to act as server, FALSE for client + * @param purpose purpose this TLS stack instance is used for + * @return TNC_IF_TNCCS stack + */ +tls_t *tnc_if_tnccs_create(bool is_server, tls_purpose_t purpose); + +#endif /** TNC_IF_TNCCS_H_ @}*/ diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c index d450c23d7..6b52acc56 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c @@ -126,6 +126,7 @@ static eap_ttls_t *eap_ttls_create(identification_t *server, { private_eap_ttls_t *this; size_t frag_size; + tls_t *tls; INIT(this, .public = { @@ -146,8 +147,13 @@ static eap_ttls_t *eap_ttls_create(identification_t *server, } frag_size = lib->settings->get_int(lib->settings, "charon.plugins.eap-ttls.fragment_size", MAX_FRAGMENT_LEN); - this->tls_eap = tls_eap_create(EAP_TTLS, is_server, server, peer, - application, frag_size); + tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application); + if (!tls) + { + free(this); + return NULL; + } + this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size); if (!this->tls_eap) { application->destroy(application); |