Optionally announce PB-TNC mutual protocol capability

This commit is contained in:
Andreas Steffen
2015-03-23 22:25:43 +01:00
parent 80322d2cee
commit c6aed8aa21
11 changed files with 428 additions and 13 deletions
+3
View File
@@ -3,3 +3,6 @@ charon.plugins.tnccs-20.max_batch_size = 65522
charon.plugins.tnccs-20.max_message_size = 65490
Maximum size of a PA-TNC message (upper limit via PT-EAP = 65497).
charon.plugins.tnccs-20.mutual = no
Enable PB-TNC mutual protocol.
@@ -30,6 +30,7 @@ libstrongswan_tnccs_20_la_SOURCES = \
messages/ietf/pb_language_preference_msg.h messages/ietf/pb_language_preference_msg.c \
messages/ietf/pb_reason_string_msg.h messages/ietf/pb_reason_string_msg.c \
messages/ietf/pb_remediation_parameters_msg.h messages/ietf/pb_remediation_parameters_msg.c \
messages/ita/pb_mutual_capability_msg.h messages/ita/pb_mutual_capability_msg.c \
messages/tcg/pb_pdp_referral_msg.h messages/tcg/pb_pdp_referral_msg.c \
state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
@@ -166,6 +166,9 @@ METHOD(pb_tnc_batch_t, add_msg, bool,
case PEN_TCG:
msg_type_names = pb_tnc_tcg_msg_type_names;
break;
case PEN_ITA:
msg_type_names = pb_tnc_ita_msg_type_names;
break;
}
DBG2(DBG_TNC, "adding %N/%N message", pen_names, msg_type.vendor_id,
msg_type_names, msg_type.type);
@@ -211,6 +214,9 @@ METHOD(pb_tnc_batch_t, build, void,
case PEN_TCG:
msg_infos = pb_tnc_tcg_msg_infos;
break;
case PEN_ITA:
msg_infos = pb_tnc_ita_msg_infos;
break;
}
if (msg_infos[msg_type.type].has_noskip_flag)
{
@@ -384,6 +390,11 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
msg_type_names = pb_tnc_tcg_msg_type_names;
msg_infos = pb_tnc_tcg_msg_infos;
}
else if (vendor_id == PEN_ITA && msg_type <= PB_ITA_MSG_ROOF)
{
msg_type_names = pb_tnc_ita_msg_type_names;
msg_infos = pb_tnc_ita_msg_infos;
}
else
{
if (msg_len < PB_TNC_MSG_HEADER_SIZE)
@@ -0,0 +1,174 @@
/*
* Copyright (C) 2015 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
* 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 "pb_mutual_capability_msg.h"
#include <bio/bio_writer.h>
#include <bio/bio_reader.h>
#include <utils/debug.h>
ENUM(pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX,
PB_MUTUAL_FULL_DUPLEX,
"half duplex",
"full duplex"
);
typedef struct private_pb_mutual_capability_msg_t private_pb_mutual_capability_msg_t;
/**
* PB-Mutual-Capability message
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |H|F| Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
# define MUTUAL_CAPABILITY_HEADER_SIZE 4
/**
* Private data of a pb_mutual_capability_msg_t object.
*
*/
struct private_pb_mutual_capability_msg_t {
/**
* Public pb_mutual_capability_msg_t interface.
*/
pb_mutual_capability_msg_t public;
/**
* PB-TNC message type
*/
pen_type_t type;
/**
* PB-TNC mutual protocols
*/
uint32_t protocols;
/**
* Encoded message
*/
chunk_t encoding;
};
METHOD(pb_tnc_msg_t, get_type, pen_type_t,
private_pb_mutual_capability_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_mutual_capability_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_msg_t, build, void,
private_pb_mutual_capability_msg_t *this)
{
bio_writer_t *writer;
if (this->encoding.ptr)
{
return;
}
writer = bio_writer_create(MUTUAL_CAPABILITY_HEADER_SIZE);
writer->write_uint32(writer, this->protocols);
this->encoding = writer->get_buf(writer);
this->encoding = chunk_clone(this->encoding);
writer->destroy(writer);
}
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_mutual_capability_msg_t *this, u_int32_t *offset)
{
bio_reader_t *reader;
*offset = 0;
/* process message */
reader = bio_reader_create(this->encoding);
reader->read_uint32(reader, &this->protocols);
reader->destroy(reader);
return SUCCESS;
}
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_mutual_capability_msg_t *this)
{
free(this->encoding.ptr);
free(this);
}
METHOD(pb_mutual_capability_msg_t, get_protocols, uint32_t,
private_pb_mutual_capability_msg_t *this)
{
return this->protocols;
}
/**
* See header
*/
pb_tnc_msg_t* pb_mutual_capability_msg_create(uint32_t protocols)
{
private_pb_mutual_capability_msg_t *this;
INIT(this,
.public = {
.pb_interface = {
.get_type = _get_type,
.get_encoding = _get_encoding,
.build = _build,
.process = _process,
.destroy = _destroy,
},
.get_protocols = _get_protocols,
},
.type = { PEN_ITA, PB_ITA_MSG_MUTUAL_CAPABILITY },
.protocols = protocols,
);
return &this->public.pb_interface;
}
/**
* See header
*/
pb_tnc_msg_t *pb_mutual_capability_msg_create_from_data(chunk_t data)
{
private_pb_mutual_capability_msg_t *this;
INIT(this,
.public = {
.pb_interface = {
.get_type = _get_type,
.get_encoding = _get_encoding,
.build = _build,
.process = _process,
.destroy = _destroy,
},
.get_protocols = _get_protocols,
},
.type = { PEN_ITA, PB_ITA_MSG_MUTUAL_CAPABILITY },
.encoding = chunk_clone(data),
);
return &this->public.pb_interface;
}
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2015 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
* 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 pb_mutual_capability_msg pb_mutual_capability_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_MUTUAL_CAPABILITY_MSG_H_
#define PB_MUTUAL_CAPABILITY_MSG_H_
typedef enum pb_tnc_mutual_protocol_type_t pb_tnc_mutual_protocol_type_t;
typedef struct pb_mutual_capability_msg_t pb_mutual_capability_msg_t;
#include "messages/pb_tnc_msg.h"
/**
* PB-TNC mutual protocol types
*/
enum pb_tnc_mutual_protocol_type_t {
PB_MUTUAL_HALF_DUPLEX = (1 << 31),
PB_MUTUAL_FULL_DUPLEX = (1 << 30)
};
/**
* enum name for pb_mutual_protocol_type_t.
*/
extern enum_name_t *pb_tnc_mutual_protocol_type_names;
/**
* Class representing the PB-Mutual-Capabilities message type.
*/
struct pb_mutual_capability_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_msg_t pb_interface;
/**
* Get the PB-TNC mutual protocol types
*
* @return PB-TNC mutual protocol types
*/
uint32_t(*get_protocols)(pb_mutual_capability_msg_t *this);
};
/**
* Create a PB-Mutual-Capability message
*
* @param protocols Supported PB-TNC mutual protocols
*/
pb_tnc_msg_t* pb_mutual_capability_msg_create(uint32_t protocols);
/**
* Create an unprocessed PB-Mutual-Capability message from raw data
*
* @param data PB-Mutual-Capability message data
*/
pb_tnc_msg_t* pb_mutual_capability_msg_create_from_data(chunk_t data);
#endif /** PB_MUTUAL_CAPABILITY_MSG_ @}*/
@@ -22,6 +22,7 @@
#include "ietf/pb_access_recommendation_msg.h"
#include "ietf/pb_remediation_parameters_msg.h"
#include "ietf/pb_reason_string_msg.h"
#include "ita/pb_mutual_capability_msg.h"
#include "tcg/pb_pdp_referral_msg.h"
#include <library.h>
@@ -37,10 +38,16 @@ ENUM(pb_tnc_msg_type_names, PB_MSG_EXPERIMENTAL, PB_MSG_REASON_STRING,
"PB-Reason-String"
);
ENUM(pb_tnc_tcg_msg_type_names, PB_TCG_MSG_PDP_REFERRAL, PB_TCG_MSG_PDP_REFERRAL,
ENUM(pb_tnc_tcg_msg_type_names, PB_TCG_MSG_PDP_REFERRAL,
PB_TCG_MSG_PDP_REFERRAL,
"PB-PDP-Referral"
);
ENUM(pb_tnc_ita_msg_type_names, PB_ITA_MSG_MUTUAL_CAPABILITY,
PB_ITA_MSG_MUTUAL_CAPABILITY,
"PB-Mutual-Capability"
);
pb_tnc_msg_info_t pb_tnc_msg_infos[] = {
{ 12, FALSE, FALSE, TRUE_OR_FALSE },
{ 24, FALSE, FALSE, TRUE },
@@ -57,6 +64,11 @@ pb_tnc_msg_info_t pb_tnc_tcg_msg_infos[] = {
{ 20, FALSE, FALSE, FALSE },
};
pb_tnc_msg_info_t pb_tnc_ita_msg_infos[] = {
{ 0 }, /* dummy entry because pb_tnc_ita_msg_type_t starts with 1 */
{ 16, FALSE, FALSE, FALSE },
};
/**
* See header
*/
@@ -91,5 +103,12 @@ pb_tnc_msg_t* pb_tnc_msg_create_from_data(pen_type_t msg_type, chunk_t value)
return pb_pdp_referral_msg_create_from_data(value);
}
}
else if (msg_type.vendor_id == PEN_ITA)
{
if (msg_type.type == PB_ITA_MSG_MUTUAL_CAPABILITY)
{
return pb_mutual_capability_msg_create_from_data(value);
}
}
return NULL;
}
@@ -63,6 +63,19 @@ enum pb_tnc_tcg_msg_type_t {
*/
extern enum_name_t *pb_tnc_tcg_msg_type_names;
/**
* PB-TNC Message Type defined in the ITA namespace
*/
enum pb_tnc_ita_msg_type_t {
PB_ITA_MSG_MUTUAL_CAPABILITY = 1,
PB_ITA_MSG_ROOF = 1
};
/**
* enum name for pb_tnc_tcg_msg_type_t.
*/
extern enum_name_t *pb_tnc_ita_msg_type_names;
/**
* Information entry describing a PB-TNC Message Type
*/
@@ -85,6 +98,11 @@ extern pb_tnc_msg_info_t pb_tnc_msg_infos[];
*/
extern pb_tnc_msg_info_t pb_tnc_tcg_msg_infos[];
/**
* Information on PB-TNC ITA Message Types
*/
extern pb_tnc_msg_info_t pb_tnc_ita_msg_infos[];
/**
* Generic interface for all PB-TNC message types.
*
@@ -22,6 +22,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/ita/pb_mutual_capability_msg.h"
#include "messages/tcg/pb_pdp_referral_msg.h"
#include "state_machine/pb_tnc_state_machine.h"
@@ -104,10 +105,15 @@ struct private_tnccs_20_client_t {
*/
u_int16_t pdp_port;
/**
* Mutual PB-TNC protocol enabled
*/
bool mutual;
};
/**
* The following function is shared with the tnccs_20_server class
* The following two functions are shared with the tnccs_20_server class
*/
void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg, bool *fatal_error)
{
@@ -160,6 +166,22 @@ void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg, bool *fatal_error)
}
}
void tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg, bool *mutual)
{
pb_mutual_capability_msg_t *mutual_msg;
uint32_t protocols;
mutual_msg = (pb_mutual_capability_msg_t*)msg;
protocols = mutual_msg->get_protocols(mutual_msg);
if (protocols & PB_MUTUAL_HALF_DUPLEX)
{
*mutual = TRUE;
DBG1(DBG_TNC, "activating mutual PB-TNC %N protocol",
pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX);
}
}
/**
* If the batch type changes then delete all accumulated PB-TNC messages
*/
@@ -364,6 +386,23 @@ static void handle_tcg_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *ms
}
}
/**
* Handle a single PB-TNC ITA standard message according to its type
*/
static void handle_ita_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
{
pen_type_t msg_type = msg->get_type(msg);
switch (msg_type.type)
{
case PB_ITA_MSG_MUTUAL_CAPABILITY:
tnccs_20_handle_ita_mutual_capability_msg(msg, &this->mutual);
break;
default:
break;
}
}
/**
* Handle a single PB-TNC message according to its type
*/
@@ -379,6 +418,9 @@ static void handle_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
case PEN_TCG:
handle_tcg_message(this, msg);
break;
case PEN_ITA:
handle_ita_message(this, msg);
break;
default:
break;
}
@@ -602,6 +644,21 @@ METHOD(tnccs_20_handler_t, begin_handshake, void,
tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
TNC_CONNECTION_STATE_HANDSHAKE);
/* Announce PB-TNC Mutual Capability if activated */
if (lib->settings->get_bool(lib->settings,
"%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
{
pb_tnc_mutual_protocol_type_t protocols;
protocols = PB_MUTUAL_HALF_DUPLEX;
DBG2(DBG_TNC, "proposing PB-TNC mutual %N protocol",
pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX);
msg = pb_mutual_capability_msg_create(protocols);
this->mutex->lock(this->mutex);
this->messages->insert_last(this->messages, msg);
this->mutex->unlock(this->mutex);
}
/* Create PB-TNC Language Preference message */
pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
msg = pb_language_preference_msg_create(chunk_create(pref_lang,
@@ -621,6 +678,12 @@ METHOD(tnccs_20_handler_t, get_send_flag, bool,
return this->send_msg;
}
METHOD(tnccs_20_handler_t, get_mutual, bool,
private_tnccs_20_client_t *this)
{
return this->mutual;
}
METHOD(tnccs_20_handler_t, add_msg, void,
private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
{
@@ -697,6 +760,7 @@ tnccs_20_handler_t* tnccs_20_client_create(tnccs_t *tnccs,
.build = _build,
.begin_handshake = _begin_handshake,
.get_send_flag = _get_send_flag,
.get_mutual = _get_mutual,
.add_msg = _add_msg,
.handle_errors = _handle_errors,
.destroy = _destroy,
@@ -64,6 +64,13 @@ struct tnccs_20_handler_t {
*/
bool (*get_send_flag)(tnccs_20_handler_t *this);
/**
* Indicates if the PB-TNC mutual protocol has been enabled
*
* @return TRUE if enabled
*/
bool (*get_mutual)(tnccs_20_handler_t *this);
/**
* Add a PB-PA message to the handler's message queue
*
+49 -11
View File
@@ -22,6 +22,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/ita/pb_mutual_capability_msg.h"
#include "messages/tcg/pb_pdp_referral_msg.h"
#include "state_machine/pb_tnc_state_machine.h"
@@ -105,19 +106,19 @@ struct private_tnccs_20_server_t {
bool eap_transport;
/**
* PDP server FQDN
* Mutual PB-TNC protocol enabled
*/
chunk_t pdp_server;
/**
* PDP server port
*/
u_int16_t pdp_port;
bool mutual;
};
extern void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg, bool *fatal_error);
/**
* The following two functions are shared with the tnccs_20_server class
*/
extern void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg,
bool *fatal_error);
extern void tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg,
bool *mutual);
/**
* If the batch type changes then delete all accumulated PB-TNC messages
@@ -213,6 +214,35 @@ static void handle_ietf_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *m
}
}
/**
* Handle a single PB-TNC ITA standard message according to its type
*/
static void handle_ita_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
{
pen_type_t msg_type = msg->get_type(msg);
switch (msg_type.type)
{
case PB_ITA_MSG_MUTUAL_CAPABILITY:
tnccs_20_handle_ita_mutual_capability_msg(msg, &this->mutual);
/* Respond with PB-TNC Mutual Capability message if activated */
if (this->mutual && lib->settings->get_bool(lib->settings,
"%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
{
pb_tnc_mutual_protocol_type_t protocols = PB_MUTUAL_HALF_DUPLEX;
msg = pb_mutual_capability_msg_create(protocols);
this->mutex->lock(this->mutex);
this->messages->insert_last(this->messages, msg);
this->mutex->unlock(this->mutex);
}
break;
default:
break;
}
}
/**
* Handle a single PB-TNC message according to its type
*/
@@ -225,6 +255,9 @@ static void handle_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
case PEN_IETF:
handle_ietf_message(this, msg);
break;
case PEN_ITA:
handle_ita_message(this, msg);
break;
default:
break;
}
@@ -259,9 +292,7 @@ METHOD(tnccs_20_handler_t, process, status_t,
DBG1(DBG_TNC, "processing PB-TNC %N batch for Connection ID %d",
pb_tnc_batch_type_names, batch_type, this->connection_id);
status = batch->process(batch, this->state_machine);
DBG2(DBG_TNC, "status after batch process: %N", status_names, status);
if (status != FAILED)
{
@@ -535,6 +566,12 @@ METHOD(tnccs_20_handler_t, get_send_flag, bool,
return this->send_msg;
}
METHOD(tnccs_20_handler_t, get_mutual, bool,
private_tnccs_20_server_t *this)
{
return this->mutual;
}
METHOD(tnccs_20_handler_t, add_msg, void,
private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
{
@@ -610,6 +647,7 @@ tnccs_20_handler_t* tnccs_20_server_create(tnccs_t *tnccs,
.build = _build,
.begin_handshake = _begin_handshake,
.get_send_flag = _get_send_flag,
.get_mutual = _get_mutual,
.add_msg = _add_msg,
.handle_errors = _handle_errors,
.destroy = _destroy,
+5
View File
@@ -270,6 +270,7 @@ int main(int argc, char *argv[])
{"port", required_argument, NULL, 'p' },
{"cert", required_argument, NULL, 'x' },
{"key", required_argument, NULL, 'k' },
{"mutual", no_argument, NULL, 'm' },
{"quiet", no_argument, NULL, 'q' },
{"debug", required_argument, NULL, 'd' },
{"optionsfrom", required_argument, NULL, '+' },
@@ -311,6 +312,10 @@ int main(int argc, char *argv[])
case 'p': /* --port <port> */
port = atoi(optarg);
continue;
case 'm': /* --mutual */
lib->settings->set_bool(lib->settings,
"%s.plugins.tnccs-20.mutual", TRUE, lib->ns);
continue;
case 'q': /* --quiet */
log_to_stderr = FALSE;
continue;