renamed tnc_ifmap2 plugin to tnc_ifmap
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 31 Mar 2013 14:37:30 +0000 (16:37 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 31 Mar 2013 14:37:30 +0000 (16:37 +0200)
20 files changed:
configure.in
src/libcharon/Makefile.am
src/libcharon/plugins/tnc_ifmap/Makefile.am [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.h [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap2/Makefile.am [deleted file]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.c [deleted file]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.h [deleted file]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_plugin.c [deleted file]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_plugin.h [deleted file]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c [deleted file]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.h [deleted file]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.c [deleted file]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.h [deleted file]

index 90d4b30..4da06f9 100644 (file)
@@ -168,7 +168,7 @@ ARG_DISBL_SET([xauth-generic],  [disable generic XAuth backend.])
 ARG_ENABL_SET([xauth-eap],      [enable XAuth backend using EAP methods to verify passwords.])
 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-ifmap2],     [enable TNC IF-MAP v2 module. Requires libxml])
+ARG_ENABL_SET([tnc-ifmap],      [enable TNC IF-MAP 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.])
@@ -338,7 +338,7 @@ if test x$fips_prf = xtrue; then
        fi
 fi
 
-if test x$smp = xtrue -o x$tnccs_11 = xtrue -o x$tnc_ifmap2 = xtrue; then
+if test x$smp = xtrue -o x$tnccs_11 = xtrue -o x$tnc_ifmap = xtrue; then
        xml=true
 fi
 
@@ -1006,7 +1006,7 @@ ADD_PLUGIN([xauth-generic],        [c charon])
 ADD_PLUGIN([xauth-eap],            [c charon])
 ADD_PLUGIN([xauth-pam],            [c charon])
 ADD_PLUGIN([xauth-noauth],         [c charon])
-ADD_PLUGIN([tnc-ifmap2],           [c charon])
+ADD_PLUGIN([tnc-ifmap],            [c charon])
 ADD_PLUGIN([tnc-pdp],              [c charon])
 ADD_PLUGIN([tnc-imc],              [c charon])
 ADD_PLUGIN([tnc-imv],              [c charon])
@@ -1147,7 +1147,7 @@ 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_IFMAP2, test x$tnc_ifmap2 = 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)
@@ -1343,7 +1343,7 @@ 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_ifmap2/Makefile
+       src/libcharon/plugins/tnc_ifmap/Makefile
        src/libcharon/plugins/tnc_pdp/Makefile
        src/libcharon/plugins/tnc_imc/Makefile
        src/libcharon/plugins/tnc_imv/Makefile
index b817bdb..f0736c5 100644 (file)
@@ -373,10 +373,10 @@ if MONOLITHIC
 endif
 endif
 
-if USE_TNC_IFMAP2
-  SUBDIRS += plugins/tnc_ifmap2
+if USE_TNC_IFMAP
+  SUBDIRS += plugins/tnc_ifmap
 if MONOLITHIC
-  libcharon_la_LIBADD += plugins/tnc_ifmap2/libstrongswan-tnc-ifmap2.la
+  libcharon_la_LIBADD += plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
 endif
 endif
 
diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.am b/src/libcharon/plugins/tnc_ifmap/Makefile.am
new file mode 100644 (file)
index 0000000..d055bbc
--- /dev/null
@@ -0,0 +1,27 @@
+
+INCLUDES = \
+       -I$(top_srcdir)/src/libstrongswan \
+       -I$(top_srcdir)/src/libtls \
+       -I$(top_srcdir)/src/libhydra \
+       -I$(top_srcdir)/src/libcharon \
+       ${xml_CFLAGS}
+
+AM_CFLAGS = -rdynamic
+
+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
+
+libstrongswan_tnc_ifmap_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c
new file mode 100644 (file)
index 0000000..0280b30
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2011-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.
+ */
+
+#include "tnc_ifmap_listener.h"
+#include "tnc_ifmap_soap.h"
+
+#include <daemon.h>
+#include <hydra.h>
+#include <utils/debug.h>
+
+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 = hydra->kernel_interface->create_address_enumerator(
+                                                                       hydra->kernel_interface, 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)
+{
+       enumerator_t *enumerator;
+       ike_sa_t *ike_sa;
+       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))
+               {
+                       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, 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)
+{
+       DESTROY_IF(this->ifmap);
+       free(this);
+}
+
+/**
+ * See header
+ */
+tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload)
+{
+       private_tnc_ifmap_listener_t *this;
+
+       INIT(this,
+               .public = {
+                       .listener = {
+                               .ike_updown = _ike_updown,
+                               .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;
+               }
+       }
+
+       return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h
new file mode 100644 (file)
index 0000000..4ecccf4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011-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_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_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c
new file mode 100644 (file)
index 0000000..c9e8424
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2011-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.
+ */
+
+#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),
+       };
+       *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_t *tnc_ifmap_plugin_create()
+{
+       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;
+}
+
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h
new file mode 100644 (file)
index 0000000..d3bba7f
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011-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_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_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c
new file mode 100644 (file)
index 0000000..bce4156
--- /dev/null
@@ -0,0 +1,805 @@
+/*
+ * Copyright (C) 2011-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.
+ */
+
+#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;
+
+};
+
+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, "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-ifmap.device_name",
+                                                                        this->ifmap_publisher_id, charon->name);
+       this->device_name = strdup(this->device_name);
+
+    return this->session_id && this->ifmap_publisher_id;
+}
+
+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,
+                                                                               u_int32_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, this->device_name);
+
+       node2 = xmlNewNode(NULL, "administrative-domain");
+       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;
+       u_int32_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);
+       id = ike_sa->get_other_id(ike_sa);
+       eap_id = ike_sa->get_other_eap_id(ike_sa);
+       host = ike_sa->get_other_host(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
+        */
+       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_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);
+
+       return success;
+}
+
+METHOD(tnc_ifmap_soap_t, destroy, void,
+       private_tnc_ifmap_soap_t *this)
+{
+       if (this->session_id)
+       {
+               endSession(this);
+               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;
+       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, charon->name);
+       server_cert = lib->settings->get_str(lib->settings,
+                                       "%s.plugins.tnc-ifmap.server_cert", NULL, charon->name);
+       client_cert = lib->settings->get_str(lib->settings,
+                                       "%s.plugins.tnc-ifmap.client_cert", NULL, charon->name);
+       client_key =  lib->settings->get_str(lib->settings,
+                                       "%s.plugins.tnc-ifmap.client_key", NULL, charon->name);
+       user_pass =   lib->settings->get_str(lib->settings,
+                                       "%s.plugins.tnc-ifmap.username_password", NULL, charon->name);
+
+       /* 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 && client_key) || user_pass))
+       {
+               DBG1(DBG_TNC, "neither MAP client certificate and private key "
+                                         "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);
+               this->creds->add_cert(this->creds, TRUE, cert);
+
+               /* load MAP client private 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);
+       }
+       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);
+       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,
+                       .purgePublisher = _purgePublisher,
+                       .publish_ike_sa = _publish_ike_sa,
+                       .publish_device_ip = _publish_device_ip,
+                       .publish_enforcement_report = _publish_enforcement_report,
+                       .endSession = _endSession,
+                       .destroy = _destroy,
+               },
+               .fd = IFMAP_NO_FD,
+               .creds = mem_cred_create(),
+       );
+
+       lib->credmgr->add_set(lib->credmgr, &this->creds->set);
+
+       if (!soap_init(this))
+       {
+               destroy(this);
+               return NULL;
+       }
+
+       return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h
new file mode 100644 (file)
index 0000000..5ab31ef
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011-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_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);
+
+       /**
+        * 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 metadate 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 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);
+
+       /**
+        * 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_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c
new file mode 100644 (file)
index 0000000..8afd6ff
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * 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_ifmap_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_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;
+
+       /**
+        * HTTPS Server URI with https:// prefix removed
+        */
+       char *uri;
+
+       /**
+        * Optional base64-encoded username:password for HTTP Basic Authentication
+        */
+       chunk_t user_pass;
+
+       /**
+        * TLS Socket
+        */
+       tls_socket_t *tls;
+
+       /**
+        * XML Document
+        */
+       xmlDocPtr doc;
+
+};
+
+/**
+ * Send HTTP POST request and receive HTTP response
+ */
+static bool http_post(private_tnc_ifmap_soap_msg_t *this, chunk_t out,
+                                                                                                                  chunk_t *in)
+{
+       char *host, *path, *request, buf[2048];
+       chunk_t line, http, parameter;
+       int len, code, content_len = 0;
+
+       /* 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(buf, sizeof(buf), "Authorization: Basic %.*s\r\n",
+                                this->user_pass.len, this->user_pass.ptr);
+       }
+       else
+       {
+               *buf = '\0';
+       }
+
+       /* Write HTTP POST request */
+       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, (path-host), host, buf, out.len, out.len, out.ptr);
+       free(host);
+
+       if (len == -1)
+       {
+               return FALSE;
+       }
+       http = chunk_create(request, len);
+       DBG3(DBG_TLS, "%B", &http);
+
+       this->tls->write(this->tls, request, len);
+       free(request);
+
+       /* Read HTTP response */
+       len = this->tls->read(this->tls, buf, sizeof(buf), TRUE);
+       if (len == -1)
+       {
+               return FALSE;
+       }
+       *in = chunk_create(buf, 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_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, *errorCode, *errorString;
+       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 POST */
+       if (!http_post(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 */
+       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)
+{
+       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,
+               },
+               .uri = uri,
+               .user_pass = user_pass,
+               .tls = tls,
+       );
+
+       return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.h
new file mode 100644 (file)
index 0000000..4f809ba
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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_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_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap2/Makefile.am b/src/libcharon/plugins/tnc_ifmap2/Makefile.am
deleted file mode 100644 (file)
index 217d897..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-
-INCLUDES = \
-       -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libtls \
-       -I$(top_srcdir)/src/libhydra \
-       -I$(top_srcdir)/src/libcharon \
-       ${xml_CFLAGS}
-
-AM_CFLAGS = -rdynamic
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-tnc-ifmap2.la
-else
-plugin_LTLIBRARIES = libstrongswan-tnc-ifmap2.la
-endif
-
-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 \
-       tnc_ifmap2_listener.h tnc_ifmap2_listener.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_listener.c b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.c
deleted file mode 100644 (file)
index 4922a3e..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2011-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.
- */
-
-#include "tnc_ifmap2_listener.h"
-#include "tnc_ifmap2_soap.h"
-
-#include <daemon.h>
-#include <hydra.h>
-#include <utils/debug.h>
-
-typedef struct private_tnc_ifmap2_listener_t private_tnc_ifmap2_listener_t;
-
-/**
- * Private data of an tnc_ifmap2_listener_t object.
- */
-struct private_tnc_ifmap2_listener_t {
-
-       /**
-        * Public tnc_ifmap2_listener_t interface.
-        */
-       tnc_ifmap2_listener_t public;
-
-       /**
-        * TNC IF-MAP 2.0 SOAP interface
-        */
-       tnc_ifmap2_soap_t *ifmap;
-
-};
-
-/**
- * Publish PEP device-ip metadata
- */
-static bool publish_device_ip_addresses(private_tnc_ifmap2_listener_t *this)
-{
-       enumerator_t *enumerator;
-       host_t *host;
-       bool success = TRUE;
-
-       enumerator = hydra->kernel_interface->create_address_enumerator(
-                                                                       hydra->kernel_interface, 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_ifmap2_listener_t *this)
-{
-       enumerator_t *enumerator;
-       ike_sa_t *ike_sa;
-       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))
-               {
-                       success = FALSE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       return success;
-}
-
-METHOD(listener_t, ike_updown, bool,
-       private_tnc_ifmap2_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, alert, bool,
-       private_tnc_ifmap2_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_ifmap2_listener_t, destroy, void,
-       private_tnc_ifmap2_listener_t *this)
-{
-       DESTROY_IF(this->ifmap);
-       free(this);
-}
-
-/**
- * See header
- */
-tnc_ifmap2_listener_t *tnc_ifmap2_listener_create(bool reload)
-{
-       private_tnc_ifmap2_listener_t *this;
-
-       INIT(this,
-               .public = {
-                       .listener = {
-                               .ike_updown = _ike_updown,
-                               .alert = _alert,
-                       },
-                       .destroy = _destroy,
-               },
-               .ifmap = tnc_ifmap2_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;
-               }
-       }
-
-       return &this->public;
-}
-
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.h b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.h
deleted file mode 100644 (file)
index dfb8adc..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011-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_listener tnc_ifmap2_listener
- * @{ @ingroup tnc_ifmap2 
- */
-
-#ifndef TNC_IFMAP2_LISTENER_H_
-#define TNC_IFMAP2_LISTENER_H_
-
-#include <bus/bus.h>
-
-typedef struct tnc_ifmap2_listener_t tnc_ifmap2_listener_t;
-
-/**
- * Listener which collects information on IKE_SAs
- */
-struct tnc_ifmap2_listener_t {
-
-       /**
-        * Implements listener_t.
-        */
-       listener_t listener;
-
-       /**
-        * Destroy a tnc_ifmap2_listener_t.
-        */
-       void (*destroy)(tnc_ifmap2_listener_t *this);
-};
-
-/**
- * Create a tnc_ifmap2_listener instance.
- *
- * @param reload       reload all IKE_SA metadata
- */
-tnc_ifmap2_listener_t *tnc_ifmap2_listener_create(bool reload);
-
-#endif /** TNC_IFMAP2_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_plugin.c b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_plugin.c
deleted file mode 100644 (file)
index 8969c11..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2011-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.
- */
-
-#include "tnc_ifmap2_plugin.h"
-#include "tnc_ifmap2_listener.h"
-
-#include <daemon.h>
-typedef struct private_tnc_ifmap2_plugin_t private_tnc_ifmap2_plugin_t;
-
-/**
- * private data of tnc_ifmap2 plugin
- */
-struct private_tnc_ifmap2_plugin_t {
-
-       /**
-        * implements plugin interface
-        */
-       tnc_ifmap2_plugin_t public;
-
-       /**
-        * Listener interface, listens to CHILD_SA state changes
-        */
-       tnc_ifmap2_listener_t *listener;
-};
-
-METHOD(plugin_t, get_name, char*,
-       private_tnc_ifmap2_plugin_t *this)
-{
-       return "tnc-ifmap2";
-}
-
-/**
- * Register tnc_ifmap2 plugin features
- */
-static bool register_tnc_ifmap2(private_tnc_ifmap2_plugin_t *this,
-                                                               plugin_feature_t *feature, bool reg, void *data)
-{
-       if (reg)
-       {
-               this->listener = tnc_ifmap2_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_ifmap2_plugin_t *this, plugin_feature_t *features[])
-{
-       static plugin_feature_t f[] = {
-               PLUGIN_CALLBACK((plugin_feature_callback_t)register_tnc_ifmap2, NULL),
-                       PLUGIN_PROVIDE(CUSTOM, "tnc-ifmap-2.1"),
-                               PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
-                               PLUGIN_SDEPEND(PRIVKEY, KEY_RSA),
-       };
-       *features = f;
-       return countof(f);
-}
-
-METHOD(plugin_t, reload, bool,
-       private_tnc_ifmap2_plugin_t *this)
-{
-       if (this->listener)
-       {
-               charon->bus->remove_listener(charon->bus, &this->listener->listener);
-               this->listener->destroy(this->listener);
-       }
-
-       this->listener = tnc_ifmap2_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_ifmap2_plugin_t *this)
-{
-       free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *tnc_ifmap2_plugin_create()
-{
-       private_tnc_ifmap2_plugin_t *this;
-
-       INIT(this,
-               .public = {
-                       .plugin = {
-                               .get_name = _get_name,
-                               .get_features = _get_features,
-                               .reload = _reload,
-                               .destroy = _destroy,
-                       },
-               },
-       );
-
-       return &this->public.plugin;
-}
-
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_plugin.h b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_plugin.h
deleted file mode 100644 (file)
index 387daa6..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011-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 tnc_ifmap2
- * @ingroup cplugins
- *
- * @defgroup tnc_ifmap2_plugin tnc_ifmap2_plugin
- * @{ @ingroup tnc_ifmap2
- */
-
-#ifndef TNC_IFMAP2_PLUGIN_H_
-#define TNC_IFMAP2_PLUGIN_H_
-
-#include <plugins/plugin.h>
-
-typedef struct tnc_ifmap2_plugin_t tnc_ifmap2_plugin_t;
-
-/**
- * TNC IF-MAP plugin
- */
-struct tnc_ifmap2_plugin_t {
-
-       /**
-        * implements plugin interface
-        */
-       plugin_t plugin;
-};
-
-#endif /** TNC_IFMAP2_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c
deleted file mode 100644 (file)
index 887a781..0000000
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * Copyright (C) 2011-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.
- */
-
-#include "tnc_ifmap2_soap.h"
-#include "tnc_ifmap2_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_ifmap2_soap_t private_tnc_ifmap2_soap_t;
-
-/**
- * Private data of an tnc_ifmap2_soap_t object.
- */
-struct private_tnc_ifmap2_soap_t {
-
-       /**
-        * Public tnc_ifmap2_soap_t interface.
-        */
-       tnc_ifmap2_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;
-
-};
-
-METHOD(tnc_ifmap2_soap_t, newSession, bool,
-       private_tnc_ifmap2_soap_t *this)
-{
-       tnc_ifmap2_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_ifmap2_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, "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;
-}
-
-METHOD(tnc_ifmap2_soap_t, purgePublisher, bool,
-       private_tnc_ifmap2_soap_t *this)
-{
-       tnc_ifmap2_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_ifmap2_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_ifmap2_soap_t *this,
-                                                                               u_int32_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_ifmap2_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_ifmap2_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_ifmap2_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_ifmap2_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_ifmap2_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_ifmap2_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_ifmap2_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_ifmap2_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, this->device_name);
-
-       node2 = xmlNewNode(NULL, "administrative-domain");
-       xmlNodeAddContent(node2, "strongswan");
-
-       return node;
-}
-
-METHOD(tnc_ifmap2_soap_t, publish_ike_sa, bool,
-       private_tnc_ifmap2_soap_t *this, ike_sa_t *ike_sa, bool up)
-{
-       tnc_ifmap2_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;
-       u_int32_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);
-       id = ike_sa->get_other_id(ike_sa);
-       eap_id = ike_sa->get_other_eap_id(ike_sa);
-       host = ike_sa->get_other_host(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
-        */
-       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_ifmap2_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_ifmap2_soap_t, publish_device_ip, bool,
-       private_tnc_ifmap2_soap_t *this, host_t *host)
-{
-       tnc_ifmap2_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_ifmap2_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_ifmap2_soap_t, publish_enforcement_report, bool,
-       private_tnc_ifmap2_soap_t *this, host_t *host, char *action, char *reason)
-{
-       tnc_ifmap2_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_ifmap2_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_ifmap2_soap_t, endSession, bool,
-       private_tnc_ifmap2_soap_t *this)
-{
-       tnc_ifmap2_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_ifmap2_soap_msg_create(this->uri, this->user_pass, this->tls);
-       success = soap_msg->post(soap_msg, request, "endSessionResult", NULL);
-       soap_msg->destroy(soap_msg);
-
-       return success;
-}
-
-METHOD(tnc_ifmap2_soap_t, destroy, void,
-       private_tnc_ifmap2_soap_t *this)
-{
-       if (this->session_id)
-       {
-               endSession(this);
-               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_ifmap2_soap_t *this)
-{
-       char *server_uri, *server_str, *port_str, *uri_str;
-       char *server_cert, *client_cert, *client_key, *user_pass;
-       int port;
-       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-ifmap2.server_uri", IFMAP_URI, charon->name);
-       server_cert = lib->settings->get_str(lib->settings,
-                                       "%s.plugins.tnc-ifmap2.server_cert", NULL, charon->name);
-       client_cert = lib->settings->get_str(lib->settings,
-                                       "%s.plugins.tnc-ifmap2.client_cert", NULL, charon->name);
-       client_key =  lib->settings->get_str(lib->settings,
-                                       "%s.plugins.tnc-ifmap2.client_key", NULL, charon->name);
-       user_pass =   lib->settings->get_str(lib->settings,
-                                       "%s.plugins.tnc-ifmap2.username_password", NULL, charon->name);
-
-       /* 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 && client_key) || user_pass))
-       {
-               DBG1(DBG_TNC, "neither MAP client certificate and private key "
-                                         "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);
-               this->creds->add_cert(this->creds, TRUE, cert);
-
-               /* load MAP client private 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);
-       }
-       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);
-       if (!this->tls)
-       {
-               DBG1(DBG_TNC, "creating TLS socket failed");
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
-/**
- * See header
- */
-tnc_ifmap2_soap_t *tnc_ifmap2_soap_create()
-{
-       private_tnc_ifmap2_soap_t *this;
-
-       INIT(this,
-               .public = {
-                       .newSession = _newSession,
-                       .purgePublisher = _purgePublisher,
-                       .publish_ike_sa = _publish_ike_sa,
-                       .publish_device_ip = _publish_device_ip,
-                       .publish_enforcement_report = _publish_enforcement_report,
-                       .endSession = _endSession,
-                       .destroy = _destroy,
-               },
-               .fd = IFMAP_NO_FD,
-               .creds = mem_cred_create(),
-       );
-
-       lib->credmgr->add_set(lib->credmgr, &this->creds->set);
-
-       if (!soap_init(this))
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       return &this->public;
-}
-
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.h b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.h
deleted file mode 100644 (file)
index 8e97880..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2011-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 tnc_ifmap2_soap
- * @{ @ingroup tnc_ifmap2
- */
-
-#ifndef TNC_IFMAP2_SOAP_H_
-#define TNC_IFMAP2_SOAP_H_
-
-#include <library.h>
-#include <networking/host.h>
-#include <sa/ike_sa.h>
-
-typedef struct tnc_ifmap2_soap_t tnc_ifmap2_soap_t;
-
-/**
- * Implements the TNC IF-MAP 2.0 SOAP Binding
- */
-struct tnc_ifmap2_soap_t {
-
-       /**
-        * Creates a new IF-MAP session
-        *
-        * @return                              TRUE if command was successful
-        */
-       bool (*newSession)(tnc_ifmap2_soap_t *this);
-
-       /**
-        * Purges all metadata published by this publisher
-        *
-        * @return                              TRUE if command was successful
-        */
-       bool (*purgePublisher)(tnc_ifmap2_soap_t *this);
-
-       /**
-        * Publish metadata about established/deleted IKE_SAs
-        *
-        * @param ike_sa                IKE_SA for which metadate is published
-        * @param up                    TRUE if IKE_SEA is up, FALSE if down
-        * @return                              TRUE if command was successful
-        */
-       bool (*publish_ike_sa)(tnc_ifmap2_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_ifmap2_soap_t *this, host_t *host);
-
-       /**
-        * 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_ifmap2_soap_t *this, host_t *host,
-                                                                          char *action, char *reason);
-
-       /**
-        * Ends an IF-MAP session
-        *
-        * @return                              TRUE if command was successful
-        */
-       bool (*endSession)(tnc_ifmap2_soap_t *this);
-
-       /**
-        * Destroy a tnc_ifmap2_soap_t.
-        */
-       void (*destroy)(tnc_ifmap2_soap_t *this);
-};
-
-/**
- * Create a tnc_ifmap2_soap instance.
- */
-tnc_ifmap2_soap_t *tnc_ifmap2_soap_create();
-
-#endif /** TNC_IFMAP2_SOAP_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.c b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap_msg.c
deleted file mode 100644 (file)
index 5cf966a..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * 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;
-
-       /**
-        * HTTPS Server URI with https:// prefix removed
-        */
-       char *uri;
-
-       /**
-        * Optional base64-encoded username:password for HTTP Basic Authentication
-        */
-       chunk_t user_pass;
-
-       /**
-        * TLS Socket
-        */
-       tls_socket_t *tls;
-
-       /**
-        * XML Document
-        */
-       xmlDocPtr doc;
-
-};
-
-/**
- * Send HTTP POST request and receive HTTP response
- */
-static bool http_post(private_tnc_ifmap2_soap_msg_t *this, chunk_t out,
-                                                                                                                  chunk_t *in)
-{
-       char *host, *path, *request, buf[2048];
-       chunk_t line, http, parameter;
-       int len, code, content_len = 0;
-
-       /* 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(buf, sizeof(buf), "Authorization: Basic %.*s\r\n",
-                                this->user_pass.len, this->user_pass.ptr);
-       }
-       else
-       {
-               *buf = '\0';
-       }
-
-       /* Write HTTP POST request */
-       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, (path-host), host, buf, out.len, out.len, out.ptr);
-       free(host);
-
-       if (len == -1)
-       {
-               return FALSE;
-       }
-       http = chunk_create(request, len);
-       DBG3(DBG_TLS, "%B", &http);
-
-       this->tls->write(this->tls, request, len);
-       free(request);
-
-       /* Read HTTP response */
-       len = this->tls->read(this->tls, buf, sizeof(buf), TRUE);
-       if (len == -1)
-       {
-               return FALSE;
-       }
-       *in = chunk_create(buf, 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, xmlNodePtr request, char *result_name,
-       xmlNodePtr *result)
-{
-       xmlDocPtr doc;
-       xmlNodePtr env, body, cur, response;
-       xmlNsPtr ns;
-       xmlChar *xml, *errorCode, *errorString;
-       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 POST */
-       if (!http_post(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 */
-       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_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(char *uri, chunk_t user_pass,
-                                                                                                 tls_socket_t *tls)
-{
-       private_tnc_ifmap2_soap_msg_t *this;
-
-       INIT(this,
-               .public = {
-                       .post = _post,
-                       .destroy = _destroy,
-               },
-               .uri = uri,
-               .user_pass = user_pass,
-               .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
deleted file mode 100644 (file)
index 2a50bfc..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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               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, 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 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_ifmap2_soap_msg_t *tnc_ifmap2_soap_msg_create(char *uri, chunk_t user_pass,
-                                                                                                 tls_socket_t *tls);
-
-#endif /** TNC_IFMAP2_SOAP_MSG_H_ @}*/