implemented TNCCS 1.1 without libtnc
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 7 Jan 2011 04:29:04 +0000 (05:29 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 7 Jan 2011 04:29:59 +0000 (05:29 +0100)
20 files changed:
src/libcharon/plugins/tnccs_11/Makefile.am
src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_contact_info_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_contact_info_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnccs_11/tnccs_11.c

index 7ccd0df..decde3c 100644 (file)
@@ -15,7 +15,15 @@ libstrongswan_tnccs_11_la_LIBADD += $(top_builddir)/src/libtls/libtls.la
 endif
 
 libstrongswan_tnccs_11_la_SOURCES = \
-       tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c
+       tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c \
+       batch/tnccs_batch.h batch/tnccs_batch.c \
+       messages/tnccs_msg.h messages/tnccs_msg.c \
+       messages/imc_imv_msg.h messages/imc_imv_msg.c \
+       messages/tnccs_error_msg.h messages/tnccs_error_msg.c \
+       messages/tnccs_preferred_language_msg.h messages/tnccs_preferred_language_msg.c \
+       messages/tnccs_reason_strings_msg.h messages/tnccs_reason_strings_msg.c \
+       messages/tnccs_recommendation_msg.h messages/tnccs_recommendation_msg.c \
+       messages/tnccs_tncs_contact_info_msg.h messages/tnccs_tncs_contact_info_msg.c
 
 libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version
 
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 (file)
index 0000000..6237dda
--- /dev/null
@@ -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;
+}
+
diff --git a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h
new file mode 100644 (file)
index 0000000..6f47e56
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_batch tnccs_batch
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_BATCH_H_
+#define TNCCS_BATCH_H_
+
+typedef enum tnccs_batch_type_t tnccs_batch_type_t;
+typedef struct tnccs_batch_t tnccs_batch_t;
+
+#include "messages/tnccs_msg.h"
+
+#include <library.h>
+
+/**
+ * Interface for a TNCCS 1.x Batch.
+ */
+struct tnccs_batch_t {
+
+       /**
+        * Get the encoding of the TNCCS 1.x Batch
+        *
+        * @return                              encoded TNCCS 1.x batch
+        */
+       chunk_t (*get_encoding)(tnccs_batch_t *this);
+
+       /**
+        * Add TNCCS message
+        *
+        * @param msg                   TNCCS message to be addedd
+        */
+       void (*add_msg)(tnccs_batch_t *this, tnccs_msg_t* msg);
+
+       /**
+        * Build the TNCCS 1.x Batch
+        */
+       void (*build)(tnccs_batch_t *this);
+
+       /**
+        * Process the TNCCS 1.x Batch
+        *
+        * @return                              return processing status
+        */
+       status_t (*process)(tnccs_batch_t *this);
+
+       /**
+        * Enumerates over all TNCCS Messages
+        *
+        * @return                              return message enumerator
+        */
+       enumerator_t* (*create_msg_enumerator)(tnccs_batch_t *this);
+
+       /**
+        * Destroys a tnccs_batch_t object.
+        */
+       void (*destroy)(tnccs_batch_t *this);
+};
+
+/**
+ * Create an empty TNCCS 1.x Batch
+ *
+ * @param is_server                    TRUE if server, FALSE if client
+ * @param batch_id                     number of the batch to be sent
+ */
+tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id);
+
+/**
+ * Create an unprocessed TNCCS 1.x Batch from data
+ *
+ * @param  is_server           TRUE if server, FALSE if client
+ * @param batch_id                     current Batch ID
+ * @param  data                                encoded PB-TNC batch
+ */
+tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id,
+                                                                                       chunk_t data);
+
+#endif /** TNCCS_BATCH_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c
new file mode 100644 (file)
index 0000000..30b5e7b
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * 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 "imc_imv_msg.h"
+
+#include <tnc/tnccs/tnccs.h>
+#include <debug.h>
+
+typedef struct private_imc_imv_msg_t private_imc_imv_msg_t;
+
+#define BYTES_PER_LINE 57
+
+/**
+ * Private data of a imc_imv_msg_t object.
+ *
+ */
+struct private_imc_imv_msg_t {
+       /**
+        * Public imc_imv_msg_t interface.
+        */
+       imc_imv_msg_t public;
+
+       /**
+        * TNCCS message type
+        */
+       tnccs_msg_type_t type;
+
+       /**
+        * XML-encoded message node
+        */
+       xmlNodePtr node;
+
+       /**
+        * IMC-IMV message type
+        */
+       TNC_MessageType msg_type;
+
+       /**
+        * IMC-IMV message body
+        */
+       chunk_t msg_body;
+
+};
+
+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;
+}
+
+/**
+ * Converts message data into multiple base64-encoded lines 
+ */
+static chunk_t encode_base64(chunk_t data)
+{
+       chunk_t encoding;
+       u_char *pos;
+       size_t b64_chars, b64_lines;
+
+       /* compute and allocate maximum size of base64 object */
+       b64_chars = 4 * ((data.len + 2) / 3);
+       b64_lines = (data.len + BYTES_PER_LINE - 1) / BYTES_PER_LINE;
+       encoding = chunk_alloc(b64_chars + b64_lines);
+       pos = encoding.ptr;
+
+       /* encode lines */
+       while (b64_lines--)
+       {
+               chunk_t data_line, b64_line;
+
+               data_line = chunk_create(data.ptr, min(data.len, BYTES_PER_LINE));
+               data.ptr += data_line.len;
+               data.len -= data_line.len;
+               b64_line = chunk_to_base64(data_line, pos);
+               pos += b64_line.len;
+               *pos = '\n';
+               pos++;
+       }
+       /* terminate last line with NULL character instead of newline */
+       *(pos-1) = '\0';
+
+       return encoding;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+       private_imc_imv_msg_t *this)
+{
+       free(this->msg_body.ptr);
+       free(this);
+}
+
+METHOD(imc_imv_msg_t, get_msg_type, TNC_MessageType,
+       private_imc_imv_msg_t *this)
+{
+       return this->msg_type;
+}
+
+METHOD(imc_imv_msg_t, get_msg_body, chunk_t,
+       private_imc_imv_msg_t *this)
+{
+       return this->msg_body;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node)
+{
+       private_imc_imv_msg_t *this;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_msg_type = _get_msg_type,
+                       .get_msg_body = _get_msg_body,
+               },
+               .type = IMC_IMV_MSG,
+               .node = node,
+       );
+
+       return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body)
+{
+       private_imc_imv_msg_t *this;
+       chunk_t b64_body;
+       char buf[10];           /* big enough for hex-encoded message type */
+       xmlNodePtr n;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_msg_type = _get_msg_type,
+                       .get_msg_body = _get_msg_body,
+               },
+               .type = IMC_IMV_MSG,
+               .node = xmlNewNode(NULL, BAD_CAST "IMC-IMV-Message"),
+               .msg_type = msg_type,
+               .msg_body = chunk_clone(msg_body),
+       );
+
+       /* add the message type number in hex */
+       n = xmlNewNode(NULL, BAD_CAST "Type");
+       snprintf(buf, 10, "%08x", this->msg_type);
+       xmlNodeSetContent(n, BAD_CAST buf);
+       xmlAddChild(this->node, n);
+
+       /* encode the message as a Base64 node */
+       n = xmlNewNode(NULL, BAD_CAST "Base64");
+       b64_body = encode_base64(this->msg_body);
+       xmlNodeSetContent(n, BAD_CAST b64_body.ptr);
+       xmlAddChild(this->node, n);
+       free(b64_body.ptr);
+
+       return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h
new file mode 100644 (file)
index 0000000..ccf31d3
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup imc_imv_msg imc_imv_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef IMC_IMV_MSG_H_
+#define IMC_IMV_MSG_H_
+
+typedef struct imc_imv_msg_t imc_imv_msg_t;
+
+#include "tnccs_msg.h"
+
+#include <tnc/tncif.h>
+
+/**
+ * Classs representing the PB-PA message type.
+ */
+struct imc_imv_msg_t {
+
+       /**
+        * TNCCS Message interface
+        */
+       tnccs_msg_t tnccs_msg_interface;
+
+       /**
+        * Get IMC-IMV message type
+        *
+        * @return                              IMC-IMV message type
+        */
+       TNC_MessageType (*get_msg_type)(imc_imv_msg_t *this);
+
+       /**
+        * Get IMC-IMV message body
+        *
+        * @return                              IMC-IMV message body
+        */
+       chunk_t (*get_msg_body)(imc_imv_msg_t *this);
+};
+
+/**
+ * Create an IMC-IMV message from XML-encoded message node
+ *
+ * @param msg_node                     XML-encoded message node
+ */
+tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node);
+
+/**
+ * Create an IMC-IMV message from parameters
+ *
+ * @param msg_type                     IMC-IMV message type
+ * @param msg_body                     IMC-IMV message body            
+ */
+tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body);
+
+#endif /** IMC_IMV_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_contact_info_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_contact_info_msg.c
new file mode 100644 (file)
index 0000000..099e818
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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_tncs_contact_info_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_tncs_contact_info_msg_t private_tnccs_tncs_contact_info_msg_t;
+
+/**
+ * Private data of a tnccs_tncs_contact_info_msg_t object.
+ *
+ */
+struct private_tnccs_tncs_contact_info_msg_t {
+       /**
+        * Public tnccs_tncs_contact_info_msg_t interface.
+        */
+       tnccs_tncs_contact_info_msg_t public;
+
+       /**
+        * TNCCS message type
+        */
+       tnccs_msg_type_t type;
+
+       /**
+        * XML-encoded message node
+        */
+       xmlNodePtr node;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+       private_tnccs_tncs_contact_info_msg_t *this)
+{
+       return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+       private_tnccs_tncs_contact_info_msg_t *this)
+{
+       return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+       private_tnccs_tncs_contact_info_msg_t *this)
+{
+       free(this);
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node)
+{
+       private_tnccs_tncs_contact_info_msg_t *this;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+               },
+               .type = TNCCS_MSG_TNCS_CONTACT_INFO,
+               .node = node,
+       );
+
+       return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create(void)
+{
+       private_tnccs_tncs_contact_info_msg_t *this;
+       xmlNodePtr n, n2;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+               },
+               .type = TNCCS_MSG_TNCS_CONTACT_INFO,
+               .node =  xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+       );
+
+       /* add the message type number in hex */
+       n = xmlNewNode(NULL, BAD_CAST "Type");
+       xmlNodeSetContent(n, BAD_CAST "00000005");
+       xmlAddChild(this->node, n);
+
+       n = xmlNewNode(NULL, BAD_CAST "XML");
+       xmlAddChild(this->node, n);
+
+/* TODO
+       n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+       xmlNodeSetContent(n2, BAD_CAST language);
+       xmlAddChild(n, n2);
+*/
+
+       return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_contact_info_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_contact_info_msg.h
new file mode 100644 (file)
index 0000000..83eac7c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_tncs_contact_info_msg tnccs_tncs_contact_info_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_TNCS_CONTACT_INFO_MSG_H_
+#define TNCCS_TNCS_CONTACT_INFO_MSG_H_
+
+typedef struct tnccs_tncs_contact_info_msg_t tnccs_tncs_contact_info_msg_t;
+
+#include "tnccs_msg.h"
+
+/**
+ * Class representing the TNCCS-TNCSContactInfo message type
+ */
+struct tnccs_tncs_contact_info_msg_t {
+
+       /**
+        * TNCCS Message interface
+        */
+       tnccs_msg_t tnccs_msg_interface;
+};
+
+/**
+ * Create a TNCCS-TNCSContactInfo message from XML-encoded message node
+ *
+ * @param msg_node                     XML-encoded message node
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node);
+
+/**
+ * Create a TNCCS-TNCSContactInfo message from parameters
+ *
+ * @param language                     preferred language string
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create(char *language);
+
+#endif /** TNCCS_TNCS_CONTACT_INFO_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c
new file mode 100644 (file)
index 0000000..f74d06a
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 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_error_msg.h"
+
+#include <debug.h>
+
+ENUM(tnccs_error_type_names, TNCCS_ERROR_BATCH_TOO_LONG, TNCCS_ERROR_OTHER,
+       "batch-too-long",
+       "malformed-batch",
+       "invalid-batch-id",
+       "invalid-recipient-type",
+       "internal-error",
+       "other"
+);
+
+typedef struct private_tnccs_error_msg_t private_tnccs_error_msg_t;
+
+/**
+ * Private data of a tnccs_error_msg_t object.
+ *
+ */
+struct private_tnccs_error_msg_t {
+       /**
+        * Public tnccs_error_msg_t interface.
+        */
+       tnccs_error_msg_t public;
+
+       /**
+        * TNCCS message type
+        */
+       tnccs_msg_type_t type;
+
+       /**
+        * XML-encoded message node
+        */
+       xmlNodePtr node;
+
+       /**
+        * Error type
+        */
+       tnccs_error_type_t error_type;
+
+       /**
+        * Error message
+        */
+       char *error_msg;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+       private_tnccs_error_msg_t *this)
+{
+       return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+       private_tnccs_error_msg_t *this)
+{
+       return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+       private_tnccs_error_msg_t *this)
+{
+       free(this->error_msg);
+       free(this);
+}
+
+METHOD(tnccs_error_msg_t, get_message, char*,
+       private_tnccs_error_msg_t *this, tnccs_error_type_t *type)
+{
+       *type = this->error_type;
+
+       return this->error_msg;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node)
+{
+       private_tnccs_error_msg_t *this;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_message = _get_message,
+               },
+               .type = TNCCS_MSG_ERROR,
+               .node = node,
+       );
+
+       return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg)
+{
+       private_tnccs_error_msg_t *this;
+       xmlNodePtr n, n2;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_message = _get_message,
+               },
+               .type = TNCCS_MSG_ERROR,
+               .node =  xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+               .error_type = type,
+               .error_msg  = strdup(msg),
+       );
+
+     n = xmlNewNode(NULL, BAD_CAST "Type");
+    xmlNodeSetContent(n, BAD_CAST "00000002");
+    xmlAddChild(this->node, n);
+
+    n = xmlNewNode(NULL, BAD_CAST "XML");
+    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));
+    xmlNodeSetContent(n2, BAD_CAST msg);
+    xmlAddChild(n, n2);
+
+       return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h
new file mode 100644 (file)
index 0000000..ca16af9
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_error_msg tnccs_error_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_ERROR_MSG_H_
+#define TNCCS_ERROR_MSG_H_
+
+typedef enum tnccs_error_type_t tnccs_error_type_t;
+typedef struct tnccs_error_msg_t tnccs_error_msg_t;
+
+#include "tnccs_msg.h"
+
+/**
+ * TNCCS error types as defined in section 8.1.4 of TCG TNC IF-TNCCS v1.2
+ */
+enum tnccs_error_type_t {
+       TNCCS_ERROR_BATCH_TOO_LONG,
+       TNCCS_ERROR_MALFORMED_BATCH,
+       TNCCS_ERROR_INVALID_BATCH_ID,
+       TNCCS_ERROR_INVALID_RECIPIENT_TYPE,
+       TNCCS_ERROR_INTERNAL_ERROR,
+       TNCCS_ERROR_OTHER
+};
+
+/**
+ * enum name for tnccs_error_type_t.
+ */
+extern enum_name_t *tnccs_error_type_names;
+
+/**
+ * Class representing the TNCCS-Error message type
+ */
+struct tnccs_error_msg_t {
+
+       /**
+        * TNCCS Message interface
+        */
+       tnccs_msg_t tnccs_msg_interface;
+
+       /**
+        * Get error message and type
+        *
+        * @param type                  TNCCS error type
+        * @return                              arbitrary error message
+        */
+       char* (*get_message)(tnccs_error_msg_t *this, tnccs_error_type_t *type);
+};
+
+/**
+ * Create a TNCCS-Error message from XML-encoded message node
+ *
+ * @param msg_node                     XML-encoded message node
+ */
+tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node);
+
+/**
+ * Create a TNCCS-Error message from parameters
+ *
+ * @param type                 TNCCS error type
+ * @param msg                  arbitrary error message
+ */
+tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg);
+
+#endif /** TNCCS_ERROR_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c
new file mode 100644 (file)
index 0000000..1a63da9
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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_msg.h"
+#include "imc_imv_msg.h"
+#include "tnccs_preferred_language_msg.h"
+
+#include <library.h>
+#include <debug.h>
+
+ENUM(tnccs_msg_type_names, IMC_IMV_MSG, TNCCS_MSG_ROOF,
+       "IMC-IMV",
+       "TNCCS-Recommendation",
+       "TNCCS-Error",
+       "TNCCS-PreferredLanguage",
+       "TNCCS-ReasonStrings",
+       "TNCCS-TNCSContactInfo"
+);
+
+/**
+ * See header
+ */
+tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node)
+{
+       tnccs_msg_type_t type = IMC_IMV_MSG;
+
+       if (streq((char*)node->name, "IMC-IMV-Message"))
+       {
+               return imc_imv_msg_create_from_node(node);
+       }
+       else if (streq((char*)node->name, "TNCC-TNCS-Message"))
+       {
+               bool found = FALSE;
+               xmlNsPtr ns = node->ns;
+               xmlNodePtr cur = node->xmlChildrenNode;
+
+               while (cur)
+               {
+                       if (streq((char*)cur->name, "Type") && cur->ns == ns)
+                       {
+                       xmlChar *content = xmlNodeGetContent(cur);
+
+                           type = strtol((char*)content, NULL, 16);
+                       xmlFree(content);
+                               found = TRUE;
+                               break;
+                       }
+               }
+               if (!found)
+               {
+                       DBG1(DBG_TNC, "ignoring TNCC-TNCS-Messsage without type");
+                       return NULL;
+               }
+               switch (type)
+               {
+                       case TNCCS_MSG_RECOMMENDATION:
+                               return tnccs_recommendation_msg_create_from_node(node);
+                       case TNCCS_MSG_ERROR:
+                               return tnccs_error_msg_create_from_node(node);
+                       case TNCCS_MSG_PREFERRED_LANGUAGE:
+                               return tnccs_preferred_language_msg_create_from_node(node);
+                       case TNCCS_MSG_REASON_STRINGS:
+                               return tnccs_reason_strings_msg_create_from_node(node);
+                       case TNCCS_MSG_TNCS_CONTACT_INFO:
+                               return tnccs_tncs_contact_info_msg_create_from_node(node);
+                       default:
+                               DBG1(DBG_TNC, "ignoring TNCC-TNCS-Message with type %d", type);
+                               return NULL;
+               }
+       }
+       DBG1(DBG_TNC, "ignoring unknown message node '%s'", (char*)node->name);
+       return NULL;
+}
+
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h
new file mode 100644 (file)
index 0000000..c4c637d
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_msg tnccs_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_MSG_H_
+#define TNCCS_MSG_H_
+
+typedef enum tnccs_msg_type_t tnccs_msg_type_t;
+typedef struct tnccs_msg_t tnccs_msg_t;
+
+#include <library.h>
+#include <libxml/parser.h>
+
+/**
+ * TNCC-TNCS messages as defined in section 2.8.5 of TCG TNC IF-TNCCS v1.2
+ */
+enum tnccs_msg_type_t {
+       IMC_IMV_MSG =                                           0,
+       TNCCS_MSG_RECOMMENDATION =                      1,
+       TNCCS_MSG_ERROR =                                       2,
+       TNCCS_MSG_PREFERRED_LANGUAGE =          3,
+       TNCCS_MSG_REASON_STRINGS =                      4,
+       TNCCS_MSG_TNCS_CONTACT_INFO =           5,
+       TNCCS_MSG_ROOF =                                        5
+};
+
+/**
+ * enum name for tnccs_msg_type_t.
+ */
+extern enum_name_t *tnccs_msg_type_names;
+
+/**
+ * Generic interface for all TNCCS message types.
+ *
+ * To handle all messages in a generic way, this interface
+ * must be implemented by each message type.
+ */
+struct tnccs_msg_t {
+
+       /**
+        * Get the TNCCS Message Type
+        *
+        * @return                              TNCCS Message Type
+        */
+       tnccs_msg_type_t (*get_type)(tnccs_msg_t *this);
+
+       /**
+        * Get the XML-encoded Message Node
+        *
+        * @return                              Message Node
+        */
+       xmlNodePtr (*get_node)(tnccs_msg_t *this);
+
+       /**
+        * Process the TNCCS Message
+        *
+        * @return                              return processing status
+        */
+       status_t (*process)(tnccs_msg_t *this);
+
+       /**
+        * Destroys a tnccs_msg_t object.
+        */
+       void (*destroy)(tnccs_msg_t *this);
+};
+
+/**
+ * Create an unprocessed TNCCS message
+ *
+ * Useful for the parser which wants a generic constructor for all
+ * tnccs_msg_t types.
+ *
+ * @param node         TNCCS message node
+ */
+tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node);
+
+#endif /** TNCCS_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c
new file mode 100644 (file)
index 0000000..d76159b
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * 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_preferred_language_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_preferred_language_msg_t private_tnccs_preferred_language_msg_t;
+
+/**
+ * Private data of a tnccs_preferred_language_msg_t object.
+ *
+ */
+struct private_tnccs_preferred_language_msg_t {
+       /**
+        * Public tnccs_preferred_language_msg_t interface.
+        */
+       tnccs_preferred_language_msg_t public;
+
+       /**
+        * TNCCS message type
+        */
+       tnccs_msg_type_t type;
+
+       /**
+        * XML-encoded message node
+        */
+       xmlNodePtr node;
+
+       /**
+        * Preferred language
+        */
+       char *preferred_language;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+       private_tnccs_preferred_language_msg_t *this)
+{
+       return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+       private_tnccs_preferred_language_msg_t *this)
+{
+       return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+       private_tnccs_preferred_language_msg_t *this)
+{
+       free(this->preferred_language);
+       free(this);
+}
+
+METHOD(tnccs_preferred_language_msg_t, get_preferred_language, char*,
+       private_tnccs_preferred_language_msg_t *this)
+{
+       return this->preferred_language;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node)
+{
+       private_tnccs_preferred_language_msg_t *this;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_preferred_language = _get_preferred_language,
+               },
+               .type = TNCCS_MSG_PREFERRED_LANGUAGE,
+               .node = node,
+       );
+
+       return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_preferred_language_msg_create(char *language)
+{
+       private_tnccs_preferred_language_msg_t *this;
+       xmlNodePtr n, n2;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_preferred_language = _get_preferred_language,
+               },
+               .type = TNCCS_MSG_PREFERRED_LANGUAGE,
+               .node =  xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+               .preferred_language = strdup(language),
+       );
+
+       /* add the message type number in hex */
+       n = xmlNewNode(NULL, BAD_CAST "Type");
+       xmlNodeSetContent(n, BAD_CAST "00000003");
+       xmlAddChild(this->node, n);
+
+       n = xmlNewNode(NULL, BAD_CAST "XML");
+       xmlAddChild(this->node, n);
+
+       n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+       xmlNodeSetContent(n2, BAD_CAST language);
+       xmlAddChild(n, n2);
+
+       return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h
new file mode 100644 (file)
index 0000000..d57cc6e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_preferred_language_msg tnccs_preferred_language_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_PREFERRED_LANGUAGE_MSG_H_
+#define TNCCS_PREFERRED_LANGUAGE_MSG_H_
+
+typedef struct tnccs_preferred_language_msg_t tnccs_preferred_language_msg_t;
+
+#include "tnccs_msg.h"
+
+#include <tnc/tncif.h>
+
+/**
+ * Class representing the TNCCS-PreferredLanguage message type
+ */
+struct tnccs_preferred_language_msg_t {
+
+       /**
+        * TNCCS Message interface
+        */
+       tnccs_msg_t tnccs_msg_interface;
+
+       /**
+        * Get preferred language string
+        *
+        * @return                              preferred language string
+        */
+       char* (*get_preferred_language)(tnccs_preferred_language_msg_t *this);
+};
+
+/**
+ * Create a TNCCS-PreferredLanguage message from XML-encoded message node
+ *
+ * @param msg_node                     XML-encoded message node
+ */
+tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node);
+
+/**
+ * Create a TNCCS-PreferredLanguage message from parameters
+ *
+ * @param language                     preferred language string
+ */
+tnccs_msg_t *tnccs_preferred_language_msg_create(char *language);
+
+#endif /** TNCCS_PREFERRED_LANGUAGE_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c
new file mode 100644 (file)
index 0000000..d04ca80
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * 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_reason_strings_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_reason_strings_t private_tnccs_reason_strings_t;
+
+/**
+ * Private data of a tnccs_reason_strings_t object.
+ *
+ */
+struct private_tnccs_reason_strings_t {
+       /**
+        * Public tnccs_reason_strings_t interface.
+        */
+       tnccs_reason_strings_t public;
+
+       /**
+        * TNCCS message type
+        */
+       tnccs_msg_type_t type;
+
+       /**
+        * XML-encoded message node
+        */
+       xmlNodePtr node;
+
+       /**
+        * Reason Language
+        */
+       char* language;
+
+       /**
+        * Reason String
+        */
+       char* reason;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+       private_tnccs_reason_strings_t *this)
+{
+       return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+       private_tnccs_reason_strings_t *this)
+{
+       return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+       private_tnccs_reason_strings_t *this)
+{
+       free(this->language);
+       free(this->reason);
+       free(this);
+}
+
+METHOD(tnccs_reason_strings_t, get_reason, char*,
+       private_tnccs_reason_strings_t *this, char **language)
+{
+       *language = this->language;
+
+       return this->reason;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_reason_strings_create_from_node(xmlNodePtr node)
+{
+       private_tnccs_reason_strings_t *this;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_reason = _get_reason,
+               },
+               .type = TNCCS_MSG_REASON_STRINGS,
+               .node = node,
+       );
+
+       return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_reason_strings_create(char *language, char *reason)
+{
+       private_tnccs_reason_strings_t *this;
+       xmlNodePtr n, n2, n3;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_reason = _get_reason,
+               },
+               .type = TNCCS_MSG_REASON_STRINGS,
+               .node =  xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+               .language = strdup(language),
+               .reason = strdup(reason),
+       );
+
+       /* add the message type number in hex */
+       n = xmlNewNode(NULL, BAD_CAST "Type");
+       xmlNodeSetContent(n, BAD_CAST "00000004");
+       xmlAddChild(this->node, n);
+
+       n = xmlNewNode(NULL, BAD_CAST "XML");
+       xmlAddChild(this->node, n);
+
+       n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+       xmlNodeSetContent(n2, BAD_CAST language);
+       xmlAddChild(n, n2);
+
+    /* could add multiple reasons here, if we had them */
+    n3 = xmlNewNode(NULL, BAD_CAST "ReasonString");
+    xmlNewProp(n3, BAD_CAST "xml:lang", BAD_CAST language);
+    xmlNodeSetContent(n3, BAD_CAST reason);
+    xmlAddChild(n2, n3);
+
+       return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h
new file mode 100644 (file)
index 0000000..c203a8e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_reason_strings tnccs_reason_strings
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_REASON_STRINGS_H_
+#define TNCCS_REASON_STRINGS_H_
+
+typedef struct tnccs_reason_strings_t tnccs_reason_strings_t;
+
+#include "tnccs_msg.h"
+
+/**
+ * Class representing the TNCCS-ReasonStrings message type
+ */
+struct tnccs_reason_strings_t {
+
+       /**
+        * TNCCS Message interface
+        */
+       tnccs_msg_t tnccs_msg_interface;
+
+       /**
+        * Get reason string and language
+        *
+        * @param language              reason language
+        * @return                              reason string
+        */
+       char* (*get_reason)(tnccs_reason_strings_t *this, char **language);
+};
+
+/**
+ * Create a TNCCS-ReasonStrings message from XML-encoded message node
+ *
+ * @param msg_node                     XML-encoded message node
+ */
+tnccs_msg_t *tnccs_reason_strings_create_from_node(xmlNodePtr node);
+
+/**
+ * Create a TNCCS-ReasonStrings message from parameters
+ *
+ * @param language                     reason language
+ * @param reason                       reason string
+ */
+tnccs_msg_t *tnccs_reason_strings_create(char *language, char *reason);
+
+#endif /** TNCCS_REASON_STRINGS_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c
new file mode 100644 (file)
index 0000000..2ac2b27
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * 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_recommendation_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_recommendation_msg_t private_tnccs_recommendation_msg_t;
+
+/**
+ * Private data of a tnccs_recommendation_msg_t object.
+ *
+ */
+struct private_tnccs_recommendation_msg_t {
+       /**
+        * Public tnccs_recommendation_msg_t interface.
+        */
+       tnccs_recommendation_msg_t public;
+
+       /**
+        * TNCCS message type
+        */
+       tnccs_msg_type_t type;
+
+       /**
+        * XML-encoded message node
+        */
+       xmlNodePtr node;
+
+       /**
+        * Action Recommendation
+        */
+       TNC_IMV_Action_Recommendation rec;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+       private_tnccs_recommendation_msg_t *this)
+{
+       return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+       private_tnccs_recommendation_msg_t *this)
+{
+       return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+       private_tnccs_recommendation_msg_t *this)
+{
+       free(this);
+}
+
+METHOD(tnccs_recommendation_msg_t, get_recommendation, TNC_IMV_Action_Recommendation,
+       private_tnccs_recommendation_msg_t *this)
+{
+       return this->rec;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node)
+{
+       private_tnccs_recommendation_msg_t *this;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_recommendation = _get_recommendation,
+               },
+               .type = TNCCS_MSG_RECOMMENDATION,
+               .node = node,
+       );
+
+       return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec)
+{
+       private_tnccs_recommendation_msg_t *this;
+       xmlNodePtr n, n2;
+       char *recommendation_string;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+                       .get_recommendation = _get_recommendation,
+               },
+               .type = TNCCS_MSG_RECOMMENDATION,
+               .node =  xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+               .rec = rec,
+       );
+
+       /* add the message type number in hex */
+       n = xmlNewNode(NULL, BAD_CAST "Type");
+       xmlNodeSetContent(n, BAD_CAST "00000001");
+       xmlAddChild(this->node, n);
+
+       n = xmlNewNode(NULL, BAD_CAST "XML");
+       xmlAddChild(this->node, n);
+
+       switch (rec)
+       {
+               case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+                       recommendation_string = "allow";
+                       break;
+               case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+                       recommendation_string = "isolate";
+                       break;
+               case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+               case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+               default:
+                       recommendation_string = "none";
+       }
+
+       n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+       xmlNodeSetContent(n2, BAD_CAST recommendation_string);
+       xmlAddChild(n, n2);
+
+       return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h
new file mode 100644 (file)
index 0000000..923a03b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_recommendation_msg tnccs_recommendation_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_RECOMMENDATION_MSG_H_
+#define TNCCS_RECOMMENDATION_MSG_H_
+
+typedef struct tnccs_recommendation_msg_t tnccs_recommendation_msg_t;
+
+#include "tnccs_msg.h"
+
+#include <tnc/tncifimv.h>
+
+/**
+ * Class representing the TNCCS-Recommendation message type
+ */
+struct tnccs_recommendation_msg_t {
+
+       /**
+        * TNCCS Message interface
+        */
+       tnccs_msg_t tnccs_msg_interface;
+
+       /**
+        * Get Action Recommendation
+        *
+        * @return                              Action Recommendation
+        */
+       TNC_IMV_Action_Recommendation (*get_recommendation)(tnccs_recommendation_msg_t *this);
+};
+
+/**
+ * Create a TNCCS-Recommendation message from XML-encoded message node
+ *
+ * @param msg_node                     XML-encoded message node
+ */
+tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node);
+
+/**
+ * Create a TNCCS-Recommendation message from parameters
+ *
+ * @param rec                          Action Recommendation
+ */
+tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation);
+
+#endif /** TNCCS_RECOMMENDATION_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c
new file mode 100644 (file)
index 0000000..34a40c2
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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_tncs_contact_info_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_tncs_contact_info_msg_t private_tnccs_tncs_contact_info_msg_t;
+
+/**
+ * Private data of a tnccs_tncs_contact_info_msg_t object.
+ *
+ */
+struct private_tnccs_tncs_contact_info_msg_t {
+       /**
+        * Public tnccs_tncs_contact_info_t interface.
+        */
+       tnccs_tncs_contact_info_msg_t public;
+
+       /**
+        * TNCCS message type
+        */
+       tnccs_msg_type_t type;
+
+       /**
+        * XML-encoded message node
+        */
+       xmlNodePtr node;
+
+       /**
+        * Preferred language
+        */
+       char *preferred_language;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+       private_tnccs_tncs_contact_info_msg_t *this)
+{
+       return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+       private_tnccs_tncs_contact_info_msg_t *this)
+{
+       return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+       private_tnccs_tncs_contact_info_msg_t *this)
+{
+       free(this->preferred_language);
+       free(this);
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node)
+{
+       private_tnccs_tncs_contact_info_msg_t *this;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+               },
+               .type = TNCCS_MSG_TNCS_CONTACT_INFO,
+               .node = node,
+       );
+
+       return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create(char *language)
+{
+       private_tnccs_tncs_contact_info_msg_t *this;
+       xmlNodePtr n, n2;
+
+       INIT(this,
+               .public = {
+                       .tnccs_msg_interface = {
+                               .get_type = _get_type,
+                               .get_node = _get_node,
+                               .destroy = _destroy,
+                       },
+               },
+               .type = TNCCS_MSG_TNCS_CONTACT_INFO,
+               .node =  xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+               .preferred_language = strdup(language),
+       );
+
+    // Add the message type number
+    n = xmlNewNode(NULL, BAD_CAST "Type");
+    xmlNodeSetContent(n, BAD_CAST "00000005");
+    xmlAddChild(this->node, n);
+
+    n = xmlNewNode(NULL, BAD_CAST "XML");
+    xmlAddChild(this->node, n);
+
+    n2 = xmlNewNode(NULL, BAD_CAST "TNCCS-TNCSContactInfo");
+    xmlNodeSetContent(n2, BAD_CAST language);
+    xmlAddChild(n, n2);
+
+       return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h
new file mode 100644 (file)
index 0000000..83eac7c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_tncs_contact_info_msg tnccs_tncs_contact_info_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_TNCS_CONTACT_INFO_MSG_H_
+#define TNCCS_TNCS_CONTACT_INFO_MSG_H_
+
+typedef struct tnccs_tncs_contact_info_msg_t tnccs_tncs_contact_info_msg_t;
+
+#include "tnccs_msg.h"
+
+/**
+ * Class representing the TNCCS-TNCSContactInfo message type
+ */
+struct tnccs_tncs_contact_info_msg_t {
+
+       /**
+        * TNCCS Message interface
+        */
+       tnccs_msg_t tnccs_msg_interface;
+};
+
+/**
+ * Create a TNCCS-TNCSContactInfo message from XML-encoded message node
+ *
+ * @param msg_node                     XML-encoded message node
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node);
+
+/**
+ * Create a TNCCS-TNCSContactInfo message from parameters
+ *
+ * @param language                     preferred language string
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create(char *language);
+
+#endif /** TNCCS_TNCS_CONTACT_INFO_MSG_H_ @}*/
index b321c26..ea185e7 100644 (file)
  */
 
 #include "tnccs_11.h"
-
-#include <libtnctncc.h>
-#include <libtnctncs.h>
+#include "batch/tnccs_batch.h"
+#include "messages/tnccs_msg.h"
+#include "messages/imc_imv_msg.h"
+#include "messages/tnccs_preferred_language_msg.h"
 
 #include <daemon.h>
 #include <debug.h>
-
-#define TNC_SEND_BUFFER_SIZE   32
-
-static chunk_t tnc_send_buffer[TNC_SEND_BUFFER_SIZE];
-
-/**
- * Buffers TNCCS batch to be sent (TODO make the buffer scalable)
- */
-static TNC_Result buffer_batch(u_int32_t id, const char *data, size_t len)
-{
-       if (id >= TNC_SEND_BUFFER_SIZE)
-       {
-               DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be stored in "
-                                         "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE);
-               return TNC_RESULT_FATAL;
-       }
-       if (tnc_send_buffer[id].ptr)
-       {
-               DBG1(DBG_TNC, "send buffer slot for Connection ID %u is already "
-                                         "occupied", id);
-               return TNC_RESULT_FATAL;
-       }
-       tnc_send_buffer[id] = chunk_alloc(len);
-       memcpy(tnc_send_buffer[id].ptr, data, len);
-
-       return TNC_RESULT_SUCCESS;
-}
-
-/**
- * Retrieves TNCCS batch to be sent
- */
-static bool retrieve_batch(u_int32_t id, chunk_t *batch)
-{
-       if (id >= TNC_SEND_BUFFER_SIZE)
-       {
-               DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be retrieved from "
-                                         "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE);
-               return FALSE;
-       }
-
-       *batch = tnc_send_buffer[id];
-       return TRUE;
-}
-
-/**
- * Frees TNCCS batch that was sent
- */
-static void free_batch(u_int32_t id)
-{
-       if (id < TNC_SEND_BUFFER_SIZE)
-       {
-               chunk_free(&tnc_send_buffer[id]);
-       }
-}
-
-/**
- * Define callback functions called by the libtnc library
- */
-TNC_Result TNC_TNCC_SendBatch(libtnc_tncc_connection* conn, 
-                                                         const char* messageBuffer, size_t messageLength)
-{
-       return buffer_batch(conn->connectionID, messageBuffer, messageLength);
-}
-
-TNC_Result TNC_TNCS_SendBatch(libtnc_tncs_connection* conn, 
-                                                         const char* messageBuffer, size_t messageLength)
-{
-       return buffer_batch(conn->connectionID, messageBuffer, messageLength);
-}
+#include <threading/mutex.h>
+#include <tnc/tncif.h>
+#include <tnc/tncifimv_names.h>
+#include <tnc/tnccs/tnccs.h>
 
 typedef struct private_tnccs_11_t private_tnccs_11_t;
 
@@ -108,116 +44,219 @@ struct private_tnccs_11_t {
        bool is_server;
 
        /**
-        * TNCC Connection to IMCs
+        * Connection ID assigned to this TNCCS connection
         */
-       libtnc_tncc_connection* tncc_connection;
+       TNC_ConnectionID connection_id;
 
        /**
-        * TNCS Connection to IMVs
+        * Last TNCCS batch ID
         */
-       libtnc_tncs_connection* tncs_connection;
+       int batch_id;
+
+       /**
+        * TNCCS batch being constructed
+        */
+       tnccs_batch_t *batch;
+
+       /**
+        * Mutex locking the batch in construction
+        */
+       mutex_t *mutex;
+
+       /**
+        * Flag set by IMC/IMV RequestHandshakeRetry() function
+        */
+       bool request_handshake_retry;
+
+       /**
+        * Set of IMV recommendations  (TNC Server only)
+        */
+       recommendations_t *recs;
 };
 
-METHOD(tls_t, process, status_t,
-       private_tnccs_11_t *this, void *buf, size_t buflen)
+METHOD(tnccs_t, send_msg, void,
+       private_tnccs_11_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
+                                                         TNC_BufferReference msg,
+                                                         TNC_UInt32 msg_len,
+                                                         TNC_MessageType msg_type)
 {
-       u_int32_t conn_id;
+       tnccs_msg_t *tnccs_msg;
 
-       if (this->is_server && !this->tncs_connection)
+       tnccs_msg = imc_imv_msg_create(msg_type, chunk_create(msg, msg_len));
+
+       /* adding an IMC-IMV Message to TNCCS batch */
+       this->mutex->lock(this->mutex);
+       if (!this->batch)
        {
-               this->tncs_connection = libtnc_tncs_CreateConnection(NULL);
-               if (!this->tncs_connection)
+               this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
+       }
+       this->batch->add_msg(this->batch, tnccs_msg);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Handle a single TNCCS message according to its type
+ */
+static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
+{
+       switch (msg->get_type(msg))
+       {
+               case IMC_IMV_MSG:
                {
-                       DBG1(DBG_TNC, "TNCS CreateConnection failed");
-                       return FAILED;
+                       imc_imv_msg_t *imc_imv_msg;
+                       TNC_MessageType msg_type;
+                       chunk_t msg_body;
+
+                       imc_imv_msg = (imc_imv_msg_t*)msg;
+                       msg_type = imc_imv_msg->get_msg_type(imc_imv_msg);
+                       msg_body = imc_imv_msg->get_msg_body(imc_imv_msg);
+
+                       DBG2(DBG_TNC, "handling IMC_IMV message type 0x%08x", msg_type);
+
+                       if (this->is_server)
+                       {
+                               charon->imvs->receive_message(charon->imvs,
+                               this->connection_id, msg_body.ptr, msg_body.len, msg_type);
+                       }
+                       else
+                       {
+                               charon->imcs->receive_message(charon->imcs,
+                               this->connection_id, msg_body.ptr, msg_body.len,msg_type);
+                       }
+                       break;
                }
-               DBG1(DBG_TNC, "assigned TNCS Connection ID %u",
-                                          this->tncs_connection->connectionID);
-               if (libtnc_tncs_BeginSession(this->tncs_connection) != TNC_RESULT_SUCCESS)
+               case TNCCS_MSG_PREFERRED_LANGUAGE:
                {
-                       DBG1(DBG_TNC, "TNCS BeginSession failed");
-                       return FAILED;
+                       tnccs_preferred_language_msg_t *lang_msg;
+                       char *lang;
+
+                       lang_msg = (tnccs_preferred_language_msg_t*)msg;
+                       lang = lang_msg->get_preferred_language(lang_msg);
+
+                       DBG2(DBG_TNC, "setting preferred language to '%s'", lang);
+                       this->recs->set_preferred_language(this->recs,
+                                                                       chunk_create(lang, strlen(lang)));
+                       break;
                }
+               default:
+                       break;
        }
-       conn_id = this->is_server ? this->tncs_connection->connectionID
-                                                         : this->tncc_connection->connectionID;
+}
 
-       DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u",
-                                  buflen, conn_id);
-       DBG3(DBG_TNC, "%.*s", buflen, buf);
+METHOD(tls_t, process, status_t,
+       private_tnccs_11_t *this, void *buf, size_t buflen)
+{
+       chunk_t data;
+       tnccs_batch_t *batch;
+       status_t status;
 
-       if (this->is_server)
+       if (this->is_server && !this->connection_id)
        {
-               if (libtnc_tncs_ReceiveBatch(this->tncs_connection, buf, buflen) !=
-                       TNC_RESULT_SUCCESS)
+               this->connection_id = charon->tnccs->create_connection(charon->tnccs,
+                                                               (tnccs_t*)this, _send_msg,
+                                                               &this->request_handshake_retry, &this->recs);
+               if (!this->connection_id)
                {
-                       DBG1(DBG_TNC, "TNCS ReceiveBatch failed");
                        return FAILED;
                }
+               charon->imvs->notify_connection_change(charon->imvs,
+                                                       this->connection_id, TNC_CONNECTION_STATE_CREATE);
        }
-       else
+
+       data = chunk_create(buf, buflen);
+       DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u",
+                                  data.len, this->connection_id);
+       DBG3(DBG_TNC, "%.*s", data.len, data.ptr);
+       batch = tnccs_batch_create_from_data(this->is_server, ++this->batch_id, data);
+       status = batch->process(batch);
+
+       if (status != FAILED)
        {
-               if (libtnc_tncc_ReceiveBatch(this->tncc_connection, buf, buflen) !=
-                       TNC_RESULT_SUCCESS)
+               enumerator_t *enumerator;
+               tnccs_msg_t *msg;
+
+               enumerator = batch->create_msg_enumerator(batch);
+               while (enumerator->enumerate(enumerator, &msg))
                {
-                       DBG1(DBG_TNC, "TNCC ReceiveBatch failed");
-                       return FAILED;
+                       handle_message(this, msg);
                }
+               enumerator->destroy(enumerator);
+
        }
+       batch->destroy(batch);
+
        return NEED_MORE;
 }
 
 METHOD(tls_t, build, status_t,
        private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen)
 {
-       chunk_t batch;
-       u_int32_t conn_id;
-       size_t len;
+       status_t status;
 
-       if (!this->is_server && !this->tncc_connection)
+       /* Initialize the connection */
+       if (!this->is_server && !this->connection_id)
        {
-               this->tncc_connection = libtnc_tncc_CreateConnection(NULL);
-               if (!this->tncc_connection)
-               {
-                       DBG1(DBG_TNC, "TNCC CreateConnection failed");
-                       return FAILED;
-               }
-               DBG1(DBG_TNC, "assigned TNCC Connection ID %u",
-                                          this->tncc_connection->connectionID);
-               if (libtnc_tncc_BeginSession(this->tncc_connection) != TNC_RESULT_SUCCESS)
+               tnccs_msg_t *msg;
+               char *pref_lang;
+
+               this->connection_id = charon->tnccs->create_connection(charon->tnccs,
+                                                                               (tnccs_t*)this, _send_msg,
+                                                                               &this->request_handshake_retry, NULL);
+               if (!this->connection_id)
                {
-                       DBG1(DBG_TNC, "TNCC BeginSession failed");
                        return FAILED;
                }
+
+               /* Create TNCCS-PreferredLanguage message */
+               pref_lang = charon->imcs->get_preferred_language(charon->imcs);
+               msg = tnccs_preferred_language_msg_create(pref_lang);
+               this->mutex->lock(this->mutex);
+               this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
+               this->batch->add_msg(this->batch, msg);
+               this->mutex->unlock(this->mutex);
+
+               charon->imcs->notify_connection_change(charon->imcs,
+                                                       this->connection_id, TNC_CONNECTION_STATE_CREATE);
+               charon->imcs->notify_connection_change(charon->imcs,
+                                                       this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+               charon->imcs->begin_handshake(charon->imcs, this->connection_id);
        }
-       conn_id = this->is_server ? this->tncs_connection->connectionID
-                                                         : this->tncc_connection->connectionID;
        
-       if (!retrieve_batch(conn_id, &batch))
-       {
-               return FAILED;
-       }
-       len = *buflen;
-       len = min(len, batch.len);
-       *buflen = len;
-       if (msglen)
-       {
-               *msglen = batch.len;
-       }
+       /* Do not allow any asynchronous IMCs or IMVs to add additional messages */
+       this->mutex->lock(this->mutex);
 
-       if (batch.len)
+       if (this->batch)
        {
+               chunk_t data;
+
+               this->batch->build(this->batch);
+               data = this->batch->get_encoding(this->batch);
                DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u",
-                                          batch.len, conn_id);
-               DBG3(DBG_TNC, "%.*s", batch.len, batch.ptr);
-               memcpy(buf, batch.ptr, len);
-               free_batch(conn_id);
-               return ALREADY_DONE;
+                                          data.len, this->connection_id);
+               DBG3(DBG_TNC, "%.*s", data.len, data.ptr);
+               *msglen = data.len;
+
+               if (data.len > *buflen)
+               {
+                       DBG1(DBG_TNC, "fragmentation of TNCCS batch not supported yet");
+               }
+               else
+               {
+                       *buflen = data.len;
+               }                               
+               memcpy(buf, data.ptr, *buflen);
+               this->batch->destroy(this->batch);
+               this->batch = NULL;
+               status = ALREADY_DONE;
        }
        else
        {
-               return INVALID_STATE;
+               DBG1(DBG_TNC, "no TNCCS Batch to send");
+               status = INVALID_STATE;
        }
+       this->mutex->unlock(this->mutex);
+
+       return status;  
 }
 
 METHOD(tls_t, is_server, bool,
@@ -237,40 +276,13 @@ METHOD(tls_t, is_complete, bool,
 {
        TNC_IMV_Action_Recommendation rec;
        TNC_IMV_Evaluation_Result eval;
-       char *group;
-       identification_t *id;
-       ike_sa_t *ike_sa;
-       auth_cfg_t *auth;
-       
-       if (this->is_server &&
-               libtnc_tncs_HaveRecommendation(this->tncs_connection, &rec, &eval) ==
-               TNC_RESULT_SUCCESS)
+
+       if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
        {
-               switch (rec)
-               {
-                       case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
-                               DBG1(DBG_TNC, "TNC recommendation is allow");
-                               group = "allow";
-                               break;                          
-                       case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
-                               DBG1(DBG_TNC, "TNC recommendation is isolate");
-                               group = "isolate";
-                               break;
-                       case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
-                       case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
-                       default:
-                               DBG1(DBG_TNC, "TNC recommendation is none");
-                               return FALSE;
-               }
-               ike_sa = charon->bus->get_sa(charon->bus);
-               if (ike_sa)
-               {
-                       auth = ike_sa->get_auth_cfg(ike_sa, FALSE);
-                       id = identification_create_from_string(group);
-                       auth->add(auth, AUTH_RULE_GROUP, id);
-                       DBG1(DBG_TNC, "added group membership '%s' based on TNC recommendation", group);
-               }
-               return TRUE;
+               DBG2(DBG_TNC, "Final recommendation is '%N' and evaluation is '%N'",
+                        action_recommendation_names, rec, evaluation_result_names, eval);
+
+               return charon->imvs->enforce_recommendation(charon->imvs, rec);
        }
        else
        {
@@ -287,20 +299,9 @@ METHOD(tls_t, get_eap_msk, chunk_t,
 METHOD(tls_t, destroy, void,
        private_tnccs_11_t *this)
 {
-       if (this->is_server)
-       {
-               if (this->tncs_connection)
-               {
-                       libtnc_tncs_DeleteConnection(this->tncs_connection);
-               }
-       }
-       else
-       {
-               if (this->tncc_connection)
-               {
-                       libtnc_tncc_DeleteConnection(this->tncc_connection);
-               }
-       }
+       charon->tnccs->remove_connection(charon->tnccs, this->connection_id);
+       this->mutex->destroy(this->mutex);
+       DESTROY_IF(this->batch);
        free(this);
 }
 
@@ -322,6 +323,7 @@ tls_t *tnccs_11_create(bool is_server)
                        .destroy = _destroy,
                },
                .is_server = is_server,
+               .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
        );
 
        return &this->public;