implemented PB-TNC message parsing checks

This commit is contained in:
Andreas Steffen
2010-12-12 00:42:31 +01:00
parent 3a4695dc5e
commit 54eb669dd5
25 changed files with 1197 additions and 607 deletions
+9 -8
View File
@@ -13,15 +13,16 @@ endif
libstrongswan_tnccs_20_la_SOURCES = \
tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
tnccs_20_types.h tnccs_20_types.c \
batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
messages/pb_tnc_message.h messages/pb_tnc_message.c \
messages/pb_pa_message.h messages/pb_pa_message.c \
messages/pb_assessment_result_message.h messages/pb_assessment_result_message.c \
messages/pb_access_recommendation_message.h messages/pb_access_recommendation_message.c \
messages/pb_error_message.h messages/pb_error_message.c \
messages/pb_language_preference_message.h messages/pb_language_preference_message.c \
messages/pb_reason_string_message.h messages/pb_reason_string_message.c \
messages/pb_tnc_msg.h messages/pb_tnc_msg.c \
messages/pb_experimental_msg.h messages/pb_experimental_msg.c \
messages/pb_pa_msg.h messages/pb_pa_msg.c \
messages/pb_assessment_result_msg.h messages/pb_assessment_result_msg.c \
messages/pb_access_recommendation_msg.h messages/pb_access_recommendation_msg.c \
messages/pb_error_msg.h messages/pb_error_msg.c \
messages/pb_language_preference_msg.h messages/pb_language_preference_msg.c \
messages/pb_reason_string_msg.h messages/pb_reason_string_msg.c \
messages/pb_remediation_parameters_msg.h messages/pb_remediation_parameters_msg.c \
state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
libstrongswan_tnccs_20_la_LDFLAGS = -module -avoid-version
@@ -14,9 +14,8 @@
* for more details.
*/
#include "tnccs_20_types.h"
#include "pb_tnc_batch.h"
#include "messages/pb_error_message.h"
#include "messages/pb_error_msg.h"
#include "state_machine/pb_tnc_state_machine.h"
#include <debug.h>
@@ -80,7 +79,7 @@ typedef struct private_pb_tnc_batch_t private_pb_tnc_batch_t;
*/
struct private_pb_tnc_batch_t {
/**
* Public pb_pa_message_t interface.
* Public pb_pa_msg_t interface.
*/
pb_tnc_batch_t public;
@@ -112,7 +111,7 @@ struct private_pb_tnc_batch_t {
/**
* Offset into encoding (used for error reporting)
*/
size_t offset;
u_int32_t offset;
};
METHOD(pb_tnc_batch_t, get_type, pb_tnc_batch_type_t,
@@ -127,8 +126,8 @@ METHOD(pb_tnc_batch_t, get_encoding, chunk_t,
return this->encoding;
}
METHOD(pb_tnc_batch_t, add_message, void,
private_pb_tnc_batch_t *this, pb_tnc_message_t* msg)
METHOD(pb_tnc_batch_t, add_msg, void,
private_pb_tnc_batch_t *this, pb_tnc_msg_t* msg)
{
DBG2(DBG_TNC, "adding %N Message", pb_tnc_msg_type_names,
msg->get_type(msg));
@@ -139,11 +138,10 @@ METHOD(pb_tnc_batch_t, build, void,
private_pb_tnc_batch_t *this)
{
u_int32_t batch_len, msg_len;
u_int8_t flags = PB_TNC_FLAG_NONE;
chunk_t msg_value;
enumerator_t *enumerator;
pb_tnc_msg_type_t msg_type;
pb_tnc_message_t *msg;
pb_tnc_msg_t *msg;
tls_writer_t *writer;
/* compute total PB-TNC batch size by summing over all messages */
@@ -169,24 +167,16 @@ METHOD(pb_tnc_batch_t, build, void,
enumerator = this->messages->create_enumerator(this->messages);
while (enumerator->enumerate(enumerator, &msg))
{
u_int8_t flags = PB_TNC_FLAG_NONE;
/* build PB-TNC message */
msg_value = msg->get_encoding(msg);
msg_len = PB_TNC_HEADER_SIZE + msg_value.len;
msg_type = msg->get_type(msg);
switch (msg_type)
if (pb_tnc_msg_infos[msg_type].has_noskip_flag)
{
case PB_MSG_PA:
case PB_MSG_ASSESSMENT_RESULT:
case PB_MSG_ERROR:
flags |= PB_TNC_FLAG_NOSKIP;
break;
case PB_MSG_EXPERIMENTAL:
case PB_MSG_ACCESS_RECOMMENDATION:
case PB_MSG_REMEDIATION_PARAMETERS:
case PB_MSG_LANGUAGE_PREFERENCE:
case PB_MSG_REASON_STRING:
break;
}
flags |= PB_TNC_FLAG_NOSKIP;
}
writer->write_uint8 (writer, flags);
writer->write_uint24(writer, IETF_VENDOR_ID);
writer->write_uint32(writer, msg_type);
@@ -203,8 +193,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
pb_tnc_state_machine_t *state_machine)
{
tls_reader_t *reader;
pb_tnc_message_t *msg;
pb_error_message_t *err_msg;
pb_tnc_msg_t *msg;
pb_error_msg_t *err_msg;
u_int8_t version, flags, reserved, type;
u_int32_t batch_len;
bool directionality;
@@ -213,10 +203,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
{
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC batch header",
this->encoding.len);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, 0);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, 0);
goto fatal;
}
@@ -232,9 +220,9 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
if (version != PB_TNC_VERSION)
{
DBG1(DBG_TNC, "unsupported TNCCS Batch Version 0x%01x", version);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_VERSION_NOT_SUPPORTED);
err_msg = (pb_error_message_t*)msg;
msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_VERSION_NOT_SUPPORTED);
err_msg = (pb_error_msg_t*)msg;
err_msg->set_bad_version(err_msg, version);
goto fatal;
}
@@ -245,10 +233,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
{
DBG1(DBG_TNC, "wrong Directionality: Batch is from a PB %s",
directionality ? "Server" : "Client");
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, 1);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, 1);
goto fatal;
}
@@ -257,10 +243,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
if (this->type > PB_BATCH_ROOF)
{
DBG1(DBG_TNC, "unknown PB-TNC Batch Type: %d", this->type);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, 3);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, 3);
goto fatal;
}
@@ -268,8 +252,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
{
DBG1(DBG_TNC, "unexpected PB-TNC Batch Type: %N",
pb_tnc_batch_type_names, this->type);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_UNEXPECTED_BATCH_TYPE);
msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_UNEXPECTED_BATCH_TYPE);
goto fatal;
}
@@ -278,10 +262,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
{
DBG1(DBG_TNC, "%u bytes of data is not equal to batch length of %u bytes",
this->encoding.len, batch_len);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, 4);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, 4);
goto fatal;
}
@@ -293,14 +275,14 @@ fatal:
return FAILED;
}
static status_t process_tnc_message(private_pb_tnc_batch_t *this)
static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
{
tls_reader_t *reader;
pb_tnc_message_t *pb_tnc_msg, *msg;
pb_error_message_t *err_msg;
pb_tnc_msg_t *pb_tnc_msg, *msg;
u_int8_t flags;
u_int32_t vendor_id, msg_type, msg_len;
u_int32_t vendor_id, msg_type, msg_len, offset;
chunk_t data, msg_value;
bool noskip_flag;
status_t status;
data = chunk_skip(this->encoding, this->offset);
@@ -309,10 +291,8 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this)
{
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message header",
data.len);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, this->offset);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset);
goto fatal;
}
@@ -323,33 +303,21 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this)
reader->read_uint32(reader, &msg_len);
reader->destroy(reader);
if (msg_len < PB_TNC_HEADER_SIZE)
{
DBG1(DBG_TNC, "%u bytes too small for PB-TNC message length", msg_len);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, this->offset + 8);
goto fatal;
}
noskip_flag = (flags & PB_TNC_FLAG_NOSKIP) != PB_TNC_FLAG_NONE;
if (msg_len > data.len)
{
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message", data.len);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, this->offset + 8);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset + 8);
goto fatal;
}
if (vendor_id == RESERVED_VENDOR_ID)
{
DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, this->offset + 1);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset + 1);
goto fatal;
}
@@ -358,23 +326,29 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this)
{
DBG1(DBG_TNC, "PB-TNC Message Type 0x%08x is reserved",
PB_TNC_RESERVED_MSG_TYPE);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, this->offset + 4);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset + 4);
goto fatal;
}
if (vendor_id != IETF_VENDOR_ID || msg_type > PB_MSG_ROOF)
{
if (flags & PB_TNC_FLAG_NOSKIP)
if (msg_len < PB_TNC_HEADER_SIZE)
{
DBG1(DBG_TNC, "%u bytes too small for PB-TNC message length",
msg_len);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset + 8);
goto fatal;
}
if (noskip_flag)
{
DBG1(DBG_TNC, "reject PB-TNC Message (Vendor ID 0x%06x / "
"Type 0x%08x)", vendor_id, msg_type);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_UNSUPPORTED_MANDATORY_MESSAGE);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, this->offset);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset);
goto fatal;
}
else
@@ -385,20 +359,42 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this)
return SUCCESS;
}
}
else
{
if (pb_tnc_msg_infos[msg_type].has_noskip_flag != TRUE_OR_FALSE &&
pb_tnc_msg_infos[msg_type].has_noskip_flag != noskip_flag)
{
DBG1(DBG_TNC, "%N Message must%s have NOSKIP flag set",
pb_tnc_msg_type_names, msg_type,
pb_tnc_msg_infos[msg_type].has_noskip_flag ? "" : " not");
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset);
goto fatal;
}
if ((msg_type == PB_MSG_ASSESSMENT_RESULT ||
msg_type == PB_MSG_ACCESS_RECOMMENDATION ||
msg_type == PB_MSG_REMEDIATION_PARAMETERS) &&
this->type != PB_BATCH_RESULT)
if (msg_len < pb_tnc_msg_infos[msg_type].min_size ||
(pb_tnc_msg_infos[msg_type].exact_size &&
msg_len != pb_tnc_msg_infos[msg_type].min_size))
{
DBG1(DBG_TNC, "%N Message length must be %s %u bytes but is %u bytes",
pb_tnc_msg_type_names, msg_type,
pb_tnc_msg_infos[msg_type].exact_size ? "exactly" : "at least",
pb_tnc_msg_infos[msg_type].min_size, msg_len);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset);
goto fatal;
}
}
if (pb_tnc_msg_infos[msg_type].in_result_batch &&
this->type != PB_BATCH_RESULT)
{
if (this->is_server)
{
DBG1(DBG_TNC,"reject %N Message received from a PB-TNC Client",
pb_tnc_msg_type_names, msg_type);
msg = pb_error_message_create(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER);
err_msg = (pb_error_message_t*)msg;
err_msg->set_offset(err_msg, this->offset);
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset);
goto fatal;
}
else
@@ -415,9 +411,15 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this)
data.len = msg_len;
DBG3(DBG_TNC, "%B", &data);
msg_value = chunk_skip(data, PB_TNC_HEADER_SIZE);
pb_tnc_msg = pb_tnc_message_create(msg_type, msg_value);
pb_tnc_msg = pb_tnc_msg_create_from_data(msg_type, msg_value);
status = pb_tnc_msg->process(pb_tnc_msg);
status = pb_tnc_msg->process(pb_tnc_msg, &offset);
if (status == FAILED || status == VERIFY_ERROR)
{
msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
PB_ERROR_INVALID_PARAMETER, this->offset);
this->errors->insert_last(this->errors, msg);
}
if (status == FAILED)
{
pb_tnc_msg->destroy(pb_tnc_msg);
@@ -425,7 +427,7 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this)
}
this->messages->insert_last(this->messages, pb_tnc_msg);
this->offset += msg_len;
return SUCCESS;
return status;
fatal:
this->errors->insert_last(this->errors, msg);
@@ -446,7 +448,7 @@ METHOD(pb_tnc_batch_t, process, status_t,
this->type);
while (this->offset < this->encoding.len)
{
switch (process_tnc_message(this))
switch (process_tnc_msg(this))
{
case FAILED:
return FAILED;
@@ -477,9 +479,9 @@ METHOD(pb_tnc_batch_t, destroy, void,
private_pb_tnc_batch_t *this)
{
this->messages->destroy_offset(this->messages,
offsetof(pb_tnc_message_t, destroy));
offsetof(pb_tnc_msg_t, destroy));
this->errors->destroy_offset(this->errors,
offsetof(pb_tnc_message_t, destroy));
offsetof(pb_tnc_msg_t, destroy));
free(this->encoding.ptr);
free(this);
}
@@ -495,7 +497,7 @@ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type)
.public = {
.get_type = _get_type,
.get_encoding = _get_encoding,
.add_message = _add_message,
.add_msg = _add_msg,
.build = _build,
.process = _process,
.create_msg_enumerator = _create_msg_enumerator,
@@ -524,7 +526,7 @@ pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data)
.public = {
.get_type = _get_type,
.get_encoding = _get_encoding,
.add_message = _add_message,
.add_msg = _add_msg,
.build = _build,
.process = _process,
.create_msg_enumerator = _create_msg_enumerator,
@@ -24,7 +24,7 @@
typedef enum pb_tnc_batch_type_t pb_tnc_batch_type_t;
typedef struct pb_tnc_batch_t pb_tnc_batch_t;
#include "messages/pb_tnc_message.h"
#include "messages/pb_tnc_msg.h"
#include "state_machine/pb_tnc_state_machine.h"
#include <library.h>
@@ -71,7 +71,7 @@ struct pb_tnc_batch_t {
*
* @param msg PB-TNC message to be addedd
*/
void (*add_message)(pb_tnc_batch_t *this, pb_tnc_message_t* msg);
void (*add_msg)(pb_tnc_batch_t *this, pb_tnc_msg_t* msg);
/**
* Build the PB-TNC Batch
@@ -13,13 +13,19 @@
* for more details.
*/
#include "pb_access_recommendation_message.h"
#include "pb_access_recommendation_msg.h"
#include <tls_writer.h>
#include <tls_reader.h>
#include <debug.h>
typedef struct private_pb_access_recommendation_message_t private_pb_access_recommendation_message_t;
ENUM(pb_access_recommendation_code_names, PB_REC_ACCESS_ALLOWED, PB_REC_QUARANTINED,
"Access Allowed",
"Access Denied",
"Quarantined"
);
typedef struct private_pb_access_recommendation_msg_t private_pb_access_recommendation_msg_t;
/**
* PB-Access-Recommendation message (see section 4.7 of RFC 5793)
@@ -32,17 +38,16 @@ typedef struct private_pb_access_recommendation_message_t private_pb_access_reco
*/
#define ACCESS_RECOMMENDATION_RESERVED 0x0000
#define ACCESS_RECOMMENDATION_MESSAGE_SIZE 4
#define ACCESS_RECOMMENDATION_MSG_SIZE 4
/**
* Private data of a private_pb_access_recommendation_message_t object.
* Private data of a private_pb_access_recommendation_msg_t object.
*
*/
struct private_pb_access_recommendation_message_t {
struct private_pb_access_recommendation_msg_t {
/**
* Public pb_access_recommendation_message_t interface.
* Public pb_access_recommendation_msg_t interface.
*/
pb_access_recommendation_message_t public;
pb_access_recommendation_msg_t public;
/**
* PB-TNC message type
@@ -60,25 +65,25 @@ struct private_pb_access_recommendation_message_t {
chunk_t encoding;
};
METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
private_pb_access_recommendation_message_t *this)
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
private_pb_access_recommendation_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_message_t, get_encoding, chunk_t,
private_pb_access_recommendation_message_t *this)
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_access_recommendation_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_message_t, build, void,
private_pb_access_recommendation_message_t *this)
METHOD(pb_tnc_msg_t, build, void,
private_pb_access_recommendation_msg_t *this)
{
tls_writer_t *writer;
/* build message */
writer = tls_writer_create(ACCESS_RECOMMENDATION_MESSAGE_SIZE);
writer = tls_writer_create(ACCESS_RECOMMENDATION_MSG_SIZE);
writer->write_uint16(writer, ACCESS_RECOMMENDATION_RESERVED);
writer->write_uint16(writer, this->recommendation);
free(this->encoding.ptr);
@@ -87,38 +92,39 @@ METHOD(pb_tnc_message_t, build, void,
writer->destroy(writer);
}
METHOD(pb_tnc_message_t, process, status_t,
private_pb_access_recommendation_message_t *this)
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_access_recommendation_msg_t *this, u_int32_t *offset)
{
tls_reader_t *reader;
u_int16_t reserved;
if (this->encoding.len < ACCESS_RECOMMENDATION_MESSAGE_SIZE)
{
DBG1(DBG_TNC,"%N message is shorter than message size of %u bytes",
pb_tnc_msg_type_names, PB_MSG_ACCESS_RECOMMENDATION,
ACCESS_RECOMMENDATION_MESSAGE_SIZE);
return FAILED;
}
/* process message */
reader = tls_reader_create(this->encoding);
reader->read_uint16(reader, &reserved);
reader->read_uint16(reader, &this->recommendation);
reader->destroy(reader);
if (this->recommendation < PB_REC_ACCESS_ALLOWED ||
this->recommendation > PB_REC_QUARANTINED)
{
DBG1(DBG_TNC, "invalid access recommendation code (%u)",
this->recommendation);
*offset = 2;
return FAILED;
}
return SUCCESS;
}
METHOD(pb_tnc_message_t, destroy, void,
private_pb_access_recommendation_message_t *this)
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_access_recommendation_msg_t *this)
{
free(this->encoding.ptr);
free(this);
}
METHOD(pb_access_recommendation_message_t, get_access_recommendation, u_int16_t,
private_pb_access_recommendation_message_t *this)
METHOD(pb_access_recommendation_msg_t, get_access_recommendation, u_int16_t,
private_pb_access_recommendation_msg_t *this)
{
return this->recommendation;
}
@@ -126,9 +132,9 @@ METHOD(pb_access_recommendation_message_t, get_access_recommendation, u_int16_t,
/**
* See header
*/
pb_tnc_message_t *pb_access_recommendation_message_create_from_data(chunk_t data)
pb_tnc_msg_t *pb_access_recommendation_msg_create_from_data(chunk_t data)
{
private_pb_access_recommendation_message_t *this;
private_pb_access_recommendation_msg_t *this;
INIT(this,
.public = {
@@ -151,9 +157,9 @@ pb_tnc_message_t *pb_access_recommendation_message_create_from_data(chunk_t data
/**
* See header
*/
pb_tnc_message_t *pb_access_recommendation_message_create(u_int16_t recommendation)
pb_tnc_msg_t *pb_access_recommendation_msg_create(u_int16_t recommendation)
{
private_pb_access_recommendation_message_t *this;
private_pb_access_recommendation_msg_t *this;
INIT(this,
.public = {
@@ -14,33 +14,49 @@
*/
/**
* @defgroup pb_access_recommendation_message pb_access_recommendation_message
* @defgroup pb_access_recommendation_msg pb_access_recommendation_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_ACCESS_RECOMMENDATION_MESSAGE_H_
#define PB_ACCESS_RECOMMENDATION_MESSAGE_H_
#ifndef PB_ACCESS_RECOMMENDATION_MSG_H_
#define PB_ACCESS_RECOMMENDATION_MSG_H_
#include "pb_tnc_message.h"
typedef enum pb_access_recommendation_code_t pb_access_recommendation_code_t;
typedef struct pb_access_recommendation_msg_t pb_access_recommendation_msg_t;
#include "pb_tnc_msg.h"
/**
* PB Access Recommendation Codes as defined in section 4.7 of RFC 5793
*/
enum pb_access_recommendation_code_t {
PB_REC_ACCESS_ALLOWED = 1,
PB_REC_ACCESS_DENIED = 2,
PB_REC_QUARANTINED = 3,
};
/**
* enum name for pb_access_recommendation_code_t.
*/
extern enum_name_t *pb_access_recommendation_code_names;
typedef struct pb_access_recommendation_message_t pb_access_recommendation_message_t;
/**
* Classs representing the PB-Access-Recommendation message type.
*/
struct pb_access_recommendation_message_t {
struct pb_access_recommendation_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_message_t pb_interface;
pb_tnc_msg_t pb_interface;
/**
* Get PB Access Recommendation
*
* @return PB Access Recommendation
*/
u_int16_t (*get_access_recommendation)(pb_access_recommendation_message_t *this);
u_int16_t (*get_access_recommendation)(pb_access_recommendation_msg_t *this);
};
/**
@@ -48,13 +64,13 @@ struct pb_access_recommendation_message_t {
*
* @param access_recommendation Access Recommendation code
*/
pb_tnc_message_t* pb_access_recommendation_message_create(u_int16_t recommendation);
pb_tnc_msg_t* pb_access_recommendation_msg_create(u_int16_t recommendation);
/**
* Create an unprocessed PB-Access-Recommendation message from raw data
*
* @param data PB-Access-Recommendation message data
*/
pb_tnc_message_t* pb_access_recommendation_message_create_from_data(chunk_t data);
pb_tnc_msg_t* pb_access_recommendation_msg_create_from_data(chunk_t data);
#endif /** PB_PA_MESSAGE_H_ @}*/
#endif /** PB_PA_MSG_H_ @}*/
@@ -13,13 +13,14 @@
* for more details.
*/
#include "pb_assessment_result_message.h"
#include "pb_assessment_result_msg.h"
#include <tls_writer.h>
#include <tls_reader.h>
#include <tnc/tncifimv.h>
#include <debug.h>
typedef struct private_pb_assessment_result_message_t private_pb_assessment_result_message_t;
typedef struct private_pb_assessment_result_msg_t private_pb_assessment_result_msg_t;
/**
* PB-Assessment-Result message (see section 4.6 of RFC 5793)
@@ -31,17 +32,17 @@ typedef struct private_pb_assessment_result_message_t private_pb_assessment_resu
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define ASSESSMENT_RESULT_MESSAGE_SIZE 4
#define ASSESSMENT_RESULT_MSG_SIZE 4
/**
* Private data of a pb_assessment_result_message_t object.
* Private data of a pb_assessment_result_msg_t object.
*
*/
struct private_pb_assessment_result_message_t {
struct private_pb_assessment_result_msg_t {
/**
* Public pb_assessment_result_message_t interface.
* Public pb_assessment_result_msg_t interface.
*/
pb_assessment_result_message_t public;
pb_assessment_result_msg_t public;
/**
* PB-TNC message type
@@ -59,25 +60,25 @@ struct private_pb_assessment_result_message_t {
chunk_t encoding;
};
METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
private_pb_assessment_result_message_t *this)
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
private_pb_assessment_result_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_message_t, get_encoding, chunk_t,
private_pb_assessment_result_message_t *this)
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_assessment_result_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_message_t, build, void,
private_pb_assessment_result_message_t *this)
METHOD(pb_tnc_msg_t, build, void,
private_pb_assessment_result_msg_t *this)
{
tls_writer_t *writer;
/* build message */
writer = tls_writer_create(ASSESSMENT_RESULT_MESSAGE_SIZE);
writer = tls_writer_create(ASSESSMENT_RESULT_MSG_SIZE);
writer->write_uint32(writer, this->assessment_result);
free(this->encoding.ptr);
this->encoding = writer->get_buf(writer);
@@ -85,36 +86,37 @@ METHOD(pb_tnc_message_t, build, void,
writer->destroy(writer);
}
METHOD(pb_tnc_message_t, process, status_t,
private_pb_assessment_result_message_t *this)
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_assessment_result_msg_t *this, u_int32_t *offset)
{
tls_reader_t *reader;
if (this->encoding.len < ASSESSMENT_RESULT_MESSAGE_SIZE)
{
DBG1(DBG_TNC,"%N message is shorter than message size of %u bytes",
pb_tnc_msg_type_names, PB_MSG_ASSESSMENT_RESULT,
ASSESSMENT_RESULT_MESSAGE_SIZE);
return FAILED;
}
/* process message */
reader = tls_reader_create(this->encoding);
reader->read_uint32(reader, &this->assessment_result);
reader->destroy(reader);
if (this->assessment_result < TNC_IMV_EVALUATION_RESULT_COMPLIANT ||
this->assessment_result > TNC_IMV_EVALUATION_RESULT_DONT_KNOW)
{
DBG1(DBG_TNC, "invalid assessment result (%u)",
this->assessment_result);
*offset = 0;
return FAILED;
}
return SUCCESS;
}
METHOD(pb_tnc_message_t, destroy, void,
private_pb_assessment_result_message_t *this)
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_assessment_result_msg_t *this)
{
free(this->encoding.ptr);
free(this);
}
METHOD(pb_assessment_result_message_t, get_assessment_result, u_int32_t,
private_pb_assessment_result_message_t *this)
METHOD(pb_assessment_result_msg_t, get_assessment_result, u_int32_t,
private_pb_assessment_result_msg_t *this)
{
return this->assessment_result;
}
@@ -122,9 +124,9 @@ METHOD(pb_assessment_result_message_t, get_assessment_result, u_int32_t,
/**
* See header
*/
pb_tnc_message_t *pb_assessment_result_message_create_from_data(chunk_t data)
pb_tnc_msg_t *pb_assessment_result_msg_create_from_data(chunk_t data)
{
private_pb_assessment_result_message_t *this;
private_pb_assessment_result_msg_t *this;
INIT(this,
.public = {
@@ -147,9 +149,9 @@ pb_tnc_message_t *pb_assessment_result_message_create_from_data(chunk_t data)
/**
* See header
*/
pb_tnc_message_t *pb_assessment_result_message_create(u_int32_t assessment_result)
pb_tnc_msg_t *pb_assessment_result_msg_create(u_int32_t assessment_result)
{
private_pb_assessment_result_message_t *this;
private_pb_assessment_result_msg_t *this;
INIT(this,
.public = {
@@ -14,33 +14,33 @@
*/
/**
* @defgroup pb_assessment_result_message pb_assessment_result_message
* @defgroup pb_assessment_result_msg pb_assessment_result_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_ASSESSMENT_RESULT_MESSAGE_H_
#define PB_ASSESSMENT_RESULT_MESSAGE_H_
#ifndef PB_ASSESSMENT_RESULT_MSG_H_
#define PB_ASSESSMENT_RESULT_MSG_H_
#include "pb_tnc_message.h"
typedef struct pb_assessment_result_msg_t pb_assessment_result_msg_t;
typedef struct pb_assessment_result_message_t pb_assessment_result_message_t;
#include "pb_tnc_msg.h"
/**
* Classs representing the PB-Assessment-Result message type.
*/
struct pb_assessment_result_message_t {
struct pb_assessment_result_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_message_t pb_interface;
pb_tnc_msg_t pb_interface;
/**
* Get PB Assessment result
*
* @return PB Assessment result
*/
u_int32_t (*get_assessment_result)(pb_assessment_result_message_t *this);
u_int32_t (*get_assessment_result)(pb_assessment_result_msg_t *this);
};
/**
@@ -48,13 +48,13 @@ struct pb_assessment_result_message_t {
*
* @param assessment_result Assessment result code
*/
pb_tnc_message_t* pb_assessment_result_message_create(u_int32_t assessment_result);
pb_tnc_msg_t* pb_assessment_result_msg_create(u_int32_t assessment_result);
/**
* Create an unprocessed PB-Assessment-Result message from raw data
*
* @param data PB-Assessment-Result message data
*/
pb_tnc_message_t* pb_assessment_result_message_create_from_data(chunk_t data);
pb_tnc_msg_t* pb_assessment_result_msg_create_from_data(chunk_t data);
#endif /** PB_PA_MESSAGE_H_ @}*/
#endif /** PB_PA_MSG_H_ @}*/
@@ -13,8 +13,7 @@
* for more details.
*/
#include "pb_error_message.h"
#include "../tnccs_20_types.h"
#include "pb_error_msg.h"
#include <debug.h>
#include <tls_writer.h>
@@ -30,7 +29,7 @@ ENUM(pb_tnc_error_code_names, PB_ERROR_UNEXPECTED_BATCH_TYPE,
"Version Not Supported"
);
typedef struct private_pb_error_message_t private_pb_error_message_t;
typedef struct private_pb_error_msg_t private_pb_error_msg_t;
/**
* PB-Error message (see section 4.9 of RFC 5793)
@@ -52,14 +51,14 @@ typedef struct private_pb_error_message_t private_pb_error_message_t;
#define ERROR_HEADER_SIZE 8
/**
* Private data of a pb_error_message_t object.
* Private data of a pb_error_msg_t object.
*
*/
struct private_pb_error_message_t {
struct private_pb_error_msg_t {
/**
* Public pb_error_message_t interface.
* Public pb_error_msg_t interface.
*/
pb_error_message_t public;
pb_error_msg_t public;
/**
* PB-TNC message type
@@ -102,20 +101,20 @@ struct private_pb_error_message_t {
refcount_t ref;
};
METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
private_pb_error_message_t *this)
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
private_pb_error_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_message_t, get_encoding, chunk_t,
private_pb_error_message_t *this)
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_error_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_message_t, build, void,
private_pb_error_message_t *this)
METHOD(pb_tnc_msg_t, build, void,
private_pb_error_msg_t *this)
{
tls_writer_t *writer;
@@ -148,8 +147,8 @@ METHOD(pb_tnc_message_t, build, void,
writer->destroy(writer);
}
METHOD(pb_tnc_message_t, process, status_t,
private_pb_error_message_t *this)
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_error_msg_t *this, u_int32_t *offset)
{
u_int8_t flags, max_version, min_version;
u_int16_t reserved;
@@ -188,15 +187,15 @@ METHOD(pb_tnc_message_t, process, status_t,
return SUCCESS;
}
METHOD(pb_tnc_message_t, get_ref, pb_tnc_message_t*,
private_pb_error_message_t *this)
METHOD(pb_tnc_msg_t, get_ref, pb_tnc_msg_t*,
private_pb_error_msg_t *this)
{
ref_get(&this->ref);
return &this->public.pb_interface;
}
METHOD(pb_tnc_message_t, destroy, void,
private_pb_error_message_t *this)
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_error_msg_t *this)
{
if (ref_put(&this->ref))
{
@@ -205,44 +204,38 @@ METHOD(pb_tnc_message_t, destroy, void,
}
}
METHOD(pb_error_message_t, get_fatal_flag, bool,
private_pb_error_message_t *this)
METHOD(pb_error_msg_t, get_fatal_flag, bool,
private_pb_error_msg_t *this)
{
return this->fatal;
}
METHOD(pb_error_message_t, get_vendor_id, u_int32_t,
private_pb_error_message_t *this)
METHOD(pb_error_msg_t, get_vendor_id, u_int32_t,
private_pb_error_msg_t *this)
{
return this->vendor_id;
}
METHOD(pb_error_message_t, get_error_code, u_int16_t,
private_pb_error_message_t *this)
METHOD(pb_error_msg_t, get_error_code, u_int16_t,
private_pb_error_msg_t *this)
{
return this->error_code;
}
METHOD(pb_error_message_t, get_offset, u_int32_t,
private_pb_error_message_t *this)
METHOD(pb_error_msg_t, get_offset, u_int32_t,
private_pb_error_msg_t *this)
{
return this->error_offset;
}
METHOD(pb_error_message_t, set_offset, void,
private_pb_error_message_t *this, u_int32_t offset)
{
this->error_offset = offset;
}
METHOD(pb_error_message_t, get_bad_version, u_int8_t,
private_pb_error_message_t *this)
METHOD(pb_error_msg_t, get_bad_version, u_int8_t,
private_pb_error_msg_t *this)
{
return this->bad_version;
}
METHOD(pb_error_message_t, set_bad_version, void,
private_pb_error_message_t *this, u_int8_t version)
METHOD(pb_error_msg_t, set_bad_version, void,
private_pb_error_msg_t *this, u_int8_t version)
{
this->bad_version = version;
}
@@ -250,10 +243,10 @@ METHOD(pb_error_message_t, set_bad_version, void,
/**
* See header
*/
pb_tnc_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id,
pb_tnc_error_code_t error_code)
pb_tnc_msg_t* pb_error_msg_create(bool fatal, u_int32_t vendor_id,
pb_tnc_error_code_t error_code)
{
private_pb_error_message_t *this;
private_pb_error_msg_t *this;
INIT(this,
.public = {
@@ -269,7 +262,6 @@ pb_tnc_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id,
.get_vendor_id = _get_vendor_id,
.get_error_code = _get_error_code,
.get_offset = _get_offset,
.set_offset = _set_offset,
.get_bad_version = _get_bad_version,
.set_bad_version = _set_bad_version,
},
@@ -286,9 +278,46 @@ pb_tnc_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id,
/**
* See header
*/
pb_tnc_message_t *pb_error_message_create_from_data(chunk_t data)
pb_tnc_msg_t* pb_error_msg_create_with_offset(bool fatal, u_int32_t vendor_id,
pb_tnc_error_code_t error_code,
u_int32_t error_offset)
{
private_pb_error_message_t *this;
private_pb_error_msg_t *this;
INIT(this,
.public = {
.pb_interface = {
.get_type = _get_type,
.get_encoding = _get_encoding,
.build = _build,
.process = _process,
.get_ref = _get_ref,
.destroy = _destroy,
},
.get_fatal_flag = _get_fatal_flag,
.get_vendor_id = _get_vendor_id,
.get_error_code = _get_error_code,
.get_offset = _get_offset,
.get_bad_version = _get_bad_version,
.set_bad_version = _set_bad_version,
},
.type = PB_MSG_ERROR,
.ref = 1,
.fatal = fatal,
.vendor_id = vendor_id,
.error_code = error_code,
.error_offset = error_offset,
);
return &this->public.pb_interface;
}
/**
* See header
*/
pb_tnc_msg_t *pb_error_msg_create_from_data(chunk_t data)
{
private_pb_error_msg_t *this;
INIT(this,
.public = {
@@ -304,7 +333,6 @@ pb_tnc_message_t *pb_error_message_create_from_data(chunk_t data)
.get_vendor_id = _get_vendor_id,
.get_error_code = _get_error_code,
.get_offset = _get_offset,
.set_offset = _set_offset,
.get_bad_version = _get_bad_version,
.set_bad_version = _set_bad_version,
},
@@ -14,27 +14,27 @@
*/
/**
* @defgroup pb_error_message pb_error_message
* @defgroup pb_error_msg pb_error_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_ERROR_MESSAGE_H_
#define PB_ERROR_MESSAGE_H_
#include "pb_tnc_message.h"
#ifndef PB_ERROR_MSG_H_
#define PB_ERROR_MSG_H_
typedef enum pb_tnc_error_code_t pb_tnc_error_code_t;
typedef struct pb_error_message_t pb_error_message_t;
typedef struct pb_error_msg_t pb_error_msg_t;
#include "pb_tnc_msg.h"
/**
* PB-TNC Error Codes as defined in section 4.9.1 of RFC 5793
*/
enum pb_tnc_error_code_t {
PB_ERROR_UNEXPECTED_BATCH_TYPE = 0,
PB_ERROR_INVALID_PARAMETER = 1,
PB_ERROR_LOCAL_ERROR = 2,
PB_ERROR_UNSUPPORTED_MANDATORY_MESSAGE = 3,
PB_ERROR_VERSION_NOT_SUPPORTED = 4
PB_ERROR_UNEXPECTED_BATCH_TYPE = 0,
PB_ERROR_INVALID_PARAMETER = 1,
PB_ERROR_LOCAL_ERROR = 2,
PB_ERROR_UNSUPPORTED_MANDATORY_MSG = 3,
PB_ERROR_VERSION_NOT_SUPPORTED = 4
};
/**
@@ -45,61 +45,54 @@ extern enum_name_t *pb_tnc_error_code_names;
/**
* Classs representing the PB-Error message type.
*/
struct pb_error_message_t {
struct pb_error_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_message_t pb_interface;
pb_tnc_msg_t pb_interface;
/**
* Get the fatal flag
*
* @return fatal flag
*/
bool (*get_fatal_flag)(pb_error_message_t *this);
bool (*get_fatal_flag)(pb_error_msg_t *this);
/**
* Get PB Error code Vendor ID
*
* @return PB Error Code Vendor ID
*/
u_int32_t (*get_vendor_id)(pb_error_message_t *this);
u_int32_t (*get_vendor_id)(pb_error_msg_t *this);
/**
* Get PB Error Code
*
* @return PB Error Code
*/
u_int16_t (*get_error_code)(pb_error_message_t *this);
u_int16_t (*get_error_code)(pb_error_msg_t *this);
/**
* Get the PB Error Offset
*
* @return PB Error Offset
*/
u_int32_t (*get_offset)(pb_error_message_t *this);
/**
* Set the PB Error Offset
*
* @param offset PB Error Offset
*/
void (*set_offset)(pb_error_message_t *this, u_int32_t offset);
u_int32_t (*get_offset)(pb_error_msg_t *this);
/**
* Get the PB Bad Version
*
* @return PB Bad Version
*/
u_int8_t (*get_bad_version)(pb_error_message_t *this);
u_int8_t (*get_bad_version)(pb_error_msg_t *this);
/**
* Set the PB Bad Version
*
* @param version PB Bad Version
*/
void (*set_bad_version)(pb_error_message_t *this, u_int8_t version);
void (*set_bad_version)(pb_error_msg_t *this, u_int8_t version);
};
/**
@@ -109,13 +102,26 @@ struct pb_error_message_t {
* @param vendor_id Error Code Vendor ID
* @param error_code Error Code
*/
pb_tnc_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id,
pb_tnc_error_code_t error_code);
pb_tnc_msg_t* pb_error_msg_create(bool fatal, u_int32_t vendor_id,
pb_tnc_error_code_t error_code);
/**
* Create a PB-Error message from parameters with offset field
*
* @param fatal fatal flag
* @param vendor_id Error Code Vendor ID
* @param error_code Error Code
* @param error_offset Error Offset
*/
pb_tnc_msg_t* pb_error_msg_create_with_offset(bool fatal, u_int32_t vendor_id,
pb_tnc_error_code_t error_code,
u_int32_t error_offset);
/**
* Create an unprocessed PB-Error message from raw data
*
* @param data PB-Error message data
*/
pb_tnc_message_t* pb_error_message_create_from_data(chunk_t data);
pb_tnc_msg_t* pb_error_msg_create_from_data(chunk_t data);
#endif /** PB_PA_MESSAGE_H_ @}*/
#endif /** PB_PA_MSG_H_ @}*/
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2010 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_experimental_msg.h"
typedef struct private_pb_experimental_msg_t private_pb_experimental_msg_t;
/**
* Private data of a private_pb_experimental_msg_t object.
*
*/
struct private_pb_experimental_msg_t {
/**
* Public pb_experimental_msg_t interface.
*/
pb_experimental_msg_t public;
/**
* PB-TNC message type
*/
pb_tnc_msg_type_t type;
/**
* Encoded message
*/
chunk_t encoding;
};
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
private_pb_experimental_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_experimental_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_msg_t, build, void,
private_pb_experimental_msg_t *this)
{
/* nothing to do since message contents equal encoding */
}
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_experimental_msg_t *this, size_t *offset)
{
return SUCCESS;
}
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_experimental_msg_t *this)
{
free(this->encoding.ptr);
free(this);
}
/**
* See header
*/
pb_tnc_msg_t *pb_experimental_msg_create_from_data(chunk_t data)
{
private_pb_experimental_msg_t *this;
INIT(this,
.public = {
.pb_interface = {
.get_type = _get_type,
.get_encoding = _get_encoding,
.build = _build,
.process = _process,
.destroy = _destroy,
},
},
.type = PB_MSG_EXPERIMENTAL,
.encoding = chunk_clone(data),
);
return &this->public.pb_interface;
}
/**
* See header
*/
pb_tnc_msg_t *pb_experimental_msg_create(chunk_t body)
{
return pb_experimental_msg_create_from_data(body);
}
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2010 Sansar Choinyambuu
* 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_experimental_msg pb_experimental_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_EXPERIMENTAL_MSG_H_
#define PB_EXPERIMENTAL_MSG_H_
typedef struct pb_experimental_msg_t pb_experimental_msg_t;
#include "pb_tnc_msg.h"
/**
* Classs representing the PB-Experimental message type.
*/
struct pb_experimental_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_msg_t pb_interface;
};
/**
* Create a PB-Experimental message from parameters
*
* @param body message body
*/
pb_tnc_msg_t* pb_experimental_msg_create(chunk_t body);
/**
* Create an unprocessed PB-Experimental message from raw data
*
* @param data PB-Experimental message data
*/
pb_tnc_msg_t* pb_experimental_msg_create_from_data(chunk_t data);
#endif /** PB_EXPERIMENTAL_MSG_H_ @}*/
@@ -13,13 +13,13 @@
* for more details.
*/
#include "pb_language_preference_message.h"
#include "pb_language_preference_msg.h"
#include <tls_writer.h>
#include <tls_reader.h>
#include <debug.h>
typedef struct private_pb_language_preference_message_t private_pb_language_preference_message_t;
typedef struct private_pb_language_preference_msg_t private_pb_language_preference_msg_t;
/**
* PB-Language-Preference message (see section 4.10 of RFC 5793)
@@ -35,14 +35,14 @@ typedef struct private_pb_language_preference_message_t private_pb_language_pref
#define PB_LANG_PREFIX_LEN strlen(PB_LANG_PREFIX)
/**
* Private data of a private_pb_language_preference_message_t object.
* Private data of a private_pb_language_preference_msg_t object.
*
*/
struct private_pb_language_preference_message_t {
struct private_pb_language_preference_msg_t {
/**
* Public pb_access_recommendation_message_t interface.
* Public pb_access_recommendation_msg_t interface.
*/
pb_language_preference_message_t public;
pb_language_preference_msg_t public;
/**
* PB-TNC message type
@@ -60,28 +60,28 @@ struct private_pb_language_preference_message_t {
chunk_t encoding;
};
METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
private_pb_language_preference_message_t *this)
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
private_pb_language_preference_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_message_t, get_encoding, chunk_t,
private_pb_language_preference_message_t *this)
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_language_preference_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_message_t, build, void,
private_pb_language_preference_message_t *this)
METHOD(pb_tnc_msg_t, build, void,
private_pb_language_preference_msg_t *this)
{
this->encoding = chunk_cat("cc",
chunk_create(PB_LANG_PREFIX, PB_LANG_PREFIX_LEN),
this->language_preference);
}
METHOD(pb_tnc_message_t, process, status_t,
private_pb_language_preference_message_t *this)
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_language_preference_msg_t *this, u_int32_t *offset)
{
chunk_t lang;
@@ -90,25 +90,36 @@ METHOD(pb_tnc_message_t, process, status_t,
{
lang = chunk_skip(this->encoding, PB_LANG_PREFIX_LEN);
this->language_preference = lang.len ? chunk_clone(lang) : chunk_empty;
return SUCCESS;
}
else
{
/* TODO generate non-fatal PB-TNC error msg */
return VERIFY_ERROR;
DBG1(DBG_TNC, "language preference must be preceded by '%s'",
PB_LANG_PREFIX);
*offset = 0;
return FAILED;
}
if (this->language_preference.len &&
this->language_preference.ptr[this->language_preference.len-1] == '\0')
{
DBG1(DBG_TNC, "language preference must not be null terminated");
*offset = PB_LANG_PREFIX_LEN + this->language_preference.len - 1;
return FAILED;
}
return SUCCESS;
}
METHOD(pb_tnc_message_t, destroy, void,
private_pb_language_preference_message_t *this)
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_language_preference_msg_t *this)
{
free(this->encoding.ptr);
free(this->language_preference.ptr);
free(this);
}
METHOD(pb_language_preference_message_t, get_language_preference, chunk_t,
private_pb_language_preference_message_t *this)
METHOD(pb_language_preference_msg_t, get_language_preference, chunk_t,
private_pb_language_preference_msg_t *this)
{
return this->language_preference;
}
@@ -116,9 +127,9 @@ METHOD(pb_language_preference_message_t, get_language_preference, chunk_t,
/**
* See header
*/
pb_tnc_message_t *pb_language_preference_message_create_from_data(chunk_t data)
pb_tnc_msg_t *pb_language_preference_msg_create_from_data(chunk_t data)
{
private_pb_language_preference_message_t *this;
private_pb_language_preference_msg_t *this;
INIT(this,
.public = {
@@ -141,9 +152,9 @@ pb_tnc_message_t *pb_language_preference_message_create_from_data(chunk_t data)
/**
* See header
*/
pb_tnc_message_t *pb_language_preference_message_create(chunk_t language_preference)
pb_tnc_msg_t *pb_language_preference_msg_create(chunk_t language_preference)
{
private_pb_language_preference_message_t *this;
private_pb_language_preference_msg_t *this;
INIT(this,
.public = {
@@ -14,33 +14,33 @@
*/
/**
* @defgroup pb_language_preference_message pb_language_preference_message
* @defgroup pb_language_preference_msg pb_language_preference_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_LANGUAGE_PREFERENCE_MESSAGE_H_
#define PB_LANGUAGE_PREFERENCE_MESSAGE_H_
#ifndef PB_LANGUAGE_PREFERENCE_MSG_H_
#define PB_LANGUAGE_PREFERENCE_MSG_H_
#include "pb_tnc_message.h"
typedef struct pb_language_preference_msg_t pb_language_preference_msg_t;
typedef struct pb_language_preference_message_t pb_language_preference_message_t;
#include "pb_tnc_msg.h"
/**
* Classs representing the PB-Language-Preference message type.
*/
struct pb_language_preference_message_t {
struct pb_language_preference_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_message_t pb_interface;
pb_tnc_msg_t pb_interface;
/**
* Get PB Language Preference
*
* @return Language preference
*/
chunk_t (*get_language_preference)(pb_language_preference_message_t *this);
chunk_t (*get_language_preference)(pb_language_preference_msg_t *this);
};
/**
@@ -48,13 +48,13 @@ struct pb_language_preference_message_t {
*
* @param language_preference Preferred language(s)
*/
pb_tnc_message_t* pb_language_preference_message_create(chunk_t language_preference);
pb_tnc_msg_t* pb_language_preference_msg_create(chunk_t language_preference);
/**
* Create an unprocessed PB-Language-Preference message from raw data
*
* @param data PB-Language-Preference message data
*/
pb_tnc_message_t* pb_language_preference_message_create_from_data(chunk_t data);
pb_tnc_msg_t* pb_language_preference_msg_create_from_data(chunk_t data);
#endif /** PB_PA_MESSAGE_H_ @}*/
#endif /** PB_PA_MSG_H_ @}*/
@@ -15,13 +15,26 @@
* for more details.
*/
#include "pb_pa_message.h"
#include "pb_pa_msg.h"
#include <tls_writer.h>
#include <tls_reader.h>
#include <tnc/tnccs/tnccs.h>
#include <debug.h>
typedef struct private_pb_pa_message_t private_pb_pa_message_t;
ENUM(pa_tnc_subtype_names, PA_SUBTYPE_TESTING, PA_SUBTYPE_NEA_CLIENT,
"Testing",
"Operating System",
"Anti-Virus",
"Anti-Spyware",
"Anti-Malware",
"Firewall",
"IDPS",
"VPN",
"NEA Client"
);
typedef struct private_pb_pa_msg_t private_pb_pa_msg_t;
/**
* PB-PA message
@@ -39,20 +52,20 @@ typedef struct private_pb_pa_message_t private_pb_pa_message_t;
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define PA_FLAG_NONE 0x00
#define PA_FLAG_EXCL (1<<7)
#define PA_FLAG_NONE 0x00
#define PA_FLAG_EXCL (1<<7)
#define PA_RESERVED_SUBTYPE 0xffffffff
#define PB_PA_HEADER_SIZE 12
/**
* Private data of a pb_pa_message_t object.
* Private data of a pb_pa_msg_t object.
*
*/
struct private_pb_pa_message_t {
struct private_pb_pa_msg_t {
/**
* Public pb_pa_message_t interface.
* Public pb_pa_msg_t interface.
*/
pb_pa_message_t public;
pb_pa_msg_t public;
/**
* PB-TNC message type
@@ -95,26 +108,26 @@ struct private_pb_pa_message_t {
chunk_t encoding;
};
METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
private_pb_pa_message_t *this)
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
private_pb_pa_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_message_t, get_encoding, chunk_t,
private_pb_pa_message_t *this)
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_pa_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_message_t, build, void,
private_pb_pa_message_t *this)
METHOD(pb_tnc_msg_t, build, void,
private_pb_pa_msg_t *this)
{
chunk_t msg_header;
tls_writer_t *writer;
/* build message header */
writer = tls_writer_create(PB_PA_HEADER_SIZE);
writer = tls_writer_create(64);
writer->write_uint8 (writer, this->excl ? PA_FLAG_EXCL : PA_FLAG_NONE);
writer->write_uint24(writer, this->vendor_id);
writer->write_uint32(writer, this->subtype);
@@ -128,20 +141,13 @@ METHOD(pb_tnc_message_t, build, void,
writer->destroy(writer);
}
METHOD(pb_tnc_message_t, process, status_t,
private_pb_pa_message_t *this)
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_pa_msg_t *this, u_int32_t *offset)
{
u_int8_t flags;
size_t msg_body_len;
tls_reader_t *reader;
if (this->encoding.len < PB_PA_HEADER_SIZE)
{
DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes",
pb_tnc_msg_type_names, PB_MSG_PA, PB_PA_HEADER_SIZE);
return FAILED;
}
/* process message header */
reader = tls_reader_create(this->encoding);
reader->read_uint8 (reader, &flags);
@@ -159,50 +165,64 @@ METHOD(pb_tnc_message_t, process, status_t,
this->msg_body = chunk_clone(this->msg_body);
}
reader->destroy(reader);
if (this->vendor_id == RESERVED_VENDOR_ID)
{
DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID);
*offset = 1;
return FAILED;
}
if (this->subtype == PA_RESERVED_SUBTYPE)
{
DBG1(DBG_TNC, "PA Subtype 0x%08x is reserved", PA_RESERVED_SUBTYPE);
*offset = 4;
}
return SUCCESS;
}
METHOD(pb_tnc_message_t, destroy, void,
private_pb_pa_message_t *this)
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_pa_msg_t *this)
{
free(this->encoding.ptr);
free(this->msg_body.ptr);
free(this);
}
METHOD(pb_pa_message_t, get_vendor_id, u_int32_t,
private_pb_pa_message_t *this, u_int32_t *subtype)
METHOD(pb_pa_msg_t, get_vendor_id, u_int32_t,
private_pb_pa_msg_t *this, u_int32_t *subtype)
{
*subtype = this->subtype;
return this->vendor_id;
}
METHOD(pb_pa_message_t, get_collector_id, u_int16_t,
private_pb_pa_message_t *this)
METHOD(pb_pa_msg_t, get_collector_id, u_int16_t,
private_pb_pa_msg_t *this)
{
return this->collector_id;
}
METHOD(pb_pa_message_t, get_validator_id, u_int16_t,
private_pb_pa_message_t *this)
METHOD(pb_pa_msg_t, get_validator_id, u_int16_t,
private_pb_pa_msg_t *this)
{
return this->validator_id;
}
METHOD(pb_pa_message_t, get_body, chunk_t,
private_pb_pa_message_t *this)
METHOD(pb_pa_msg_t, get_body, chunk_t,
private_pb_pa_msg_t *this)
{
return this->msg_body;
}
METHOD(pb_pa_message_t, get_exclusive_flag, bool,
private_pb_pa_message_t *this)
METHOD(pb_pa_msg_t, get_exclusive_flag, bool,
private_pb_pa_msg_t *this)
{
return this->excl;
}
METHOD(pb_pa_message_t, set_exclusive_flag, void,
private_pb_pa_message_t *this, bool excl)
METHOD(pb_pa_msg_t, set_exclusive_flag, void,
private_pb_pa_msg_t *this, bool excl)
{
this->excl = excl;
}
@@ -210,9 +230,9 @@ METHOD(pb_pa_message_t, set_exclusive_flag, void,
/**
* See header
*/
pb_tnc_message_t *pb_pa_message_create_from_data(chunk_t data)
pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data)
{
private_pb_pa_message_t *this;
private_pb_pa_msg_t *this;
INIT(this,
.public = {
@@ -239,12 +259,11 @@ pb_tnc_message_t *pb_pa_message_create_from_data(chunk_t data)
/**
* See header
*/
pb_tnc_message_t *pb_pa_message_create(u_int32_t vendor_id, u_int32_t subtype,
u_int16_t collector_id,
u_int16_t validator_id,
chunk_t msg_body)
pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
u_int16_t collector_id, u_int16_t validator_id,
chunk_t msg_body)
{
private_pb_pa_message_t *this;
private_pb_pa_msg_t *this;
INIT(this,
.public = {
@@ -14,26 +14,47 @@
*/
/**
* @defgroup pb_pa_message pb_pa_message
* @defgroup pb_pa_msg pb_pa_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_PA_MESSAGE_H_
#define PB_PA_MESSAGE_H_
#ifndef PB_PA_MSG_H_
#define PB_PA_MSG_H_
#include "pb_tnc_message.h"
typedef enum pa_tnc_subtype_t pa_tnc_subtype_t;
typedef struct pb_pa_msg_t pb_pa_msg_t;
typedef struct pb_pa_message_t pb_pa_message_t;
#include "pb_tnc_msg.h"
/**
* PA-TNC Subtypes as defined in section 3.5 of RFC 5792
*/
enum pa_tnc_subtype_t {
PA_SUBTYPE_TESTING = 0,
PA_SUBTYPE_OPERATING_SYSTEM = 1,
PA_SUBTYPE_ANTI_VIRUS = 2,
PA_SUBTYPE_ANTI_SPYWARE = 3,
PA_SUBTYPE_ANTI_MALWARE = 4,
PA_SUBTYPE_FIREWALL = 5,
PA_SUBTYPE_IDPS = 6,
PA_SUBTYPE_VPN = 7,
PA_SUBTYPE_NEA_CLIENT = 8
};
/**
* enum name for pa_tnc_subtype_t.
*/
extern enum_name_t *pa_tnc_subtype_names;
/**
* Classs representing the PB-PA message type.
*/
struct pb_pa_message_t {
struct pb_pa_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_message_t pb_interface;
pb_tnc_msg_t pb_interface;
/**
* Get PA Message Vendor ID and Subtype
@@ -41,42 +62,42 @@ struct pb_pa_message_t {
* @param subtype PA Subtype
* @return PA Message Vendor ID
*/
u_int32_t (*get_vendor_id)(pb_pa_message_t *this, u_int32_t *subtype);
u_int32_t (*get_vendor_id)(pb_pa_msg_t *this, u_int32_t *subtype);
/**
* Get Posture Collector ID
*
* @return Posture Collector ID
*/
u_int16_t (*get_collector_id)(pb_pa_message_t *this);
u_int16_t (*get_collector_id)(pb_pa_msg_t *this);
/**
* Get Posture Validator ID
*
* @return Posture Validator ID
*/
u_int16_t (*get_validator_id)(pb_pa_message_t *this);
u_int16_t (*get_validator_id)(pb_pa_msg_t *this);
/**
* Get the PA Message Body
*
* @return PA Message Body
*/
chunk_t (*get_body)(pb_pa_message_t *this);
chunk_t (*get_body)(pb_pa_msg_t *this);
/**
* Get the exclusive flag
*
* @return exclusive flag
*/
bool (*get_exclusive_flag)(pb_pa_message_t *this);
bool (*get_exclusive_flag)(pb_pa_msg_t *this);
/**
* Set the exclusive flag
*
* @param excl vexclusive flag
*/
void (*set_exclusive_flag)(pb_pa_message_t *this, bool excl);
void (*set_exclusive_flag)(pb_pa_msg_t *this, bool excl);
};
/**
@@ -88,16 +109,15 @@ struct pb_pa_message_t {
* @param validator_id Posture Validator ID
* @param msg_body PA Message Body
*/
pb_tnc_message_t *pb_pa_message_create(u_int32_t vendor_id, u_int32_t subtype,
u_int16_t collector_id,
u_int16_t validator_id,
chunk_t msg_body);
pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
u_int16_t collector_id, u_int16_t validator_id,
chunk_t msg_body);
/**
* Create an unprocessed PB-PA message from raw data
*
* @param data PB-PA message data
*/
pb_tnc_message_t* pb_pa_message_create_from_data(chunk_t data);
pb_tnc_msg_t* pb_pa_msg_create_from_data(chunk_t data);
#endif /** PB_PA_MESSAGE_H_ @}*/
#endif /** PB_PA_MSG_H_ @}*/
@@ -13,13 +13,13 @@
* for more details.
*/
#include "pb_reason_string_message.h"
#include "pb_reason_string_msg.h"
#include <tls_writer.h>
#include <tls_reader.h>
#include <debug.h>
typedef struct private_pb_reason_string_message_t private_pb_reason_string_message_t;
typedef struct private_pb_reason_string_msg_t private_pb_reason_string_msg_t;
/**
* PB-Language-Preference message (see section 4.11 of RFC 5793)
@@ -35,17 +35,15 @@ typedef struct private_pb_reason_string_message_t private_pb_reason_string_messa
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define REASON_STRING_HEADER_SIZE 5
/**
* Private data of a private_pb_reason_string_message_t object.
* Private data of a private_pb_reason_string_msg_t object.
*
*/
struct private_pb_reason_string_message_t {
struct private_pb_reason_string_msg_t {
/**
* Public pb_reason_string_message_t interface.
* Public pb_reason_string_msg_t interface.
*/
pb_reason_string_message_t public;
pb_reason_string_msg_t public;
/**
* PB-TNC message type
@@ -68,30 +66,27 @@ struct private_pb_reason_string_message_t {
chunk_t encoding;
};
METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
private_pb_reason_string_message_t *this)
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
private_pb_reason_string_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_message_t, get_encoding, chunk_t,
private_pb_reason_string_message_t *this)
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_reason_string_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_message_t, build, void,
private_pb_reason_string_message_t *this)
METHOD(pb_tnc_msg_t, build, void,
private_pb_reason_string_msg_t *this)
{
tls_writer_t *writer;
/* build message */
writer = tls_writer_create(REASON_STRING_HEADER_SIZE);
writer->write_uint32(writer, this->reason_string.len);
writer->write_data(writer, this->reason_string);
writer->write_uint8(writer, this->language_code.len);
writer->write_data(writer, this->language_code);
writer = tls_writer_create(64);
writer->write_data32(writer, this->reason_string);
writer->write_data8 (writer, this->language_code);
free(this->encoding.ptr);
this->encoding = writer->get_buf(writer);
@@ -99,41 +94,54 @@ METHOD(pb_tnc_message_t, build, void,
writer->destroy(writer);
}
METHOD(pb_tnc_message_t, process, status_t,
private_pb_reason_string_message_t *this)
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_reason_string_msg_t *this, u_int32_t *offset)
{
tls_reader_t *reader;
if (this->encoding.len < REASON_STRING_HEADER_SIZE)
{
DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes",
pb_tnc_msg_type_names, PB_MSG_REASON_STRING,
REASON_STRING_HEADER_SIZE);
return FAILED;
}
/* process message */
reader = tls_reader_create(this->encoding);
if (!reader->read_data32(reader, &this->reason_string))
{
DBG1(DBG_TNC, "Could not parse reason string");
DBG1(DBG_TNC, "could not parse reason string");
reader->destroy(reader);
*offset = 0;
return FAILED;
};
this->reason_string = chunk_clone(this->reason_string);
if (this->reason_string.len &&
this->reason_string.ptr[this->reason_string.len-1] == '\0')
{
DBG1(DBG_TNC, "reason string must not be null terminated");
reader->destroy(reader);
*offset = 3 + this->reason_string.len;
return FAILED;
}
if (!reader->read_data8(reader, &this->language_code))
{
DBG1(DBG_TNC, "Could not parse language code");
DBG1(DBG_TNC, "could not parse language code");
reader->destroy(reader);
*offset = 4 + this->reason_string.len;
return FAILED;
};
this->language_code = chunk_clone(this->language_code);
reader->destroy(reader);
if (this->language_code.len &&
this->language_code.ptr[this->language_code.len-1] == '\0')
{
DBG1(DBG_TNC, "language code must not be null terminated");
*offset = 4 + this->reason_string.len + this->language_code.len;
return FAILED;
}
return SUCCESS;
}
METHOD(pb_tnc_message_t, destroy, void,
private_pb_reason_string_message_t *this)
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_reason_string_msg_t *this)
{
free(this->encoding.ptr);
free(this->reason_string.ptr);
@@ -141,14 +149,14 @@ METHOD(pb_tnc_message_t, destroy, void,
free(this);
}
METHOD(pb_reason_string_message_t, get_reason_string, chunk_t,
private_pb_reason_string_message_t *this)
METHOD(pb_reason_string_msg_t, get_reason_string, chunk_t,
private_pb_reason_string_msg_t *this)
{
return this->reason_string;
}
METHOD(pb_reason_string_message_t, get_language_code, chunk_t,
private_pb_reason_string_message_t *this)
METHOD(pb_reason_string_msg_t, get_language_code, chunk_t,
private_pb_reason_string_msg_t *this)
{
return this->language_code;
}
@@ -156,9 +164,9 @@ METHOD(pb_reason_string_message_t, get_language_code, chunk_t,
/**
* See header
*/
pb_tnc_message_t *pb_reason_string_message_create_from_data(chunk_t data)
pb_tnc_msg_t *pb_reason_string_msg_create_from_data(chunk_t data)
{
private_pb_reason_string_message_t *this;
private_pb_reason_string_msg_t *this;
INIT(this,
.public = {
@@ -182,10 +190,10 @@ pb_tnc_message_t *pb_reason_string_message_create_from_data(chunk_t data)
/**
* See header
*/
pb_tnc_message_t *pb_reason_string_message_create(chunk_t reason_string,
chunk_t language_code)
pb_tnc_msg_t *pb_reason_string_msg_create(chunk_t reason_string,
chunk_t language_code)
{
private_pb_reason_string_message_t *this;
private_pb_reason_string_msg_t *this;
INIT(this,
.public = {
@@ -14,40 +14,40 @@
*/
/**
* @defgroup pb_reason_string_message pb_reason_string_message
* @defgroup pb_reason_string_msg pb_reason_string_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_REASON_STRING_MESSAGE_H_
#define PB_REASON_STRING_MESSAGE_H_
#ifndef PB_REASON_STRING_MSG_H_
#define PB_REASON_STRING_MSG_H_
#include "pb_tnc_message.h"
typedef struct pb_reason_string_msg_t pb_reason_string_msg_t;
typedef struct pb_reason_string_message_t pb_reason_string_message_t;
#include "pb_tnc_msg.h"
/**
* Classs representing the PB-Reason-String message type.
*/
struct pb_reason_string_message_t {
struct pb_reason_string_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_message_t pb_interface;
pb_tnc_msg_t pb_interface;
/**
* Get Reason String
*
* @return Reason string
*/
chunk_t (*get_reason_string)(pb_reason_string_message_t *this);
chunk_t (*get_reason_string)(pb_reason_string_msg_t *this);
/**
* Get Reason String Language Code
*
* @return Language code
*/
chunk_t (*get_language_code)(pb_reason_string_message_t *this);
chunk_t (*get_language_code)(pb_reason_string_msg_t *this);
};
/**
@@ -56,14 +56,14 @@ struct pb_reason_string_message_t {
* @param reason_string Reason string
* @param language_code Language code
*/
pb_tnc_message_t* pb_reason_string_message_create(chunk_t reason_string,
chunk_t language_code);
pb_tnc_msg_t* pb_reason_string_msg_create(chunk_t reason_string,
chunk_t language_code);
/**
* Create an unprocessed PB-Reason-String message from raw data
*
* @param data PB-Reason-String message data
*/
pb_tnc_message_t* pb_reason_string_message_create_from_data(chunk_t data);
pb_tnc_msg_t* pb_reason_string_msg_create_from_data(chunk_t data);
#endif /** PB_PA_MESSAGE_H_ @}*/
#endif /** PB_PA_MSG_H_ @}*/
@@ -0,0 +1,259 @@
/*
* Copyright (C) 2010 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_remediation_parameters_msg.h"
#include <tls_writer.h>
#include <tls_reader.h>
#include <debug.h>
ENUM(pb_tnc_remed_param_type_names, PB_REMEDIATION_URI, PB_REMEDIATION_STRING,
"Remediation-URI",
"Remediation-String"
);
typedef struct private_pb_remediation_parameters_msg_t private_pb_remediation_parameters_msg_t;
/**
* PB-Remediation-Parameters message (see section 4.8 of RFC 5793)
*
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved | Remediation Parameters Vendor ID |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Remediation Parameters Type |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Remediation Parameters (Variable Length) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Remediation String Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Remediation String (Variable Length) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Lang Code Len | Remediation String Lang Code (Variable Len) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
/**
* Private data of a private_pb_remediation_parameters_msg_t object.
*
*/
struct private_pb_remediation_parameters_msg_t {
/**
* Public pb_remediation_parameters_msg_t interface.
*/
pb_remediation_parameters_msg_t public;
/**
* PB-TNC message type
*/
pb_tnc_msg_type_t type;
/**
* Remediation Parameters Vendor ID
*/
u_int32_t vendor_id;
/**
* Remediation Parameters Type
*/
u_int32_t parameters_type;
/**
* Remediation Parameters string
*/
chunk_t remediation_string;
/**
* Language code
*/
chunk_t language_code;
/**
* Encoded message
*/
chunk_t encoding;
};
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
private_pb_remediation_parameters_msg_t *this)
{
return this->type;
}
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
private_pb_remediation_parameters_msg_t *this)
{
return this->encoding;
}
METHOD(pb_tnc_msg_t, build, void,
private_pb_remediation_parameters_msg_t *this)
{
tls_writer_t *writer;
/* build message */
writer = tls_writer_create(64);
writer->write_uint32(writer, this->vendor_id);
writer->write_uint32(writer, this->parameters_type);
writer->write_data32(writer, this->remediation_string);
writer->write_data8 (writer, this->language_code);
free(this->encoding.ptr);
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_remediation_parameters_msg_t *this, size_t *offset)
{
tls_reader_t *reader;
/* process message */
reader = tls_reader_create(this->encoding);
reader->read_uint32(reader, &this->vendor_id);
reader->read_uint32(reader, &this->parameters_type);
if (!reader->read_data32(reader, &this->remediation_string))
{
DBG1(DBG_TNC, "could not parse remediation string");
reader->destroy(reader);
*offset = 8;
return FAILED;
};
this->remediation_string = chunk_clone(this->remediation_string);
if (this->remediation_string.len &&
this->remediation_string.ptr[this->remediation_string.len-1] == '\0')
{
DBG1(DBG_TNC, "remediation string must not be null terminated");
reader->destroy(reader);
*offset = 11 + this->remediation_string.len;
return FAILED;
}
if (!reader->read_data8(reader, &this->language_code))
{
DBG1(DBG_TNC, "could not parse language code");
reader->destroy(reader);
*offset = 12 + this->remediation_string.len;
return FAILED;
};
this->language_code = chunk_clone(this->language_code);
reader->destroy(reader);
if (this->language_code.len &&
this->language_code.ptr[this->language_code.len-1] == '\0')
{
DBG1(DBG_TNC, "language code must not be null terminated");
*offset = 12 + this->remediation_string.len + this->language_code.len;
return FAILED;
}
return SUCCESS;
}
METHOD(pb_tnc_msg_t, destroy, void,
private_pb_remediation_parameters_msg_t *this)
{
free(this->encoding.ptr);
free(this->remediation_string.ptr);
free(this->language_code.ptr);
free(this);
}
METHOD(pb_remediation_parameters_msg_t, get_vendor_id, u_int32_t,
private_pb_remediation_parameters_msg_t *this, u_int32_t *type)
{
*type = this->parameters_type;
return this->vendor_id;
}
METHOD(pb_remediation_parameters_msg_t, get_remediation_string, chunk_t,
private_pb_remediation_parameters_msg_t *this)
{
return this->remediation_string;
}
METHOD(pb_remediation_parameters_msg_t, get_language_code, chunk_t,
private_pb_remediation_parameters_msg_t *this)
{
return this->language_code;
}
/**
* See header
*/
pb_tnc_msg_t *pb_remediation_parameters_msg_create_from_data(chunk_t data)
{
private_pb_remediation_parameters_msg_t *this;
INIT(this,
.public = {
.pb_interface = {
.get_type = _get_type,
.get_encoding = _get_encoding,
.build = _build,
.process = _process,
.destroy = _destroy,
},
.get_vendor_id = _get_vendor_id,
.get_remediation_string = _get_remediation_string,
.get_language_code = _get_language_code,
},
.type = PB_MSG_REASON_STRING,
.encoding = chunk_clone(data),
);
return &this->public.pb_interface;
}
/**
* See header
*/
pb_tnc_msg_t* pb_remediation_parameters_msg_create(u_int32_t vendor_id,
u_int32_t type,
chunk_t remediation_string,
chunk_t language_code)
{
private_pb_remediation_parameters_msg_t *this;
INIT(this,
.public = {
.pb_interface = {
.get_type = _get_type,
.get_encoding = _get_encoding,
.build = _build,
.process = _process,
.destroy = _destroy,
},
.get_vendor_id = _get_vendor_id,
.get_remediation_string = _get_remediation_string,
.get_language_code = _get_language_code,
},
.type = PB_MSG_REASON_STRING,
.vendor_id = vendor_id,
.parameters_type = type,
.remediation_string = chunk_clone(remediation_string),
.language_code = chunk_clone(language_code),
);
return &this->public.pb_interface;
}
@@ -0,0 +1,96 @@
/*
* Copyright (C) 2010 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_remediation_parameters_msg pb_remediation_parameters_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_REMEDIATION_PARAMETERS_MSG_H_
#define PB_REMEDIATION_PARAMETERS_MSG_H_
typedef enum pb_tnc_remed_param_type_t pb_tnc_remed_param_type_t;
typedef struct pb_remediation_parameters_msg_t pb_remediation_parameters_msg_t;
#include "pb_tnc_msg.h"
/**
* PB-TNC Remediation Parameter Types as defined in section 4.8.1 of RFC 5793
*/
enum pb_tnc_remed_param_type_t {
PB_REMEDIATION_URI = 1,
PB_REMEDIATION_STRING = 2,
};
/**
* enum name for pb_tnc_remed_param_type_t.
*/
extern enum_name_t *pb_tnc_remed_param_type_names;
/**
* Classs representing the PB-Remediation-Parameters message type.
*/
struct pb_remediation_parameters_msg_t {
/**
* PB-TNC Message interface
*/
pb_tnc_msg_t pb_interface;
/**
* Get Remediation Parameters Vendor ID and Type
*
* @param type Remediation Parameters Type
* @return Remediation Parameters Vendor ID
*/
u_int32_t (*get_vendor_id)(pb_remediation_parameters_msg_t *this,
u_int32_t *type);
/**
* Get Remediation String
*
* @return Remediation String
*/
chunk_t (*get_remediation_string)(pb_remediation_parameters_msg_t *this);
/**
* Get Reason String Language Code
*
* @return Language Code
*/
chunk_t (*get_language_code)(pb_remediation_parameters_msg_t *this);
};
/**
* Create a PB-Remediation-Parameters message from parameters
*
* @param vendor_id Remediation Parameters Vendor ID
* @param type Remediation Parameters Type
* @param remediation_string Remediation String
* @param language_code Language Code
*/
pb_tnc_msg_t* pb_remediation_parameters_msg_create(u_int32_t vendor_id,
u_int32_t type,
chunk_t remediation_string,
chunk_t language_code);
/**
* Create an unprocessed PB-Remediation-Parameters message from raw data
*
* @param data PB-Remediation-Parameters message data
*/
pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_data(chunk_t data);
#endif /** PB_PA_MSG_H_ @}*/
@@ -13,13 +13,15 @@
* for more details.
*/
#include "pb_tnc_message.h"
#include "pb_pa_message.h"
#include "pb_error_message.h"
#include "pb_language_preference_message.h"
#include "pb_assessment_result_message.h"
#include "pb_access_recommendation_message.h"
#include "pb_reason_string_message.h"
#include "pb_tnc_msg.h"
#include "pb_experimental_msg.h"
#include "pb_pa_msg.h"
#include "pb_error_msg.h"
#include "pb_language_preference_msg.h"
#include "pb_assessment_result_msg.h"
#include "pb_access_recommendation_msg.h"
#include "pb_remediation_parameters_msg.h"
#include "pb_reason_string_msg.h"
#include <library.h>
@@ -34,29 +36,40 @@ ENUM(pb_tnc_msg_type_names, PB_MSG_EXPERIMENTAL, PB_MSG_REASON_STRING,
"PB-Reason-String"
);
pb_tnc_msg_info_t pb_tnc_msg_infos[] = {
{ 12, FALSE, FALSE, TRUE_OR_FALSE },
{ 24, FALSE, FALSE, TRUE },
{ 16, TRUE, TRUE, TRUE },
{ 16, TRUE, TRUE, FALSE },
{ 20, FALSE, TRUE, FALSE },
{ 20, FALSE, FALSE, TRUE },
{ 12, FALSE, FALSE, FALSE },
{ 17, FALSE, TRUE, FALSE },
};
/**
* See header
*/
pb_tnc_message_t* pb_tnc_message_create(pb_tnc_msg_type_t type, chunk_t value)
pb_tnc_msg_t* pb_tnc_msg_create_from_data(pb_tnc_msg_type_t type, chunk_t value)
{
switch (type)
{
case PB_MSG_PA:
return pb_pa_message_create_from_data(value);
return pb_pa_msg_create_from_data(value);
case PB_MSG_ERROR:
return pb_error_message_create_from_data(value);
return pb_error_msg_create_from_data(value);
case PB_MSG_EXPERIMENTAL:
return NULL;
return pb_experimental_msg_create_from_data(value);
case PB_MSG_LANGUAGE_PREFERENCE:
return pb_language_preference_message_create_from_data(value);
return pb_language_preference_msg_create_from_data(value);
case PB_MSG_ASSESSMENT_RESULT:
return pb_assessment_result_message_create_from_data(value);
return pb_assessment_result_msg_create_from_data(value);
case PB_MSG_ACCESS_RECOMMENDATION:
return pb_access_recommendation_message_create_from_data(value);
return pb_access_recommendation_msg_create_from_data(value);
case PB_MSG_REMEDIATION_PARAMETERS:
return NULL;
return pb_remediation_parameters_msg_create_from_data(value);
case PB_MSG_REASON_STRING:
return pb_reason_string_message_create_from_data(value);
return pb_reason_string_msg_create_from_data(value);
}
return NULL;
}
@@ -14,17 +14,20 @@
*/
/**
* @defgroup pb_tnc_message pb_tnc_message
* @defgroup pb_tnc_msg pb_tnc_msg
* @{ @ingroup tnccs_20
*/
#ifndef PB_TNC_MESSAGE_H_
#define PB_TNC_MESSAGE_H_
#include <library.h>
#include <tnccs_20_types.h>
#ifndef PB_TNC_MSG_H_
#define PB_TNC_MSG_H_
typedef enum pb_tnc_msg_type_t pb_tnc_msg_type_t;
typedef struct pb_tnc_msg_info_t pb_tnc_msg_info_t;
typedef struct pb_tnc_msg_t pb_tnc_msg_t;
#include <library.h>
#define PB_TNC_VERSION 2
/**
* PB-TNC Message Types as defined in section 4.3 of RFC 5793
@@ -46,7 +49,22 @@ enum pb_tnc_msg_type_t {
*/
extern enum_name_t *pb_tnc_msg_type_names;
typedef struct pb_tnc_message_t pb_tnc_message_t;
/**
* Information entry describing a PB-TNC Message Type
*/
struct pb_tnc_msg_info_t {
u_int32_t min_size;
bool exact_size;
bool in_result_batch;
bool has_noskip_flag;
};
#define TRUE_OR_FALSE 2
/**
* Information on PB-TNC Message Types
*/
extern pb_tnc_msg_info_t pb_tnc_msg_infos[];
/**
* Generic interface for all PB-TNC message types.
@@ -54,45 +72,46 @@ typedef struct pb_tnc_message_t pb_tnc_message_t;
* To handle all messages in a generic way, this interface
* must be implemented by each message type.
*/
struct pb_tnc_message_t {
struct pb_tnc_msg_t {
/**
* Get the PB-TNC Message Type
*
* @return PB-TNC Message Type
*/
pb_tnc_msg_type_t (*get_type)(pb_tnc_message_t *this);
pb_tnc_msg_type_t (*get_type)(pb_tnc_msg_t *this);
/**
* Get the encoding of the PB-TNC Message Value
*
* @return encoded PB-TNC Message Value
*/
chunk_t (*get_encoding)(pb_tnc_message_t *this);
chunk_t (*get_encoding)(pb_tnc_msg_t *this);
/**
* Build the PB-TNC Message Value
*/
void (*build)(pb_tnc_message_t *this);
void (*build)(pb_tnc_msg_t *this);
/**
* Process the PB-TNC Message Value
*
* @param relative offset where an error occurred
* @return return processing status
*/
status_t (*process)(pb_tnc_message_t *this);
status_t (*process)(pb_tnc_msg_t *this, u_int32_t *offset);
/**
* Get a new reference to the message.
*
* @return this, with an increased refcount
*/
pb_tnc_message_t* (*get_ref)(pb_tnc_message_t *this);
pb_tnc_msg_t* (*get_ref)(pb_tnc_msg_t *this);
/**
* Destroys a pb_tnc_message_t object.
* Destroys a pb_tnc_msg_t object.
*/
void (*destroy)(pb_tnc_message_t *this);
void (*destroy)(pb_tnc_msg_t *this);
};
/**
@@ -104,6 +123,6 @@ struct pb_tnc_message_t {
* @param type PB-TNC message type
* @param value PB-TNC message value
*/
pb_tnc_message_t* pb_tnc_message_create(pb_tnc_msg_type_t type, chunk_t value);
pb_tnc_msg_t* pb_tnc_msg_create_from_data(pb_tnc_msg_type_t type, chunk_t value);
#endif /** PB_TNC_MESSAGE_H_ @}*/
#endif /** PB_TNC_MSG_H_ @}*/
@@ -14,13 +14,8 @@
*/
#include "pb_tnc_state_machine.h"
#include "messages/pb_error_message.h"
#include <debug.h>
#include <utils/linked_list.h>
#include <tls_writer.h>
#include <tls_reader.h>
#include <tnc/tnccs/tnccs.h>
ENUM(pb_tnc_state_names, PB_STATE_INIT, PB_STATE_END,
"Init",
+77 -46
View File
@@ -15,15 +15,15 @@
*/
#include "tnccs_20.h"
#include "tnccs_20_types.h"
#include "batch/pb_tnc_batch.h"
#include "messages/pb_tnc_message.h"
#include "messages/pb_pa_message.h"
#include "messages/pb_error_message.h"
#include "messages/pb_assessment_result_message.h"
#include "messages/pb_access_recommendation_message.h"
#include "messages/pb_reason_string_message.h"
#include "messages/pb_language_preference_message.h"
#include "messages/pb_tnc_msg.h"
#include "messages/pb_pa_msg.h"
#include "messages/pb_error_msg.h"
#include "messages/pb_assessment_result_msg.h"
#include "messages/pb_access_recommendation_msg.h"
#include "messages/pb_remediation_parameters_msg.h"
#include "messages/pb_reason_string_msg.h"
#include "messages/pb_language_preference_msg.h"
#include "state_machine/pb_tnc_state_machine.h"
#include <debug.h>
@@ -70,6 +70,11 @@ struct private_tnccs_20_t {
*/
mutex_t *mutex;
/**
* Flag set while processingn
*/
bool fatal_error;
/**
* Flag set by IMC/IMV RequestHandshakeRetry() function
*/
@@ -81,7 +86,7 @@ struct private_tnccs_20_t {
recommendations_t *recs;
};
METHOD(tnccs_t, send_message, void,
METHOD(tnccs_t, send_msg, void,
private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
TNC_BufferReference msg,
TNC_UInt32 msg_len,
@@ -89,13 +94,13 @@ METHOD(tnccs_t, send_message, void,
{
TNC_MessageSubtype msg_sub_type;
TNC_VendorID msg_vendor_id;
pb_tnc_message_t *pb_tnc_msg;
pb_tnc_msg_t *pb_tnc_msg;
pb_tnc_batch_type_t batch_type;
msg_sub_type = msg_type & TNC_SUBTYPE_ANY;
msg_vendor_id = (msg_type >> 8) & TNC_VENDORID_ANY;
pb_tnc_msg = pb_pa_message_create(msg_vendor_id, msg_sub_type, imc_id, imv_id,
pb_tnc_msg = pb_pa_msg_create(msg_vendor_id, msg_sub_type, imc_id, imv_id,
chunk_create(msg, msg_len));
/* adding PA message to SDATA or CDATA batch only */
@@ -107,7 +112,7 @@ METHOD(tnccs_t, send_message, void,
}
if (this->batch->get_type(this->batch) == batch_type)
{
this->batch->add_message(this->batch, pb_tnc_msg);
this->batch->add_msg(this->batch, pb_tnc_msg);
}
else
{
@@ -119,21 +124,21 @@ METHOD(tnccs_t, send_message, void,
/**
* Handle a single PB-TNC message according to its type
*/
static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg)
static void handle_msg(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
{
switch (msg->get_type(msg))
{
case PB_MSG_EXPERIMENTAL:
/* for experiments */
/* nothing to do */
break;
case PB_MSG_PA:
{
pb_pa_message_t *pa_msg;
pb_pa_msg_t *pa_msg;
TNC_MessageType msg_type;
u_int32_t vendor_id, subtype;
chunk_t msg_body;
pa_msg = (pb_pa_message_t*)msg;
pa_msg = (pb_pa_msg_t*)msg;
vendor_id = pa_msg->get_vendor_id(pa_msg, &subtype);
msg_type = (vendor_id << 8) | (subtype & 0xff);
msg_body = pa_msg->get_body(pa_msg);
@@ -154,10 +159,10 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg)
}
case PB_MSG_ASSESSMENT_RESULT:
{
pb_assessment_result_message_t *assess_msg;
pb_assessment_result_msg_t *assess_msg;
u_int32_t result;
assess_msg = (pb_assessment_result_message_t*)msg;
assess_msg = (pb_assessment_result_msg_t*)msg;
result = assess_msg->get_assessment_result(assess_msg);
DBG1(DBG_TNC, "assessment result is '%N'",
evaluation_result_names, result);
@@ -165,13 +170,13 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg)
}
case PB_MSG_ACCESS_RECOMMENDATION:
{
pb_access_recommendation_message_t *rec_msg;
u_int16_t rec;
pb_access_recommendation_msg_t *rec_msg;
pb_access_recommendation_code_t rec;
rec_msg = (pb_access_recommendation_message_t*)msg;
rec_msg = (pb_access_recommendation_msg_t*)msg;
rec = rec_msg->get_access_recommendation(rec_msg);
DBG1(DBG_TNC, "access recommendation is '%N'",
action_recommendation_names, rec);
pb_access_recommendation_code_names, rec);
break;
}
case PB_MSG_REMEDIATION_PARAMETERS:
@@ -181,22 +186,27 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg)
}
case PB_MSG_ERROR:
{
pb_error_message_t *err_msg;
pb_error_msg_t *err_msg;
bool fatal;
u_int32_t vendor_id;
u_int16_t error_code;
err_msg = (pb_error_message_t*)msg;
err_msg = (pb_error_msg_t*)msg;
fatal = err_msg->get_fatal_flag(err_msg);
vendor_id = err_msg->get_vendor_id(err_msg);
error_code = err_msg->get_error_code(err_msg);
if (fatal)
{
this->fatal_error = TRUE;
}
if (vendor_id == IETF_VENDOR_ID)
{
switch (error_code)
{
case PB_ERROR_INVALID_PARAMETER:
case PB_ERROR_UNSUPPORTED_MANDATORY_MESSAGE:
case PB_ERROR_UNSUPPORTED_MANDATORY_MSG:
DBG1(DBG_TNC, "received %s PB-TNC Error '%N' "
"(offset %u bytes)",
fatal ? "fatal" : "non-fatal",
@@ -230,10 +240,10 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg)
}
case PB_MSG_LANGUAGE_PREFERENCE:
{
pb_language_preference_message_t *lang_msg;
pb_language_preference_msg_t *lang_msg;
chunk_t lang;
lang_msg = (pb_language_preference_message_t*)msg;
lang_msg = (pb_language_preference_msg_t*)msg;
lang = lang_msg->get_language_preference(lang_msg);
DBG2(DBG_TNC, "setting language preference to '%.*s'",
@@ -243,10 +253,10 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg)
}
case PB_MSG_REASON_STRING:
{
pb_reason_string_message_t *reason_msg;
pb_reason_string_msg_t *reason_msg;
chunk_t reason_string, language_code;
reason_msg = (pb_reason_string_message_t*)msg;
reason_msg = (pb_reason_string_msg_t*)msg;
reason_string = reason_msg->get_reason_string(reason_msg);
language_code = reason_msg->get_language_code(reason_msg);
DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len,
@@ -280,14 +290,14 @@ METHOD(tls_t, process, status_t,
{
chunk_t data;
pb_tnc_batch_t *batch;
pb_tnc_message_t *msg;
pb_tnc_msg_t *msg;
enumerator_t *enumerator;
status_t status;
if (this->is_server && !this->connection_id)
{
this->connection_id = charon->tnccs->create_connection(charon->tnccs,
(tnccs_t*)this, _send_message,
(tnccs_t*)this, _send_msg,
&this->request_handshake_retry, &this->recs);
if (!this->connection_id)
{
@@ -307,7 +317,7 @@ METHOD(tls_t, process, status_t,
if (status != FAILED)
{
enumerator_t *enumerator;
pb_tnc_message_t *msg;
pb_tnc_msg_t *msg;
pb_tnc_batch_type_t batch_type;
bool empty = TRUE;
@@ -331,7 +341,7 @@ METHOD(tls_t, process, status_t,
enumerator = batch->create_msg_enumerator(batch);
while (enumerator->enumerate(enumerator, &msg))
{
handle_message(this, msg);
handle_msg(this, msg);
empty = FALSE;
}
enumerator->destroy(enumerator);
@@ -340,7 +350,16 @@ METHOD(tls_t, process, status_t,
if (this->is_server && batch_type == PB_BATCH_CLOSE && empty)
{
batch->destroy(batch);
return SUCCESS;
if (this->fatal_error)
{
DBG1(DBG_TNC, "a fatal PB-TNC Error occurred, "
"terminating connection");
return FAILED;
}
else
{
return SUCCESS;
}
}
if (this->is_server)
@@ -356,6 +375,7 @@ METHOD(tls_t, process, status_t,
switch (status)
{
case FAILED:
this->fatal_error = TRUE;
this->mutex->lock(this->mutex);
if (this->batch)
{
@@ -371,7 +391,7 @@ METHOD(tls_t, process, status_t,
while (enumerator->enumerate(enumerator, &msg))
{
this->mutex->lock(this->mutex);
this->batch->add_message(this->batch, msg->get_ref(msg));
this->batch->add_msg(this->batch, msg->get_ref(msg));
this->mutex->unlock(this->mutex);
}
enumerator->destroy(enumerator);
@@ -395,7 +415,7 @@ static void check_and_build_recommendation(private_tnccs_20_t *this)
TNC_IMVID id;
chunk_t reason, language;
enumerator_t *enumerator;
pb_tnc_message_t *msg;
pb_tnc_msg_t *msg;
if (!this->recs->have_recommendation(this->recs, &rec, &eval))
{
@@ -405,17 +425,21 @@ static void check_and_build_recommendation(private_tnccs_20_t *this)
{
this->batch = pb_tnc_batch_create(this->is_server, PB_BATCH_RESULT);
msg = pb_assessment_result_message_create(eval);
this->batch->add_message(this->batch, msg);
msg = pb_assessment_result_msg_create(eval);
this->batch->add_msg(this->batch, msg);
msg = pb_access_recommendation_message_create(rec);
this->batch->add_message(this->batch, msg);
/**
* IMV Action Recommendation and PB Access Recommendation codes
* are shifted by one.
*/
msg = pb_access_recommendation_msg_create(rec + 1);
this->batch->add_msg(this->batch, msg);
enumerator = this->recs->create_reason_enumerator(this->recs);
while (enumerator->enumerate(enumerator, &id, &reason, &language))
{
msg = pb_reason_string_message_create(reason, language);
this->batch->add_message(this->batch, msg);
msg = pb_reason_string_msg_create(reason, language);
this->batch->add_msg(this->batch, msg);
}
enumerator->destroy(enumerator);
}
@@ -429,11 +453,11 @@ METHOD(tls_t, build, status_t,
/* Initialize the connection */
if (!this->is_server && !this->connection_id)
{
pb_tnc_message_t *msg;
pb_tnc_msg_t *msg;
char *pref_lang;
this->connection_id = charon->tnccs->create_connection(charon->tnccs,
(tnccs_t*)this, _send_message,
(tnccs_t*)this, _send_msg,
&this->request_handshake_retry, NULL);
if (!this->connection_id)
{
@@ -442,11 +466,11 @@ METHOD(tls_t, build, status_t,
/* Create PB-TNC Language Preference Message */
pref_lang = charon->imcs->get_preferred_language(charon->imcs);
msg = pb_language_preference_message_create(chunk_create(pref_lang,
msg = pb_language_preference_msg_create(chunk_create(pref_lang,
strlen(pref_lang)));
this->mutex->lock(this->mutex);
this->batch = pb_tnc_batch_create(this->is_server, PB_BATCH_CDATA);
this->batch->add_message(this->batch, msg);
this->batch->add_msg(this->batch, msg);
this->mutex->unlock(this->mutex);
charon->imcs->notify_connection_change(charon->imcs,
@@ -456,6 +480,13 @@ METHOD(tls_t, build, status_t,
charon->imcs->begin_handshake(charon->imcs, this->connection_id);
}
if (this->is_server && this->fatal_error &&
this->state_machine->get_state(this->state_machine) == PB_STATE_END)
{
DBG1(DBG_TNC, "a fatal PB-TNC Error occurred, terminating connection");
return FAILED;
}
/* Do not allow any asynchronous IMCs or IMVs to add additional messages */
this->mutex->lock(this->mutex);
@@ -1,33 +0,0 @@
/*
* Copyright (C) 2010 Sansar Choinynambuu
* 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 "tnccs_20_types.h"
ENUM(pb_tnc_remed_param_type_names, PB_REMEDIATION_URI, PB_REMEDIATION_STRING,
"Remediation-URI",
"Remediation-String"
);
ENUM(pa_tnc_subtype_names, PA_SUBTYPE_TESTING, PA_SUBTYPE_NEA_CLIENT,
"Testing",
"Operating System",
"Anti-Virus",
"Anti-Spyware",
"Anti-Malware",
"Firewall",
"IDPS",
"VPN",
"NEA Client"
);
@@ -1,64 +0,0 @@
/*
* Copyright (C) 2010 Sansar Choinynambuu
* 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 tnccs_20_types_h tnccs_20
* @{ @ingroup tnccs_20
*/
#ifndef TNCCS_20_TYPES_H_
#define TNCCS_20_TYPES_H_
#define PB_TNC_VERSION 2
#include <library.h>
typedef enum pb_tnc_remed_param_type_t pb_tnc_remed_param_type_t;
typedef enum pa_tnc_subtype_t pa_tnc_subtype_t;
/**
* PB-TNC Remediation Parameter Types as defined in section 4.8.1 of RFC 5793
*/
enum pb_tnc_remed_param_type_t {
PB_REMEDIATION_URI = 1,
PB_REMEDIATION_STRING = 2,
};
/**
* enum name for pb_tnc_remed_param_type_t.
*/
extern enum_name_t *pb_tnc_remed_param_type_names;
/**
* PA-TNC Subtypes as defined in section 3.5 of RFC 5792
*/
enum pa_tnc_subtype_t {
PA_SUBTYPE_TESTING = 0,
PA_SUBTYPE_OPERATING_SYSTEM = 1,
PA_SUBTYPE_ANTI_VIRUS = 2,
PA_SUBTYPE_ANTI_SPYWARE = 3,
PA_SUBTYPE_ANTI_MALWARE = 4,
PA_SUBTYPE_FIREWALL = 5,
PA_SUBTYPE_IDPS = 6,
PA_SUBTYPE_VPN = 7,
PA_SUBTYPE_NEA_CLIENT = 8
};
/**
* enum name for pa_tnc_subtype_t.
*/
extern enum_name_t *pa_tnc_subtype_names;
#endif /** TNCCS_20_TYPES_H_ @}*/