Implemented TCG/PB-PDP_Referral message

This commit is contained in:
Andreas Steffen
2013-09-17 21:57:08 +02:00
parent ddfc589600
commit 2c4d772a79
6 changed files with 155 additions and 13 deletions
+12
View File
@@ -68,6 +68,11 @@ struct private_tnc_pdp_t {
*/
eap_type_t type;
/**
* PT-TLS port of the server
*/
u_int16_t pt_tls_port;
/**
* PT-TLS IPv4 socket
*/
@@ -798,6 +803,8 @@ tnc_pdp_t *tnc_pdp_create(void)
destroy(this);
return NULL;
}
this->pt_tls_port = pt_tls_port;
if (this->pt_tls_ipv4)
{
lib->watcher->add(lib->watcher, this->pt_tls_ipv4, WATCHER_READ,
@@ -807,6 +814,7 @@ tnc_pdp_t *tnc_pdp_create(void)
{
DBG1(DBG_NET, "could not open IPv4 PT-TLS socket, IPv4 disabled");
}
if (this->pt_tls_ipv6)
{
lib->watcher->add(lib->watcher, this->pt_tls_ipv6, WATCHER_READ,
@@ -816,6 +824,10 @@ tnc_pdp_t *tnc_pdp_create(void)
{
DBG1(DBG_NET, "could not open IPv6 PT-TLS socket, IPv6 disabled");
}
/* register PT-TLS service */
lib->set(lib, "pt-tls-server", this->server);
lib->set(lib, "pt-tls-port", &this->pt_tls_port);
}
/* Create IPv4 and IPv6 RADIUS listening sockets */
@@ -396,7 +396,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
msg_type_names = pb_tnc_msg_type_names;
msg_infos = pb_tnc_msg_infos;
}
else if (vendor_id == PEN_IETF && msg_type <= PB_TCG_MSG_ROOF)
else if (vendor_id == PEN_TCG && msg_type <= PB_TCG_MSG_ROOF)
{
msg_type_names = pb_tnc_tcg_msg_type_names;
msg_infos = pb_tnc_tcg_msg_infos;
@@ -414,16 +414,16 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
if (noskip_flag)
{
DBG1(DBG_TNC, "reject PB-TNC message (Vendor ID 0x%06x / "
"Type 0x%08x)", vendor_id, msg_type);
DBG1(DBG_TNC, "reject PB-TNC message 0x%06x/0x%08x)",
vendor_id, msg_type);
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset);
goto fatal;
}
else
{
DBG1(DBG_TNC, "ignore PB-TNC message (Vendor ID 0x%06x / "
"Type 0x%08x)", vendor_id, msg_type);
DBG1(DBG_TNC, "ignore PB-TNC message 0x%06x/0x%08x)",
vendor_id, msg_type);
this->offset += msg_len;
return SUCCESS;
}
@@ -79,6 +79,11 @@ typedef struct private_pb_pdp_referral_msg_t private_pb_pdp_referral_msg_t;
*
*/
# define PDP_REFERRAL_HEADER_SIZE 8
# define PDP_REFERRAL_ID_HEADER_SIZE 4
# define PDP_REFERRAL_RESERVED 0x00
# define PDP_REFERRAL_PROTOCOL 0x00
/**
* Private data of a pb_pdp_referral_msg_t object.
*
@@ -104,6 +109,21 @@ struct private_pb_pdp_referral_msg_t {
*/
chunk_t identifier;
/**
* PDP FQDN Identifier
*/
chunk_t fqdn;
/**
* PT protocol the PDP is using
*/
u_int8_t protocol;
/**
* PT port the PDP is using
*/
u_int16_t port;
/**
* Encoded message
*/
@@ -131,10 +151,11 @@ METHOD(pb_tnc_msg_t, build, void,
{
return;
}
writer = bio_writer_create(64);
writer->write_uint32(writer, this->identifier_type.vendor_id);
writer = bio_writer_create(PDP_REFERRAL_HEADER_SIZE + this->identifier.len);
writer->write_uint8 (writer, PDP_REFERRAL_RESERVED);
writer->write_uint24(writer, this->identifier_type.vendor_id);
writer->write_uint32(writer, this->identifier_type.type);
writer->write_data(writer, this->identifier);
writer->write_data (writer, this->identifier);
this->encoding = writer->get_buf(writer);
this->encoding = chunk_clone(this->encoding);
@@ -146,7 +167,6 @@ METHOD(pb_tnc_msg_t, process, status_t,
{
bio_reader_t *reader;
u_int8_t reserved;
status_t status = SUCCESS;
*offset = 0;
@@ -160,11 +180,25 @@ METHOD(pb_tnc_msg_t, process, status_t,
this->identifier = chunk_clone(this->identifier);
reader->destroy(reader);
if (this->identifier_type.vendor_id == PEN_TCG)
if (this->identifier_type.vendor_id == PEN_TCG &&
this->identifier_type.type == PB_PDP_ID_FQDN)
{
/* TODO parse PDP Identifier Types */
reader = bio_reader_create(this->identifier);
*offset += PDP_REFERRAL_HEADER_SIZE;
if (this->identifier.len <= PDP_REFERRAL_ID_HEADER_SIZE)
{
reader->destroy(reader);
return FAILED;
}
reader->read_uint8 (reader, &reserved);
reader->read_uint8 (reader, &this->protocol);
reader->read_uint16(reader, &this->port);
reader->read_data (reader, reader->remaining(reader), &this->fqdn);
this->fqdn = chunk_clone(this->fqdn);
reader->destroy(reader);
}
return status;
return SUCCESS;
}
METHOD(pb_tnc_msg_t, destroy, void,
@@ -172,6 +206,7 @@ METHOD(pb_tnc_msg_t, destroy, void,
{
free(this->encoding.ptr);
free(this->identifier.ptr);
free(this->fqdn.ptr);
free(this);
}
@@ -187,6 +222,20 @@ METHOD(pb_pdp_referral_msg_t, get_identifier, chunk_t,
return this->identifier;
}
METHOD(pb_pdp_referral_msg_t, get_fqdn, chunk_t,
private_pb_pdp_referral_msg_t *this, u_int8_t *protocol, u_int16_t *port)
{
if (protocol)
{
*protocol = this->protocol;
}
if (port)
{
*port = this->port;
}
return this->fqdn;
}
/**
* See header
*/
@@ -215,6 +264,27 @@ pb_tnc_msg_t* pb_pdp_referral_msg_create(pen_type_t identifier_type,
return &this->public.pb_interface;
}
/**
* See header
*/
pb_tnc_msg_t* pb_pdp_referral_msg_create_from_fqdn(chunk_t fqdn, u_int16_t port)
{
pb_tnc_msg_t *msg;
bio_writer_t *writer;
pen_type_t type = { PEN_TCG, PB_PDP_ID_FQDN };
writer = bio_writer_create(PDP_REFERRAL_ID_HEADER_SIZE + fqdn.len);
writer->write_uint8 (writer, PDP_REFERRAL_RESERVED);
writer->write_uint8 (writer, PDP_REFERRAL_PROTOCOL);
writer->write_uint16(writer, port);
writer->write_data (writer, fqdn);
msg = pb_pdp_referral_msg_create(type, writer->get_buf(writer));
writer->destroy(writer);
return msg;
}
/**
* See header
*/
@@ -233,6 +303,7 @@ pb_tnc_msg_t *pb_pdp_referral_msg_create_from_data(chunk_t data)
},
.get_identifier_type = _get_identifier_type,
.get_identifier = _get_identifier,
.get_fqdn = _get_fqdn,
},
.type = { PEN_TCG, PB_TCG_MSG_PDP_REFERRAL },
.encoding = chunk_clone(data),
@@ -67,6 +67,16 @@ struct pb_pdp_referral_msg_t {
*/
chunk_t (*get_identifier)(pb_pdp_referral_msg_t *this);
/**
* Get the PDP Identifier Value
*
* @param protocol PT transport protocol
* @param port PT port the PDP is listening on
* @return Fully Qualified Domain Name of PDP
*/
chunk_t (*get_fqdn)(pb_pdp_referral_msg_t *this, u_int8_t *protocol,
u_int16_t *port);
};
/**
@@ -78,6 +88,14 @@ struct pb_pdp_referral_msg_t {
pb_tnc_msg_t* pb_pdp_referral_msg_create(pen_type_t identifier_type,
chunk_t identifier);
/**
* Create a PB-PDP-Referral message of TCG Type PDP FQDN Identifier
*
* @param fqdn Fully Qualified Domain Name of PDP
* @param port PT-TLS port the PDP is listening on
*/
pb_tnc_msg_t* pb_pdp_referral_msg_create_from_fqdn(chunk_t fqdn, u_int16_t port);
/**
* Create an unprocessed PB-PDP-Referral message from raw data
*
+40 -1
View File
@@ -24,6 +24,7 @@
#include "messages/ietf/pb_remediation_parameters_msg.h"
#include "messages/ietf/pb_reason_string_msg.h"
#include "messages/ietf/pb_language_preference_msg.h"
#include "messages/tcg/pb_pdp_referral_msg.h"
#include "state_machine/pb_tnc_state_machine.h"
#include <tncif_names.h>
@@ -452,8 +453,31 @@ static void handle_tcg_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
switch (msg_type.type)
{
case PB_TCG_MSG_PDP_REFERRAL:
/* TODO handle PDP Referral */
{
pb_pdp_referral_msg_t *pdp_msg;
pen_type_t pdp_id_type;
chunk_t pdp_server;
u_int8_t pdp_protocol;
u_int16_t pdp_port;
pdp_msg = (pb_pdp_referral_msg_t*)msg;
pdp_id_type = pdp_msg->get_identifier_type(pdp_msg);
if (pdp_id_type.vendor_id == PEN_TCG &&
pdp_id_type.type == PB_PDP_ID_FQDN)
{
pdp_server = pdp_msg->get_fqdn(pdp_msg, &pdp_protocol,
&pdp_port);
if (pdp_protocol != 0)
{
DBG1(DBG_TNC, "unsupported PDP transport protocol");
break;
}
DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u",
pdp_server.len, pdp_server.ptr, pdp_port);
}
break;
}
default:
break;
}
@@ -510,6 +534,8 @@ METHOD(tls_t, process, status_t,
pb_tnc_batch_t *batch;
pb_tnc_msg_t *msg;
enumerator_t *enumerator;
identification_t *pdp_server;
u_int16_t *pdp_port;
status_t status;
if (this->is_server && !this->connection_id)
@@ -526,6 +552,19 @@ METHOD(tls_t, process, status_t,
TNC_CONNECTION_STATE_CREATE);
tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
TNC_CONNECTION_STATE_HANDSHAKE);
/* Send a PB-TNC TCG PDP Referral message if PDP is known */
pdp_server = (identification_t*)lib->get(lib, "pt-tls-server");
pdp_port = (u_int16_t*)lib->get(lib, "pt-tls-port");
if ((this->transport == TNC_IFT_EAP_1_1 ||
this->transport == TNC_IFT_EAP_2_0) && pdp_server && pdp_port)
{
msg = pb_pdp_referral_msg_create_from_fqdn(
pdp_server->get_encoding(pdp_server), *pdp_port);
this->messages->insert_last(this->messages, msg);
}
}
data = chunk_create(buf, buflen);
@@ -1,8 +1,10 @@
carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
carol::cat /var/log/daemon.log::PDP server.*aaa.strongswan.org.*is listening on port 271::YES
carol::cat /var/log/daemon.log::PB-TNC access recommendation is .*Access Allowed::YES
carol::cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
carol::cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.100/32 === 10.1.0.0/28::YES
dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
dave:: cat /var/log/daemon.log::PDP server.*aaa.strongswan.org.*is listening on port 271::YES
dave:: cat /var/log/daemon.log::PB-TNC access recommendation is .*Quarantined::YES
dave:: cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
dave:: cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.200/32 === 10.1.0.16/28::YES