mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-15 00:00:16 -04:00
implemented parsing of TNCCS 1.1 messages
This commit is contained in:
parent
33749b879c
commit
5fee822a93
@ -106,8 +106,6 @@ METHOD(tnccs_batch_t, process, status_t,
|
|||||||
xmlChar *batchid, *recipient;
|
xmlChar *batchid, *recipient;
|
||||||
int batch_id;
|
int batch_id;
|
||||||
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
this->doc = xmlParseMemory(this->encoding.ptr, this->encoding.len);
|
this->doc = xmlParseMemory(this->encoding.ptr, this->encoding.len);
|
||||||
if (!this->doc)
|
if (!this->doc)
|
||||||
{
|
{
|
||||||
@ -206,30 +204,28 @@ METHOD(tnccs_batch_t, process, status_t,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tnccs_msg = tnccs_msg_create_from_node(cur);
|
tnccs_msg = tnccs_msg_create_from_node(cur, this->errors);
|
||||||
|
|
||||||
|
/* exit if a message parsing error occurred */
|
||||||
|
if (this->errors->get_count(this->errors) > 0)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore unrecognized messages */
|
||||||
if (!tnccs_msg)
|
if (!tnccs_msg)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names,
|
|
||||||
tnccs_msg->get_type(tnccs_msg));
|
|
||||||
status = tnccs_msg->process(tnccs_msg);
|
|
||||||
if (status == FAILED)
|
|
||||||
{
|
|
||||||
tnccs_msg->destroy(tnccs_msg);
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
this->messages->insert_last(this->messages, tnccs_msg);
|
this->messages->insert_last(this->messages, tnccs_msg);
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
|
||||||
fatal:
|
fatal:
|
||||||
DBG1(DBG_TNC, "%s", error_msg);
|
|
||||||
msg = tnccs_error_msg_create(error_type, error_msg);
|
msg = tnccs_error_msg_create(error_type, error_msg);
|
||||||
this->errors->insert_last(this->errors, msg);
|
this->errors->insert_last(this->errors, msg);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnccs_batch_t, create_msg_enumerator, enumerator_t*,
|
METHOD(tnccs_batch_t, create_msg_enumerator, enumerator_t*,
|
||||||
@ -238,6 +234,12 @@ METHOD(tnccs_batch_t, create_msg_enumerator, enumerator_t*,
|
|||||||
return this->messages->create_enumerator(this->messages);
|
return this->messages->create_enumerator(this->messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(tnccs_batch_t, create_error_enumerator, enumerator_t*,
|
||||||
|
private_tnccs_batch_t *this)
|
||||||
|
{
|
||||||
|
return this->errors->create_enumerator(this->errors);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tnccs_batch_t, destroy, void,
|
METHOD(tnccs_batch_t, destroy, void,
|
||||||
private_tnccs_batch_t *this)
|
private_tnccs_batch_t *this)
|
||||||
{
|
{
|
||||||
@ -267,6 +269,7 @@ tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id)
|
|||||||
.build = _build,
|
.build = _build,
|
||||||
.process = _process,
|
.process = _process,
|
||||||
.create_msg_enumerator = _create_msg_enumerator,
|
.create_msg_enumerator = _create_msg_enumerator,
|
||||||
|
.create_error_enumerator = _create_error_enumerator,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.is_server = is_server,
|
.is_server = is_server,
|
||||||
@ -305,6 +308,7 @@ tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id, chunk_
|
|||||||
.build = _build,
|
.build = _build,
|
||||||
.process = _process,
|
.process = _process,
|
||||||
.create_msg_enumerator = _create_msg_enumerator,
|
.create_msg_enumerator = _create_msg_enumerator,
|
||||||
|
.create_error_enumerator = _create_error_enumerator,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.is_server = is_server,
|
.is_server = is_server,
|
||||||
|
@ -66,6 +66,13 @@ struct tnccs_batch_t {
|
|||||||
*/
|
*/
|
||||||
enumerator_t* (*create_msg_enumerator)(tnccs_batch_t *this);
|
enumerator_t* (*create_msg_enumerator)(tnccs_batch_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerates over all parsing errors
|
||||||
|
*
|
||||||
|
* @return return error enumerator
|
||||||
|
*/
|
||||||
|
enumerator_t* (*create_error_enumerator)(tnccs_batch_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys a tnccs_batch_t object.
|
* Destroys a tnccs_batch_t object.
|
||||||
*/
|
*/
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <tnc/tnccs/tnccs.h>
|
#include <tnc/tnccs/tnccs.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <utils/lexparser.h>
|
||||||
|
|
||||||
typedef struct private_imc_imv_msg_t private_imc_imv_msg_t;
|
typedef struct private_imc_imv_msg_t private_imc_imv_msg_t;
|
||||||
|
|
||||||
@ -54,26 +55,8 @@ struct private_imc_imv_msg_t {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
|
||||||
private_imc_imv_msg_t *this)
|
|
||||||
{
|
|
||||||
return this->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
|
||||||
private_imc_imv_msg_t *this)
|
|
||||||
{
|
|
||||||
return this->node;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, process, status_t,
|
|
||||||
private_imc_imv_msg_t *this)
|
|
||||||
{
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts message data into multiple base64-encoded lines
|
* Encodes message data into multiple base64-encoded lines
|
||||||
*/
|
*/
|
||||||
static chunk_t encode_base64(chunk_t data)
|
static chunk_t encode_base64(chunk_t data)
|
||||||
{
|
{
|
||||||
@ -106,6 +89,41 @@ static chunk_t encode_base64(chunk_t data)
|
|||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes message data from multiple base64-encoded lines
|
||||||
|
*/
|
||||||
|
static chunk_t decode_base64(chunk_t data)
|
||||||
|
{
|
||||||
|
chunk_t decoding, data_line, b64_line;
|
||||||
|
u_char *pos;
|
||||||
|
|
||||||
|
/* compute and allocate maximum size of decoded message data */
|
||||||
|
decoding = chunk_alloc(3 * ((data.len + 3) / 4));
|
||||||
|
pos = decoding.ptr;
|
||||||
|
decoding.len = 0;
|
||||||
|
|
||||||
|
while (fetchline(&data, &b64_line))
|
||||||
|
{
|
||||||
|
data_line = chunk_from_base64(b64_line, pos);
|
||||||
|
pos += data_line.len;
|
||||||
|
decoding.len += data_line.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return decoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
||||||
|
private_imc_imv_msg_t *this)
|
||||||
|
{
|
||||||
|
return this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
||||||
|
private_imc_imv_msg_t *this)
|
||||||
|
{
|
||||||
|
return this->node;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, destroy, void,
|
METHOD(tnccs_msg_t, destroy, void,
|
||||||
private_imc_imv_msg_t *this)
|
private_imc_imv_msg_t *this)
|
||||||
{
|
{
|
||||||
@ -128,16 +146,19 @@ METHOD(imc_imv_msg_t, get_msg_body, chunk_t,
|
|||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node)
|
tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node, linked_list_t *errors)
|
||||||
{
|
{
|
||||||
private_imc_imv_msg_t *this;
|
private_imc_imv_msg_t *this;
|
||||||
|
xmlNsPtr ns;
|
||||||
|
xmlNodePtr cur;
|
||||||
|
xmlChar *content;
|
||||||
|
chunk_t b64_body;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_msg_type = _get_msg_type,
|
.get_msg_type = _get_msg_type,
|
||||||
@ -147,6 +168,26 @@ tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node)
|
|||||||
.node = node,
|
.node = node,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ns = node->ns;
|
||||||
|
cur = node->xmlChildrenNode;
|
||||||
|
while (cur)
|
||||||
|
{
|
||||||
|
if (streq((char*)cur->name, "Type") && cur->ns == ns)
|
||||||
|
{
|
||||||
|
content = xmlNodeGetContent(cur);
|
||||||
|
this->msg_type = strtoul((char*)content, NULL, 16);
|
||||||
|
xmlFree(content);
|
||||||
|
}
|
||||||
|
else if (streq((char*)cur->name, "Base64") && cur->ns == ns)
|
||||||
|
{
|
||||||
|
content = xmlNodeGetContent(cur);
|
||||||
|
b64_body = chunk_create((char*)content, strlen((char*)content));
|
||||||
|
this->msg_body = decode_base64(b64_body);
|
||||||
|
xmlFree(content);
|
||||||
|
}
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
return &this->public.tnccs_msg_interface;
|
return &this->public.tnccs_msg_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +206,6 @@ tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body)
|
|||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_msg_type = _get_msg_type,
|
.get_msg_type = _get_msg_type,
|
||||||
|
@ -56,8 +56,9 @@ struct imc_imv_msg_t {
|
|||||||
* Create an IMC-IMV message from XML-encoded message node
|
* Create an IMC-IMV message from XML-encoded message node
|
||||||
*
|
*
|
||||||
* @param msg_node XML-encoded message node
|
* @param msg_node XML-encoded message node
|
||||||
*/
|
* @param errors linked list of TNCCS error messages
|
||||||
tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node);
|
*/
|
||||||
|
tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node, linked_list_t *errors);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an IMC-IMV message from parameters
|
* Create an IMC-IMV message from parameters
|
||||||
|
@ -57,6 +57,11 @@ struct private_tnccs_error_msg_t {
|
|||||||
* Error message
|
* Error message
|
||||||
*/
|
*/
|
||||||
char *error_msg;
|
char *error_msg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reference count
|
||||||
|
*/
|
||||||
|
refcount_t ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
||||||
@ -71,17 +76,21 @@ METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
|||||||
return this->node;
|
return this->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, process, status_t,
|
METHOD(tnccs_msg_t, get_ref, tnccs_msg_t*,
|
||||||
private_tnccs_error_msg_t *this)
|
private_tnccs_error_msg_t *this)
|
||||||
{
|
{
|
||||||
return SUCCESS;
|
ref_get(&this->ref);
|
||||||
|
return &this->public.tnccs_msg_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, destroy, void,
|
METHOD(tnccs_msg_t, destroy, void,
|
||||||
private_tnccs_error_msg_t *this)
|
private_tnccs_error_msg_t *this)
|
||||||
{
|
{
|
||||||
free(this->error_msg);
|
if (ref_put(&this->ref))
|
||||||
free(this);
|
{
|
||||||
|
free(this->error_msg);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnccs_error_msg_t, get_message, char*,
|
METHOD(tnccs_error_msg_t, get_message, char*,
|
||||||
@ -98,21 +107,42 @@ METHOD(tnccs_error_msg_t, get_message, char*,
|
|||||||
tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node)
|
tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node)
|
||||||
{
|
{
|
||||||
private_tnccs_error_msg_t *this;
|
private_tnccs_error_msg_t *this;
|
||||||
|
xmlChar *error_type_name, *error_msg;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_message = _get_message,
|
.get_message = _get_message,
|
||||||
},
|
},
|
||||||
.type = TNCCS_MSG_ERROR,
|
.type = TNCCS_MSG_ERROR,
|
||||||
.node = node,
|
.node = node,
|
||||||
|
.error_type = TNCCS_ERROR_OTHER,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
error_type_name = xmlGetProp(node, (const xmlChar*)"type");
|
||||||
|
if (error_type_name)
|
||||||
|
{
|
||||||
|
this->error_type = enum_from_name(tnccs_error_type_names,
|
||||||
|
(char*)error_type_name);
|
||||||
|
if (this->error_type == -1)
|
||||||
|
{
|
||||||
|
this->error_type = TNCCS_ERROR_OTHER;
|
||||||
|
}
|
||||||
|
xmlFree(error_type_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_msg = xmlNodeGetContent(node);
|
||||||
|
if (error_msg)
|
||||||
|
{
|
||||||
|
this->error_msg = strdup((char*)error_msg);
|
||||||
|
xmlFree(error_msg);
|
||||||
|
}
|
||||||
|
|
||||||
return &this->public.tnccs_msg_interface;
|
return &this->public.tnccs_msg_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +159,7 @@ tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg)
|
|||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_message = _get_message,
|
.get_message = _get_message,
|
||||||
@ -140,18 +170,20 @@ tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg)
|
|||||||
.error_msg = strdup(msg),
|
.error_msg = strdup(msg),
|
||||||
);
|
);
|
||||||
|
|
||||||
n = xmlNewNode(NULL, BAD_CAST "Type");
|
DBG1(DBG_TNC, "%s", msg);
|
||||||
xmlNodeSetContent(n, BAD_CAST "00000002");
|
|
||||||
xmlAddChild(this->node, n);
|
|
||||||
|
|
||||||
n = xmlNewNode(NULL, BAD_CAST "XML");
|
n = xmlNewNode(NULL, BAD_CAST "Type");
|
||||||
xmlAddChild(this->node, n);
|
xmlNodeSetContent(n, BAD_CAST "00000002");
|
||||||
|
xmlAddChild(this->node, n);
|
||||||
|
|
||||||
n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
|
n = xmlNewNode(NULL, BAD_CAST "XML");
|
||||||
xmlNewProp(n2, BAD_CAST "type",
|
xmlAddChild(this->node, n);
|
||||||
|
|
||||||
|
n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
|
||||||
|
xmlNewProp(n2, BAD_CAST "type",
|
||||||
BAD_CAST enum_to_name(tnccs_error_type_names, type));
|
BAD_CAST enum_to_name(tnccs_error_type_names, type));
|
||||||
xmlNodeSetContent(n2, BAD_CAST msg);
|
xmlNodeSetContent(n2, BAD_CAST msg);
|
||||||
xmlAddChild(n, n2);
|
xmlAddChild(n, n2);
|
||||||
|
|
||||||
return &this->public.tnccs_msg_interface;
|
return &this->public.tnccs_msg_interface;
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ struct tnccs_error_msg_t {
|
|||||||
/**
|
/**
|
||||||
* Get error message and type
|
* Get error message and type
|
||||||
*
|
*
|
||||||
* @param type TNCCS error type
|
* @param type TNCCS error type
|
||||||
* @return arbitrary error message
|
* @return arbitrary error message
|
||||||
*/
|
*/
|
||||||
char* (*get_message)(tnccs_error_msg_t *this, tnccs_error_type_t *type);
|
char* (*get_message)(tnccs_error_msg_t *this, tnccs_error_type_t *type);
|
||||||
};
|
};
|
||||||
@ -65,7 +65,7 @@ struct tnccs_error_msg_t {
|
|||||||
/**
|
/**
|
||||||
* Create a TNCCS-Error message from XML-encoded message node
|
* Create a TNCCS-Error message from XML-encoded message node
|
||||||
*
|
*
|
||||||
* @param msg_node XML-encoded message node
|
* @param msg_node XML-encoded message node
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node);
|
tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node);
|
||||||
|
|
||||||
|
@ -36,19 +36,24 @@ ENUM(tnccs_msg_type_names, IMC_IMV_MSG, TNCCS_MSG_ROOF,
|
|||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node)
|
tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors)
|
||||||
{
|
{
|
||||||
|
char *error_msg, buf[BUF_LEN];
|
||||||
|
tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||||
|
tnccs_msg_t *msg;
|
||||||
tnccs_msg_type_t type = IMC_IMV_MSG;
|
tnccs_msg_type_t type = IMC_IMV_MSG;
|
||||||
|
|
||||||
if (streq((char*)node->name, "IMC-IMV-Message"))
|
if (streq((char*)node->name, "IMC-IMV-Message"))
|
||||||
{
|
{
|
||||||
return imc_imv_msg_create_from_node(node);
|
DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names, type);
|
||||||
|
return imc_imv_msg_create_from_node(node, errors);
|
||||||
}
|
}
|
||||||
else if (streq((char*)node->name, "TNCC-TNCS-Message"))
|
else if (streq((char*)node->name, "TNCC-TNCS-Message"))
|
||||||
{
|
{
|
||||||
bool found = FALSE;
|
bool found = FALSE;
|
||||||
xmlNsPtr ns = node->ns;
|
xmlNsPtr ns = node->ns;
|
||||||
xmlNodePtr cur = node->xmlChildrenNode;
|
xmlNodePtr cur = node->xmlChildrenNode;
|
||||||
|
xmlNodePtr xml_msg_node = NULL;
|
||||||
|
|
||||||
while (cur)
|
while (cur)
|
||||||
{
|
{
|
||||||
@ -59,27 +64,66 @@ tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node)
|
|||||||
type = strtol((char*)content, NULL, 16);
|
type = strtol((char*)content, NULL, 16);
|
||||||
xmlFree(content);
|
xmlFree(content);
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
}
|
||||||
|
else if (streq((char*)cur->name, "XML") && cur->ns == ns)
|
||||||
|
{
|
||||||
|
xml_msg_node = cur->xmlChildrenNode;
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
DBG1(DBG_TNC, "ignoring TNCC-TNCS-Messsage without type");
|
error_msg = "Type is missing in TNCC-TNCS-Message";
|
||||||
return NULL;
|
goto fatal;
|
||||||
}
|
}
|
||||||
|
if (!xml_msg_node)
|
||||||
|
{
|
||||||
|
error_msg = "XML node is missing in TNCC-TNCS-Message";
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
cur = xml_msg_node;
|
||||||
|
|
||||||
|
/* skip empty and blank nodes */
|
||||||
|
while (cur && xmlIsBlankNode(cur))
|
||||||
|
{
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
if (!cur)
|
||||||
|
{
|
||||||
|
error_msg = "XML node is empty";
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if TNCCS message type and node name agree */
|
||||||
|
if (type >= TNCCS_MSG_RECOMMENDATION && type <= TNCCS_MSG_ROOF)
|
||||||
|
{
|
||||||
|
DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names, type);
|
||||||
|
if (cur->ns != ns)
|
||||||
|
{
|
||||||
|
error_msg = "node is not in the TNCCS message namespace";
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
if (type != enum_from_name(tnccs_msg_type_names, (char*)cur->name))
|
||||||
|
{
|
||||||
|
error_msg = buf;
|
||||||
|
snprintf(buf, BUF_LEN, "expected '%N' node but was '%s'",
|
||||||
|
tnccs_msg_type_names, type, (char*)cur->name);
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TNCCS_MSG_RECOMMENDATION:
|
case TNCCS_MSG_RECOMMENDATION:
|
||||||
return tnccs_recommendation_msg_create_from_node(node);
|
return tnccs_recommendation_msg_create_from_node(cur, errors);
|
||||||
case TNCCS_MSG_ERROR:
|
case TNCCS_MSG_ERROR:
|
||||||
return tnccs_error_msg_create_from_node(node);
|
return tnccs_error_msg_create_from_node(cur);
|
||||||
case TNCCS_MSG_PREFERRED_LANGUAGE:
|
case TNCCS_MSG_PREFERRED_LANGUAGE:
|
||||||
return tnccs_preferred_language_msg_create_from_node(node);
|
return tnccs_preferred_language_msg_create_from_node(cur, errors);
|
||||||
case TNCCS_MSG_REASON_STRINGS:
|
case TNCCS_MSG_REASON_STRINGS:
|
||||||
return tnccs_reason_strings_msg_create_from_node(node);
|
return tnccs_reason_strings_msg_create_from_node(cur, errors);
|
||||||
case TNCCS_MSG_TNCS_CONTACT_INFO:
|
case TNCCS_MSG_TNCS_CONTACT_INFO:
|
||||||
return tnccs_tncs_contact_info_msg_create_from_node(node);
|
return tnccs_tncs_contact_info_msg_create_from_node(cur, errors);
|
||||||
default:
|
default:
|
||||||
DBG1(DBG_TNC, "ignoring TNCC-TNCS-Message with type %d", type);
|
DBG1(DBG_TNC, "ignoring TNCC-TNCS-Message with type %d", type);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -87,5 +131,10 @@ tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node)
|
|||||||
}
|
}
|
||||||
DBG1(DBG_TNC, "ignoring unknown message node '%s'", (char*)node->name);
|
DBG1(DBG_TNC, "ignoring unknown message node '%s'", (char*)node->name);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
fatal:
|
||||||
|
msg = tnccs_error_msg_create(error_type, error_msg);
|
||||||
|
errors->insert_last(errors, msg);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ typedef enum tnccs_msg_type_t tnccs_msg_type_t;
|
|||||||
typedef struct tnccs_msg_t tnccs_msg_t;
|
typedef struct tnccs_msg_t tnccs_msg_t;
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
#include <utils/linked_list.h>
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,6 +75,13 @@ struct tnccs_msg_t {
|
|||||||
*/
|
*/
|
||||||
status_t (*process)(tnccs_msg_t *this);
|
status_t (*process)(tnccs_msg_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new reference to the message.
|
||||||
|
*
|
||||||
|
* @return this, with an increased refcount
|
||||||
|
*/
|
||||||
|
tnccs_msg_t* (*get_ref)(tnccs_msg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys a tnccs_msg_t object.
|
* Destroys a tnccs_msg_t object.
|
||||||
*/
|
*/
|
||||||
@ -81,13 +89,14 @@ struct tnccs_msg_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an unprocessed TNCCS message
|
* Create a pre-processed TNCCS message
|
||||||
*
|
*
|
||||||
* Useful for the parser which wants a generic constructor for all
|
* Useful for the parser which wants a generic constructor for all
|
||||||
* tnccs_msg_t types.
|
* tnccs_msg_t types.
|
||||||
*
|
*
|
||||||
* @param node TNCCS message node
|
* @param node TNCCS message node
|
||||||
|
* @param errors linked list of TNCCS error messages
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node);
|
tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors);
|
||||||
|
|
||||||
#endif /** TNCCS_MSG_H_ @}*/
|
#endif /** TNCCS_MSG_H_ @}*/
|
||||||
|
@ -57,12 +57,6 @@ METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
|||||||
return this->node;
|
return this->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, process, status_t,
|
|
||||||
private_tnccs_preferred_language_msg_t *this)
|
|
||||||
{
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, destroy, void,
|
METHOD(tnccs_msg_t, destroy, void,
|
||||||
private_tnccs_preferred_language_msg_t *this)
|
private_tnccs_preferred_language_msg_t *this)
|
||||||
{
|
{
|
||||||
@ -79,16 +73,17 @@ METHOD(tnccs_preferred_language_msg_t, get_preferred_language, char*,
|
|||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node)
|
tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node,
|
||||||
|
linked_list_t *errors)
|
||||||
{
|
{
|
||||||
private_tnccs_preferred_language_msg_t *this;
|
private_tnccs_preferred_language_msg_t *this;
|
||||||
|
xmlChar *language;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_preferred_language = _get_preferred_language,
|
.get_preferred_language = _get_preferred_language,
|
||||||
@ -97,6 +92,10 @@ tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node)
|
|||||||
.node = node,
|
.node = node,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
language = xmlNodeGetContent(node);
|
||||||
|
this->preferred_language = strdup((char*)language);
|
||||||
|
xmlFree(language);
|
||||||
|
|
||||||
return &this->public.tnccs_msg_interface;
|
return &this->public.tnccs_msg_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +112,6 @@ tnccs_msg_t *tnccs_preferred_language_msg_create(char *language)
|
|||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_preferred_language = _get_preferred_language,
|
.get_preferred_language = _get_preferred_language,
|
||||||
|
@ -49,8 +49,10 @@ struct tnccs_preferred_language_msg_t {
|
|||||||
* Create a TNCCS-PreferredLanguage message from XML-encoded message node
|
* Create a TNCCS-PreferredLanguage message from XML-encoded message node
|
||||||
*
|
*
|
||||||
* @param msg_node XML-encoded message node
|
* @param msg_node XML-encoded message node
|
||||||
|
* @param errors linked list of TNCCS error messages
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node);
|
tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node,
|
||||||
|
linked_list_t *errors);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a TNCCS-PreferredLanguage message from parameters
|
* Create a TNCCS-PreferredLanguage message from parameters
|
||||||
|
@ -62,12 +62,6 @@ METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
|||||||
return this->node;
|
return this->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, process, status_t,
|
|
||||||
private_tnccs_reason_strings_msg_t *this)
|
|
||||||
{
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, destroy, void,
|
METHOD(tnccs_msg_t, destroy, void,
|
||||||
private_tnccs_reason_strings_msg_t *this)
|
private_tnccs_reason_strings_msg_t *this)
|
||||||
{
|
{
|
||||||
@ -87,7 +81,8 @@ METHOD(tnccs_reason_strings_msg_t, get_reason, char*,
|
|||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node)
|
tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
|
||||||
|
linked_list_t *errors)
|
||||||
{
|
{
|
||||||
private_tnccs_reason_strings_msg_t *this;
|
private_tnccs_reason_strings_msg_t *this;
|
||||||
|
|
||||||
@ -96,7 +91,6 @@ tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node)
|
|||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_reason = _get_reason,
|
.get_reason = _get_reason,
|
||||||
@ -121,7 +115,6 @@ tnccs_msg_t *tnccs_reason_strings_msg_create(char *language, char *reason)
|
|||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_reason = _get_reason,
|
.get_reason = _get_reason,
|
||||||
|
@ -48,8 +48,10 @@ struct tnccs_reason_strings_msg_t {
|
|||||||
* Create a TNCCS-ReasonStrings message from XML-encoded message node
|
* Create a TNCCS-ReasonStrings message from XML-encoded message node
|
||||||
*
|
*
|
||||||
* @param msg_node XML-encoded message node
|
* @param msg_node XML-encoded message node
|
||||||
|
* @param errors linked list of TNCCS error messages
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node);
|
tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
|
||||||
|
linked_list_t *errors);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a TNCCS-ReasonStrings message from parameters
|
* Create a TNCCS-ReasonStrings message from parameters
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tnccs_recommendation_msg.h"
|
#include "tnccs_recommendation_msg.h"
|
||||||
|
#include "tnccs_error_msg.h"
|
||||||
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
@ -57,12 +58,6 @@ METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
|||||||
return this->node;
|
return this->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, process, status_t,
|
|
||||||
private_tnccs_recommendation_msg_t *this)
|
|
||||||
{
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, destroy, void,
|
METHOD(tnccs_msg_t, destroy, void,
|
||||||
private_tnccs_recommendation_msg_t *this)
|
private_tnccs_recommendation_msg_t *this)
|
||||||
{
|
{
|
||||||
@ -78,16 +73,20 @@ METHOD(tnccs_recommendation_msg_t, get_recommendation, TNC_IMV_Action_Recommenda
|
|||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node)
|
tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node,
|
||||||
|
linked_list_t *errors)
|
||||||
{
|
{
|
||||||
private_tnccs_recommendation_msg_t *this;
|
private_tnccs_recommendation_msg_t *this;
|
||||||
|
xmlChar *rec_string;
|
||||||
|
char *error_msg, buf[BUF_LEN];
|
||||||
|
tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||||
|
tnccs_msg_t *msg;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_recommendation = _get_recommendation,
|
.get_recommendation = _get_recommendation,
|
||||||
@ -96,7 +95,41 @@ tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node)
|
|||||||
.node = node,
|
.node = node,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
rec_string = xmlGetProp(node, (const xmlChar*)"type");
|
||||||
|
if (!rec_string)
|
||||||
|
{
|
||||||
|
error_msg = "type property in TNCCS-Recommendation is missing";
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
else if (streq((char*)rec_string, "allow"))
|
||||||
|
{
|
||||||
|
this->rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;
|
||||||
|
}
|
||||||
|
else if (streq((char*)rec_string, "isolate"))
|
||||||
|
{
|
||||||
|
this->rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE;
|
||||||
|
}
|
||||||
|
else if (streq((char*)rec_string, "none"))
|
||||||
|
{
|
||||||
|
this->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_msg = buf;
|
||||||
|
snprintf(buf, BUF_LEN, "unsupported type property value '%s' "
|
||||||
|
"in TNCCS-Recommendation", rec_string);
|
||||||
|
xmlFree(rec_string);
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
xmlFree(rec_string);
|
||||||
|
|
||||||
return &this->public.tnccs_msg_interface;
|
return &this->public.tnccs_msg_interface;
|
||||||
|
|
||||||
|
fatal:
|
||||||
|
msg = tnccs_error_msg_create(error_type, error_msg);
|
||||||
|
errors->insert_last(errors, msg);
|
||||||
|
_destroy(this);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,14 +139,13 @@ tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec)
|
|||||||
{
|
{
|
||||||
private_tnccs_recommendation_msg_t *this;
|
private_tnccs_recommendation_msg_t *this;
|
||||||
xmlNodePtr n, n2;
|
xmlNodePtr n, n2;
|
||||||
char *recommendation_string;
|
char *rec_string;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_recommendation = _get_recommendation,
|
.get_recommendation = _get_recommendation,
|
||||||
@ -134,19 +166,19 @@ tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec)
|
|||||||
switch (rec)
|
switch (rec)
|
||||||
{
|
{
|
||||||
case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
|
case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
|
||||||
recommendation_string = "allow";
|
rec_string = "allow";
|
||||||
break;
|
break;
|
||||||
case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
|
case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
|
||||||
recommendation_string = "isolate";
|
rec_string = "isolate";
|
||||||
break;
|
break;
|
||||||
case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
|
case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
|
||||||
case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
|
case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
|
||||||
default:
|
default:
|
||||||
recommendation_string = "none";
|
rec_string = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
|
n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
|
||||||
xmlNodeSetContent(n2, BAD_CAST recommendation_string);
|
xmlNodeSetContent(n2, BAD_CAST rec_string);
|
||||||
xmlAddChild(n, n2);
|
xmlAddChild(n, n2);
|
||||||
|
|
||||||
return &this->public.tnccs_msg_interface;
|
return &this->public.tnccs_msg_interface;
|
||||||
|
@ -49,8 +49,10 @@ struct tnccs_recommendation_msg_t {
|
|||||||
* Create a TNCCS-Recommendation message from XML-encoded message node
|
* Create a TNCCS-Recommendation message from XML-encoded message node
|
||||||
*
|
*
|
||||||
* @param msg_node XML-encoded message node
|
* @param msg_node XML-encoded message node
|
||||||
|
* @param errors linked list of TNCCS error messages
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node);
|
tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node,
|
||||||
|
linked_list_t *errors);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a TNCCS-Recommendation message from parameters
|
* Create a TNCCS-Recommendation message from parameters
|
||||||
|
@ -51,11 +51,6 @@ METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
|||||||
return this->node;
|
return this->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnccs_msg_t, process, status_t,
|
|
||||||
private_tnccs_tncs_contact_info_msg_t *this)
|
|
||||||
{
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
METHOD(tnccs_msg_t, destroy, void,
|
METHOD(tnccs_msg_t, destroy, void,
|
||||||
private_tnccs_tncs_contact_info_msg_t *this)
|
private_tnccs_tncs_contact_info_msg_t *this)
|
||||||
{
|
{
|
||||||
@ -65,7 +60,8 @@ METHOD(tnccs_msg_t, destroy, void,
|
|||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node)
|
tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node,
|
||||||
|
linked_list_t *errors)
|
||||||
{
|
{
|
||||||
private_tnccs_tncs_contact_info_msg_t *this;
|
private_tnccs_tncs_contact_info_msg_t *this;
|
||||||
|
|
||||||
@ -74,7 +70,6 @@ tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node)
|
|||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -98,7 +93,6 @@ tnccs_msg_t *tnccs_tncs_contact_info_msg_create(void)
|
|||||||
.tnccs_msg_interface = {
|
.tnccs_msg_interface = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.get_node = _get_node,
|
.get_node = _get_node,
|
||||||
.process = _process,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -40,8 +40,10 @@ struct tnccs_tncs_contact_info_msg_t {
|
|||||||
* Create a TNCCS-TNCSContactInfo message from XML-encoded message node
|
* Create a TNCCS-TNCSContactInfo message from XML-encoded message node
|
||||||
*
|
*
|
||||||
* @param msg_node XML-encoded message node
|
* @param msg_node XML-encoded message node
|
||||||
|
* @param errors linked list of TNCCS error messages
|
||||||
*/
|
*/
|
||||||
tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node);
|
tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node,
|
||||||
|
linked_list_t *errors);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a TNCCS-TNCSContactInfo message from parameters
|
* Create a TNCCS-TNCSContactInfo message from parameters
|
||||||
|
@ -17,7 +17,10 @@
|
|||||||
#include "batch/tnccs_batch.h"
|
#include "batch/tnccs_batch.h"
|
||||||
#include "messages/tnccs_msg.h"
|
#include "messages/tnccs_msg.h"
|
||||||
#include "messages/imc_imv_msg.h"
|
#include "messages/imc_imv_msg.h"
|
||||||
|
#include "messages/tnccs_error_msg.h"
|
||||||
#include "messages/tnccs_preferred_language_msg.h"
|
#include "messages/tnccs_preferred_language_msg.h"
|
||||||
|
#include "messages/tnccs_reason_strings_msg.h"
|
||||||
|
#include "messages/tnccs_recommendation_msg.h"
|
||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
@ -63,6 +66,16 @@ struct private_tnccs_11_t {
|
|||||||
*/
|
*/
|
||||||
mutex_t *mutex;
|
mutex_t *mutex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag set while processing
|
||||||
|
*/
|
||||||
|
bool fatal_error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag set by TNCCS-Recommendation message
|
||||||
|
*/
|
||||||
|
bool delete_state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag set by IMC/IMV RequestHandshakeRetry() function
|
* Flag set by IMC/IMV RequestHandshakeRetry() function
|
||||||
*/
|
*/
|
||||||
@ -125,6 +138,54 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TNCCS_MSG_RECOMMENDATION:
|
||||||
|
{
|
||||||
|
tnccs_recommendation_msg_t *rec_msg;
|
||||||
|
TNC_IMV_Action_Recommendation rec;
|
||||||
|
TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
|
||||||
|
|
||||||
|
rec_msg = (tnccs_recommendation_msg_t*)msg;
|
||||||
|
rec = rec_msg->get_recommendation(rec_msg);
|
||||||
|
if (this->is_server)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "ignoring NCCS-Recommendation message from "
|
||||||
|
" TNC client");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBG1(DBG_TNC, "TNC recommendation is '%N'",
|
||||||
|
action_recommendation_names, rec);
|
||||||
|
switch (rec)
|
||||||
|
{
|
||||||
|
case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
|
||||||
|
state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
|
||||||
|
break;
|
||||||
|
case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
|
||||||
|
state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
|
||||||
|
break;
|
||||||
|
case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
|
||||||
|
default:
|
||||||
|
state = TNC_CONNECTION_STATE_ACCESS_NONE;
|
||||||
|
}
|
||||||
|
charon->imcs->notify_connection_change(charon->imcs,
|
||||||
|
this->connection_id, state);
|
||||||
|
this->delete_state = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TNCCS_MSG_ERROR:
|
||||||
|
{
|
||||||
|
tnccs_error_msg_t *err_msg;
|
||||||
|
tnccs_error_type_t error_type;
|
||||||
|
char *error_msg;
|
||||||
|
|
||||||
|
err_msg = (tnccs_error_msg_t*)msg;
|
||||||
|
error_msg = err_msg->get_message(err_msg, &error_type);
|
||||||
|
DBG1(DBG_TNC, "received TNCCS-Error '%N': %s",
|
||||||
|
tnccs_error_type_names, error_type, error_msg);
|
||||||
|
|
||||||
|
/* we assume that all errors are fatal */
|
||||||
|
this->fatal_error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TNCCS_MSG_PREFERRED_LANGUAGE:
|
case TNCCS_MSG_PREFERRED_LANGUAGE:
|
||||||
{
|
{
|
||||||
tnccs_preferred_language_msg_t *lang_msg;
|
tnccs_preferred_language_msg_t *lang_msg;
|
||||||
@ -148,6 +209,8 @@ METHOD(tls_t, process, status_t,
|
|||||||
{
|
{
|
||||||
chunk_t data;
|
chunk_t data;
|
||||||
tnccs_batch_t *batch;
|
tnccs_batch_t *batch;
|
||||||
|
tnccs_msg_t *msg;
|
||||||
|
enumerator_t *enumerator;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
if (this->is_server && !this->connection_id)
|
if (this->is_server && !this->connection_id)
|
||||||
@ -170,11 +233,28 @@ METHOD(tls_t, process, status_t,
|
|||||||
batch = tnccs_batch_create_from_data(this->is_server, ++this->batch_id, data);
|
batch = tnccs_batch_create_from_data(this->is_server, ++this->batch_id, data);
|
||||||
status = batch->process(batch);
|
status = batch->process(batch);
|
||||||
|
|
||||||
if (status != FAILED)
|
if (status == FAILED)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
this->fatal_error = TRUE;
|
||||||
tnccs_msg_t *msg;
|
this->mutex->lock(this->mutex);
|
||||||
|
if (this->batch)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "cancelling TNCCS batch");
|
||||||
|
this->batch->destroy(this->batch);
|
||||||
|
}
|
||||||
|
this->batch = tnccs_batch_create(this->is_server, this->batch_id);
|
||||||
|
|
||||||
|
/* add error messages to outbound batch */
|
||||||
|
enumerator = batch->create_error_enumerator(batch);
|
||||||
|
while (enumerator->enumerate(enumerator, &msg))
|
||||||
|
{
|
||||||
|
this->batch->add_msg(this->batch, msg->get_ref(msg));
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
enumerator = batch->create_msg_enumerator(batch);
|
enumerator = batch->create_msg_enumerator(batch);
|
||||||
while (enumerator->enumerate(enumerator, &msg))
|
while (enumerator->enumerate(enumerator, &msg))
|
||||||
{
|
{
|
||||||
@ -182,6 +262,22 @@ METHOD(tls_t, process, status_t,
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
/* received any TNCCS-Error messages */
|
||||||
|
if (this->fatal_error)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "a fatal TNCCS-Error occurred, terminating connection");
|
||||||
|
batch->destroy(batch);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->is_server)
|
||||||
|
{
|
||||||
|
charon->imvs->batch_ending(charon->imvs, this->connection_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
charon->imcs->batch_ending(charon->imcs, this->connection_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
batch->destroy(batch);
|
batch->destroy(batch);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user