tnc-ifmap: Remove prototypical IF-MAP plugin
This was primarily used in our labs to visualize some TNC aspects but the third-party daemon and frontend we used have not seen any development in a decade. There never was any industry interest in this protocol anyway, so just remove it.
This commit is contained in:
@@ -89,7 +89,6 @@ plugins = \
|
||||
plugins/sql.opt \
|
||||
plugins/stroke.opt \
|
||||
plugins/systime-fix.opt \
|
||||
plugins/tnc-ifmap.opt \
|
||||
plugins/tnc-imc.opt \
|
||||
plugins/tnc-imv.opt \
|
||||
plugins/tnc-pdp.opt \
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
charon.plugins.tnc-ifmap.client_cert =
|
||||
Path to X.509 certificate file of IF-MAP client.
|
||||
|
||||
charon.plugins.tnc-ifmap.client_key =
|
||||
Path to private key file of IF-MAP client.
|
||||
|
||||
charon.plugins.tnc-ifmap.device_name =
|
||||
Unique name of strongSwan server as a PEP and/or PDP device.
|
||||
|
||||
charon.plugins.tnc-ifmap.renew_session_interval = 150
|
||||
Interval in seconds between periodic IF-MAP RenewSession requests.
|
||||
|
||||
charon.plugins.tnc-ifmap.server_uri = https://localhost:8444/imap
|
||||
URI of the form [https://]servername[:port][/path].
|
||||
|
||||
charon.plugins.tnc-ifmap.server_cert =
|
||||
Path to X.509 certificate file of IF-MAP server.
|
||||
|
||||
charon.plugins.tnc-ifmap.username_password =
|
||||
Credentials of IF-MAP client of the form username:password. If set, make
|
||||
sure to adjust the permissions of the config file accordingly.
|
||||
+1
-5
@@ -249,7 +249,6 @@ ARG_ENABL_SET([imc-swima], [enable IMC swima module.])
|
||||
ARG_ENABL_SET([imv-swima], [enable IMV swima module.])
|
||||
ARG_ENABL_SET([imc-hcd], [enable IMC hcd module.])
|
||||
ARG_ENABL_SET([imv-hcd], [enable IMV hcd module.])
|
||||
ARG_ENABL_SET([tnc-ifmap], [enable TNC IF-MAP module. Requires libxml])
|
||||
ARG_ENABL_SET([tnc-imc], [enable TNC IMC module.])
|
||||
ARG_ENABL_SET([tnc-imv], [enable TNC IMV module.])
|
||||
ARG_ENABL_SET([tnc-pdp], [enable TNC policy decision point module.])
|
||||
@@ -457,7 +456,7 @@ if test x$swanctl = xtrue; then
|
||||
vici=true
|
||||
fi
|
||||
|
||||
if test x$tnccs_11 = xtrue -o x$tnc_ifmap = xtrue; then
|
||||
if test x$tnccs_11 = xtrue; then
|
||||
xml=true
|
||||
fi
|
||||
|
||||
@@ -1564,7 +1563,6 @@ ADD_PLUGIN([xauth-generic], [c charon cmd])
|
||||
ADD_PLUGIN([xauth-eap], [c charon])
|
||||
ADD_PLUGIN([xauth-pam], [c charon])
|
||||
ADD_PLUGIN([xauth-noauth], [c charon])
|
||||
ADD_PLUGIN([tnc-ifmap], [c charon])
|
||||
ADD_PLUGIN([tnc-pdp], [c charon])
|
||||
ADD_PLUGIN([tnc-imc], [t charon])
|
||||
ADD_PLUGIN([tnc-imv], [t charon])
|
||||
@@ -1718,7 +1716,6 @@ AM_CONDITIONAL(USE_XAUTH_GENERIC, test x$xauth_generic = xtrue)
|
||||
AM_CONDITIONAL(USE_XAUTH_EAP, test x$xauth_eap = xtrue)
|
||||
AM_CONDITIONAL(USE_XAUTH_PAM, test x$xauth_pam = xtrue)
|
||||
AM_CONDITIONAL(USE_XAUTH_NOAUTH, test x$xauth_noauth = xtrue)
|
||||
AM_CONDITIONAL(USE_TNC_IFMAP, test x$tnc_ifmap = xtrue)
|
||||
AM_CONDITIONAL(USE_TNC_PDP, test x$tnc_pdp = xtrue)
|
||||
AM_CONDITIONAL(USE_TNC_IMC, test x$tnc_imc = xtrue)
|
||||
AM_CONDITIONAL(USE_TNC_IMV, test x$tnc_imv = xtrue)
|
||||
@@ -2006,7 +2003,6 @@ AC_CONFIG_FILES([
|
||||
src/libcharon/plugins/xauth_eap/Makefile
|
||||
src/libcharon/plugins/xauth_pam/Makefile
|
||||
src/libcharon/plugins/xauth_noauth/Makefile
|
||||
src/libcharon/plugins/tnc_ifmap/Makefile
|
||||
src/libcharon/plugins/tnc_pdp/Makefile
|
||||
src/libcharon/plugins/save_keys/Makefile
|
||||
src/libcharon/plugins/socket_default/Makefile
|
||||
|
||||
@@ -481,13 +481,6 @@ if MONOLITHIC
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_TNC_IFMAP
|
||||
SUBDIRS += plugins/tnc_ifmap
|
||||
if MONOLITHIC
|
||||
libcharon_la_LIBADD += plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_TNC_PDP
|
||||
SUBDIRS += plugins/tnc_pdp
|
||||
if MONOLITHIC
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libtls \
|
||||
-I$(top_srcdir)/src/libcharon
|
||||
|
||||
AM_CFLAGS = \
|
||||
${xml_CFLAGS} \
|
||||
$(PLUGIN_CFLAGS)
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-tnc-ifmap.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-tnc-ifmap.la
|
||||
endif
|
||||
|
||||
libstrongswan_tnc_ifmap_la_LIBADD = \
|
||||
$(top_builddir)/src/libtls/libtls.la ${xml_LIBS}
|
||||
|
||||
libstrongswan_tnc_ifmap_la_SOURCES = \
|
||||
tnc_ifmap_plugin.h tnc_ifmap_plugin.c \
|
||||
tnc_ifmap_listener.h tnc_ifmap_listener.c \
|
||||
tnc_ifmap_soap.h tnc_ifmap_soap.c \
|
||||
tnc_ifmap_soap_msg.h tnc_ifmap_soap_msg.c \
|
||||
tnc_ifmap_http.h tnc_ifmap_http.c \
|
||||
tnc_ifmap_renew_session_job.h tnc_ifmap_renew_session_job.c
|
||||
|
||||
libstrongswan_tnc_ifmap_la_LDFLAGS = -module -avoid-version
|
||||
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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_ifmap_http.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <utils/lexparser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct private_tnc_ifmap_http_t private_tnc_ifmap_http_t;
|
||||
|
||||
/**
|
||||
* Private data of an tnc_ifmap_http_t object.
|
||||
*/
|
||||
struct private_tnc_ifmap_http_t {
|
||||
|
||||
/**
|
||||
* Public tnc_ifmap_http_t interface.
|
||||
*/
|
||||
tnc_ifmap_http_t public;
|
||||
|
||||
/**
|
||||
* HTTPS Server URI with https:// prefix removed
|
||||
*/
|
||||
char *uri;
|
||||
|
||||
/**
|
||||
* Optional base64-encoded username:password for HTTP Basic Authentication
|
||||
*/
|
||||
chunk_t user_pass;
|
||||
|
||||
/**
|
||||
* HTTP chunked mode
|
||||
*/
|
||||
bool chunked;
|
||||
|
||||
};
|
||||
|
||||
METHOD(tnc_ifmap_http_t, build, status_t,
|
||||
private_tnc_ifmap_http_t *this, chunk_t *in, chunk_t *out)
|
||||
{
|
||||
char *host, *path, *request, auth[128];
|
||||
int len;
|
||||
|
||||
/* Duplicate host[/path] string since we are going to manipulate it */
|
||||
len = strlen(this->uri) + 2;
|
||||
host = malloc(len);
|
||||
memset(host, '\0', len);
|
||||
strcpy(host, this->uri);
|
||||
|
||||
/* Extract appended path or set to root */
|
||||
path = strchr(host, '/');
|
||||
if (!path)
|
||||
{
|
||||
path = host + len - 2;
|
||||
*path = '/';
|
||||
}
|
||||
|
||||
/* Use Basic Authentication? */
|
||||
if (this->user_pass.len)
|
||||
{
|
||||
snprintf(auth, sizeof(auth), "Authorization: Basic %.*s\r\n",
|
||||
(int)this->user_pass.len, this->user_pass.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
*auth = '\0';
|
||||
}
|
||||
|
||||
/* Write HTTP POST request, TODO break up into chunks */
|
||||
len = asprintf(&request,
|
||||
"POST %s HTTP/1.1\r\n"
|
||||
"Host: %.*s\r\n"
|
||||
"%s"
|
||||
"Content-Type: application/soap+xml;charset=utf-8\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n"
|
||||
"%.*s", path, (int)(path-host), host, auth, (int)in->len,
|
||||
(int)in->len, in->ptr);
|
||||
free(host);
|
||||
|
||||
if (len == -1)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
*out = chunk_create(request, len);
|
||||
DBG3(DBG_TLS, "sending HTTP POST request %B", out);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static bool process_header(chunk_t *in, bool *chunked, u_int *content_len)
|
||||
{
|
||||
chunk_t line, version, parameter;
|
||||
int code;
|
||||
u_int len;
|
||||
|
||||
/* Process HTTP protocol version */
|
||||
if (!fetchline(in, &line) || !extract_token(&version, ' ', &line) ||
|
||||
!match("HTTP/1.1", &version) || 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;
|
||||
}
|
||||
|
||||
*content_len = 0;
|
||||
*chunked = 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) && eat_whitespace(&line))
|
||||
{
|
||||
if (match("Content-Length", ¶meter))
|
||||
{
|
||||
if (sscanf(line.ptr, "%u", &len) == 1)
|
||||
{
|
||||
*content_len = len;
|
||||
}
|
||||
}
|
||||
else if (match("Transfer-Encoding", ¶meter) &&
|
||||
match("chunked", &line))
|
||||
{
|
||||
*chunked = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_http_t, process, status_t,
|
||||
private_tnc_ifmap_http_t *this, chunk_t *in, chunk_t *out)
|
||||
{
|
||||
u_int len = 0;
|
||||
chunk_t line, out_chunk;
|
||||
|
||||
DBG3(DBG_TLS, "receiving HTTP response %B", in);
|
||||
|
||||
if (!this->chunked)
|
||||
{
|
||||
if (!process_header(in, &this->chunked, &len))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
while (in->len)
|
||||
{
|
||||
if (this->chunked)
|
||||
{
|
||||
if (!fetchline(in, &line) || sscanf(line.ptr, "%x", &len) != 1)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
DBG3(DBG_TLS, "received HTTP response is chunked (%u bytes)", len);
|
||||
|
||||
/* Received last chunk? */
|
||||
if (len == 0)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check size of of remaining HTTP body */
|
||||
if (len > in->len)
|
||||
{
|
||||
DBG1(DBG_TNC, "insufficient data in HTTP body");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (this->chunked)
|
||||
{
|
||||
out_chunk = *in;
|
||||
out_chunk.len = len;
|
||||
*out = chunk_cat("mc", *out, out_chunk);
|
||||
*in = chunk_skip(*in, len);
|
||||
if (!fetchline(in, &line) || line.len > 0)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len)
|
||||
{
|
||||
in->len = len;
|
||||
}
|
||||
*out = chunk_clone(*in);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_http_t, destroy, void,
|
||||
private_tnc_ifmap_http_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnc_ifmap_http_t *tnc_ifmap_http_create(char *uri, chunk_t user_pass)
|
||||
{
|
||||
private_tnc_ifmap_http_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.uri = uri,
|
||||
.user_pass = user_pass,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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_ifmap_http tnc_ifmap_http
|
||||
* @{ @ingroup tnc_ifmap
|
||||
*/
|
||||
|
||||
#ifndef TNC_IFMAP_HTTP_H_
|
||||
#define TNC_IFMAP_HTTP_H_
|
||||
|
||||
#include <library.h>
|
||||
#include <tls_socket.h>
|
||||
|
||||
#include <libxml/parser.h>
|
||||
|
||||
typedef struct tnc_ifmap_http_t tnc_ifmap_http_t;
|
||||
|
||||
/**
|
||||
* Interface for building and processing HTTP messages
|
||||
*/
|
||||
struct tnc_ifmap_http_t {
|
||||
|
||||
/**
|
||||
* Build a HTTP POST message
|
||||
*
|
||||
* @param in input data
|
||||
* @param out HTTP POST request
|
||||
* @result status return code
|
||||
*/
|
||||
status_t (*build)(tnc_ifmap_http_t *this, chunk_t *in, chunk_t *out);
|
||||
|
||||
/**
|
||||
* Receive a HTTP [chunked] response
|
||||
*
|
||||
* @param in [chunked] HTTP response
|
||||
* @param out output data
|
||||
* @result status return code
|
||||
*/
|
||||
status_t (*process)(tnc_ifmap_http_t *this, chunk_t *in, chunk_t *out);
|
||||
|
||||
/**
|
||||
* Destroy a tnc_ifmap_http_t object.
|
||||
*/
|
||||
void (*destroy)(tnc_ifmap_http_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a tnc_ifmap_http instance.
|
||||
*
|
||||
* @param uri HTTPS URI with https:// prefix removed
|
||||
* @param user_pass Optional username:password for HTTP Basic Authentication
|
||||
*/
|
||||
tnc_ifmap_http_t *tnc_ifmap_http_create(char *uri, chunk_t user_pass);
|
||||
|
||||
#endif /** TNC_IFMAP_HTTP_H_ @}*/
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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 "tnc_ifmap_listener.h"
|
||||
#include "tnc_ifmap_soap.h"
|
||||
#include "tnc_ifmap_renew_session_job.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#define IFMAP_RENEW_SESSION_INTERVAL 150
|
||||
|
||||
typedef struct private_tnc_ifmap_listener_t private_tnc_ifmap_listener_t;
|
||||
|
||||
/**
|
||||
* Private data of an tnc_ifmap_listener_t object.
|
||||
*/
|
||||
struct private_tnc_ifmap_listener_t {
|
||||
|
||||
/**
|
||||
* Public tnc_ifmap_listener_t interface.
|
||||
*/
|
||||
tnc_ifmap_listener_t public;
|
||||
|
||||
/**
|
||||
* TNC IF-MAP 2.0 SOAP interface
|
||||
*/
|
||||
tnc_ifmap_soap_t *ifmap;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Publish PEP device-ip metadata
|
||||
*/
|
||||
static bool publish_device_ip_addresses(private_tnc_ifmap_listener_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
bool success = TRUE;
|
||||
|
||||
enumerator = charon->kernel->create_address_enumerator(charon->kernel,
|
||||
ADDR_TYPE_REGULAR);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
if (!this->ifmap->publish_device_ip(this->ifmap, host))
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish all IKE_SA metadata
|
||||
*/
|
||||
static bool reload_metadata(private_tnc_ifmap_listener_t *this)
|
||||
{
|
||||
ike_sa_t *ike_sa;
|
||||
enumerator_t *enumerator;
|
||||
bool success = TRUE;
|
||||
|
||||
enumerator = charon->controller->create_ike_sa_enumerator(
|
||||
charon->controller, FALSE);
|
||||
while (enumerator->enumerate(enumerator, &ike_sa))
|
||||
{
|
||||
if (ike_sa->get_state(ike_sa) != IKE_ESTABLISHED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!this->ifmap->publish_ike_sa(this->ifmap, ike_sa, TRUE) ||
|
||||
!this->ifmap->publish_virtual_ips(this->ifmap, ike_sa, TRUE))
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(listener_t, ike_updown, bool,
|
||||
private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, bool up)
|
||||
{
|
||||
if (ike_sa->get_state(ike_sa) != IKE_CONNECTING)
|
||||
{
|
||||
this->ifmap->publish_ike_sa(this->ifmap, ike_sa, up);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(listener_t, assign_vips, bool,
|
||||
private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, bool assign)
|
||||
{
|
||||
this->ifmap->publish_virtual_ips(this->ifmap, ike_sa, assign);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(listener_t, alert, bool,
|
||||
private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, alert_t alert,
|
||||
va_list args)
|
||||
{
|
||||
if (alert == ALERT_PEER_AUTH_FAILED)
|
||||
{
|
||||
this->ifmap->publish_enforcement_report(this->ifmap,
|
||||
ike_sa->get_other_host(ike_sa),
|
||||
"block", "authentication failed");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_listener_t, destroy, void,
|
||||
private_tnc_ifmap_listener_t *this)
|
||||
{
|
||||
if (this->ifmap)
|
||||
{
|
||||
if (this->ifmap->get_session_id(this->ifmap))
|
||||
{
|
||||
this->ifmap->endSession(this->ifmap);
|
||||
}
|
||||
this->ifmap->destroy(this->ifmap);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload)
|
||||
{
|
||||
private_tnc_ifmap_listener_t *this;
|
||||
job_t *job;
|
||||
uint32_t reschedule;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.listener = {
|
||||
.ike_updown = _ike_updown,
|
||||
.assign_vips = _assign_vips,
|
||||
.alert = _alert,
|
||||
},
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.ifmap = tnc_ifmap_soap_create(),
|
||||
);
|
||||
|
||||
if (!this->ifmap)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
if (!this->ifmap->newSession(this->ifmap))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
if (!this->ifmap->purgePublisher(this->ifmap))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
if (!publish_device_ip_addresses(this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
if (reload)
|
||||
{
|
||||
if (!reload_metadata(this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* schedule periodic transmission of IF-MAP renewSession request */
|
||||
reschedule = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.tnc-ifmap.renew_session_interval",
|
||||
IFMAP_RENEW_SESSION_INTERVAL, lib->ns);
|
||||
|
||||
job = (job_t*)tnc_ifmap_renew_session_job_create(
|
||||
this->ifmap->get_ref(this->ifmap), reschedule);
|
||||
lib->scheduler->schedule_job(lib->scheduler, job, reschedule);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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_ifmap_listener tnc_ifmap_listener
|
||||
* @{ @ingroup tnc_ifmap
|
||||
*/
|
||||
|
||||
#ifndef TNC_IFMAP_LISTENER_H_
|
||||
#define TNC_IFMAP_LISTENER_H_
|
||||
|
||||
#include <bus/bus.h>
|
||||
|
||||
typedef struct tnc_ifmap_listener_t tnc_ifmap_listener_t;
|
||||
|
||||
/**
|
||||
* Listener which collects information on IKE_SAs
|
||||
*/
|
||||
struct tnc_ifmap_listener_t {
|
||||
|
||||
/**
|
||||
* Implements listener_t.
|
||||
*/
|
||||
listener_t listener;
|
||||
|
||||
/**
|
||||
* Destroy a tnc_ifmap_listener_t.
|
||||
*/
|
||||
void (*destroy)(tnc_ifmap_listener_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a tnc_ifmap_listener instance.
|
||||
*
|
||||
* @param reload reload all IKE_SA metadata
|
||||
*/
|
||||
tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload);
|
||||
|
||||
#endif /** TNC_IFMAP_LISTENER_H_ @}*/
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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 "tnc_ifmap_plugin.h"
|
||||
#include "tnc_ifmap_listener.h"
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
typedef struct private_tnc_ifmap_plugin_t private_tnc_ifmap_plugin_t;
|
||||
|
||||
/**
|
||||
* private data of tnc_ifmap plugin
|
||||
*/
|
||||
struct private_tnc_ifmap_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
tnc_ifmap_plugin_t public;
|
||||
|
||||
/**
|
||||
* Listener interface, listens to CHILD_SA state changes
|
||||
*/
|
||||
tnc_ifmap_listener_t *listener;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_tnc_ifmap_plugin_t *this)
|
||||
{
|
||||
return "tnc-ifmap";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register tnc_ifmap plugin features
|
||||
*/
|
||||
static bool register_tnc_ifmap(private_tnc_ifmap_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
this->listener = tnc_ifmap_listener_create(FALSE);
|
||||
if (!this->listener)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->listener)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
tnc_ifmap_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)register_tnc_ifmap, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "tnc-ifmap-2.1"),
|
||||
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
|
||||
PLUGIN_SDEPEND(PRIVKEY, KEY_RSA),
|
||||
PLUGIN_SDEPEND(CUSTOM, "stroke"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, reload, bool,
|
||||
private_tnc_ifmap_plugin_t *this)
|
||||
{
|
||||
if (this->listener)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
}
|
||||
|
||||
this->listener = tnc_ifmap_listener_create(TRUE);
|
||||
if (!this->listener)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_tnc_ifmap_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
PLUGIN_DEFINE(tnc_ifmap)
|
||||
{
|
||||
private_tnc_ifmap_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.reload = _reload,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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_ifmap tnc_ifmap
|
||||
* @ingroup cplugins
|
||||
*
|
||||
* @defgroup tnc_ifmap_plugin tnc_ifmap_plugin
|
||||
* @{ @ingroup tnc_ifmap
|
||||
*/
|
||||
|
||||
#ifndef TNC_IFMAP_PLUGIN_H_
|
||||
#define TNC_IFMAP_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct tnc_ifmap_plugin_t tnc_ifmap_plugin_t;
|
||||
|
||||
/**
|
||||
* TNC IF-MAP plugin
|
||||
*/
|
||||
struct tnc_ifmap_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** TNC_IFMAP_PLUGIN_H_ @}*/
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
|
||||
#include "tnc_ifmap_renew_session_job.h"
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
|
||||
typedef struct private_tnc_ifmap_renew_session_job_t private_tnc_ifmap_renew_session_job_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_tnc_ifmap_renew_session_job_t {
|
||||
|
||||
/**
|
||||
* public tnc_ifmap_renew_session_job_t interface
|
||||
*/
|
||||
tnc_ifmap_renew_session_job_t public;
|
||||
|
||||
/**
|
||||
* TNC IF-MAP 2.0 SOAP interface
|
||||
*/
|
||||
tnc_ifmap_soap_t *ifmap;
|
||||
|
||||
/**
|
||||
* Reschedule time interval in seconds
|
||||
*/
|
||||
uint32_t reschedule;
|
||||
};
|
||||
|
||||
METHOD(job_t, destroy, void,
|
||||
private_tnc_ifmap_renew_session_job_t *this)
|
||||
{
|
||||
this->ifmap->destroy(this->ifmap);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(job_t, execute, job_requeue_t,
|
||||
private_tnc_ifmap_renew_session_job_t *this)
|
||||
{
|
||||
if (this->ifmap->orphaned(this->ifmap))
|
||||
{
|
||||
DBG2(DBG_TNC, "removing orphaned ifmap renewSession job for '%s'",
|
||||
this->ifmap->get_session_id(this->ifmap));
|
||||
return JOB_REQUEUE_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this->ifmap->renewSession(this->ifmap))
|
||||
{
|
||||
DBG1(DBG_TNC, "sending ifmap renewSession failed");
|
||||
/* TODO take some action */
|
||||
}
|
||||
return JOB_RESCHEDULE(this->reschedule);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(job_t, get_priority, job_priority_t,
|
||||
private_tnc_ifmap_renew_session_job_t *this)
|
||||
{
|
||||
return JOB_PRIO_MEDIUM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
tnc_ifmap_renew_session_job_t *tnc_ifmap_renew_session_job_create(
|
||||
tnc_ifmap_soap_t *ifmap, uint32_t reschedule)
|
||||
{
|
||||
private_tnc_ifmap_renew_session_job_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.job_interface = {
|
||||
.execute = _execute,
|
||||
.get_priority = _get_priority,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.ifmap = ifmap,
|
||||
.reschedule = reschedule,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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_ifmap_renew_session_job tnc_ifmap_renew_session_job
|
||||
* @{ @ingroup tnc_ifmap
|
||||
*/
|
||||
|
||||
#ifndef TNC_IFMAP_RENEW_SESSION_JOB_H_
|
||||
#define TNC_IFMAP_RENEW_SESSION_JOB_H_
|
||||
|
||||
typedef struct tnc_ifmap_renew_session_job_t tnc_ifmap_renew_session_job_t;
|
||||
|
||||
#include "tnc_ifmap_soap.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <processing/jobs/job.h>
|
||||
|
||||
/**
|
||||
* Job periodically sending an IF-MAP RenewSession request.
|
||||
*/
|
||||
struct tnc_ifmap_renew_session_job_t {
|
||||
|
||||
/**
|
||||
* implements job_t interface
|
||||
*/
|
||||
job_t job_interface;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an tnc_ifmap_renew_session job.
|
||||
*
|
||||
* @param ifmap TNC IF-MAP object
|
||||
* @param reschedule reschedule time in seconds
|
||||
*/
|
||||
tnc_ifmap_renew_session_job_t *tnc_ifmap_renew_session_job_create(
|
||||
tnc_ifmap_soap_t *ifmap, uint32_t reschedule);
|
||||
|
||||
#endif /** TNC_IFMAP_RENEW_SESSION_JOB_H_ @}*/
|
||||
@@ -1,927 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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 "tnc_ifmap_soap.h"
|
||||
#include "tnc_ifmap_soap_msg.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <credentials/sets/mem_cred.h>
|
||||
#include <daemon.h>
|
||||
|
||||
#include <tls_socket.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define IFMAP_NS "http://www.trustedcomputinggroup.org/2010/IFMAP/2"
|
||||
#define IFMAP_META_NS "http://www.trustedcomputinggroup.org/2010/IFMAP-METADATA/2"
|
||||
#define IFMAP_URI "https://localhost:8444/imap"
|
||||
#define IFMAP_NO_FD -1
|
||||
|
||||
typedef struct private_tnc_ifmap_soap_t private_tnc_ifmap_soap_t;
|
||||
|
||||
/**
|
||||
* Private data of an tnc_ifmap_soap_t object.
|
||||
*/
|
||||
struct private_tnc_ifmap_soap_t {
|
||||
|
||||
/**
|
||||
* Public tnc_ifmap_soap_t interface.
|
||||
*/
|
||||
tnc_ifmap_soap_t public;
|
||||
|
||||
/**
|
||||
* SOAP Session ID
|
||||
*/
|
||||
xmlChar *session_id;
|
||||
|
||||
/**
|
||||
* IF-MAP Publisher ID
|
||||
*/
|
||||
xmlChar *ifmap_publisher_id;
|
||||
|
||||
/**
|
||||
* IF-MAP namespace
|
||||
*/
|
||||
xmlNsPtr ns;
|
||||
|
||||
/**
|
||||
* IF-MAP metadata namespace
|
||||
*/
|
||||
xmlNsPtr ns_meta;
|
||||
|
||||
/**
|
||||
* PEP and PDP device name
|
||||
*/
|
||||
char *device_name;
|
||||
|
||||
/**
|
||||
* HTTPS Server URI with https:// prefix removed
|
||||
*/
|
||||
char *uri;
|
||||
|
||||
/**
|
||||
* Optional base64-encoded username:password for HTTP Basic Authentication
|
||||
*/
|
||||
chunk_t user_pass;
|
||||
|
||||
/**
|
||||
* IF-MAP Server (IP address and port)
|
||||
*/
|
||||
host_t *host;
|
||||
|
||||
/**
|
||||
* TLS socket
|
||||
*/
|
||||
tls_socket_t *tls;
|
||||
|
||||
/**
|
||||
* File descriptor for secure TCP socket
|
||||
*/
|
||||
int fd;
|
||||
|
||||
/**
|
||||
* In memory credential set
|
||||
*/
|
||||
mem_cred_t *creds;
|
||||
|
||||
/**
|
||||
* reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
|
||||
};
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, newSession, bool,
|
||||
private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
tnc_ifmap_soap_msg_t *soap_msg;
|
||||
xmlNodePtr request, result;
|
||||
|
||||
/*build newSession request */
|
||||
request = xmlNewNode(NULL, "newSession");
|
||||
this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
|
||||
xmlSetNs(request, this->ns);
|
||||
|
||||
soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
|
||||
if (!soap_msg->post(soap_msg, request, "newSessionResult", &result))
|
||||
{
|
||||
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");
|
||||
soap_msg->destroy(soap_msg);
|
||||
|
||||
DBG1(DBG_TNC, "created ifmap session '%s' as publisher '%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-ifmap.device_name",
|
||||
this->ifmap_publisher_id, lib->ns);
|
||||
this->device_name = strdup(this->device_name);
|
||||
|
||||
return this->session_id && this->ifmap_publisher_id;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, renewSession, bool,
|
||||
private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
tnc_ifmap_soap_msg_t *soap_msg;
|
||||
xmlNodePtr request;
|
||||
bool success;
|
||||
|
||||
/* build renewSession request */
|
||||
request = xmlNewNode(NULL, "renewSession");
|
||||
this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
|
||||
xmlSetNs(request, this->ns);
|
||||
xmlNewProp(request, "session-id", this->session_id);
|
||||
|
||||
soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
|
||||
success = soap_msg->post(soap_msg, request, "renewSessionResult", NULL);
|
||||
soap_msg->destroy(soap_msg);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, purgePublisher, bool,
|
||||
private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
tnc_ifmap_soap_msg_t *soap_msg;
|
||||
xmlNodePtr request;
|
||||
bool success;
|
||||
|
||||
/* build purgePublisher request */
|
||||
request = xmlNewNode(NULL, "purgePublisher");
|
||||
this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
|
||||
xmlSetNs(request, this->ns);
|
||||
xmlNewProp(request, "session-id", this->session_id);
|
||||
xmlNewProp(request, "ifmap-publisher-id", this->ifmap_publisher_id);
|
||||
|
||||
soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
|
||||
success = soap_msg->post(soap_msg, request, "purgePublisherReceived", NULL);
|
||||
soap_msg->destroy(soap_msg);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an access-request based on device_name and ike_sa_id
|
||||
*/
|
||||
static xmlNodePtr create_access_request(private_tnc_ifmap_soap_t *this,
|
||||
uint32_t id)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
char buf[BUF_LEN];
|
||||
|
||||
node = xmlNewNode(NULL, "access-request");
|
||||
|
||||
snprintf(buf, BUF_LEN, "%s:%d", this->device_name, id);
|
||||
xmlNewProp(node, "name", buf);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an identity
|
||||
*/
|
||||
static xmlNodePtr create_identity(private_tnc_ifmap_soap_t *this,
|
||||
identification_t *id, bool is_user)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
char buf[BUF_LEN], *id_type;
|
||||
|
||||
node = xmlNewNode(NULL, "identity");
|
||||
|
||||
snprintf(buf, BUF_LEN, "%Y", id);
|
||||
xmlNewProp(node, "name", buf);
|
||||
|
||||
switch (id->get_type(id))
|
||||
{
|
||||
case ID_IPV4_ADDR:
|
||||
id_type = "other";
|
||||
xmlNewProp(node, "other-type-definition", "36906:ipv4-address");
|
||||
break;
|
||||
case ID_FQDN:
|
||||
id_type = is_user ? "username" : "dns-name";
|
||||
break;
|
||||
case ID_RFC822_ADDR:
|
||||
id_type = "email-address";
|
||||
break;
|
||||
case ID_IPV6_ADDR:
|
||||
id_type = "other";
|
||||
xmlNewProp(node, "other-type-definition", "36906:ipv6-address");
|
||||
break;
|
||||
case ID_DER_ASN1_DN:
|
||||
id_type = "distinguished-name";
|
||||
break;
|
||||
case ID_KEY_ID:
|
||||
id_type = "other";
|
||||
xmlNewProp(node, "other-type-definition", "36906:key-id");
|
||||
break;
|
||||
default:
|
||||
id_type = "other";
|
||||
xmlNewProp(node, "other-type-definition", "36906:other");
|
||||
}
|
||||
xmlNewProp(node, "type", id_type);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create enforcement-report metadata
|
||||
*/
|
||||
static xmlNodePtr create_enforcement_report(private_tnc_ifmap_soap_t *this,
|
||||
xmlChar *action, xmlChar *reason)
|
||||
{
|
||||
xmlNodePtr node, node2, node3;
|
||||
|
||||
node = xmlNewNode(NULL, "metadata");
|
||||
node2 = xmlNewNode(this->ns_meta, "enforcement-report");
|
||||
xmlAddChild(node, node2);
|
||||
xmlNewProp(node2, "ifmap-cardinality", "multiValue");
|
||||
|
||||
node3 = xmlNewNode(NULL, "enforcement-action");
|
||||
xmlAddChild(node2, node3);
|
||||
xmlNodeAddContent(node3, action);
|
||||
|
||||
node3 = xmlNewNode(NULL, "enforcement-reason");
|
||||
xmlAddChild(node2, node3);
|
||||
xmlNodeAddContent(node3, reason);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create delete filter
|
||||
*/
|
||||
static xmlNodePtr create_delete_filter(private_tnc_ifmap_soap_t *this,
|
||||
char *metadata)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
char buf[BUF_LEN];
|
||||
|
||||
node = xmlNewNode(NULL, "delete");
|
||||
|
||||
snprintf(buf, BUF_LEN, "meta:%s[@ifmap-publisher-id='%s']",
|
||||
metadata, this->ifmap_publisher_id);
|
||||
xmlNewProp(node, "filter", buf);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a publish request
|
||||
*/
|
||||
static xmlNodePtr create_publish_request(private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
xmlNodePtr request;
|
||||
|
||||
request = xmlNewNode(NULL, "publish");
|
||||
this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
|
||||
xmlSetNs(request, this->ns);
|
||||
this->ns_meta = xmlNewNs(request, IFMAP_META_NS, "meta");
|
||||
xmlNewProp(request, "session-id", this->session_id);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a device
|
||||
*/
|
||||
static xmlNodePtr create_device(private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
xmlNodePtr node, node2;
|
||||
|
||||
node = xmlNewNode(NULL, "device");
|
||||
node2 = xmlNewNode(NULL, "name");
|
||||
xmlAddChild(node, node2);
|
||||
xmlNodeAddContent(node2, this->device_name);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ip-address
|
||||
*/
|
||||
static xmlNodePtr create_ip_address(private_tnc_ifmap_soap_t *this,
|
||||
host_t *host)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
char buf[BUF_LEN];
|
||||
|
||||
node = xmlNewNode(NULL, "ip-address");
|
||||
|
||||
if (host->get_family(host) == AF_INET6)
|
||||
{
|
||||
chunk_t address;
|
||||
int len, written, i;
|
||||
char *pos;
|
||||
bool first = TRUE;
|
||||
|
||||
/* output IPv6 address in canonical IF-MAP 2.0 format */
|
||||
address = host->get_address(host);
|
||||
pos = buf;
|
||||
len = sizeof(buf);
|
||||
|
||||
for (i = 0; i < address.len; i = i + 2)
|
||||
{
|
||||
written = snprintf(pos, len, "%s%x", first ? "" : ":",
|
||||
256*address.ptr[i] + address.ptr[i+1]);
|
||||
if (written < 0 || written >= len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += written;
|
||||
len -= written;
|
||||
first = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, BUF_LEN, "%H", host);
|
||||
}
|
||||
|
||||
xmlNewProp(node, "value", buf);
|
||||
xmlNewProp(node, "type", host->get_family(host) == AF_INET ? "IPv4" : "IPv6");
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create metadata
|
||||
*/
|
||||
static xmlNodePtr create_metadata(private_tnc_ifmap_soap_t *this,
|
||||
xmlChar *metadata)
|
||||
{
|
||||
xmlNodePtr node, node2;
|
||||
|
||||
node = xmlNewNode(NULL, "metadata");
|
||||
node2 = xmlNewNode(this->ns_meta, metadata);
|
||||
xmlAddChild(node, node2);
|
||||
xmlNewProp(node2, "ifmap-cardinality", "singleValue");
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create capability metadata
|
||||
*/
|
||||
static xmlNodePtr create_capability(private_tnc_ifmap_soap_t *this,
|
||||
identification_t *name)
|
||||
{
|
||||
xmlNodePtr node, node2;
|
||||
char buf[BUF_LEN];
|
||||
|
||||
node = xmlNewNode(this->ns_meta, "capability");
|
||||
xmlNewProp(node, "ifmap-cardinality", "multiValue");
|
||||
|
||||
node2 = xmlNewNode(NULL, "name");
|
||||
xmlAddChild(node, node2);
|
||||
snprintf(buf, BUF_LEN, "%Y", name);
|
||||
xmlNodeAddContent(node2, buf);
|
||||
|
||||
node2 = xmlNewNode(NULL, "administrative-domain");
|
||||
xmlAddChild(node, node2);
|
||||
xmlNodeAddContent(node2, "strongswan");
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, publish_ike_sa, bool,
|
||||
private_tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, bool up)
|
||||
{
|
||||
tnc_ifmap_soap_msg_t *soap_msg;
|
||||
xmlNodePtr request, node, node2 = NULL;
|
||||
enumerator_t *e1, *e2;
|
||||
auth_rule_t type;
|
||||
identification_t *id, *eap_id, *group;
|
||||
host_t *host;
|
||||
auth_cfg_t *auth;
|
||||
uint32_t ike_sa_id;
|
||||
bool is_user = FALSE, first = TRUE, success;
|
||||
|
||||
/* extract relevant data from IKE_SA*/
|
||||
ike_sa_id = ike_sa->get_unique_id(ike_sa);
|
||||
host = ike_sa->get_other_host(ike_sa);
|
||||
id = ike_sa->get_other_id(ike_sa);
|
||||
eap_id = ike_sa->get_other_eap_id(ike_sa);
|
||||
|
||||
/* in the presence of an EAP Identity, treat it as a username */
|
||||
if (!id->equals(id, eap_id))
|
||||
{
|
||||
is_user = TRUE;
|
||||
id = eap_id;
|
||||
}
|
||||
|
||||
/* build publish request */
|
||||
request = create_publish_request(this);
|
||||
|
||||
/* delete any existing enforcement reports */
|
||||
if (up)
|
||||
{
|
||||
node = create_delete_filter(this, "enforcement-report");
|
||||
xmlAddChild(request, node);
|
||||
xmlAddChild(node, create_ip_address(this, host));
|
||||
xmlAddChild(node, create_device(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* update or delete authenticated-as metadata
|
||||
*/
|
||||
if (up)
|
||||
{
|
||||
node = xmlNewNode(NULL, "update");
|
||||
}
|
||||
else
|
||||
{
|
||||
node = create_delete_filter(this, "authenticated-as");
|
||||
}
|
||||
xmlAddChild(request, node);
|
||||
|
||||
/* add access-request, identity and [if up] metadata */
|
||||
xmlAddChild(node, create_access_request(this, ike_sa_id));
|
||||
xmlAddChild(node, create_identity(this, id, is_user));
|
||||
if (up)
|
||||
{
|
||||
xmlAddChild(node, create_metadata(this, "authenticated-as"));
|
||||
}
|
||||
|
||||
/**
|
||||
* update or delete access-request-ip metadata for physical IP address
|
||||
*/
|
||||
if (up)
|
||||
{
|
||||
node = xmlNewNode(NULL, "update");
|
||||
}
|
||||
else
|
||||
{
|
||||
node = create_delete_filter(this, "access-request-ip");
|
||||
}
|
||||
xmlAddChild(request, node);
|
||||
|
||||
/* add access-request, ip-address and [if up] metadata */
|
||||
xmlAddChild(node, create_access_request(this, ike_sa_id));
|
||||
xmlAddChild(node, create_ip_address(this, host));
|
||||
if (up)
|
||||
{
|
||||
xmlAddChild(node, create_metadata(this, "access-request-ip"));
|
||||
}
|
||||
|
||||
/**
|
||||
* update or delete authenticated-by metadata
|
||||
*/
|
||||
if (up)
|
||||
{
|
||||
node = xmlNewNode(NULL, "update");
|
||||
}
|
||||
else
|
||||
{
|
||||
node = create_delete_filter(this, "authenticated-by");
|
||||
}
|
||||
xmlAddChild(request, node);
|
||||
|
||||
/* add access-request, device and [if up] metadata */
|
||||
xmlAddChild(node, create_access_request(this, ike_sa_id));
|
||||
xmlAddChild(node, create_device(this));
|
||||
if (up)
|
||||
{
|
||||
xmlAddChild(node, create_metadata(this, "authenticated-by"));
|
||||
}
|
||||
|
||||
/**
|
||||
* update or delete capability metadata
|
||||
*/
|
||||
e1 = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
|
||||
while (e1->enumerate(e1, &auth) && (first || up))
|
||||
{
|
||||
e2 = auth->create_enumerator(auth);
|
||||
while (e2->enumerate(e2, &type, &group))
|
||||
{
|
||||
/* look for group memberships */
|
||||
if (type == AUTH_RULE_GROUP)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = FALSE;
|
||||
|
||||
if (up)
|
||||
{
|
||||
node = xmlNewNode(NULL, "update");
|
||||
}
|
||||
else
|
||||
{
|
||||
node = create_delete_filter(this, "capability");
|
||||
}
|
||||
xmlAddChild(request, node);
|
||||
|
||||
/* add access-request */
|
||||
xmlAddChild(node, create_access_request(this, ike_sa_id));
|
||||
if (!up)
|
||||
{
|
||||
break;
|
||||
}
|
||||
node2 = xmlNewNode(NULL, "metadata");
|
||||
xmlAddChild(node, node2);
|
||||
}
|
||||
xmlAddChild(node2, create_capability(this, group));
|
||||
}
|
||||
}
|
||||
e2->destroy(e2);
|
||||
}
|
||||
e1->destroy(e1);
|
||||
|
||||
soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
|
||||
success = soap_msg->post(soap_msg, request, "publishReceived", NULL);
|
||||
soap_msg->destroy(soap_msg);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, publish_device_ip, bool,
|
||||
private_tnc_ifmap_soap_t *this, host_t *host)
|
||||
{
|
||||
tnc_ifmap_soap_msg_t *soap_msg;
|
||||
xmlNodePtr request, update;
|
||||
bool success;
|
||||
|
||||
/* build publish update request */
|
||||
request = create_publish_request(this);
|
||||
update = xmlNewNode(NULL, "update");
|
||||
xmlAddChild(request, update);
|
||||
|
||||
/* add device, ip-address and metadata */
|
||||
xmlAddChild(update, create_device(this));
|
||||
xmlAddChild(update, create_ip_address(this, host));
|
||||
xmlAddChild(update, create_metadata(this, "device-ip"));
|
||||
|
||||
soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
|
||||
success = soap_msg->post(soap_msg, request, "publishReceived", NULL);
|
||||
soap_msg->destroy(soap_msg);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, publish_virtual_ips, bool,
|
||||
private_tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, bool assign)
|
||||
{
|
||||
tnc_ifmap_soap_msg_t *soap_msg;
|
||||
xmlNodePtr request, node;
|
||||
uint32_t ike_sa_id;
|
||||
enumerator_t *enumerator;
|
||||
host_t *vip;
|
||||
bool success;
|
||||
|
||||
/* extract relevant data from IKE_SA*/
|
||||
ike_sa_id = ike_sa->get_unique_id(ike_sa);
|
||||
|
||||
/* build publish request */
|
||||
request = create_publish_request(this);
|
||||
|
||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
|
||||
while (enumerator->enumerate(enumerator, &vip))
|
||||
{
|
||||
/**
|
||||
* update or delete access-request-ip metadata for a virtual IP address
|
||||
*/
|
||||
if (assign)
|
||||
{
|
||||
node = xmlNewNode(NULL, "update");
|
||||
}
|
||||
else
|
||||
{
|
||||
node = create_delete_filter(this, "access-request-ip");
|
||||
}
|
||||
xmlAddChild(request, node);
|
||||
|
||||
/* add access-request, virtual ip-address and [if assign] metadata */
|
||||
xmlAddChild(node, create_access_request(this, ike_sa_id));
|
||||
xmlAddChild(node, create_ip_address(this, vip));
|
||||
if (assign)
|
||||
{
|
||||
xmlAddChild(node, create_metadata(this, "access-request-ip"));
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
|
||||
success = soap_msg->post(soap_msg, request, "publishReceived", NULL);
|
||||
soap_msg->destroy(soap_msg);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, publish_enforcement_report, bool,
|
||||
private_tnc_ifmap_soap_t *this, host_t *host, char *action, char *reason)
|
||||
{
|
||||
tnc_ifmap_soap_msg_t *soap_msg;
|
||||
xmlNodePtr request, update;
|
||||
bool success;
|
||||
|
||||
/* build publish update request */
|
||||
request = create_publish_request(this);
|
||||
update = xmlNewNode(NULL, "update");
|
||||
xmlAddChild(request, update);
|
||||
|
||||
/* add ip-address and metadata */
|
||||
xmlAddChild(update, create_ip_address(this, host));
|
||||
xmlAddChild(update, create_device(this));
|
||||
xmlAddChild(update, create_enforcement_report(this, action, reason));
|
||||
|
||||
soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
|
||||
success = soap_msg->post(soap_msg, request, "publishReceived", NULL);
|
||||
soap_msg->destroy(soap_msg);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, endSession, bool,
|
||||
private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
tnc_ifmap_soap_msg_t *soap_msg;
|
||||
xmlNodePtr request;
|
||||
bool success;
|
||||
|
||||
/* build endSession request */
|
||||
request = xmlNewNode(NULL, "endSession");
|
||||
this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
|
||||
xmlSetNs(request, this->ns);
|
||||
xmlNewProp(request, "session-id", this->session_id);
|
||||
|
||||
soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
|
||||
success = soap_msg->post(soap_msg, request, "endSessionResult", NULL);
|
||||
soap_msg->destroy(soap_msg);
|
||||
|
||||
DBG1(DBG_TNC, "ended ifmap session '%s' as publisher '%s'",
|
||||
this->session_id, this->ifmap_publisher_id);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, get_session_id, char*,
|
||||
private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
return this->session_id;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, orphaned, bool,
|
||||
private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
return this->ref == 1;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, get_ref, tnc_ifmap_soap_t*,
|
||||
private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_t, destroy, void,
|
||||
private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
if (this->session_id)
|
||||
{
|
||||
xmlFree(this->session_id);
|
||||
xmlFree(this->ifmap_publisher_id);
|
||||
free(this->device_name);
|
||||
}
|
||||
DESTROY_IF(this->tls);
|
||||
DESTROY_IF(this->host);
|
||||
|
||||
if (this->fd != IFMAP_NO_FD)
|
||||
{
|
||||
close(this->fd);
|
||||
}
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
||||
this->creds->destroy(this->creds);
|
||||
free(this->user_pass.ptr);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
static bool soap_init(private_tnc_ifmap_soap_t *this)
|
||||
{
|
||||
char *server_uri, *server_str, *port_str, *uri_str;
|
||||
char *server_cert, *client_cert, *client_key, *user_pass;
|
||||
int port;
|
||||
auth_cfg_t *auth;
|
||||
certificate_t *cert;
|
||||
private_key_t *key;
|
||||
identification_t *server_id, *client_id = NULL;
|
||||
|
||||
/* getting configuration parameters from strongswan.conf */
|
||||
server_uri = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap.server_uri", IFMAP_URI, lib->ns);
|
||||
server_cert = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap.server_cert", NULL, lib->ns);
|
||||
client_cert = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap.client_cert", NULL, lib->ns);
|
||||
client_key = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap.client_key", NULL, lib->ns);
|
||||
user_pass = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-ifmap.username_password", NULL, lib->ns);
|
||||
|
||||
/* load [self-signed] MAP server certificate */
|
||||
if (!server_cert)
|
||||
{
|
||||
DBG1(DBG_TNC, "MAP server certificate not defined");
|
||||
return FALSE;
|
||||
}
|
||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||
BUILD_FROM_FILE, server_cert, BUILD_END);
|
||||
if (!cert)
|
||||
{
|
||||
DBG1(DBG_TNC, "loading MAP server certificate from '%s' failed",
|
||||
server_cert);
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_TNC, "loaded MAP server certificate from '%s'", server_cert);
|
||||
server_id = cert->get_subject(cert);
|
||||
this->creds->add_cert(this->creds, TRUE, cert);
|
||||
|
||||
/* check availability of client credentials */
|
||||
if (!client_cert && !user_pass)
|
||||
{
|
||||
DBG1(DBG_TNC, "neither MAP client certificate "
|
||||
"nor username:password defined");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (client_cert)
|
||||
{
|
||||
/* load MAP client certificate */
|
||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||
BUILD_FROM_FILE, client_cert, BUILD_END);
|
||||
if (!cert)
|
||||
{
|
||||
DBG1(DBG_TNC, "loading MAP client certificate from '%s' failed",
|
||||
client_cert);
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_TNC, "loaded MAP client certificate from '%s'", client_cert);
|
||||
cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
|
||||
|
||||
/* load MAP client private key */
|
||||
if (client_key)
|
||||
{
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
|
||||
BUILD_FROM_FILE, client_key, BUILD_END);
|
||||
if (!key)
|
||||
{
|
||||
DBG1(DBG_TNC, "loading MAP client private key from '%s' failed",
|
||||
client_key);
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_TNC, "loaded MAP client RSA private key from '%s'",
|
||||
client_key);
|
||||
this->creds->add_key(this->creds, key);
|
||||
}
|
||||
|
||||
/* set client ID to certificate distinguished name */
|
||||
client_id = cert->get_subject(cert);
|
||||
|
||||
/* check if we have a private key matching the certificate */
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
|
||||
key = lib->credmgr->get_private(lib->credmgr, KEY_RSA, client_id, auth);
|
||||
auth->destroy(auth);
|
||||
if (!key)
|
||||
{
|
||||
DBG1(DBG_TNC, "no RSA private key matching MAP client certificate");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set base64-encoded username:password for HTTP Basic Authentication */
|
||||
this->user_pass = chunk_to_base64(chunk_from_str(user_pass), NULL);
|
||||
}
|
||||
|
||||
/* remove HTTPS prefix if any */
|
||||
if (strlen(server_uri) >= 8 && strncaseeq(server_uri, "https://", 8))
|
||||
{
|
||||
server_uri += 8;
|
||||
}
|
||||
this->uri = server_uri;
|
||||
|
||||
/* duplicate server string since we are going to manipulate it */
|
||||
server_str = strdup(server_uri);
|
||||
|
||||
/* extract server name and port from server URI */
|
||||
port_str = strchr(server_str, ':');
|
||||
if (port_str)
|
||||
{
|
||||
*port_str++ = '\0';
|
||||
if (sscanf(port_str, "%d", &port) != 1)
|
||||
{
|
||||
DBG1(DBG_TNC, "parsing server port %s failed", port_str);
|
||||
free(server_str);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use default https port */
|
||||
port = 443;
|
||||
uri_str = strchr(server_str, '/');
|
||||
if (uri_str)
|
||||
{
|
||||
*uri_str = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* open TCP socket and connect to MAP server */
|
||||
this->host = host_create_from_dns(server_str, 0, port);
|
||||
if (!this->host)
|
||||
{
|
||||
DBG1(DBG_TNC, "resolving hostname %s failed", server_str);
|
||||
free(server_str);
|
||||
return FALSE;
|
||||
}
|
||||
free(server_str);
|
||||
|
||||
this->fd = socket(this->host->get_family(this->host), SOCK_STREAM, 0);
|
||||
if (this->fd == IFMAP_NO_FD)
|
||||
{
|
||||
DBG1(DBG_TNC, "opening socket failed: %s", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (connect(this->fd, this->host->get_sockaddr(this->host),
|
||||
*this->host->get_sockaddr_len(this->host)) == -1)
|
||||
{
|
||||
DBG1(DBG_TNC, "connecting to %#H failed: %s",
|
||||
this->host, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* open TLS socket */
|
||||
this->tls = tls_socket_create(FALSE, server_id, client_id, this->fd,
|
||||
NULL, TLS_UNSPEC, TLS_UNSPEC, 0);
|
||||
if (!this->tls)
|
||||
{
|
||||
DBG1(DBG_TNC, "creating TLS socket failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnc_ifmap_soap_t *tnc_ifmap_soap_create()
|
||||
{
|
||||
private_tnc_ifmap_soap_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.newSession = _newSession,
|
||||
.renewSession = _renewSession,
|
||||
.purgePublisher = _purgePublisher,
|
||||
.publish_ike_sa = _publish_ike_sa,
|
||||
.publish_device_ip = _publish_device_ip,
|
||||
.publish_virtual_ips = _publish_virtual_ips,
|
||||
.publish_enforcement_report = _publish_enforcement_report,
|
||||
.endSession = _endSession,
|
||||
.get_session_id = _get_session_id,
|
||||
.orphaned = _orphaned,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.fd = IFMAP_NO_FD,
|
||||
.creds = mem_cred_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
||||
|
||||
if (!soap_init(this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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_ifmap_soap tnc_ifmap_soap
|
||||
* @{ @ingroup tnc_ifmap
|
||||
*/
|
||||
|
||||
#ifndef TNC_IFMAP_SOAP_H_
|
||||
#define TNC_IFMAP_SOAP_H_
|
||||
|
||||
#include <library.h>
|
||||
#include <networking/host.h>
|
||||
#include <sa/ike_sa.h>
|
||||
|
||||
typedef struct tnc_ifmap_soap_t tnc_ifmap_soap_t;
|
||||
|
||||
/**
|
||||
* Implements the TNC IF-MAP 2.0 SOAP Binding
|
||||
*/
|
||||
struct tnc_ifmap_soap_t {
|
||||
|
||||
/**
|
||||
* Creates a new IF-MAP session
|
||||
*
|
||||
* @return TRUE if command was successful
|
||||
*/
|
||||
bool (*newSession)(tnc_ifmap_soap_t *this);
|
||||
|
||||
/**
|
||||
* Check if the IF-MAP session is still active
|
||||
*
|
||||
* @return TRUE if command was successful
|
||||
*/
|
||||
bool (*renewSession)(tnc_ifmap_soap_t *this);
|
||||
|
||||
/**
|
||||
* Purges all metadata published by this publisher
|
||||
*
|
||||
* @return TRUE if command was successful
|
||||
*/
|
||||
bool (*purgePublisher)(tnc_ifmap_soap_t *this);
|
||||
|
||||
/**
|
||||
* Publish metadata about established/deleted IKE_SAs
|
||||
*
|
||||
* @param ike_sa IKE_SA for which metadata is published
|
||||
* @param up TRUE if IKE_SEA is up, FALSE if down
|
||||
* @return TRUE if command was successful
|
||||
*/
|
||||
bool (*publish_ike_sa)(tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, bool up);
|
||||
|
||||
/**
|
||||
* Publish PEP device-ip metadata
|
||||
*
|
||||
* @param host IP address of local endpoint
|
||||
* @return TRUE if command was successful
|
||||
*/
|
||||
bool (*publish_device_ip)(tnc_ifmap_soap_t *this, host_t *host);
|
||||
|
||||
/**
|
||||
* Publish Virtual IP access-request-ip metadata
|
||||
*
|
||||
* @param ike_sa IKE_SA for which Virtual IP metadata is published
|
||||
* @param assign TRUE if assigned, FALSE if removed
|
||||
* @return TRUE if command was successful
|
||||
*/
|
||||
bool (*publish_virtual_ips)(tnc_ifmap_soap_t *this, ike_sa_t *ike_sa,
|
||||
bool assign);
|
||||
|
||||
/**
|
||||
* Publish enforcement-report metadata
|
||||
*
|
||||
* @param host Host to be enforced
|
||||
* @param action Enforcement action ("block" or "quarantine")
|
||||
* @param reason Enforcement reason
|
||||
* @return TRUE if command was successful
|
||||
*/
|
||||
bool (*publish_enforcement_report)(tnc_ifmap_soap_t *this, host_t *host,
|
||||
char *action, char *reason);
|
||||
|
||||
/**
|
||||
* Ends an IF-MAP session
|
||||
*
|
||||
* @return TRUE if command was successful
|
||||
*/
|
||||
bool (*endSession)(tnc_ifmap_soap_t *this);
|
||||
|
||||
/**
|
||||
* Get ID of IF-MAP session
|
||||
*
|
||||
* @return IF-MAP session ID
|
||||
*/
|
||||
char* (*get_session_id)(tnc_ifmap_soap_t *this);
|
||||
|
||||
/**
|
||||
* Check for an orphaned IF-MAP session
|
||||
*
|
||||
* @return TRUE if IF-MAP session is orphaned
|
||||
*/
|
||||
bool (*orphaned)(tnc_ifmap_soap_t *this);
|
||||
|
||||
/**
|
||||
* Get a reference to an IF-MAP session
|
||||
*
|
||||
* @return referenced IF-MAP session
|
||||
*/
|
||||
tnc_ifmap_soap_t* (*get_ref)(tnc_ifmap_soap_t *this);
|
||||
|
||||
/**
|
||||
* Destroy a tnc_ifmap_soap_t.
|
||||
*/
|
||||
void (*destroy)(tnc_ifmap_soap_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a tnc_ifmap_soap instance.
|
||||
*/
|
||||
tnc_ifmap_soap_t *tnc_ifmap_soap_create();
|
||||
|
||||
#endif /** TNC_IFMAP_SOAP_H_ @}*/
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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 "tnc_ifmap_soap_msg.h"
|
||||
#include "tnc_ifmap_http.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
#define SOAP_NS "http://www.w3.org/2003/05/soap-envelope"
|
||||
|
||||
typedef struct private_tnc_ifmap_soap_msg_t private_tnc_ifmap_soap_msg_t;
|
||||
|
||||
/**
|
||||
* Private data of an tnc_ifmap_soap_msg_t object.
|
||||
*/
|
||||
struct private_tnc_ifmap_soap_msg_t {
|
||||
|
||||
/**
|
||||
* Public tnc_ifmap_soap_msg_t interface.
|
||||
*/
|
||||
tnc_ifmap_soap_msg_t public;
|
||||
|
||||
/**
|
||||
* HTTP POST request builder and response processing
|
||||
*/
|
||||
tnc_ifmap_http_t *http;
|
||||
|
||||
/**
|
||||
* TLS socket
|
||||
*/
|
||||
tls_socket_t *tls;
|
||||
|
||||
/**
|
||||
* XML Document
|
||||
*/
|
||||
xmlDocPtr doc;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 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_ifmap_soap_msg_t, post, bool,
|
||||
private_tnc_ifmap_soap_msg_t *this, xmlNodePtr request, char *result_name,
|
||||
xmlNodePtr *result)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr env, body, cur, response;
|
||||
xmlNsPtr ns;
|
||||
xmlChar *xml_str, *errorCode, *errorString;
|
||||
int xml_len, len, written;
|
||||
chunk_t xml, http;
|
||||
char buf[4096] = { 0 };
|
||||
status_t status;
|
||||
|
||||
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_str, &xml_len, 1);
|
||||
xmlFreeDoc(doc);
|
||||
DBG3(DBG_TNC, "%.*s", xml_len, xml_str);
|
||||
xml = chunk_create(xml_str, xml_len);
|
||||
|
||||
/* Send SOAP-XML request via HTTPS POST */
|
||||
do
|
||||
{
|
||||
status = this->http->build(this->http, &xml, &http);
|
||||
if (status == FAILED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
written = this->tls->write(this->tls, http.ptr, http.len);
|
||||
free(http.ptr);
|
||||
if (written != http.len)
|
||||
{
|
||||
status = FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (status == NEED_MORE);
|
||||
|
||||
xmlFree(xml_str);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Receive SOAP-XML response via [chunked] HTTPS */
|
||||
xml = chunk_empty;
|
||||
do
|
||||
{
|
||||
/* reduce size so the buffer is null-terminated */
|
||||
len = this->tls->read(this->tls, buf, sizeof(buf)-1, TRUE);
|
||||
if (len <= 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
http = chunk_create(buf, len);
|
||||
|
||||
status = this->http->process(this->http, &http, &xml);
|
||||
if (status == FAILED)
|
||||
{
|
||||
free(xml.ptr);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
while (status == NEED_MORE);
|
||||
|
||||
DBG3(DBG_TNC, "parsing XML message %B", &xml);
|
||||
this->doc = xmlParseMemory(xml.ptr, xml.len);
|
||||
free(xml.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 */
|
||||
response = find_child(cur, "response");
|
||||
if (!response)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get IF-MAP result */
|
||||
cur = find_child(response, result_name);
|
||||
if (!cur)
|
||||
{
|
||||
cur = find_child(response, "errorResult");
|
||||
if (cur)
|
||||
{
|
||||
DBG1(DBG_TNC, "received errorResult");
|
||||
|
||||
errorCode = xmlGetProp(cur, "errorCode");
|
||||
if (errorCode)
|
||||
{
|
||||
DBG1(DBG_TNC, " %s", errorCode);
|
||||
xmlFree(errorCode);
|
||||
}
|
||||
|
||||
cur = find_child(cur, "errorString");
|
||||
if (cur)
|
||||
{
|
||||
errorString = xmlNodeGetContent(cur);
|
||||
if (errorString)
|
||||
{
|
||||
DBG1(DBG_TNC, " %s", errorString);
|
||||
xmlFree(errorString);
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
*result = cur;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(tnc_ifmap_soap_msg_t, destroy, void,
|
||||
private_tnc_ifmap_soap_msg_t *this)
|
||||
{
|
||||
this->http->destroy(this->http);
|
||||
if (this->doc)
|
||||
{
|
||||
xmlFreeDoc(this->doc);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnc_ifmap_soap_msg_t *tnc_ifmap_soap_msg_create(char *uri, chunk_t user_pass,
|
||||
tls_socket_t *tls)
|
||||
{
|
||||
private_tnc_ifmap_soap_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.post = _post,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.http = tnc_ifmap_http_create(uri, user_pass),
|
||||
.tls = tls,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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_ifmap_soap_msg tnc_ifmap_soap_msg
|
||||
* @{ @ingroup tnc_ifmap
|
||||
*/
|
||||
|
||||
#ifndef TNC_IFMAP_SOAP_MSG_H_
|
||||
#define TNC_IFMAP_SOAP_MSG_H_
|
||||
|
||||
#include <library.h>
|
||||
#include <tls_socket.h>
|
||||
|
||||
#include <libxml/parser.h>
|
||||
|
||||
typedef struct tnc_ifmap_soap_msg_t tnc_ifmap_soap_msg_t;
|
||||
|
||||
/**
|
||||
* Interface for sending and receiving SOAP-XML messages
|
||||
*/
|
||||
struct tnc_ifmap_soap_msg_t {
|
||||
|
||||
/**
|
||||
* Post an IF-MAP request in a SOAP-XML message and return a result
|
||||
*
|
||||
* @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_ifmap_soap_msg_t *this, xmlNodePtr request,
|
||||
char *result_name, xmlNodePtr* result);
|
||||
|
||||
/**
|
||||
* Destroy a tnc_ifmap_soap_msg_t object.
|
||||
*/
|
||||
void (*destroy)(tnc_ifmap_soap_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a tnc_ifmap_soap_msg instance.
|
||||
*
|
||||
* @param uri HTTPS URI with https:// prefix removed
|
||||
* @param user_pass Optional username:password for HTTP Basic Authentication
|
||||
* @param tls TLS socket protecting the SOAP message
|
||||
*/
|
||||
tnc_ifmap_soap_msg_t *tnc_ifmap_soap_msg_create(char *uri, chunk_t user_pass,
|
||||
tls_socket_t *tls);
|
||||
|
||||
#endif /** TNC_IFMAP_SOAP_MSG_H_ @}*/
|
||||
@@ -39,7 +39,6 @@ CONFIG_OPTS = \
|
||||
--enable-eap-ttls \
|
||||
--enable-eap-peap \
|
||||
--enable-eap-tnc \
|
||||
--enable-tnc-ifmap \
|
||||
--enable-tnc-pdp \
|
||||
--enable-tnc-imc \
|
||||
--enable-tnc-imv \
|
||||
|
||||
Reference in New Issue
Block a user