]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
set up a new IF-MAP session
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 29 Mar 2013 08:42:06 +0000 (09:42 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 29 Mar 2013 08:42:06 +0000 (09:42 +0100)
configure.in
src/libcharon/Makefile.am
src/libcharon/plugins/tnc_ifmap2/Makefile.am [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap2/gaga.txt [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.c [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.h [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_plugin.c [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_plugin.h [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.c [new file with mode: 0644]
src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_soap.h [new file with mode: 0644]

index 9dc510b2463c5dfa9ec6ce98e854c2ec1153cdab..659d4e9bae3d387f94c40884477769d072e85668 100644 (file)
@@ -169,6 +169,7 @@ ARG_ENABL_SET([xauth-eap],      [enable XAuth backend using EAP methods to verif
 ARG_ENABL_SET([xauth-pam],      [enable XAuth backend using PAM to verify passwords.])
 ARG_ENABL_SET([xauth-noauth],   [enable XAuth pseudo-backend that does not actually verify or even request any credentials.])
 ARG_ENABL_SET([tnc-ifmap],      [enable TNC IF-MAP module.])
+ARG_ENABL_SET([tnc-ifmap2],     [enable TNC IF-MAP v2 module.])
 ARG_ENABL_SET([tnc-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.])
@@ -1017,6 +1018,7 @@ ADD_PLUGIN([xauth-eap],            [c charon])
 ADD_PLUGIN([xauth-pam],            [c charon])
 ADD_PLUGIN([xauth-noauth],         [c charon])
 ADD_PLUGIN([tnc-ifmap],            [c charon])
+ADD_PLUGIN([tnc-ifmap2],           [c charon])
 ADD_PLUGIN([tnc-pdp],              [c charon])
 ADD_PLUGIN([tnc-imc],              [c charon])
 ADD_PLUGIN([tnc-imv],              [c charon])
@@ -1158,6 +1160,7 @@ AM_CONDITIONAL(USE_XAUTH_EAP, test x$xauth_eap = xtrue)
 AM_CONDITIONAL(USE_XAUTH_PAM, test x$xauth_pam = xtrue)
 AM_CONDITIONAL(USE_XAUTH_NOAUTH, test x$xauth_noauth = xtrue)
 AM_CONDITIONAL(USE_TNC_IFMAP, test x$tnc_ifmap = xtrue)
+AM_CONDITIONAL(USE_TNC_IFMAP2, test x$tnc_ifmap2 = 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)
@@ -1354,6 +1357,7 @@ AC_CONFIG_FILES([
        src/libcharon/plugins/xauth_pam/Makefile
        src/libcharon/plugins/xauth_noauth/Makefile
        src/libcharon/plugins/tnc_ifmap/Makefile
+       src/libcharon/plugins/tnc_ifmap2/Makefile
        src/libcharon/plugins/tnc_pdp/Makefile
        src/libcharon/plugins/tnc_imc/Makefile
        src/libcharon/plugins/tnc_imv/Makefile
index f0736c5ca98c9ad21882d45515602073c884bfc3..a8ead50b1f225b0c1d6a607433318d19f1ad5123 100644 (file)
@@ -380,6 +380,13 @@ if MONOLITHIC
 endif
 endif
 
+if USE_TNC_IFMAP2
+  SUBDIRS += plugins/tnc_ifmap2
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/tnc_ifmap2/libstrongswan-tnc-ifmap2.la
+endif
+endif
+
 if USE_TNC_PDP
   SUBDIRS += plugins/tnc_pdp
 if MONOLITHIC
diff --git a/src/libcharon/plugins/tnc_ifmap2/Makefile.am b/src/libcharon/plugins/tnc_ifmap2/Makefile.am
new file mode 100644 (file)
index 0000000..20bb3ca
--- /dev/null
@@ -0,0 +1,24 @@
+
+INCLUDES = \
+       -I$(top_srcdir)/src/libstrongswan \
+       -I$(top_srcdir)/src/libtls \
+       -I$(top_srcdir)/src/libhydra \
+       -I$(top_srcdir)/src/libcharon
+
+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
+
+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
+
+libstrongswan_tnc_ifmap2_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libcharon/plugins/tnc_ifmap2/gaga.txt b/src/libcharon/plugins/tnc_ifmap2/gaga.txt
new file mode 100644 (file)
index 0000000..c93a50a
--- /dev/null
@@ -0,0 +1,32 @@
+POST /ifmap HTTP/1.1
+Content-Type: application/soap+xml; charset=utf-8
+Content-Length: 236
+
+<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
+  <soapenv:Body>
+    <ifmap:newSession xmlns:ifmap="http://www.trustedcomputinggroup.org/2010/IFMAP/2"></ifmap:newSession>
+  </soapenv:Body>
+</soapenv:Envelope>
+
+2013-03-27 20:29:56,704 [pool-5-thread-2] DEBUG  - ChannelAcceptor: New connection from 127.0.0.1:44019 on port 8444
+2013-03-27 20:29:56,887 [pool-6-thread-1] DEBUG  - ChannelThread: Client koala.strongsec.com authenticated successfully on channel 127.0.0.1:44019:0
+2013-03-27 20:29:56,891 [pool-1-thread-1] TRACE  - EventProcessor: RequestChannelEvent on channel 127.0.0.1:44019:0
+2013-03-27 20:29:57,057 [pool-1-thread-1] DEBUG  - EventProcessor: newSession for koala.strongsec.com on 127.0.0.1:44019:0
+2013-03-27 20:29:57,058 [pool-1-thread-1] TRACE  - ClientService: newSession for koala.strongsec.com--515754026-1 and maxPollResultSize=5000000 bytes
+2013-03-27 20:29:57,058 [pool-1-thread-1] TRACE  - Adding new Publisher: sessionid=1890214968-1490695359-237418166-218822252 publisherid=koala.strongsec.com--515754026-1
+2013-03-27 20:29:57,058 [pool-1-thread-1] TRACE  - Creating new Publisher...
+2013-03-27 20:29:57,064 [pool-3-thread-1] TRACE  - ActionProcessor: Forward response to channel 127.0.0.1:44019:0
+2013-03-27 20:29:57,065 [pool-3-thread-1] DEBUG  - ChannelThread: Sending reply to koala.strongsec.com
+2013-03-27 20:29:57,066 [pool-3-thread-1] TRACE  - ChannelThread: Length of reply on wire=376
+2013-03-27 20:29:57,091 [pool-5-thread-2] DEBUG  - ChannelAcceptor: New connection from 127.0.0.1:44020 on port 8444
+2013-03-27 20:29:57,103 [pool-6-thread-1] DEBUG  - ChannelThread: 127.0.0.1:44019:0 closed
+2013-03-27 20:29:57,104 [pool-1-thread-2] DEBUG  - EventProcessor: Got ClosedChannelEvent for 127.0.0.1:44019:0
+2013-03-27 20:29:57,104 [pool-1-thread-2] DEBUG  - EventProcessor: Creating Timer for koala.strongsec.com
+
+2013-03-27 20:29:57,120 [pool-6-thread-2] DEBUG  - ChannelThread: Client koala.strongsec.com authenticated successfully on channel 127.0.0.1:44020:1
+2013-03-27 20:29:57,122 [pool-1-thread-3] TRACE  - EventProcessor: RequestChannelEvent on channel 127.0.0.1:44020:1
+2013-03-27 20:29:57,129 [pool-1-thread-3] DEBUG  - EventProcessor: purgePublisher for koala.strongsec.com on 127.0.0.1:44020:1
+2013-03-27 20:29:57,129 [pool-1-thread-3] TRACE  - EventProcessor: koala.strongsec.com uses 127.0.0.1:44020:1 as new SSRC
+2013-03-27 20:29:57,130 [pool-1-thread-3] TRACE  - EventProcessor: Cancel timer for koala.strongsec.com
+2013-03-27 20:29:57,130 [pool-1-thread-3] DEBUG  - ClientService: publisher{koala.strongsec.com--515754026-1} is purging 0 metadata objects of publisher{koala.strongsec.com--515754026-1}
+
diff --git a/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.c b/src/libcharon/plugins/tnc_ifmap2/tnc_ifmap2_listener.c
new file mode 100644 (file)
index 0000000..4922a3e
--- /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_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
new file mode 100644 (file)
index 0000000..dfb8adc
--- /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_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
new file mode 100644 (file)
index 0000000..8969c11
--- /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_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
new file mode 100644 (file)
index 0000000..387daa6
--- /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_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
new file mode 100644 (file)
index 0000000..994b36c
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * 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 <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_NO_FD            -1
+#define IFMAP_SERVER_ID        "C=DE, ST=Niedersachsen, L=Hannover, O=Hochschule Hannover, OU=Trust@FHH, CN=irond.trust.inform.fh-hannover.de"         
+#define IFMAP_NS               "http://www.trustedcomputinggroup.org/2010/IFMAP/2"
+#define IFMAP_META_NS  "http://www.trustedcomputinggroup.org/2010/IFMAP-METADATA/2"
+#define IFMAP_LOGFILE  "strongswan_ifmap.log"
+#define IFMAP_SERVER   "https://localhost:8443/"
+
+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
+        */
+       char *session_id;
+
+       /**
+        * IF-MAP Publisher ID
+        */
+       char *ifmap_publisher_id;
+
+       /**
+        * PEP and PDP device name
+        */
+       char *device_name;
+
+       /**
+        * IF-MAP Server host
+        */
+       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;
+
+};
+
+/**
+ * Send request and receive result via SOAP
+ */
+static bool send_receive(private_tnc_ifmap2_soap_t *this,
+                                                                        char *request_qname, chunk_t request,
+                                                                        char *receipt_qname, chunk_t *result)
+
+{
+       int written, len;
+       char *pos;
+
+       char soap[] =
+               "<?xml version=\"1.0\"?>"
+               "<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\">"
+               "  <env:Body>"
+               "    <ifmap:newSession xmlns:ifmap=\"http://www.trustedcomputinggroup.org/2010/IFMAP/2\"></ifmap:newSession>"
+               "  </env:Body>"
+               "</env:Envelope>";
+
+       char http_header[] =
+                "POST /ifmap HTTP/1.1\r\n"
+                "Content-Type: application/soap+xml; charset=utf-8\r\n"
+                "Content-Length: ";
+
+       char buf[2048];
+
+       pos = buf;
+       len = sizeof(buf);
+       written = snprintf(pos, len, "%s", http_header);
+       pos += written;
+       len -= written;
+       written = snprintf(pos, len, "%d\r\n\r\n%s", strlen(soap), soap);
+       this->tls->write(this->tls, buf, strlen(buf));
+       len = this->tls->read(this->tls, buf, sizeof(buf), TRUE);
+       *result = chunk_create(buf, len);
+       DBG2(DBG_TNC, "%B", result);
+       return TRUE;
+}
+
+METHOD(tnc_ifmap2_soap_t, newSession, bool,
+       private_tnc_ifmap2_soap_t *this)
+{
+       chunk_t request, result;
+
+       send_receive(this, "newSession", request, "newSessionResult", &result);
+
+    return this->session_id && this->ifmap_publisher_id;
+}
+
+METHOD(tnc_ifmap2_soap_t, purgePublisher, bool,
+       private_tnc_ifmap2_soap_t *this)
+{
+       /* send purgePublisher request and receive purgePublisherReceived */
+       /* return send_receive(this, "purgePublisher", request,
+                                                         "purgePublisherReceived", NULL); */
+       return FALSE;
+}
+
+METHOD(tnc_ifmap2_soap_t, publish_ike_sa, bool,
+       private_tnc_ifmap2_soap_t *this, ike_sa_t *ike_sa, bool up)
+{
+       /* send publish request and receive publishReceived */
+       /* return send_receive(this, "publish", request, "publishReceived", NULL); */
+       return FALSE;
+}
+
+METHOD(tnc_ifmap2_soap_t, publish_device_ip, bool,
+       private_tnc_ifmap2_soap_t *this, host_t *host)
+{
+       /* send publish request and receive publishReceived */
+       /* return send_receive(this, "publish", request, "publishReceived", NULL); */
+       return FALSE;
+}
+
+METHOD(tnc_ifmap2_soap_t, publish_enforcement_report, bool,
+       private_tnc_ifmap2_soap_t *this, host_t *host, char *action, char *reason)
+{
+       /* send publish request and receive publishReceived */
+       /* return send_receive(this, "publish", request, "publishReceived", NULL); */
+       return FALSE;
+}
+
+METHOD(tnc_ifmap2_soap_t, endSession, bool,
+       private_tnc_ifmap2_soap_t *this)
+{
+       /* send endSession request and receive end SessionResult */
+       /* return send_receive(this, "endSession", request, "endSessionResult", NULL); */
+       return FALSE;
+}
+
+METHOD(tnc_ifmap2_soap_t, destroy, void,
+       private_tnc_ifmap2_soap_t *this)
+{
+       if (this->session_id)
+       {
+               endSession(this);
+               free(this->session_id);
+               free(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);
+}
+
+static bool soap_init(private_tnc_ifmap2_soap_t *this)
+{
+       char *server, *server_cert, *client_cert, *client_key;
+       certificate_t *cert;
+       private_key_t *key;
+       identification_t *server_id, *client_id;
+
+       /** Load [self-signed] MAP server certificate */
+       server_cert = lib->settings->get_str(lib->settings,
+                                       "%s.plugins.tnc-ifmap2.server_cert", NULL, charon->name);
+       if (!server_cert)
+       {
+               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);
+
+       /* Load MAP client certificate */
+       client_cert = lib->settings->get_str(lib->settings,
+                                       "%s.plugins.tnc-ifmap2.client_cert", NULL, charon->name);
+       if (!client_cert)
+       {
+               DBG1(DBG_TNC, "MAP client certificate not defined");
+               return FALSE;
+       }
+       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);
+       client_id = cert->get_subject(cert);
+       this->creds->add_cert(this->creds, TRUE, cert);
+
+       /* Load MAP client private key */
+       client_key = lib->settings->get_str(lib->settings,
+                                       "%s.plugins.tnc-ifmap2.client_key", NULL, charon->name);
+       if (!client_key)
+       {
+               DBG1(DBG_TNC, "MAP client private key not defined");
+               return FALSE;
+       }
+       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);
+
+       /* Open TCP socket and connect to MAP server */
+       server = "127.0.0.1";
+       this->host = host_create_from_dns(server, 0, 8444);
+       if (!this->host)
+       {
+               DBG1(DBG_TNC, "resolving hostname %s failed", server);
+               return FALSE;
+       }
+
+       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
new file mode 100644 (file)
index 0000000..8e97880
--- /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_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_ @}*/