mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-05 00:00:45 -04:00
Implemented add_segment method for PA-TNC attributes
This commit is contained in:
parent
e77df5a1f6
commit
eba0cbcee3
@ -26,6 +26,7 @@ typedef struct pa_tnc_attr_t pa_tnc_attr_t;
|
|||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <pen/pen.h>
|
#include <pen/pen.h>
|
||||||
|
|
||||||
|
#define PA_TNC_ATTR_INFO_SIZE 8
|
||||||
#define PA_TNC_ATTR_HEADER_SIZE 12
|
#define PA_TNC_ATTR_HEADER_SIZE 12
|
||||||
|
|
||||||
#define PA_TNC_ATTR_FLAG_NONE 0x00
|
#define PA_TNC_ATTR_FLAG_NONE 0x00
|
||||||
@ -73,11 +74,18 @@ struct pa_tnc_attr_t {
|
|||||||
/**
|
/**
|
||||||
* Process the value of an PA-TNC attribute to extract its parameters
|
* Process the value of an PA-TNC attribute to extract its parameters
|
||||||
*
|
*
|
||||||
* @param relative error offset within attribute body
|
* @param offset relative error offset within attribute body
|
||||||
* @return result status
|
* @return result status
|
||||||
*/
|
*/
|
||||||
status_t (*process)(pa_tnc_attr_t *this, uint32_t *offset);
|
status_t (*process)(pa_tnc_attr_t *this, uint32_t *offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a data segment to an attribute allowing incremental processing
|
||||||
|
*
|
||||||
|
* @param segment data segment to be appended
|
||||||
|
*/
|
||||||
|
void (*add_segment)(pa_tnc_attr_t *this, chunk_t segment);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a new reference to the PA-TNC attribute
|
* Get a new reference to the PA-TNC attribute
|
||||||
*
|
*
|
||||||
|
@ -120,14 +120,12 @@ METHOD(pa_tnc_attr_manager_t, get_names, enum_name_t*,
|
|||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PA_TNC_ATTR_INFO_SIZE 8
|
|
||||||
|
|
||||||
METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
|
METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
|
||||||
private_pa_tnc_attr_manager_t *this, bio_reader_t *reader, uint32_t *offset,
|
private_pa_tnc_attr_manager_t *this, bio_reader_t *reader, bool segmented,
|
||||||
chunk_t msg_info, pa_tnc_attr_t **error)
|
uint32_t *offset, chunk_t msg_info, pa_tnc_attr_t **error)
|
||||||
{
|
{
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint32_t type, length, attr_offset;
|
uint32_t type, length, value_len;
|
||||||
chunk_t value;
|
chunk_t value;
|
||||||
ietf_attr_pa_tnc_error_t *error_attr;
|
ietf_attr_pa_tnc_error_t *error_attr;
|
||||||
pen_t vendor_id;
|
pen_t vendor_id;
|
||||||
@ -177,8 +175,9 @@ METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
length -= PA_TNC_ATTR_HEADER_SIZE;
|
length -= PA_TNC_ATTR_HEADER_SIZE;
|
||||||
|
value_len = segmented ? reader->remaining(reader) : length;
|
||||||
|
|
||||||
if (!reader->read_data(reader, length, &value))
|
if (!reader->read_data(reader, value_len, &value))
|
||||||
{
|
{
|
||||||
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
|
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
|
||||||
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
@ -220,7 +219,7 @@ METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
|
|||||||
if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP))
|
if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP))
|
||||||
{
|
{
|
||||||
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
|
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
|
||||||
offset += length;
|
(*offset) += PA_TNC_ATTR_HEADER_SIZE + length;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,21 +231,7 @@ METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
|
|||||||
error_attr->set_unsupported_attr(error_attr, flags, unsupported_type);
|
error_attr->set_unsupported_attr(error_attr, flags, unsupported_type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (attr->process(attr, &attr_offset) != SUCCESS)
|
(*offset) += PA_TNC_ATTR_HEADER_SIZE;
|
||||||
{
|
|
||||||
attr->destroy(attr);
|
|
||||||
attr = NULL;
|
|
||||||
if (vendor_id == PEN_IETF && type == IETF_ATTR_PA_TNC_ERROR)
|
|
||||||
{
|
|
||||||
/* error while processing a PA-TNC error attribute - abort */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
|
|
||||||
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
|
||||||
msg_info, *offset + PA_TNC_ATTR_HEADER_SIZE + attr_offset);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
(*offset) += length;
|
|
||||||
|
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
@ -66,13 +66,14 @@ struct pa_tnc_attr_manager_t {
|
|||||||
* Create and pre-parse a PA-TNC attribute object from data
|
* Create and pre-parse a PA-TNC attribute object from data
|
||||||
*
|
*
|
||||||
* @param reader PA-TNC attribute as encoded data
|
* @param reader PA-TNC attribute as encoded data
|
||||||
|
* @param segmented TRUE if attribute is segmented
|
||||||
* @param offset Offset in bytes where an error has been found
|
* @param offset Offset in bytes where an error has been found
|
||||||
* @param msg_info Message info added to an error attribute
|
* @param msg_info Message info added to an error attribute
|
||||||
* @param error Error attribute if an error occurred
|
* @param error Error attribute if an error occurred
|
||||||
* @return PA-TNC attribute object if supported, NULL else
|
* @return PA-TNC attribute object if supported, NULL else
|
||||||
*/
|
*/
|
||||||
pa_tnc_attr_t* (*create)(pa_tnc_attr_manager_t *this, bio_reader_t *reader,
|
pa_tnc_attr_t* (*create)(pa_tnc_attr_manager_t *this, bio_reader_t *reader,
|
||||||
uint32_t *offset, chunk_t msg_info,
|
bool segmented, uint32_t *offset, chunk_t msg_info,
|
||||||
pa_tnc_attr_t **error);
|
pa_tnc_attr_t **error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +37,8 @@ typedef struct private_pa_tnc_msg_t private_pa_tnc_msg_t;
|
|||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define PA_TNC_RESERVED 0x000000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data of a pa_tnc_msg_t object.
|
* Private data of a pa_tnc_msg_t object.
|
||||||
*
|
*
|
||||||
@ -187,8 +189,10 @@ METHOD(pa_tnc_msg_t, process, status_t,
|
|||||||
{
|
{
|
||||||
bio_reader_t *reader;
|
bio_reader_t *reader;
|
||||||
pa_tnc_attr_t *attr, *error;
|
pa_tnc_attr_t *attr, *error;
|
||||||
|
pen_type_t attr_type;
|
||||||
|
chunk_t attr_value;
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
uint32_t reserved, offset;
|
uint32_t reserved, offset, attr_offset;
|
||||||
pen_type_t error_code = { PEN_IETF, PA_ERROR_INVALID_PARAMETER };
|
pen_type_t error_code = { PEN_IETF, PA_ERROR_INVALID_PARAMETER };
|
||||||
|
|
||||||
/* process message header */
|
/* process message header */
|
||||||
@ -219,15 +223,32 @@ METHOD(pa_tnc_msg_t, process, status_t,
|
|||||||
while (reader->remaining(reader) > 0)
|
while (reader->remaining(reader) > 0)
|
||||||
{
|
{
|
||||||
attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
|
attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
|
||||||
reader, &offset, this->encoding, &error);
|
reader, FALSE, &offset, this->encoding, &error);
|
||||||
if (error)
|
if (!attr)
|
||||||
{
|
{
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (attr)
|
attr_value = attr->get_value(attr);
|
||||||
|
attr_type = attr->get_type(attr);
|
||||||
|
|
||||||
|
if (attr->process(attr, &attr_offset) != SUCCESS)
|
||||||
{
|
{
|
||||||
this->attributes->insert_last(this->attributes, attr);
|
attr->destroy(attr);
|
||||||
|
|
||||||
|
if (attr_type.vendor_id == PEN_IETF &&
|
||||||
|
attr_type.type == IETF_ATTR_PA_TNC_ERROR)
|
||||||
|
{
|
||||||
|
/* suppress error while processing a PA-TNC error attribute */
|
||||||
|
offset += attr_value.len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
|
||||||
|
error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
this->encoding, offset + attr_offset);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
offset += attr_value.len;
|
||||||
|
this->attributes->insert_last(this->attributes, attr);
|
||||||
}
|
}
|
||||||
reader->destroy(reader);
|
reader->destroy(reader);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -25,9 +25,6 @@ typedef struct pa_tnc_msg_t pa_tnc_msg_t;
|
|||||||
|
|
||||||
#define PA_TNC_VERSION 0x01
|
#define PA_TNC_VERSION 0x01
|
||||||
#define PA_TNC_HEADER_SIZE 8
|
#define PA_TNC_HEADER_SIZE 8
|
||||||
#define PA_TNC_RESERVED 0x000000
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "pa_tnc_attr.h"
|
#include "pa_tnc_attr.h"
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "seg_contract.h"
|
#include "seg_contract.h"
|
||||||
#include "seg_env.h"
|
#include "seg_env.h"
|
||||||
|
#include "ietf/ietf_attr_pa_tnc_error.h"
|
||||||
#include "tcg/seg/tcg_seg_attr_seg_env.h"
|
#include "tcg/seg/tcg_seg_attr_seg_env.h"
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
@ -195,9 +196,10 @@ METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
|
|||||||
tcg_seg_attr_seg_env_t *seg_env_attr;
|
tcg_seg_attr_seg_env_t *seg_env_attr;
|
||||||
seg_env_t *current, *seg_env = NULL;
|
seg_env_t *current, *seg_env = NULL;
|
||||||
pa_tnc_attr_t *base_attr;
|
pa_tnc_attr_t *base_attr;
|
||||||
|
pen_type_t error_code;
|
||||||
uint32_t base_attr_id;
|
uint32_t base_attr_id;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
chunk_t segment_data;
|
chunk_t segment_data, msg_info;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
|
seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
|
||||||
@ -212,10 +214,7 @@ METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
|
|||||||
if (current->get_base_attr_id(current) == base_attr_id)
|
if (current->get_base_attr_id(current) == base_attr_id)
|
||||||
{
|
{
|
||||||
seg_env = current;
|
seg_env = current;
|
||||||
if (!(*more))
|
this->seg_envs->remove_at(this->seg_envs, enumerator);
|
||||||
{
|
|
||||||
this->seg_envs->remove_at(this->seg_envs, enumerator);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,13 +226,17 @@ METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
|
|||||||
{
|
{
|
||||||
DBG1(DBG_TNC, "base attribute ID %d is already in use",
|
DBG1(DBG_TNC, "base attribute ID %d is already in use",
|
||||||
base_attr_id);
|
base_attr_id);
|
||||||
|
this->seg_envs->insert_last(this->seg_envs, seg_env);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
DBG2(DBG_TNC, "received first segment for base attribute ID %d "
|
DBG2(DBG_TNC, "received first segment for base attribute ID %d "
|
||||||
"(%d bytes)", base_attr_id, segment_data.len);
|
"(%d bytes)", base_attr_id, segment_data.len);
|
||||||
seg_env = seg_env_create_from_data(base_attr_id, segment_data,
|
seg_env = seg_env_create_from_data(base_attr_id, segment_data,
|
||||||
this->max_seg_size);
|
this->max_seg_size, error);
|
||||||
this->seg_envs->insert_last(this->seg_envs, seg_env);
|
if (!seg_env)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -245,19 +248,36 @@ METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
|
|||||||
DBG2(DBG_TNC, "received %s segment for base attribute ID %d "
|
DBG2(DBG_TNC, "received %s segment for base attribute ID %d "
|
||||||
"(%d bytes)", (*more) ? "next" : "last", base_attr_id,
|
"(%d bytes)", (*more) ? "next" : "last", base_attr_id,
|
||||||
segment_data.len);
|
segment_data.len);
|
||||||
seg_env->add_segment(seg_env, segment_data);
|
if (!seg_env->add_segment(seg_env, segment_data, error))
|
||||||
|
{
|
||||||
|
seg_env->destroy(seg_env);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
base_attr = seg_env->get_base_attr(seg_env);
|
||||||
|
|
||||||
if (*more)
|
if (*more)
|
||||||
{
|
{
|
||||||
return NULL;
|
/* reinsert into list since more segments are to come */
|
||||||
|
this->seg_envs->insert_last(this->seg_envs, seg_env);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* added the last segment */
|
||||||
|
if (!base_attr)
|
||||||
|
{
|
||||||
|
/* base attribute waits for more data */
|
||||||
|
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
|
||||||
|
msg_info = seg_env->get_base_attr_info(seg_env);
|
||||||
|
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
|
||||||
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
msg_info, PA_TNC_ATTR_INFO_SIZE);
|
||||||
|
}
|
||||||
|
seg_env->destroy(seg_env);
|
||||||
}
|
}
|
||||||
base_attr = seg_env->get_base_attr(seg_env, error);
|
|
||||||
seg_env->destroy(seg_env);
|
|
||||||
|
|
||||||
return base_attr;
|
return base_attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
METHOD(seg_contract_t, is_issuer, bool,
|
METHOD(seg_contract_t, is_issuer, bool,
|
||||||
private_seg_contract_t *this)
|
private_seg_contract_t *this)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "imcv.h"
|
#include "imcv.h"
|
||||||
#include "pa_tnc/pa_tnc_msg.h"
|
#include "pa_tnc/pa_tnc_msg.h"
|
||||||
|
#include "ietf/ietf_attr_pa_tnc_error.h"
|
||||||
#include "tcg/seg/tcg_seg_attr_seg_env.h"
|
#include "tcg/seg/tcg_seg_attr_seg_env.h"
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
@ -47,21 +48,26 @@ struct private_seg_env_t {
|
|||||||
*/
|
*/
|
||||||
pa_tnc_attr_t *base_attr;
|
pa_tnc_attr_t *base_attr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Attribute Info to be used for PA-TNC error messages
|
||||||
|
*/
|
||||||
|
u_char base_attr_info[8];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Attribute needs more segment data
|
||||||
|
*/
|
||||||
|
bool need_more;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to remaining attribute data to be sent
|
||||||
|
*/
|
||||||
|
chunk_t data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum PA-TNC attribute segment size
|
* Maximum PA-TNC attribute segment size
|
||||||
*/
|
*/
|
||||||
uint32_t max_seg_size;
|
uint32_t max_seg_size;
|
||||||
|
|
||||||
/**
|
|
||||||
* TRUE if attribute is assembled from data
|
|
||||||
*/
|
|
||||||
bool from_data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remaining attribute data to be sent or received data being accumulated
|
|
||||||
*/
|
|
||||||
chunk_t data;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(seg_env_t, get_base_attr_id, uint32_t,
|
METHOD(seg_env_t, get_base_attr_id, uint32_t,
|
||||||
@ -71,33 +77,15 @@ METHOD(seg_env_t, get_base_attr_id, uint32_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(seg_env_t, get_base_attr, pa_tnc_attr_t*,
|
METHOD(seg_env_t, get_base_attr, pa_tnc_attr_t*,
|
||||||
private_seg_env_t *this, pa_tnc_attr_t** error)
|
private_seg_env_t *this)
|
||||||
{
|
{
|
||||||
*error = NULL;
|
return this->need_more ? NULL : this->base_attr->get_ref(this->base_attr);
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->base_attr)
|
METHOD(seg_env_t, get_base_attr_info, chunk_t,
|
||||||
{
|
private_seg_env_t *this)
|
||||||
bio_writer_t *writer;
|
{
|
||||||
bio_reader_t *reader;
|
return chunk_create(this->base_attr_info, 8);
|
||||||
chunk_t msg_info;
|
|
||||||
uint32_t offset = 0;
|
|
||||||
|
|
||||||
writer = bio_writer_create(8);
|
|
||||||
writer->write_uint8 (writer, PA_TNC_VERSION);
|
|
||||||
writer->write_uint24(writer, PA_TNC_RESERVED);
|
|
||||||
writer->write_uint8 (writer, BASE_ATTR_ID_PREFIX);
|
|
||||||
writer->write_uint24(writer, this->base_attr_id);
|
|
||||||
msg_info = writer->extract_buf(writer);
|
|
||||||
writer->destroy(writer);
|
|
||||||
|
|
||||||
reader = bio_reader_create(this->data);
|
|
||||||
this->base_attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
|
|
||||||
reader, &offset, msg_info, error);
|
|
||||||
chunk_free(&msg_info);
|
|
||||||
reader->destroy(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->base_attr ? this->base_attr->get_ref(this->base_attr) : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(seg_env_t, first_segment, pa_tnc_attr_t*,
|
METHOD(seg_env_t, first_segment, pa_tnc_attr_t*,
|
||||||
@ -175,19 +163,44 @@ METHOD(seg_env_t, next_segment, pa_tnc_attr_t*,
|
|||||||
return seg_env_attr;
|
return seg_env_attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(seg_env_t, add_segment, void,
|
METHOD(seg_env_t, add_segment, bool,
|
||||||
private_seg_env_t *this, chunk_t segment_data)
|
private_seg_env_t *this, chunk_t segment, pa_tnc_attr_t **error)
|
||||||
{
|
{
|
||||||
this->data = chunk_cat("mc", this->data, segment_data);
|
pen_type_t type, error_code;
|
||||||
|
uint32_t attr_offset;
|
||||||
|
chunk_t msg_info;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
/* not all attributes might have implemented the add_segment method */
|
||||||
|
if (!this->base_attr->add_segment)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
this->base_attr->add_segment(this->base_attr, segment);
|
||||||
|
status = this->base_attr->process(this->base_attr, &attr_offset);
|
||||||
|
|
||||||
|
if (status != SUCCESS && status != NEED_MORE)
|
||||||
|
{
|
||||||
|
type = this->base_attr->get_type(this->base_attr);
|
||||||
|
if (type.vendor_id == PEN_IETF && type.type == IETF_ATTR_PA_TNC_ERROR)
|
||||||
|
{
|
||||||
|
/* error while processing a PA-TNC error attribute - abort */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
|
||||||
|
msg_info = get_base_attr_info(this);
|
||||||
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
msg_info, PA_TNC_ATTR_HEADER_SIZE + attr_offset);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
this->need_more = (status == NEED_MORE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(seg_env_t, destroy, void,
|
METHOD(seg_env_t, destroy, void,
|
||||||
private_seg_env_t *this)
|
private_seg_env_t *this)
|
||||||
{
|
{
|
||||||
if (this->from_data)
|
|
||||||
{
|
|
||||||
chunk_free(&this->data);
|
|
||||||
}
|
|
||||||
DESTROY_IF(this->base_attr);
|
DESTROY_IF(this->base_attr);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@ -218,6 +231,7 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
|
|||||||
.public = {
|
.public = {
|
||||||
.get_base_attr_id = _get_base_attr_id,
|
.get_base_attr_id = _get_base_attr_id,
|
||||||
.get_base_attr = _get_base_attr,
|
.get_base_attr = _get_base_attr,
|
||||||
|
.get_base_attr_info = _get_base_attr_info,
|
||||||
.first_segment = _first_segment,
|
.first_segment = _first_segment,
|
||||||
.next_segment = _next_segment,
|
.next_segment = _next_segment,
|
||||||
.add_segment = _add_segment,
|
.add_segment = _add_segment,
|
||||||
@ -236,14 +250,20 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
|
|||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
seg_env_t *seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
|
seg_env_t *seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
|
||||||
uint32_t max_seg_size)
|
uint32_t max_seg_size, pa_tnc_attr_t** error)
|
||||||
{
|
{
|
||||||
private_seg_env_t *this;
|
private_seg_env_t *this;
|
||||||
|
pen_type_t type, error_code;
|
||||||
|
bio_reader_t *reader;
|
||||||
|
chunk_t msg_info;
|
||||||
|
uint32_t offset = 0, attr_offset;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.get_base_attr_id = _get_base_attr_id,
|
.get_base_attr_id = _get_base_attr_id,
|
||||||
.get_base_attr = _get_base_attr,
|
.get_base_attr = _get_base_attr,
|
||||||
|
.get_base_attr_info = _get_base_attr_info,
|
||||||
.first_segment = _first_segment,
|
.first_segment = _first_segment,
|
||||||
.next_segment = _next_segment,
|
.next_segment = _next_segment,
|
||||||
.add_segment = _add_segment,
|
.add_segment = _add_segment,
|
||||||
@ -251,10 +271,41 @@ seg_env_t *seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
|
|||||||
},
|
},
|
||||||
.base_attr_id = base_attr_id,
|
.base_attr_id = base_attr_id,
|
||||||
.max_seg_size = max_seg_size,
|
.max_seg_size = max_seg_size,
|
||||||
.data = chunk_clone(data),
|
|
||||||
.from_data = TRUE,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* create info field to be used by PA-TNC error messages */
|
||||||
|
memset(this->base_attr_info, 0xff, 4);
|
||||||
|
htoun32(this->base_attr_info + 4, base_attr_id);
|
||||||
|
msg_info = get_base_attr_info(this);
|
||||||
|
|
||||||
|
/* extract from base attribute segment from data */
|
||||||
|
reader = bio_reader_create(data);
|
||||||
|
this->base_attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
|
||||||
|
reader, TRUE, &offset, msg_info, error);
|
||||||
|
reader->destroy(reader);
|
||||||
|
|
||||||
|
if (!this->base_attr)
|
||||||
|
{
|
||||||
|
destroy(this);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
status = this->base_attr->process(this->base_attr, &attr_offset);
|
||||||
|
|
||||||
|
if (status != SUCCESS && status != NEED_MORE)
|
||||||
|
{
|
||||||
|
type = this->base_attr->get_type(this->base_attr);
|
||||||
|
if (!(type.vendor_id == PEN_IETF &&
|
||||||
|
type.type == IETF_ATTR_PA_TNC_ERROR))
|
||||||
|
{
|
||||||
|
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
|
||||||
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
msg_info, PA_TNC_ATTR_HEADER_SIZE + attr_offset);
|
||||||
|
}
|
||||||
|
destroy(this);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
this->need_more = (status == NEED_MORE);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,12 +50,18 @@ struct seg_env_t {
|
|||||||
uint32_t (*get_base_attr_id)(seg_env_t *this);
|
uint32_t (*get_base_attr_id)(seg_env_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Base Attribute
|
* Get Base Attribute if it contains processed [incremental] data
|
||||||
*
|
*
|
||||||
* @param error Error attribute if an error occurred or NULL
|
|
||||||
* @return Base Attribute (must be destroyed) or NULL
|
* @return Base Attribute (must be destroyed) or NULL
|
||||||
*/
|
*/
|
||||||
pa_tnc_attr_t* (*get_base_attr)(seg_env_t *this, pa_tnc_attr_t **error);
|
pa_tnc_attr_t* (*get_base_attr)(seg_env_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Attribute Info to be used by PA-TNC error messages
|
||||||
|
*
|
||||||
|
* @return Message info string
|
||||||
|
*/
|
||||||
|
chunk_t (*get_base_attr_info)(seg_env_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the first segment envelope of the base attribute
|
* Generate the first segment envelope of the base attribute
|
||||||
@ -76,8 +82,11 @@ struct seg_env_t {
|
|||||||
* Generate the first segment envelope of the base attribute
|
* Generate the first segment envelope of the base attribute
|
||||||
*
|
*
|
||||||
* @param segment Attribute segment to be added
|
* @param segment Attribute segment to be added
|
||||||
|
* @param error Error attribute if a parsing error occurred
|
||||||
|
* return TRUE if segment was successfully added
|
||||||
*/
|
*/
|
||||||
void (*add_segment)(seg_env_t *this, chunk_t segment);
|
bool (*add_segment)(seg_env_t *this, chunk_t segment,
|
||||||
|
pa_tnc_attr_t** error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys a seg_env_t object.
|
* Destroys a seg_env_t object.
|
||||||
@ -101,8 +110,10 @@ seg_env_t* seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
|
|||||||
* @param base_attr_id Base Attribute ID
|
* @param base_attr_id Base Attribute ID
|
||||||
* @param data First attribute segment
|
* @param data First attribute segment
|
||||||
* @param max_seg_size Maximum segment size
|
* @param max_seg_size Maximum segment size
|
||||||
|
* @param error Error attribute if a parsing error occurred
|
||||||
*/
|
*/
|
||||||
seg_env_t* seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
|
seg_env_t* seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
|
||||||
uint32_t max_seg_size);
|
uint32_t max_seg_size,
|
||||||
|
pa_tnc_attr_t** error);
|
||||||
|
|
||||||
#endif /** SEG_ENV_H_ @}*/
|
#endif /** SEG_ENV_H_ @}*/
|
||||||
|
@ -220,6 +220,12 @@ METHOD(pa_tnc_attr_t, process, status_t,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, add_segment, void,
|
||||||
|
private_tcg_swid_attr_req_t *this, chunk_t segment)
|
||||||
|
{
|
||||||
|
this->value = chunk_cat("mc", this->value, segment);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||||
private_tcg_swid_attr_req_t *this)
|
private_tcg_swid_attr_req_t *this)
|
||||||
{
|
{
|
||||||
@ -285,6 +291,7 @@ pa_tnc_attr_t *tcg_swid_attr_req_create(u_int8_t flags, u_int32_t request_id,
|
|||||||
.set_noskip_flag = _set_noskip_flag,
|
.set_noskip_flag = _set_noskip_flag,
|
||||||
.build = _build,
|
.build = _build,
|
||||||
.process = _process,
|
.process = _process,
|
||||||
|
.add_segment = _add_segment,
|
||||||
.get_ref = _get_ref,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
@ -321,6 +328,7 @@ pa_tnc_attr_t *tcg_swid_attr_req_create_from_data(size_t length, chunk_t data)
|
|||||||
.set_noskip_flag = _set_noskip_flag,
|
.set_noskip_flag = _set_noskip_flag,
|
||||||
.build = _build,
|
.build = _build,
|
||||||
.process = _process,
|
.process = _process,
|
||||||
|
.add_segment = _add_segment,
|
||||||
.get_ref = _get_ref,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
@ -224,6 +224,12 @@ METHOD(pa_tnc_attr_t, process, status_t,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, add_segment, void,
|
||||||
|
private_tcg_swid_attr_tag_id_inv_t *this, chunk_t segment)
|
||||||
|
{
|
||||||
|
this->value = chunk_cat("mc", this->value, segment);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||||
private_tcg_swid_attr_tag_id_inv_t *this)
|
private_tcg_swid_attr_tag_id_inv_t *this)
|
||||||
{
|
{
|
||||||
@ -288,6 +294,7 @@ pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create(uint32_t request_id,
|
|||||||
.set_noskip_flag = _set_noskip_flag,
|
.set_noskip_flag = _set_noskip_flag,
|
||||||
.build = _build,
|
.build = _build,
|
||||||
.process = _process,
|
.process = _process,
|
||||||
|
.add_segment = _add_segment,
|
||||||
.get_ref = _get_ref,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
@ -325,6 +332,7 @@ pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create_from_data(size_t length,
|
|||||||
.set_noskip_flag = _set_noskip_flag,
|
.set_noskip_flag = _set_noskip_flag,
|
||||||
.build = _build,
|
.build = _build,
|
||||||
.process = _process,
|
.process = _process,
|
||||||
|
.add_segment = _add_segment,
|
||||||
.get_ref = _get_ref,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
@ -213,6 +213,12 @@ METHOD(pa_tnc_attr_t, process, status_t,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, add_segment, void,
|
||||||
|
private_tcg_swid_attr_tag_inv_t *this, chunk_t segment)
|
||||||
|
{
|
||||||
|
this->value = chunk_cat("mc", this->value, segment);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||||
private_tcg_swid_attr_tag_inv_t *this)
|
private_tcg_swid_attr_tag_inv_t *this)
|
||||||
{
|
{
|
||||||
@ -276,6 +282,7 @@ pa_tnc_attr_t *tcg_swid_attr_tag_inv_create(uint32_t request_id,
|
|||||||
.set_noskip_flag = _set_noskip_flag,
|
.set_noskip_flag = _set_noskip_flag,
|
||||||
.build = _build,
|
.build = _build,
|
||||||
.process = _process,
|
.process = _process,
|
||||||
|
.add_segment = _add_segment,
|
||||||
.get_ref = _get_ref,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
@ -312,6 +319,7 @@ pa_tnc_attr_t *tcg_swid_attr_tag_inv_create_from_data(size_t length,
|
|||||||
.set_noskip_flag = _set_noskip_flag,
|
.set_noskip_flag = _set_noskip_flag,
|
||||||
.build = _build,
|
.build = _build,
|
||||||
.process = _process,
|
.process = _process,
|
||||||
|
.add_segment = _add_segment,
|
||||||
.get_ref = _get_ref,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user