implement NewSession and PurgePublisher messages using the libxml2 library
This commit is contained in:
parent
e99aab35de
commit
b885c3cde6
|
@ -169,11 +169,11 @@ ARG_ENABL_SET([xauth-eap], [enable XAuth backend using EAP methods to verif
|
|||
ARG_ENABL_SET([xauth-pam], [enable XAuth backend using PAM to verify passwords.])
|
||||
ARG_ENABL_SET([xauth-noauth], [enable XAuth pseudo-backend that does not actually verify or even request any credentials.])
|
||||
ARG_ENABL_SET([tnc-ifmap], [enable TNC IF-MAP module.])
|
||||
ARG_ENABL_SET([tnc-ifmap2], [enable TNC IF-MAP v2 module.])
|
||||
ARG_ENABL_SET([tnc-ifmap2], [enable TNC IF-MAP v2 module. Requires libxml])
|
||||
ARG_ENABL_SET([tnc-pdp], [enable TNC policy decision point module.])
|
||||
ARG_ENABL_SET([tnc-imc], [enable TNC IMC module.])
|
||||
ARG_ENABL_SET([tnc-imv], [enable TNC IMV module.])
|
||||
ARG_ENABL_SET([tnccs-11], [enable TNCCS 1.1 protocol module.])
|
||||
ARG_ENABL_SET([tnccs-11], [enable TNCCS 1.1 protocol module. Requires libxml])
|
||||
ARG_ENABL_SET([tnccs-20], [enable TNCCS 2.0 protocol module.])
|
||||
ARG_ENABL_SET([tnccs-dynamic], [enable dynamic TNCCS protocol discovery module.])
|
||||
ARG_ENABL_SET([imc-test], [enable IMC test module.])
|
||||
|
@ -339,7 +339,7 @@ if test x$fips_prf = xtrue; then
|
|||
fi
|
||||
fi
|
||||
|
||||
if test x$smp = xtrue -o x$tnccs_11 = xtrue; then
|
||||
if test x$smp = xtrue -o x$tnccs_11 = xtrue -o x$tnc_ifmap2 = xtrue; then
|
||||
xml=true
|
||||
fi
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ INCLUDES = \
|
|||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libtls \
|
||||
-I$(top_srcdir)/src/libhydra \
|
||||
-I$(top_srcdir)/src/libcharon
|
||||
-I$(top_srcdir)/src/libcharon \
|
||||
${xml_CFLAGS}
|
||||
|
||||
AM_CFLAGS = -rdynamic
|
||||
|
||||
|
@ -13,7 +14,8 @@ else
|
|||
plugin_LTLIBRARIES = libstrongswan-tnc-ifmap2.la
|
||||
endif
|
||||
|
||||
libstrongswan_tnc_ifmap2_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
|
||||
libstrongswan_tnc_ifmap2_la_LIBADD = \
|
||||
$(top_builddir)/src/libtls/libtls.la ${xml_LIBS}
|
||||
|
||||
libstrongswan_tnc_ifmap2_la_SOURCES = \
|
||||
tnc_ifmap2_plugin.h tnc_ifmap2_plugin.c \
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
POST /ifmap HTTP/1.1
|
||||
Content-Type: application/soap+xml; charset=utf-8
|
||||
Content-Length: 236
|
||||
|
||||
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
|
||||
<soapenv:Body>
|
||||
<ifmap:newSession xmlns:ifmap="http://www.trustedcomputinggroup.org/2010/IFMAP/2"></ifmap:newSession>
|
||||
</soapenv:Body>
|
||||
</soapenv:Envelope>
|
||||
|
||||
2013-03-27 20:29:56,704 [pool-5-thread-2] DEBUG - ChannelAcceptor: New connection from 127.0.0.1:44019 on port 8444
|
||||
2013-03-27 20:29:56,887 [pool-6-thread-1] DEBUG - ChannelThread: Client koala.strongsec.com authenticated successfully on channel 127.0.0.1:44019:0
|
||||
2013-03-27 20:29:56,891 [pool-1-thread-1] TRACE - EventProcessor: RequestChannelEvent on channel 127.0.0.1:44019:0
|
||||
2013-03-27 20:29:57,057 [pool-1-thread-1] DEBUG - EventProcessor: newSession for koala.strongsec.com on 127.0.0.1:44019:0
|
||||
2013-03-27 20:29:57,058 [pool-1-thread-1] TRACE - ClientService: newSession for koala.strongsec.com--515754026-1 and maxPollResultSize=5000000 bytes
|
||||
2013-03-27 20:29:57,058 [pool-1-thread-1] TRACE - Adding new Publisher: sessionid=1890214968-1490695359-237418166-218822252 publisherid=koala.strongsec.com--515754026-1
|
||||
2013-03-27 20:29:57,058 [pool-1-thread-1] TRACE - Creating new Publisher...
|
||||
2013-03-27 20:29:57,064 [pool-3-thread-1] TRACE - ActionProcessor: Forward response to channel 127.0.0.1:44019:0
|
||||
2013-03-27 20:29:57,065 [pool-3-thread-1] DEBUG - ChannelThread: Sending reply to koala.strongsec.com
|
||||
2013-03-27 20:29:57,066 [pool-3-thread-1] TRACE - ChannelThread: Length of reply on wire=376
|
||||
2013-03-27 20:29:57,091 [pool-5-thread-2] DEBUG - ChannelAcceptor: New connection from 127.0.0.1:44020 on port 8444
|
||||
2013-03-27 20:29:57,103 [pool-6-thread-1] DEBUG - ChannelThread: 127.0.0.1:44019:0 closed
|
||||
2013-03-27 20:29:57,104 [pool-1-thread-2] DEBUG - EventProcessor: Got ClosedChannelEvent for 127.0.0.1:44019:0
|
||||
2013-03-27 20:29:57,104 [pool-1-thread-2] DEBUG - EventProcessor: Creating Timer for koala.strongsec.com
|
||||
|
||||
2013-03-27 20:29:57,120 [pool-6-thread-2] DEBUG - ChannelThread: Client koala.strongsec.com authenticated successfully on channel 127.0.0.1:44020:1
|
||||
2013-03-27 20:29:57,122 [pool-1-thread-3] TRACE - EventProcessor: RequestChannelEvent on channel 127.0.0.1:44020:1
|
||||
2013-03-27 20:29:57,129 [pool-1-thread-3] DEBUG - EventProcessor: purgePublisher for koala.strongsec.com on 127.0.0.1:44020:1
|
||||
2013-03-27 20:29:57,129 [pool-1-thread-3] TRACE - EventProcessor: koala.strongsec.com uses 127.0.0.1:44020:1 as new SSRC
|
||||
2013-03-27 20:29:57,130 [pool-1-thread-3] TRACE - EventProcessor: Cancel timer for koala.strongsec.com
|
||||
2013-03-27 20:29:57,130 [pool-1-thread-3] DEBUG - ClientService: publisher{koala.strongsec.com--515754026-1} is purging 0 metadata objects of publisher{koala.strongsec.com--515754026-1}
|
||||
|
|
@ -13,25 +13,33 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for asprintf() */
|
||||
|
||||
#include "tnc_ifmap2_soap.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 IFMAP_NO_FD -1
|
||||
#define IFMAP_SERVER_ID "C=DE, ST=Niedersachsen, L=Hannover, O=Hochschule Hannover, OU=Trust@FHH, CN=irond.trust.inform.fh-hannover.de"
|
||||
#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"
|
||||
#define IFMAP_SERVER "https://localhost:8443/"
|
||||
#define IFMAP_NO_FD -1
|
||||
|
||||
typedef struct private_tnc_ifmap2_soap_t private_tnc_ifmap2_soap_t;
|
||||
|
||||
|
@ -82,53 +90,236 @@ 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(¶meter, ':', &line) &&
|
||||
match("Content-Length", ¶meter) &&
|
||||
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 send_receive(private_tnc_ifmap2_soap_t *this,
|
||||
char *request_qname, chunk_t request,
|
||||
char *receipt_qname, chunk_t *result)
|
||||
|
||||
static bool soap_send_receive(private_tnc_ifmap2_soap_t *this,
|
||||
char *request_name, xmlNodePtr request,
|
||||
char *result_name, xmlNodePtr *result,
|
||||
xmlDocPtr *result_doc)
|
||||
{
|
||||
int written, len;
|
||||
char *pos;
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr env, body, cur;
|
||||
xmlNsPtr ns;
|
||||
xmlChar *xml;
|
||||
int len;
|
||||
chunk_t in, out;
|
||||
|
||||
char soap[] =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\">"
|
||||
" <env:Body>"
|
||||
" <ifmap:newSession xmlns:ifmap=\"http://www.trustedcomputinggroup.org/2010/IFMAP/2\"></ifmap:newSession>"
|
||||
" </env:Body>"
|
||||
"</env:Envelope>";
|
||||
*result_doc = NULL;
|
||||
DBG2(DBG_TNC, "sending ifmap %s", request_name);
|
||||
|
||||
char http_header[] =
|
||||
"POST /ifmap HTTP/1.1\r\n"
|
||||
"Content-Type: application/soap+xml; charset=utf-8\r\n"
|
||||
"Content-Length: ";
|
||||
/* 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);
|
||||
|
||||
char buf[2048];
|
||||
/* Add SOAP Body containing IF-MAP request */
|
||||
body = xmlNewNode(ns, "Body");
|
||||
xmlAddChild(body, request);
|
||||
xmlAddChild(env, body);
|
||||
|
||||
pos = buf;
|
||||
len = sizeof(buf);
|
||||
written = snprintf(pos, len, "%s", http_header);
|
||||
pos += written;
|
||||
len -= written;
|
||||
written = snprintf(pos, len, "%d\r\n\r\n%s", strlen(soap), soap);
|
||||
|
||||
this->tls->write(this->tls, buf, strlen(buf));
|
||||
len = this->tls->read(this->tls, buf, sizeof(buf), TRUE);
|
||||
*result = chunk_create(buf, len);
|
||||
DBG2(DBG_TNC, "%B", result);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
chunk_t request, result;
|
||||
xmlNodePtr request, result;
|
||||
xmlDocPtr result_doc;
|
||||
xmlNsPtr ns;
|
||||
|
||||
send_receive(this, "newSession", request, "newSessionResult", &result);
|
||||
/*build newSession request */
|
||||
request = xmlNewNode(NULL, "newSession");
|
||||
ns = xmlNewNs(request, IFMAP_NS, "ifmap");
|
||||
xmlSetNs(request, ns);
|
||||
|
||||
if (!soap_send_receive(this, "newSession", request, "newSessionResult",
|
||||
&result, &result_doc))
|
||||
{
|
||||
if (result_doc)
|
||||
{
|
||||
xmlFreeDoc(result_doc);
|
||||
}
|
||||
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);
|
||||
|
||||
DBG1(DBG_TNC, "session-id: %s, ifmap-publisher-id: %s",
|
||||
this->session_id, this->ifmap_publisher_id);
|
||||
|
||||
/* set PEP and PDP device name (defaults to IF-MAP Publisher ID) */
|
||||
this->device_name = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap2.device_name",
|
||||
this->ifmap_publisher_id, charon->name);
|
||||
this->device_name = strdup(this->device_name);
|
||||
|
||||
return this->session_id && this->ifmap_publisher_id;
|
||||
}
|
||||
|
@ -136,10 +327,25 @@ METHOD(tnc_ifmap2_soap_t, newSession, bool,
|
|||
METHOD(tnc_ifmap2_soap_t, purgePublisher, bool,
|
||||
private_tnc_ifmap2_soap_t *this)
|
||||
{
|
||||
/* send purgePublisher request and receive purgePublisherReceived */
|
||||
/* return send_receive(this, "purgePublisher", request,
|
||||
"purgePublisherReceived", NULL); */
|
||||
return FALSE;
|
||||
xmlNodePtr request;
|
||||
xmlDocPtr result_doc;
|
||||
xmlNsPtr ns;
|
||||
bool success;
|
||||
|
||||
/* build purgePublisher request */
|
||||
request = xmlNewNode(NULL, "purgePublisher");
|
||||
ns = xmlNewNs(request, IFMAP_NS, "ifmap");
|
||||
xmlSetNs(request, ns);
|
||||
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);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap2_soap_t, publish_ike_sa, bool,
|
||||
|
@ -203,7 +409,9 @@ static bool soap_init(private_tnc_ifmap2_soap_t *this)
|
|||
private_key_t *key;
|
||||
identification_t *server_id, *client_id;
|
||||
|
||||
/** Load [self-signed] MAP server certificate */
|
||||
/**
|
||||
* Load [self-signed] MAP server certificate
|
||||
*/
|
||||
server_cert = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap2.server_cert", NULL, charon->name);
|
||||
if (!server_cert)
|
||||
|
@ -223,7 +431,9 @@ static bool soap_init(private_tnc_ifmap2_soap_t *this)
|
|||
server_id = cert->get_subject(cert);
|
||||
this->creds->add_cert(this->creds, TRUE, cert);
|
||||
|
||||
/* Load MAP client certificate */
|
||||
/**
|
||||
* Load MAP client certificate
|
||||
*/
|
||||
client_cert = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap2.client_cert", NULL, charon->name);
|
||||
if (!client_cert)
|
||||
|
@ -243,7 +453,9 @@ static bool soap_init(private_tnc_ifmap2_soap_t *this)
|
|||
client_id = cert->get_subject(cert);
|
||||
this->creds->add_cert(this->creds, TRUE, cert);
|
||||
|
||||
/* Load MAP client private key */
|
||||
/**
|
||||
* Load MAP client private key
|
||||
*/
|
||||
client_key = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap2.client_key", NULL, charon->name);
|
||||
if (!client_key)
|
||||
|
@ -262,7 +474,9 @@ static bool soap_init(private_tnc_ifmap2_soap_t *this)
|
|||
DBG1(DBG_TNC, "loaded MAP client RSA private key from '%s'", client_key);
|
||||
this->creds->add_key(this->creds, key);
|
||||
|
||||
/* Open TCP socket and connect to MAP server */
|
||||
/**
|
||||
* Open TCP socket and connect to MAP server
|
||||
*/
|
||||
server = "127.0.0.1";
|
||||
this->host = host_create_from_dns(server, 0, 8444);
|
||||
if (!this->host)
|
||||
|
@ -286,7 +500,9 @@ static bool soap_init(private_tnc_ifmap2_soap_t *this)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Open TLS socket */
|
||||
/**
|
||||
* Open TLS socket
|
||||
*/
|
||||
this->tls = tls_socket_create(FALSE, server_id, client_id, this->fd, NULL);
|
||||
if (!this->tls)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue