implemented the RFC 5792 PA-TNC protocol and an example IMC/IMV pair

This commit is contained in:
Andreas Steffen
2011-05-30 21:30:09 +02:00
parent 61420db66c
commit 510f37abd4
27 changed files with 3089 additions and 1 deletions
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright (C) 2011 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 "pa_tnc_attr.h"
#include "ietf/ietf_attr.h"
#include "ietf/ietf_attr_pa_tnc_error.h"
#include "ita/ita_attr_command.h"
/**
* See header
*/
pa_tnc_attr_t* pa_tnc_attr_create_from_data(pen_t vendor_id, u_int32_t type,
chunk_t value)
{
switch (vendor_id)
{
case PEN_IETF:
switch (type)
{
case IETF_ATTR_PA_TNC_ERROR:
return ietf_attr_pa_tnc_error_create_from_data(value);
case IETF_ATTR_TESTING:
case IETF_ATTR_ATTRIBUTE_REQUEST:
case IETF_ATTR_PRODUCT_INFORMATION:
case IETF_ATTR_NUMERIC_VERSION:
case IETF_ATTR_STRING_VERSION:
case IETF_ATTR_OPERATIONAL_STATUS:
case IETF_ATTR_PORT_FILTER:
case IETF_ATTR_INSTALLED_PACKAGES:
case IETF_ATTR_ASSESSMENT_RESULT:
case IETF_ATTR_REMEDIATION_INSTRUCTIONS:
case IETF_ATTR_FORWARDING_ENABLED:
case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
case IETF_ATTR_RESERVED:
default:
break;
}
break;
case PEN_ITA:
switch (type)
{
case ITA_ATTR_COMMAND:
return ita_attr_command_create_from_data(value);
default:
break;
}
break;
default:
break;
}
return NULL;
}
+99
View File
@@ -0,0 +1,99 @@
/*
* Copyright (C) 2011 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 pa_tnc_attr pa_tnc_attr
* @{ @ingroup libimcv
*/
#ifndef PA_TNC_ATTR_H_
#define PA_TNC_ATTR_H_
typedef struct pa_tnc_attr_t pa_tnc_attr_t;
#include <library.h>
#include <tnc/pen/pen.h>
/**
* Interface for an RFC 5792 PA-TNC Posture Attribute.
*
*/
struct pa_tnc_attr_t {
/**
* Get the vendor ID of an PA-TNC attribute
*
* @return attribute vendor ID
*/
u_int32_t (*get_vendor_id)(pa_tnc_attr_t *this);
/**
* Get the type of an PA-TNC attribute
*
* @return attribute type
*/
u_int32_t (*get_type)(pa_tnc_attr_t *this);
/**
* Get the value of an PA-TNC attribute
*
* @return attribute value
*/
chunk_t (*get_value)(pa_tnc_attr_t *this);
/**
* Get the noskip flag
*
* @return TRUE if the noskip flag is set
*/
bool (*get_noskip_flag)(pa_tnc_attr_t *this);
/**
* Set the noskip flag
*
* @param noskip_flag TRUE if the noskip flag is to be set
*/
void (*set_noskip_flag)(pa_tnc_attr_t *this, bool noskip);
/**
* Build value of an PA-TNC attribute from its parameters
*/
void (*build)(pa_tnc_attr_t *this);
/**
* Process the value of an PA-TNC attribute to extract its parameters
*
* @return result status
*/
status_t (*process)(pa_tnc_attr_t *this);
/**
* Destroys a pa_tnc_attr_t object.
*/
void (*destroy)(pa_tnc_attr_t *this);
};
/**
* Create a PA-TNC attribute from data
*
* @param vendor_id attribute vendor ID
* @param type attribute type
* @param value attribute value
*
*/
pa_tnc_attr_t* pa_tnc_attr_create_from_data(pen_t vendor_id, u_int32_t type,
chunk_t value);
#endif /** PA_TNC_ATTR_H_ @}*/
+292
View File
@@ -0,0 +1,292 @@
/*
* Copyright (C) 2011 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 "pa_tnc_msg.h"
#include <tls_writer.h>
#include <tls_reader.h>
#include <utils/linked_list.h>
#include <tnc/pen/pen.h>
#include <debug.h>
typedef struct private_pa_tnc_msg_t private_pa_tnc_msg_t;
/**
* PA-TNC message header
*
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Version | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Message Identifier |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define PA_TNC_HEADER_SIZE 8
#define PA_TNC_VERSION 0x01
#define PA_TNC_RESERVED 0x000000
/**
* PA-TNC attribute
*
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Flags | PA-TNC Attribute Vendor ID |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | PA-TNC Attribute Type |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | PA-TNC Attribute Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Attribute Value (Variable Length) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define PA_TNC_ATTR_FLAG_NONE 0x00
#define PA_TNC_ATTR_FLAG_NOSKIP (1<<7)
#define PA_TNC_ATTR_HEADER_SIZE 12
/**
* Private data of a pa_tnc_msg_t object.
*
*/
struct private_pa_tnc_msg_t {
/**
* Public pa_tnc_msg_t interface.
*/
pa_tnc_msg_t public;
/**
* List of PA-TNC attributes
*/
linked_list_t *attributes;
/**
* Message identifier
*/
u_int32_t identifier;
/**
* Encoded message
*/
chunk_t encoding;
};
METHOD(pa_tnc_msg_t, get_encoding, chunk_t,
private_pa_tnc_msg_t *this)
{
return this->encoding;
}
METHOD(pa_tnc_msg_t, add_attribute, void,
private_pa_tnc_msg_t *this, pa_tnc_attr_t *attr)
{
this->attributes->insert_last(this->attributes, attr);
}
METHOD(pa_tnc_msg_t, build, void,
private_pa_tnc_msg_t *this)
{
tls_writer_t *writer;
enumerator_t *enumerator;
pa_tnc_attr_t *attr;
pen_t vendor_id;
u_int32_t type;
u_int8_t flags;
chunk_t value;
rng_t *rng;
/* create a random message identifier */
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
rng->get_bytes(rng, sizeof(this->identifier), (u_int8_t*)&this->identifier);
rng->destroy(rng);
DBG2(DBG_TNC, "creating PA-TNC message with ID 0x%08x", this->identifier);
/* build message header */
writer = tls_writer_create(PA_TNC_HEADER_SIZE);
writer->write_uint8 (writer, PA_TNC_VERSION);
writer->write_uint24(writer, PA_TNC_RESERVED);
writer->write_uint32(writer, this->identifier);
/* build and append encoding of PA-TNC attributes */
enumerator = this->attributes->create_enumerator(this->attributes);
while (enumerator->enumerate(enumerator, &attr))
{
attr->build(attr);
vendor_id = attr->get_vendor_id(attr);
type = attr->get_type(attr);
value = attr->get_value(attr);
flags = attr->get_noskip_flag(attr) ? PA_TNC_ATTR_FLAG_NOSKIP :
PA_TNC_ATTR_FLAG_NONE;
DBG2(DBG_TNC, "creating PA-TNC attribute type 0x%06x(%N)/0x%08x",
vendor_id, pen_names, vendor_id, type);
DBG3(DBG_TNC, "%B", &value);
writer->write_uint8 (writer, flags);
writer->write_uint24(writer, vendor_id);
writer->write_uint32(writer, type);
writer->write_uint32(writer, PA_TNC_ATTR_HEADER_SIZE + value.len);
writer->write_data (writer, value);
}
enumerator->destroy(enumerator);
free(this->encoding.ptr);
this->encoding = chunk_clone(writer->get_buf(writer));
writer->destroy(writer);
}
METHOD(pa_tnc_msg_t, process, status_t,
private_pa_tnc_msg_t *this)
{
u_int8_t version;
u_int32_t reserved;
tls_reader_t *reader;
status_t status = FAILED;
reader = tls_reader_create(this->encoding);
/* process message header */
if (reader->remaining(reader) < PA_TNC_HEADER_SIZE)
{
DBG1(DBG_TNC, "%u bytes insufficient to parse PA-TNC message header",
this->encoding.len);
goto end;
}
reader->read_uint8 (reader, &version);
reader->read_uint24(reader, &reserved);
reader->read_uint32(reader, &this->identifier);
if (version != PA_TNC_VERSION)
{
DBG1(DBG_TNC, "PA-TNC version %u not supported", version);
goto end;
}
DBG2(DBG_TNC, "processing PA-TNC message with ID 0x%08x", this->identifier);
/* pre-process PA-TNC attributes */
while (reader->remaining(reader) >= PA_TNC_ATTR_HEADER_SIZE)
{
pen_t vendor_id;
u_int8_t flags;
u_int32_t type, length;
chunk_t value;
pa_tnc_attr_t *attr;
reader->read_uint8 (reader, &flags);
reader->read_uint24(reader, &vendor_id);
reader->read_uint32(reader, &type);
reader->read_uint32(reader, &length);
DBG2(DBG_TNC, "processing PA-TNC attribute type 0x%06x(%N)/0x%08x",
vendor_id, pen_names, vendor_id, type);
if (length < PA_TNC_ATTR_HEADER_SIZE)
{
DBG1(DBG_TNC, "%u bytes too small for PA-TNC attribute length",
length);
goto end;
}
length -= PA_TNC_ATTR_HEADER_SIZE;
if (!reader->read_data(reader, length , &value))
{
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
goto end;
}
DBG3(DBG_TNC, "%B", &value);
attr = pa_tnc_attr_create_from_data(vendor_id, type, value);
if (!attr)
{
if (flags & PA_TNC_ATTR_FLAG_NOSKIP)
{
DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag");
goto end;
}
else
{
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
}
}
if (attr->process(attr) != SUCCESS)
{
attr->destroy(attr);
goto end;
}
add_attribute(this, attr);
}
if (reader->remaining(reader) == 0)
{
status = SUCCESS;
}
end:
reader->destroy(reader);
return status;
}
METHOD(pa_tnc_msg_t, create_attribute_enumerator, enumerator_t*,
private_pa_tnc_msg_t *this)
{
return this->attributes->create_enumerator(this->attributes);
}
METHOD(pa_tnc_msg_t, destroy, void,
private_pa_tnc_msg_t *this)
{
this->attributes->destroy_offset(this->attributes,
offsetof(pa_tnc_attr_t, destroy));
free(this->encoding.ptr);
free(this);
}
/**
* See header
*/
pa_tnc_msg_t *pa_tnc_msg_create_from_data(chunk_t data)
{
private_pa_tnc_msg_t *this;
INIT(this,
.public = {
.get_encoding = _get_encoding,
.add_attribute = _add_attribute,
.build = _build,
.process = _process,
.create_attribute_enumerator = _create_attribute_enumerator,
.destroy = _destroy,
},
.encoding = chunk_clone(data),
.attributes = linked_list_create(),
);
return &this->public;
}
/**
* See header
*/
pa_tnc_msg_t *pa_tnc_msg_create(void)
{
return pa_tnc_msg_create_from_data(chunk_empty);
}
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright (C) 2011 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 pa_tnc_msg pa_tnc_msg
* @{ @ingroup libimcv
*/
#ifndef PA_TNC_MSG_H_
#define PA_TNC_MSG_H_
typedef struct pa_tnc_msg_t pa_tnc_msg_t;
#include "pa_tnc_attr.h"
#include <library.h>
/**
* Interface for the RFC 5792 PA-TNC Posture Attribute protocol.
*
*/
struct pa_tnc_msg_t {
/**
* Get the encoding of the PA-TNC message
*
* @return encoded PA-TNC message
*/
chunk_t (*get_encoding)(pa_tnc_msg_t *this);
/**
* Add a PA-TNC attribute
*
* @param attr PA-TNC attribute to be addedd
*/
void (*add_attribute)(pa_tnc_msg_t *this, pa_tnc_attr_t* attr);
/**
* Build the PA-TNC message
*/
void (*build)(pa_tnc_msg_t *this);
/**
* Process the PA-TNC message
*
* @return return processing status
*/
status_t (*process)(pa_tnc_msg_t *this);
/**
* Enumerates over all PA-TNC attributes
*
* @return return attribute enumerator
*/
enumerator_t* (*create_attribute_enumerator)(pa_tnc_msg_t *this);
/**
* Destroys a pa_tnc_msg_t object.
*/
void (*destroy)(pa_tnc_msg_t *this);
};
/**
* Create an empty PA-TNC message
*/
pa_tnc_msg_t* pa_tnc_msg_create(void);
/**
* Create an unprocessed PA-TNC message from received data
*
* @param data PA-TNC message data
*/
pa_tnc_msg_t* pa_tnc_msg_create_from_data(chunk_t data);
#endif /** PA_TNC_MSG_H_ @}*/