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/plugins/eap_tnc/eap_tnc.c | |
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/plugins/eap_tnc/eap_tnc.c')
-rw-r--r-- | src/libcharon/plugins/eap_tnc/eap_tnc.c | 156 |
1 files changed, 68 insertions, 88 deletions
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); +} |