aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/plugins/tnc_ifmap2/Makefile.am3
-rw-r--r--src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c232
-rw-r--r--src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.c267
-rw-r--r--src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.h61
4 files changed, 343 insertions, 220 deletions
diff --git a/src/libcharon/plugins/tnc_ifmap2/Makefile.am b/src/libcharon/plugins/tnc_ifmap2/Makefile.am
index 11524795c..217d8972f 100644
--- a/src/libcharon/plugins/tnc_ifmap2/Makefile.am
+++ b/src/libcharon/plugins/tnc_ifmap2/Makefile.am
@@ -20,7 +20,8 @@ libstrongswan_tnc_ifmap2_la_LIBADD = \
libstrongswan_tnc_ifmap2_la_SOURCES = \
tnc_ifmap2_plugin.h tnc_ifmap2_plugin.c \
tnc_ifmap2_listener.h tnc_ifmap2_listener.c \
- tnc_ifmap2_soap.h tnc_ifmap2_soap.c
+ tnc_ifmap2_soap.h tnc_ifmap2_soap.c \
+ tnc_ifmap2_soap_msg.h tnc_ifmap2_soap_msg.c
libstrongswan_tnc_ifmap2_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c
index 65f92653b..4c9334dbd 100644
--- a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c
+++ b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c
@@ -13,28 +13,20 @@
* for more details.
*/
-#define _GNU_SOURCE /* for asprintf() */
-
#include "tnc_ifmap2_soap.h"
+#include "tnc_ifmap2_soap_msg.h"
#include <utils/debug.h>
-#include <utils/lexparser.h>
#include <credentials/sets/mem_cred.h>
#include <daemon.h>
#include <tls_socket.h>
-#include <libxml/parser.h>
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
-#define SOAP_NS "http://www.w3.org/2003/05/soap-envelope"
#define IFMAP_NS "http://www.trustedcomputinggroup.org/2010/IFMAP/2"
#define IFMAP_META_NS "http://www.trustedcomputinggroup.org/2010/IFMAP-METADATA/2"
#define IFMAP_LOGFILE "strongswan_ifmap.log"
@@ -90,206 +82,11 @@ struct private_tnc_ifmap2_soap_t {
};
-/**
- * Send HTTP POST request and receive HTTP response
- */
-static bool http_send_receive(private_tnc_ifmap2_soap_t *this, chunk_t out,
- chunk_t *in)
-{
- char header[] =
- "POST /ifmap HTTP/1.1\r\n"
- "Content-Type: application/soap+xml;charset=utf-8\r\n"
- "Content-Length: ";
- char *request, response[2048];
- chunk_t line, http, parameter;
- int len, code, content_len = 0;
-
- /* Write HTTP POST request */
- len = asprintf(&request, "%s%d\r\n\r\n%.*s", header, out.len,
- out.len, out.ptr);
- if (len == -1)
- {
- return FALSE;
- }
- this->tls->write(this->tls, request, len);
- free(request);
-
- /* Read HTTP response */
- len = this->tls->read(this->tls, response, sizeof(response), TRUE);
- if (len == -1)
- {
- return FALSE;
- }
- *in = chunk_create(response, len);
-
- /* Process HTTP protocol version */
- if (!fetchline(in, &line) || !extract_token(&http, ' ', &line) ||
- !match("HTTP/1.1", &http) || sscanf(line.ptr, "%d", &code) != 1)
- {
- DBG1(DBG_TNC, "malformed http response header");
- return FALSE;
- }
- if (code != 200)
- {
- DBG1(DBG_TNC, "http response returns error code %d", code);
- return FALSE;
- }
-
- /* Process HTTP header line by line until the HTTP body is reached */
- while (fetchline(in, &line))
- {
- if (line.len == 0)
- {
- break;
- }
-
- if (extract_token(&parameter, ':', &line) &&
- match("Content-Length", &parameter) &&
- sscanf(line.ptr, "%d", &len) == 1)
- {
- content_len = len;
- }
- }
-
- /* Found Content-Length parameter and check size of HTTP body */
- if (content_len)
- {
- if (content_len > in->len)
- {
- DBG1(DBG_TNC, "http body is smaller than content length");
- return FALSE;
- }
- in->len = content_len;
- }
- *in = chunk_clone(*in);
-
- return TRUE;
-}
-
-/**
- * Find a child node with a given name
- */
-static xmlNodePtr find_child(xmlNodePtr parent, const xmlChar* name)
-{
- xmlNodePtr child;
-
- child = parent->xmlChildrenNode;
- while (child)
- {
- if (xmlStrcmp(child->name, name) == 0)
- {
- return child;
- }
- child = child->next;
- }
-
- DBG1(DBG_TNC, "child node \"%s\" not found", name);
- return NULL;
-}
-
-/**
- * Send request and receive result via SOAP
- */
-static bool soap_send_receive(private_tnc_ifmap2_soap_t *this,
- char *request_name, xmlNodePtr request,
- char *result_name, xmlNodePtr *result,
- xmlDocPtr *result_doc)
-{
- xmlDocPtr doc;
- xmlNodePtr env, body, cur;
- xmlNsPtr ns;
- xmlChar *xml;
- int len;
- chunk_t in, out;
-
- *result_doc = NULL;
- DBG2(DBG_TNC, "sending ifmap %s", request_name);
-
- /* Generate XML Document containing SOAP Envelope */
- doc = xmlNewDoc("1.0");
- env =xmlNewNode(NULL, "Envelope");
- ns = xmlNewNs(env, SOAP_NS, "env");
- xmlSetNs(env, ns);
- xmlDocSetRootElement(doc, env);
-
- /* Add SOAP Body containing IF-MAP request */
- body = xmlNewNode(ns, "Body");
- xmlAddChild(body, request);
- xmlAddChild(env, body);
-
- /* Convert XML Document into a character string */
- xmlDocDumpFormatMemory(doc, &xml, &len, 1);
- xmlFreeDoc(doc);
- DBG3(DBG_TNC, "%.*s", len, xml);
- out = chunk_create(xml, len);
-
- /* Send SOAP-XML request via HTTP */
- if (!http_send_receive(this, out, &in))
- {
- xmlFree(xml);
- return FALSE;
- }
- xmlFree(xml);
-
- DBG3(DBG_TNC, "%B", &in);
- doc = xmlParseMemory(in.ptr, in.len);
- free(in.ptr);
-
- if (!doc)
- {
- DBG1(DBG_TNC, "failed to parse XML message");
- return FALSE;
- }
- *result_doc = doc;
-
- /* check out XML document */
- cur = xmlDocGetRootElement(doc);
- if (!cur)
- {
- DBG1(DBG_TNC, "empty XML message");
- return FALSE;
- }
-
- /* get XML Document type is a SOAP Envelope */
- if (xmlStrcmp(cur->name, "Envelope"))
- {
- DBG1(DBG_TNC, "XML message does not contain a SOAP Envelope");
- return FALSE;
- }
-
- /* get SOAP Body */
- cur = find_child(cur, "Body");
- if (!cur)
- {
- return FALSE;
- }
-
- /* get IF-MAP response */
- cur = find_child(cur, "response");
- if (!cur)
- {
- return FALSE;
- }
-
- /* get IF-MAP result */
- cur = find_child(cur, result_name);
- if (!cur)
- {
- return FALSE;
- }
-
- if (result)
- {
- *result = cur;
- }
- return TRUE;
-}
-
METHOD(tnc_ifmap2_soap_t, newSession, bool,
private_tnc_ifmap2_soap_t *this)
{
+ tnc_ifmap2_soap_msg_t *soap_msg;
xmlNodePtr request, result;
- xmlDocPtr result_doc;
xmlNsPtr ns;
/*build newSession request */
@@ -297,20 +94,18 @@ METHOD(tnc_ifmap2_soap_t, newSession, bool,
ns = xmlNewNs(request, IFMAP_NS, "ifmap");
xmlSetNs(request, ns);
- if (!soap_send_receive(this, "newSession", request, "newSessionResult",
- &result, &result_doc))
+ soap_msg = tnc_ifmap2_soap_msg_create(this->tls);
+ if (!soap_msg->post(soap_msg, "newSession", request,
+ "newSessionResult", &result))
{
- if (result_doc)
- {
- xmlFreeDoc(result_doc);
- }
+ soap_msg->destroy(soap_msg);
return FALSE;
}
/* get session-id and ifmap-publisher-id properties */
this->session_id = xmlGetProp(result, "session-id");
this->ifmap_publisher_id = xmlGetProp(result, "ifmap-publisher-id");
- xmlFreeDoc(result_doc);
+ soap_msg->destroy(soap_msg);
DBG1(DBG_TNC, "session-id: %s, ifmap-publisher-id: %s",
this->session_id, this->ifmap_publisher_id);
@@ -327,8 +122,8 @@ METHOD(tnc_ifmap2_soap_t, newSession, bool,
METHOD(tnc_ifmap2_soap_t, purgePublisher, bool,
private_tnc_ifmap2_soap_t *this)
{
+ tnc_ifmap2_soap_msg_t *soap_msg;
xmlNodePtr request;
- xmlDocPtr result_doc;
xmlNsPtr ns;
bool success;
@@ -339,12 +134,11 @@ METHOD(tnc_ifmap2_soap_t, purgePublisher, bool,
xmlNewProp(request, "session-id", this->session_id);
xmlNewProp(request, "ifmap-publisher-id", this->ifmap_publisher_id);
- success = soap_send_receive(this, "purgePublisher", request,
- "purgePublisherReceived", NULL, &result_doc);
- if (result_doc)
- {
- xmlFreeDoc(result_doc);
- }
+ soap_msg = tnc_ifmap2_soap_msg_create(this->tls);
+ success = soap_msg->post(soap_msg, "purgePublisher", request,
+ "purgePublisherReceived", NULL);
+ soap_msg->destroy(soap_msg);
+
return success;
}
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.c b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.c
new file mode 100644
index 000000000..7bea62d83
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#define _GNU_SOURCE /* for asprintf() */
+
+#include "tnc_ifmap2_soap_msg.h"
+
+#include <utils/debug.h>
+#include <utils/lexparser.h>
+
+#include <stdio.h>
+
+#define SOAP_NS "http://www.w3.org/2003/05/soap-envelope"
+
+typedef struct private_tnc_ifmap2_soap_msg_t private_tnc_ifmap2_soap_msg_t;
+
+/**
+ * Private data of an tnc_ifmap2_soap_msg_t object.
+ */
+struct private_tnc_ifmap2_soap_msg_t {
+
+ /**
+ * Public tnc_ifmap2_soap_msg_t interface.
+ */
+ tnc_ifmap2_soap_msg_t public;
+
+ /**
+ * TLS Socket
+ */
+ tls_socket_t *tls;
+
+ /**
+ * XML Document
+ */
+ xmlDocPtr doc;
+
+};
+
+/**
+ * Send HTTP POST request and receive HTTP response
+ */
+static bool http_send_receive(private_tnc_ifmap2_soap_msg_t *this,
+ chunk_t out, chunk_t *in)
+{
+ char header[] =
+ "POST /ifmap HTTP/1.1\r\n"
+ "Content-Type: application/soap+xml;charset=utf-8\r\n"
+ "Content-Length: ";
+ char *request, response[2048];
+ chunk_t line, http, parameter;
+ int len, code, content_len = 0;
+
+ /* Write HTTP POST request */
+ len = asprintf(&request, "%s%d\r\n\r\n%.*s", header, out.len,
+ out.len, out.ptr);
+ if (len == -1)
+ {
+ return FALSE;
+ }
+ this->tls->write(this->tls, request, len);
+ free(request);
+
+ /* Read HTTP response */
+ len = this->tls->read(this->tls, response, sizeof(response), TRUE);
+ if (len == -1)
+ {
+ return FALSE;
+ }
+ *in = chunk_create(response, len);
+
+ /* Process HTTP protocol version */
+ if (!fetchline(in, &line) || !extract_token(&http, ' ', &line) ||
+ !match("HTTP/1.1", &http) || sscanf(line.ptr, "%d", &code) != 1)
+ {
+ DBG1(DBG_TNC, "malformed http response header");
+ return FALSE;
+ }
+ if (code != 200)
+ {
+ DBG1(DBG_TNC, "http response returns error code %d", code);
+ return FALSE;
+ }
+
+ /* Process HTTP header line by line until the HTTP body is reached */
+ while (fetchline(in, &line))
+ {
+ if (line.len == 0)
+ {
+ break;
+ }
+
+ if (extract_token(&parameter, ':', &line) &&
+ match("Content-Length", &parameter) &&
+ sscanf(line.ptr, "%d", &len) == 1)
+ {
+ content_len = len;
+ }
+ }
+
+ /* Found Content-Length parameter and check size of HTTP body */
+ if (content_len)
+ {
+ if (content_len > in->len)
+ {
+ DBG1(DBG_TNC, "http body is smaller than content length");
+ return FALSE;
+ }
+ in->len = content_len;
+ }
+ *in = chunk_clone(*in);
+
+ return TRUE;
+}
+
+/**
+ * Find a child node with a given name
+ */
+static xmlNodePtr find_child(xmlNodePtr parent, const xmlChar* name)
+{
+ xmlNodePtr child;
+
+ child = parent->xmlChildrenNode;
+ while (child)
+ {
+ if (xmlStrcmp(child->name, name) == 0)
+ {
+ return child;
+ }
+ child = child->next;
+ }
+
+ DBG1(DBG_TNC, "child node \"%s\" not found", name);
+ return NULL;
+}
+
+METHOD(tnc_ifmap2_soap_msg_t, post, bool,
+ private_tnc_ifmap2_soap_msg_t *this, char *request_name, xmlNodePtr request,
+ char *result_name, xmlNodePtr *result)
+{
+ xmlDocPtr doc;
+ xmlNodePtr env, body, cur;
+ xmlNsPtr ns;
+ xmlChar *xml;
+ int len;
+ chunk_t in, out;
+
+ DBG2(DBG_TNC, "sending ifmap %s", request_name);
+
+ /* Generate XML Document containing SOAP Envelope */
+ doc = xmlNewDoc("1.0");
+ env =xmlNewNode(NULL, "Envelope");
+ ns = xmlNewNs(env, SOAP_NS, "env");
+ xmlSetNs(env, ns);
+ xmlDocSetRootElement(doc, env);
+
+ /* Add SOAP Body containing IF-MAP request */
+ body = xmlNewNode(ns, "Body");
+ xmlAddChild(body, request);
+ xmlAddChild(env, body);
+
+ /* Convert XML Document into a character string */
+ xmlDocDumpFormatMemory(doc, &xml, &len, 1);
+ xmlFreeDoc(doc);
+ DBG3(DBG_TNC, "%.*s", len, xml);
+ out = chunk_create(xml, len);
+
+ /* Send SOAP-XML request via HTTP */
+ if (!http_send_receive(this, out, &in))
+ {
+ xmlFree(xml);
+ return FALSE;
+ }
+ xmlFree(xml);
+
+ DBG3(DBG_TNC, "%B", &in);
+ this->doc = xmlParseMemory(in.ptr, in.len);
+ free(in.ptr);
+
+ if (!this->doc)
+ {
+ DBG1(DBG_TNC, "failed to parse XML message");
+ return FALSE;
+ }
+
+ /* check out XML document */
+ cur = xmlDocGetRootElement(this->doc);
+ if (!cur)
+ {
+ DBG1(DBG_TNC, "empty XML message");
+ return FALSE;
+ }
+
+ /* get XML Document type is a SOAP Envelope */
+ if (xmlStrcmp(cur->name, "Envelope"))
+ {
+ DBG1(DBG_TNC, "XML message does not contain a SOAP Envelope");
+ return FALSE;
+ }
+
+ /* get SOAP Body */
+ cur = find_child(cur, "Body");
+ if (!cur)
+ {
+ return FALSE;
+ }
+
+ /* get IF-MAP response */
+ cur = find_child(cur, "response");
+ if (!cur)
+ {
+ return FALSE;
+ }
+
+ /* get IF-MAP result */
+ cur = find_child(cur, result_name);
+ if (!cur)
+ {
+ return FALSE;
+ }
+
+ if (result)
+ {
+ *result = cur;
+ }
+ return TRUE;
+}
+
+METHOD(tnc_ifmap2_soap_msg_t, destroy, void,
+ private_tnc_ifmap2_soap_msg_t *this)
+{
+ if (this->doc)
+ {
+ xmlFreeDoc(this->doc);
+ }
+ free(this);
+}
+
+/**
+ * See header
+ */
+tnc_ifmap2_soap_msg_t *tnc_ifmap2_soap_msg_create(tls_socket_t *tls)
+{
+ private_tnc_ifmap2_soap_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .post = _post,
+ .destroy = _destroy,
+ },
+ .tls = tls,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.h b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.h
new file mode 100644
index 000000000..21ab5eecd
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 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 tnc_ifmap2_soap_msg tnc_ifmap2_soap_msg
+ * @{ @ingroup tnc_ifmap2
+ */
+
+#ifndef TNC_IFMAP2_SOAP_MSG_H_
+#define TNC_IFMAP2_SOAP_MSG_H_
+
+#include <library.h>
+#include <tls_socket.h>
+
+#include <libxml/parser.h>
+
+typedef struct tnc_ifmap2_soap_msg_t tnc_ifmap2_soap_msg_t;
+
+/**
+ * Interface for sending and receiving SOAP-XML messages
+ */
+struct tnc_ifmap2_soap_msg_t {
+
+ /**
+ * Post an IF-MAP request in a SOAP-XML message and return a result
+ *
+ * @param request_name name of the IF-MAP request
+ * @param request XML-encoded IF-MAP request
+ * @param result_name name of the IF-MAP result
+ * @param result XML-encoded IF-MAP result
+ */
+ bool (*post)(tnc_ifmap2_soap_msg_t *this,
+ char *request_name, xmlNodePtr request,
+ char *result_name, xmlNodePtr* result);
+
+ /**
+ * Destroy a tnc_ifmap2_soap_msg_t object.
+ */
+ void (*destroy)(tnc_ifmap2_soap_msg_t *this);
+};
+
+/**
+ * Create a tnc_ifmap2_soap_msg instance.
+ *
+ * @param tls TLS socket protecting the SOAP message
+ */
+tnc_ifmap2_soap_msg_t *tnc_ifmap2_soap_msg_create(tls_socket_t *tls);
+
+#endif /** TNC_IFMAP2_SOAP_MSG_H_ @}*/