Determine type of unsupported PA-TNC attribute in error message
This commit is contained in:
@@ -133,14 +133,19 @@ struct private_ietf_attr_pa_tnc_error_t {
|
|||||||
chunk_t msg_info;
|
chunk_t msg_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* First 8 bytes of unsupported PA-TNC attribute
|
* Flags of unsupported PA-TNC attribute
|
||||||
*/
|
*/
|
||||||
chunk_t attr_info;
|
uint8_t flags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor ID and type of unsupported PA-TNC attribute
|
||||||
|
*/
|
||||||
|
pen_type_t unsupported_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PA-TNC error offset
|
* PA-TNC error offset
|
||||||
*/
|
*/
|
||||||
u_int32_t error_offset;
|
uint32_t error_offset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference count
|
* Reference count
|
||||||
@@ -200,7 +205,9 @@ METHOD(pa_tnc_attr_t, build, void,
|
|||||||
writer->write_uint16(writer, PA_ERROR_VERSION_RESERVED);
|
writer->write_uint16(writer, PA_ERROR_VERSION_RESERVED);
|
||||||
break;
|
break;
|
||||||
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
|
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
|
||||||
writer->write_data(writer, this->attr_info);
|
writer->write_uint8 (writer, this->flags);
|
||||||
|
writer->write_uint24(writer, this->unsupported_type.vendor_id);
|
||||||
|
writer->write_uint32(writer, this->unsupported_type.type);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -211,10 +218,11 @@ METHOD(pa_tnc_attr_t, build, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pa_tnc_attr_t, process, status_t,
|
METHOD(pa_tnc_attr_t, process, status_t,
|
||||||
private_ietf_attr_pa_tnc_error_t *this, u_int32_t *offset)
|
private_ietf_attr_pa_tnc_error_t *this, uint32_t *offset)
|
||||||
{
|
{
|
||||||
bio_reader_t *reader;
|
bio_reader_t *reader;
|
||||||
u_int8_t reserved;
|
uint8_t reserved;
|
||||||
|
uint32_t vendor_id, type;
|
||||||
|
|
||||||
if (this->value.len < PA_ERROR_HEADER_SIZE)
|
if (this->value.len < PA_ERROR_HEADER_SIZE)
|
||||||
{
|
{
|
||||||
@@ -250,8 +258,7 @@ METHOD(pa_tnc_attr_t, process, status_t,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
|
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
|
||||||
if (!reader->read_data(reader, PA_ERROR_ATTR_INFO_SIZE,
|
if (reader->remaining(reader) < PA_ERROR_ATTR_INFO_SIZE)
|
||||||
&this->attr_info))
|
|
||||||
{
|
{
|
||||||
reader->destroy(reader);
|
reader->destroy(reader);
|
||||||
DBG1(DBG_TNC, "insufficient data for unsupported attribute "
|
DBG1(DBG_TNC, "insufficient data for unsupported attribute "
|
||||||
@@ -259,7 +266,10 @@ METHOD(pa_tnc_attr_t, process, status_t,
|
|||||||
*offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE;
|
*offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE;
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
this->attr_info = chunk_clone(this->attr_info);
|
reader->read_uint8 (reader, &this->flags);
|
||||||
|
reader->read_uint24(reader, &vendor_id);
|
||||||
|
reader->read_uint32(reader, &type);
|
||||||
|
this->unsupported_type = pen_type_create(vendor_id, type);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -289,7 +299,6 @@ METHOD(pa_tnc_attr_t, destroy, void,
|
|||||||
{
|
{
|
||||||
free(this->value.ptr);
|
free(this->value.ptr);
|
||||||
free(this->msg_info.ptr);
|
free(this->msg_info.ptr);
|
||||||
free(this->attr_info.ptr);
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,19 +315,24 @@ METHOD(ietf_attr_pa_tnc_error_t, get_msg_info, chunk_t,
|
|||||||
return this->msg_info;
|
return this->msg_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ietf_attr_pa_tnc_error_t, get_attr_info, chunk_t,
|
METHOD(ietf_attr_pa_tnc_error_t, get_unsupported_attr, pen_type_t,
|
||||||
private_ietf_attr_pa_tnc_error_t *this)
|
private_ietf_attr_pa_tnc_error_t *this, uint8_t *flags)
|
||||||
{
|
{
|
||||||
return this->attr_info;
|
if (flags)
|
||||||
|
{
|
||||||
|
*flags = this->flags;
|
||||||
|
}
|
||||||
|
return this->unsupported_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ietf_attr_pa_tnc_error_t, set_attr_info, void,
|
METHOD(ietf_attr_pa_tnc_error_t, set_unsupported_attr, void,
|
||||||
private_ietf_attr_pa_tnc_error_t *this, chunk_t attr_info)
|
private_ietf_attr_pa_tnc_error_t *this, uint8_t flags, pen_type_t type)
|
||||||
{
|
{
|
||||||
this->attr_info = chunk_clone(attr_info);
|
this->flags = flags;
|
||||||
|
this->unsupported_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ietf_attr_pa_tnc_error_t, get_offset, u_int32_t,
|
METHOD(ietf_attr_pa_tnc_error_t, get_offset, uint32_t,
|
||||||
private_ietf_attr_pa_tnc_error_t *this)
|
private_ietf_attr_pa_tnc_error_t *this)
|
||||||
{
|
{
|
||||||
return this->error_offset;
|
return this->error_offset;
|
||||||
@@ -345,8 +359,8 @@ static private_ietf_attr_pa_tnc_error_t* create_generic()
|
|||||||
},
|
},
|
||||||
.get_error_code = _get_error_code,
|
.get_error_code = _get_error_code,
|
||||||
.get_msg_info = _get_msg_info,
|
.get_msg_info = _get_msg_info,
|
||||||
.get_attr_info = _get_attr_info,
|
.get_unsupported_attr = _get_unsupported_attr,
|
||||||
.set_attr_info = _set_attr_info,
|
.set_unsupported_attr = _set_unsupported_attr,
|
||||||
.get_offset = _get_offset,
|
.get_offset = _get_offset,
|
||||||
},
|
},
|
||||||
.type = { PEN_IETF, IETF_ATTR_PA_TNC_ERROR },
|
.type = { PEN_IETF, IETF_ATTR_PA_TNC_ERROR },
|
||||||
@@ -385,7 +399,7 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_type_t error_code,
|
|||||||
*/
|
*/
|
||||||
pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code,
|
pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code,
|
||||||
chunk_t msg_info,
|
chunk_t msg_info,
|
||||||
u_int32_t error_offset)
|
uint32_t error_offset)
|
||||||
{
|
{
|
||||||
private_ietf_attr_pa_tnc_error_t *this;
|
private_ietf_attr_pa_tnc_error_t *this;
|
||||||
|
|
||||||
|
|||||||
@@ -69,25 +69,29 @@ struct ietf_attr_pa_tnc_error_t {
|
|||||||
chunk_t (*get_msg_info)(ietf_attr_pa_tnc_error_t *this);
|
chunk_t (*get_msg_info)(ietf_attr_pa_tnc_error_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get first 8 bytes of unsupported PA-TNC attribute
|
* Get flags, vendor ID and type of unsupported PA-TNC attribute
|
||||||
*
|
*
|
||||||
* @return PA-TNC attribute info
|
* @param flags PA-TNC attribute flags
|
||||||
|
* @return PA-TNC attribute vendor ID and type
|
||||||
*/
|
*/
|
||||||
chunk_t (*get_attr_info)(ietf_attr_pa_tnc_error_t *this);
|
pen_type_t (*get_unsupported_attr)(ietf_attr_pa_tnc_error_t *this,
|
||||||
|
uint8_t *flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set first 8 bytes of unsupported PA-TNC attribute
|
* Set flags, vendor ID and type of unsupported PA-TNC attribute
|
||||||
*
|
*
|
||||||
* @param attr_info PA-TNC message info
|
* @param flags PA-TNC attribute flags
|
||||||
|
* @param attr_info PA-TNC attribute vendor ID and type
|
||||||
*/
|
*/
|
||||||
void (*set_attr_info)(ietf_attr_pa_tnc_error_t *this, chunk_t attr_info);
|
void (*set_unsupported_attr)(ietf_attr_pa_tnc_error_t *this, uint8_t flags,
|
||||||
|
pen_type_t type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the PA-TNC error offset
|
* Get the PA-TNC error offset
|
||||||
*
|
*
|
||||||
* @return PA-TNC error offset
|
* @return PA-TNC error offset
|
||||||
*/
|
*/
|
||||||
u_int32_t (*get_offset)(ietf_attr_pa_tnc_error_t *this);
|
uint32_t (*get_offset)(ietf_attr_pa_tnc_error_t *this);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,7 +115,7 @@ pa_tnc_attr_t* ietf_attr_pa_tnc_error_create(pen_type_t error_code,
|
|||||||
*/
|
*/
|
||||||
pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code,
|
pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code,
|
||||||
chunk_t header,
|
chunk_t header,
|
||||||
u_int32_t error_offset);
|
uint32_t error_offset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an ietf_attr_pa_tnc_error_t object from received data
|
* Creates an ietf_attr_pa_tnc_error_t object from received data
|
||||||
|
|||||||
@@ -236,13 +236,12 @@ METHOD(pa_tnc_msg_t, process, status_t,
|
|||||||
pen_t vendor_id;
|
pen_t vendor_id;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint32_t type, length;
|
uint32_t type, length;
|
||||||
chunk_t value, attr_info;
|
chunk_t value;
|
||||||
pa_tnc_attr_t *attr;
|
pa_tnc_attr_t *attr;
|
||||||
enum_name_t *pa_attr_names;
|
enum_name_t *pa_attr_names;
|
||||||
ietf_attr_pa_tnc_error_t *error_attr;
|
ietf_attr_pa_tnc_error_t *error_attr;
|
||||||
|
pen_type_t unsupported_type;
|
||||||
|
|
||||||
attr_info = reader->peek(reader);
|
|
||||||
attr_info.len = PA_TNC_ATTR_INFO_SIZE;
|
|
||||||
reader->read_uint8 (reader, &flags);
|
reader->read_uint8 (reader, &flags);
|
||||||
reader->read_uint24(reader, &vendor_id);
|
reader->read_uint24(reader, &vendor_id);
|
||||||
reader->read_uint32(reader, &type);
|
reader->read_uint32(reader, &type);
|
||||||
@@ -297,23 +296,21 @@ METHOD(pa_tnc_msg_t, process, status_t,
|
|||||||
vendor_id, type, value);
|
vendor_id, type, value);
|
||||||
if (!attr)
|
if (!attr)
|
||||||
{
|
{
|
||||||
if (flags & PA_TNC_ATTR_FLAG_NOSKIP)
|
if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP))
|
||||||
{
|
|
||||||
DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag");
|
|
||||||
error_code = pen_type_create(PEN_IETF,
|
|
||||||
PA_ERROR_ATTR_TYPE_NOT_SUPPORTED);
|
|
||||||
error = ietf_attr_pa_tnc_error_create(error_code,
|
|
||||||
this->encoding);
|
|
||||||
error_attr = (ietf_attr_pa_tnc_error_t*)error;
|
|
||||||
error_attr->set_attr_info(error_attr, attr_info);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
|
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
|
||||||
offset += length;
|
offset += length;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag");
|
||||||
|
unsupported_type = pen_type_create(vendor_id, type);
|
||||||
|
error_code = pen_type_create(PEN_IETF,
|
||||||
|
PA_ERROR_ATTR_TYPE_NOT_SUPPORTED);
|
||||||
|
error = ietf_attr_pa_tnc_error_create(error_code, this->encoding);
|
||||||
|
error_attr = (ietf_attr_pa_tnc_error_t*)error;
|
||||||
|
error_attr->set_unsupported_attr(error_attr, flags, unsupported_type);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->process(attr, &attr_offset) != SUCCESS)
|
if (attr->process(attr, &attr_offset) != SUCCESS)
|
||||||
@@ -355,8 +352,10 @@ METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool,
|
|||||||
private_pa_tnc_msg_t *this)
|
private_pa_tnc_msg_t *this)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
enum_name_t *pa_attr_names;
|
||||||
pa_tnc_attr_t *attr;
|
pa_tnc_attr_t *attr;
|
||||||
pen_type_t type;
|
pen_type_t type, unsupported_type;
|
||||||
|
uint8_t flags;
|
||||||
bool fatal_error = FALSE;
|
bool fatal_error = FALSE;
|
||||||
|
|
||||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||||
@@ -368,7 +367,7 @@ METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool,
|
|||||||
{
|
{
|
||||||
ietf_attr_pa_tnc_error_t *error_attr;
|
ietf_attr_pa_tnc_error_t *error_attr;
|
||||||
pen_type_t error_code;
|
pen_type_t error_code;
|
||||||
chunk_t msg_info, attr_info;
|
chunk_t msg_info;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
|
|
||||||
error_attr = (ietf_attr_pa_tnc_error_t*)attr;
|
error_attr = (ietf_attr_pa_tnc_error_t*)attr;
|
||||||
@@ -391,8 +390,28 @@ METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool,
|
|||||||
DBG1(DBG_TNC, " occurred at offset of %u bytes", offset);
|
DBG1(DBG_TNC, " occurred at offset of %u bytes", offset);
|
||||||
break;
|
break;
|
||||||
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
|
case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
|
||||||
attr_info = error_attr->get_attr_info(error_attr);
|
unsupported_type =
|
||||||
DBG1(DBG_TNC, " unsupported attribute %#B", &attr_info);
|
error_attr->get_unsupported_attr(error_attr, &flags);
|
||||||
|
pa_attr_names =
|
||||||
|
imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
|
||||||
|
unsupported_type.vendor_id);
|
||||||
|
if (pa_attr_names)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, " unsupported attribute type '%N/%N' "
|
||||||
|
"0x%06x/0x%08x, flags 0x%02x",
|
||||||
|
pen_names, unsupported_type.vendor_id,
|
||||||
|
pa_attr_names, unsupported_type.type,
|
||||||
|
unsupported_type.vendor_id, unsupported_type.type,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, " unsupported attribute type '%N' "
|
||||||
|
"0x%06x/0x%08x, flags 0x%02x",
|
||||||
|
pen_names, unsupported_type.vendor_id,
|
||||||
|
unsupported_type.vendor_id, unsupported_type.type,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user