Implemented PT-EAP protocol (RFC 7171)

This commit is contained in:
Andreas Steffen
2014-05-12 06:59:21 +02:00
parent ab21875f50
commit 8d59090349
56 changed files with 337 additions and 236 deletions
+37 -17
View File
@@ -46,6 +46,11 @@ struct private_eap_tnc_t {
*/
eap_tnc_t public;
/**
* Inner EAP authentication type
*/
eap_type_t type;
/**
* Outer EAP authentication type
*/
@@ -124,7 +129,7 @@ METHOD(eap_method_t, initiate, status_t,
private_eap_tnc_t *this, eap_payload_t **out)
{
chunk_t data;
u_int32_t auth_type;
uint32_t auth_type;
/* Determine TNC Client Authentication Type */
switch (this->auth_type)
@@ -175,10 +180,10 @@ METHOD(eap_method_t, process, status_t,
}
METHOD(eap_method_t, get_type, eap_type_t,
private_eap_tnc_t *this, u_int32_t *vendor)
private_eap_tnc_t *this, uint32_t *vendor)
{
*vendor = 0;
return EAP_TNC;
return this->type;
}
METHOD(eap_method_t, get_msk, status_t,
@@ -192,14 +197,14 @@ METHOD(eap_method_t, get_msk, status_t,
return FAILED;
}
METHOD(eap_method_t, get_identifier, u_int8_t,
METHOD(eap_method_t, get_identifier, uint8_t,
private_eap_tnc_t *this)
{
return this->tls_eap->get_identifier(this->tls_eap);
}
METHOD(eap_method_t, set_identifier, void,
private_eap_tnc_t *this, u_int8_t identifier)
private_eap_tnc_t *this, uint8_t identifier)
{
this->tls_eap->set_identifier(this->tls_eap, identifier);
}
@@ -214,7 +219,7 @@ METHOD(eap_method_t, destroy, void,
private_eap_tnc_t *this)
{
chunk_t pdp_server;
u_int16_t pdp_port;
uint16_t pdp_port;
tls_t *tls;
pdp_server = this->tnccs->get_pdp_server(this->tnccs, &pdp_port);
@@ -245,13 +250,14 @@ METHOD(eap_inner_method_t, set_auth_type, void,
* Generic private constructor
*/
static eap_tnc_t *eap_tnc_create(identification_t *server,
identification_t *peer, bool is_server)
identification_t *peer, bool is_server,
eap_type_t type)
{
private_eap_tnc_t *this;
int max_msg_count;
char* protocol;
tnccs_t *tnccs;
tnccs_type_t type;
tnccs_type_t tnccs_type;
INIT(this,
.public = {
@@ -270,24 +276,25 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
.set_auth_type = _set_auth_type,
},
},
.type = type,
);
max_msg_count = lib->settings->get_int(lib->settings,
"%s.plugins.eap-tnc.max_message_count",
EAP_TNC_MAX_MESSAGE_COUNT, lib->ns);
protocol = lib->settings->get_str(lib->settings,
"%s.plugins.eap-tnc.protocol", "tnccs-1.1", lib->ns);
"%s.plugins.eap-tnc.protocol", "tnccs-2.0", lib->ns);
if (strcaseeq(protocol, "tnccs-2.0"))
{
type = TNCCS_2_0;
tnccs_type = TNCCS_2_0;
}
else if (strcaseeq(protocol, "tnccs-1.1"))
{
type = TNCCS_1_1;
tnccs_type = TNCCS_1_1;
}
else if (strcaseeq(protocol, "tnccs-dynamic") && is_server)
{
type = TNCCS_DYNAMIC;
tnccs_type = TNCCS_DYNAMIC;
}
else
{
@@ -295,8 +302,9 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
free(this);
return NULL;
}
tnccs = tnc->tnccs->create_instance(tnc->tnccs, type,
is_server, server, peer, TNC_IFT_EAP_1_1,
tnccs = tnc->tnccs->create_instance(tnc->tnccs, tnccs_type,
is_server, server, peer,
(type == EAP_TNC) ? TNC_IFT_EAP_1_1 : TNC_IFT_EAP_2_0,
is_server ? enforce_recommendation : NULL);
if (!tnccs)
{
@@ -305,7 +313,7 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
return NULL;
}
this->tnccs = tnccs->get_ref(tnccs);
this->tls_eap = tls_eap_create(EAP_TNC, &tnccs->tls,
this->tls_eap = tls_eap_create(type, &tnccs->tls,
EAP_TNC_MAX_MESSAGE_LEN,
max_msg_count, FALSE);
if (!this->tls_eap)
@@ -319,11 +327,23 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
eap_tnc_t *eap_tnc_create_server(identification_t *server,
identification_t *peer)
{
return eap_tnc_create(server, peer, TRUE);
return eap_tnc_create(server, peer, TRUE, EAP_TNC);
}
eap_tnc_t *eap_tnc_create_peer(identification_t *server,
identification_t *peer)
{
return eap_tnc_create(server, peer, FALSE);
return eap_tnc_create(server, peer, FALSE, EAP_TNC);
}
eap_tnc_t *eap_tnc_pt_create_server(identification_t *server,
identification_t *peer)
{
return eap_tnc_create(server, peer, TRUE, EAP_PT_EAP);
}
eap_tnc_t *eap_tnc_pt_create_peer(identification_t *server,
identification_t *peer)
{
return eap_tnc_create(server, peer, FALSE, EAP_PT_EAP);
}
+25 -3
View File
@@ -26,7 +26,7 @@ typedef struct eap_tnc_t eap_tnc_t;
#include <sa/eap/eap_inner_method.h>
/**
* Implementation of the eap_method_t interface using EAP-TNC.
* Implementation of the eap_method_t interface using EAP-TNC or PT-EAP.
*/
struct eap_tnc_t {
@@ -43,7 +43,8 @@ struct eap_tnc_t {
* @param peer ID of the EAP client
* @return eap_tnc_t object
*/
eap_tnc_t *eap_tnc_create_server(identification_t *server, identification_t *peer);
eap_tnc_t *eap_tnc_create_server(identification_t *server,
identification_t *peer);
/**
* Creates the EAP method EAP-TNC acting as peer.
@@ -52,6 +53,27 @@ eap_tnc_t *eap_tnc_create_server(identification_t *server, identification_t *pee
* @param peer ID of the EAP client
* @return eap_tnc_t object
*/
eap_tnc_t *eap_tnc_create_peer(identification_t *server, identification_t *peer);
eap_tnc_t *eap_tnc_create_peer(identification_t *server,
identification_t *peer);
/**
* Creates the EAP method PT-EAP acting as server.
*
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_tnc_t object
*/
eap_tnc_t *eap_tnc_pt_create_server(identification_t *server,
identification_t *peer);
/**
* Creates the EAP method PT-EAP acting as peer.
*
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_tnc_t object
*/
eap_tnc_t *eap_tnc_pt_create_peer(identification_t *server,
identification_t *peer);
#endif /** EAP_TNC_H_ @}*/
@@ -36,6 +36,14 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(EAP_PEER, EAP_TNC),
PLUGIN_DEPENDS(EAP_PEER, EAP_TTLS),
PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
PLUGIN_CALLBACK(eap_method_register, eap_tnc_pt_create_server),
PLUGIN_PROVIDE(EAP_SERVER, EAP_PT_EAP),
PLUGIN_DEPENDS(EAP_SERVER, EAP_TTLS),
PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
PLUGIN_CALLBACK(eap_method_register, eap_tnc_pt_create_peer),
PLUGIN_PROVIDE(EAP_PEER, EAP_PT_EAP),
PLUGIN_DEPENDS(EAP_PEER, EAP_TTLS),
PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
};
*features = f;
return countof(f);
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Andreas Steffen
* Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
* Copyright (C) 2010-2014 Andreas Steffen
* 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
@@ -107,22 +107,34 @@ static status_t start_phase2_auth(private_eap_ttls_server_t *this)
}
/**
* If configured, start EAP-TNC protocol
* If configured, start PT-EAP or legacy EAP-TNC protocol
*/
static status_t start_phase2_tnc(private_eap_ttls_server_t *this,
eap_type_t auth_type)
{
eap_inner_method_t *inner_method;
eap_type_t type;
char *eap_type_str;
if (this->start_phase2_tnc && lib->settings->get_bool(lib->settings,
"%s.plugins.eap-ttls.phase2_tnc", FALSE, lib->ns))
{
DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, EAP_TNC);
this->method = charon->eap->create_instance(charon->eap, EAP_TNC,
eap_type_str = lib->settings->get_str(lib->settings,
"%s.plugins.eap-ttls.phase2_tnc_method", "pt",
lib->ns);
type = eap_type_from_string(eap_type_str);
if (type == 0)
{
DBG1(DBG_IKE, "unrecognized phase2 EAP TNC method \"%s\"",
eap_type_str);
return FAILED;
}
DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, type);
this->method = charon->eap->create_instance(charon->eap, type,
0, EAP_SERVER, this->server, this->peer);
if (this->method == NULL)
{
DBG1(DBG_IKE, "%N method not available", eap_type_names, EAP_TNC);
DBG1(DBG_IKE, "%N method not available", eap_type_names, type);
return FAILED;
}
inner_method = (eap_inner_method_t *)this->method;
@@ -135,7 +147,7 @@ static status_t start_phase2_tnc(private_eap_ttls_server_t *this,
}
else
{
DBG1(DBG_IKE, "%N method failed", eap_type_names, EAP_TNC);
DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
return FAILED;
}
}
@@ -151,7 +163,7 @@ METHOD(tls_application_t, process, status_t,
eap_payload_t *in;
eap_code_t code;
eap_type_t type = EAP_NAK, received_type;
u_int32_t vendor, received_vendor;
uint32_t vendor, received_vendor;
status = this->avp->process(this->avp, reader, &data);
switch (status)
@@ -297,7 +309,7 @@ METHOD(tls_application_t, build, status_t,
chunk_t data;
eap_code_t code;
eap_type_t type;
u_int32_t vendor;
uint32_t vendor;
if (this->method == NULL && this->start_phase2 &&
lib->settings->get_bool(lib->settings,