diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2011-01-07 05:29:04 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2011-01-07 05:29:59 +0100 |
commit | d9e21bf180ea6b828241ced6bc31d61096d7976d (patch) | |
tree | 761619833af51f4f1b776dddff26f359c2db401f /src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c | |
parent | cfa190bb7c6a641caf81c679ab7042f16c70b555 (diff) | |
download | strongswan-d9e21bf180ea6b828241ced6bc31d61096d7976d.tar.bz2 strongswan-d9e21bf180ea6b828241ced6bc31d61096d7976d.tar.xz |
implemented TNCCS 1.1 without libtnc
Diffstat (limited to 'src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c')
-rw-r--r-- | src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c new file mode 100644 index 000000000..6237ddab3 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2006 Mike McCauley (mikem@open.com.au) + * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "tnccs_batch.h" + +#include <debug.h> +#include <utils/linked_list.h> +#include <tnc/tnccs/tnccs.h> + +#include <libxml/parser.h> + +typedef struct private_tnccs_batch_t private_tnccs_batch_t; + +/** + * Private data of a tnccs_batch_t object. + * + */ +struct private_tnccs_batch_t { + /** + * Public tnccs_batch_t interface. + */ + tnccs_batch_t public; + + /** + * Batch ID + */ + int batch_id; + + /** + * TNCC if TRUE, TNCS if FALSE + */ + bool is_server; + + /** + * linked list of TNCCS messages + */ + linked_list_t *messages; + + /** + * XML document + */ + xmlDocPtr doc; + + /** + * Encoded message + */ + chunk_t encoding; +}; + +METHOD(tnccs_batch_t, get_encoding, chunk_t, + private_tnccs_batch_t *this) +{ + return this->encoding; +} + +METHOD(tnccs_batch_t, add_msg, void, + private_tnccs_batch_t *this, tnccs_msg_t* msg) +{ + xmlNodePtr root; + + DBG2(DBG_TNC, "adding %N message", tnccs_msg_type_names, + msg->get_type(msg)); + this->messages->insert_last(this->messages, msg); + root = xmlDocGetRootElement(this->doc); + xmlAddChild(root, msg->get_node(msg)); +} + +METHOD(tnccs_batch_t, build, void, + private_tnccs_batch_t *this) +{ + xmlChar *xmlbuf; + int buf_size; + + xmlDocDumpFormatMemory(this->doc, &xmlbuf, &buf_size, 1); + this->encoding = chunk_create((u_char*)xmlbuf, buf_size); + this->encoding = chunk_clone(this->encoding); + xmlFree(xmlbuf); +} + +METHOD(tnccs_batch_t, process, status_t, + private_tnccs_batch_t *this) +{ + tnccs_msg_t *tnccs_msg; + xmlNodePtr cur; + xmlNsPtr ns; + xmlChar *batchid, *recipient; + int batch_id; + + status_t status; + + this->doc = xmlParseMemory(this->encoding.ptr, this->encoding.len); + if (!this->doc) + { + DBG1(DBG_TNC, "failed to parse XML message"); + return FAILED; + } + + /* check out the XML document */ + cur = xmlDocGetRootElement(this->doc); + if (!cur) + { + DBG1(DBG_TNC, "empty XML document"); + return FAILED; + } + + /* check TNCCS namespace */ + ns = xmlSearchNsByHref(this->doc, cur, (const xmlChar*) + "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#"); + if (!ns) + { + DBG1(DBG_TNC, "TNCCS namespace not found"); + return FAILED; + } + + /* check XML document type */ + if (xmlStrcmp(cur->name, (const xmlChar*)"TNCCS-Batch")) + { + DBG1(DBG_TNC, "wrong XML document type '%s', expected TNCCS-Batch", + cur->name); + return FAILED; + } + + /* check presence of BatchID property */ + batchid = xmlGetProp(cur, (const xmlChar*)"BatchId"); + if (!batchid) + { + DBG1(DBG_TNC, "BatchId is missing"); + return FAILED; + } + + /* check BatchID */ + batch_id = atoi((char*)batchid); + xmlFree(batchid); + if (batch_id != this->batch_id) + { + DBG1(DBG_TNC, "BatchID %d expected, got %d", this->batch_id, batch_id); + return FAILED; + } + + /* check presence of Recipient property */ + recipient = xmlGetProp(cur, (const xmlChar*)"Recipient"); + if (!recipient) + { + DBG1(DBG_TNC, "Recipient is missing"); + return FAILED; + } + + /* check recipient */ + if (!streq((char*)recipient, this->is_server ? "TNCS" : "TNCC")) + { + DBG1(DBG_TNC, "message recipient expected '%s', got '%s'", + this->is_server ? "TNCS" : "TNCC", (char*)recipient); + xmlFree(recipient); + return FAILED; + } + xmlFree(recipient); + + /* Now walk the tree, handling message nodes as we go */ + for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) + { + /* ignore empty or blank nodes */ + if (xmlIsBlankNode(cur)) + { + continue; + } + + /* ignore nodes with wrong namespace */ + if (cur->ns != ns) + { + DBG1(DBG_TNC, "ignoring message node '%s' having wrong namespace", + (char*)cur->name); + continue; + } + + tnccs_msg = tnccs_msg_create_from_node(cur); + if (!tnccs_msg) + { + continue; + } + + status = tnccs_msg->process(tnccs_msg); + if (status == FAILED) + { + tnccs_msg->destroy(tnccs_msg); + return FAILED; + } + this->messages->insert_last(this->messages, tnccs_msg); + } + return SUCCESS; +} + +METHOD(tnccs_batch_t, create_msg_enumerator, enumerator_t*, + private_tnccs_batch_t *this) +{ + return this->messages->create_enumerator(this->messages); +} + +METHOD(tnccs_batch_t, destroy, void, + private_tnccs_batch_t *this) +{ + this->messages->destroy_offset(this->messages, + offsetof(tnccs_msg_t, destroy)); + xmlFreeDoc(this->doc); + free(this->encoding.ptr); + free(this); +} + +/** + * See header + */ +tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id) +{ + private_tnccs_batch_t *this; + xmlNodePtr n; + char buf[12]; + const char *recipient; + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .add_msg = _add_msg, + .build = _build, + .process = _process, + .create_msg_enumerator = _create_msg_enumerator, + .destroy = _destroy, + }, + .is_server = is_server, + .messages = linked_list_create(), + .batch_id = batch_id, + .doc = xmlNewDoc(BAD_CAST "1.0"), + ); + + DBG2(DBG_TNC, "creating TNCCS Batch #%d", this->batch_id); + n = xmlNewNode(NULL, BAD_CAST "TNCCS-Batch"); + snprintf(buf, sizeof(buf), "%d", batch_id); + recipient = this->is_server ? "TNCC" : "TNCS"; + xmlNewProp(n, BAD_CAST "BatchId", BAD_CAST buf); + xmlNewProp(n, BAD_CAST "Recipient", BAD_CAST recipient); + xmlNewProp(n, BAD_CAST "xmlns", BAD_CAST "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#"); + xmlNewProp(n, BAD_CAST "xmlns:xsi", BAD_CAST "http://www.w3.org/2001/XMLSchema-instance"); + xmlNewProp(n, BAD_CAST "xsi:schemaLocation", BAD_CAST "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS# " + "https://www.trustedcomputinggroup.org/XML/SCHEMA/TNCCS_1.0.xsd"); + xmlDocSetRootElement(this->doc, n); + + return &this->public; +} + +/** + * See header + */ +tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id, chunk_t data) +{ + private_tnccs_batch_t *this; + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .add_msg = _add_msg, + .build = _build, + .process = _process, + .create_msg_enumerator = _create_msg_enumerator, + .destroy = _destroy, + }, + .is_server = is_server, + .batch_id = batch_id, + .messages = linked_list_create(), + .encoding = chunk_clone(data), + ); + + return &this->public; +} + |