aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins/tnc_ifmap
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2011-08-08 08:29:43 +0200
committerAndreas Steffen <andreas.steffen@strongswan.org>2011-08-10 09:29:34 +0200
commitcc7cfbc16efa6c522184037933a0566a17ec1904 (patch)
tree46727ccaa385c61f584103b8cd34c4ae73bbcc4c /src/libcharon/plugins/tnc_ifmap
parent2c5e71b0c5d03df35d003db3cb1a1e4c650d7f9f (diff)
downloadstrongswan-cc7cfbc16efa6c522184037933a0566a17ec1904.tar.bz2
strongswan-cc7cfbc16efa6c522184037933a0566a17ec1904.tar.xz
moved ifmap code into tnc_ifmap_soap
Diffstat (limited to 'src/libcharon/plugins/tnc_ifmap')
-rw-r--r--src/libcharon/plugins/tnc_ifmap/Makefile.am3
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c495
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h4
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c542
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h79
5 files changed, 641 insertions, 482 deletions
diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.am b/src/libcharon/plugins/tnc_ifmap/Makefile.am
index 4527afd46..50c312ee1 100644
--- a/src/libcharon/plugins/tnc_ifmap/Makefile.am
+++ b/src/libcharon/plugins/tnc_ifmap/Makefile.am
@@ -14,7 +14,8 @@ endif
libstrongswan_tnc_ifmap_la_SOURCES = \
tnc_ifmap_plugin.h tnc_ifmap_plugin.c \
- tnc_ifmap_listener.h tnc_ifmap_listener.c
+ tnc_ifmap_listener.h tnc_ifmap_listener.c \
+ tnc_ifmap_soap.h tnc_ifmap_soap.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
index 3bee07636..36dec395f 100644
--- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c
@@ -14,19 +14,11 @@
*/
#include "tnc_ifmap_listener.h"
+#include "tnc_ifmap_soap.h"
#include <daemon.h>
-#include <config/child_cfg.h>
+#include <debug.h>
-#include <axis2_util.h>
-#include <axis2_client.h>
-#include <axiom_soap.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_LOGFILE "strongswan_ifmap.log"
-#define IFMAP_SERVER "https://localhost:8443/"
-
typedef struct private_tnc_ifmap_listener_t private_tnc_ifmap_listener_t;
/**
@@ -40,401 +32,12 @@ struct private_tnc_ifmap_listener_t {
tnc_ifmap_listener_t public;
/**
- * Axis2/C environment
- */
- axutil_env_t *env;
-
- /**
- * Axis2 service client
- */
- axis2_svc_client_t* svc_client;
-
- /**
- * SOAP Session ID
- */
- char *session_id;
-
- /**
- * IF-MAP Publisher ID
- */
- char *ifmap_publisher_id;
-
- /**
- * PEP and PDP device name
+ * TNC IF-MAP 2.0 SOAP interface
*/
- char *device_name;
+ tnc_ifmap_soap_t *ifmap;
};
-static bool newSession(private_tnc_ifmap_listener_t *this)
-{
- axiom_node_t *request, *result, *node;
- axiom_element_t *el;
- axiom_namespace_t *ns;
- axiom_attribute_t *attr;
- axis2_char_t *value;
- axutil_qname_t *qname;
-
- bool success = FALSE;
-
- /* build newSession request */
- ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
- el = axiom_element_create(this->env, NULL, "newSession", ns, &request);
- attr = axiom_attribute_create(this->env, "max-poll-result-size", "1000000", NULL);
- axiom_element_add_attribute(el, this->env, attr, request);
-
- /* send newSession request */
- result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
- if (!result)
- {
- return FALSE;
- }
-
- /* process newSessionResult */
- node = axiom_node_get_first_child(result, this->env);
- if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
- {
- el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
- qname = axiom_element_get_qname(el, this->env, node);
- success = streq("newSessionResult",
- axutil_qname_to_string(qname, this->env));
-
- /* process the attributes */
- if (success)
- {
- value = axiom_element_get_attribute_value_by_name(el, this->env,
- "session-id");
- this->session_id = strdup(value);
- value = axiom_element_get_attribute_value_by_name(el, this->env,
- "ifmap-publisher-id");
- this->ifmap_publisher_id = strdup(value);
-
- DBG1(DBG_TNC, "session-id: %s, ifmap-publisher-id: %s",
- this->session_id, this->ifmap_publisher_id);
- success = this->session_id && this->ifmap_publisher_id;
-
- value = axiom_element_get_attribute_value_by_name(el, this->env,
- "max-poll-result-size");
- if (value)
- {
- DBG1(DBG_TNC, "max-poll-result-size: %s", value);
- }
- }
- else
- {
- DBG1(DBG_TNC, "%s", axiom_element_to_string(el, this->env, node));
- }
- }
- axiom_node_free_tree(result, this->env);
-
- return success;
-}
-
-static bool purgePublisher(private_tnc_ifmap_listener_t *this)
-{
- axiom_node_t *request, *result, *node;
- axiom_element_t *el;
- axiom_namespace_t *ns;
- axiom_attribute_t *attr;
- axutil_qname_t *qname;
- bool success = FALSE;
-
- /* build purgePublisher request */
- ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
- el = axiom_element_create(this->env, NULL, "purgePublisher", ns,
- &request);
- attr = axiom_attribute_create(this->env, "session-id",
- this->session_id, NULL);
- axiom_element_add_attribute(el, this->env, attr, request);
- attr = axiom_attribute_create(this->env, "ifmap-publisher-id",
- this->ifmap_publisher_id, NULL);
- axiom_element_add_attribute(el, this->env, attr, request);
-
- /* send purgePublisher request */
- result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
- if (!result)
- {
- return FALSE;
- }
-
- /* process purgePublisherReceived */
- node = axiom_node_get_first_child(result, this->env);
- if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
- {
- el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
- qname = axiom_element_get_qname(el, this->env, node);
- success = streq("purgePublisherReceived",
- axutil_qname_to_string(qname, this->env));
- if (!success)
- {
- DBG1(DBG_TNC, "%s", axiom_element_to_string(el, this->env, node));
- }
- }
- axiom_node_free_tree(result, this->env);
-
- return success;
-}
-
-static bool publish(private_tnc_ifmap_listener_t *this, u_int32_t ike_sa_id,
- identification_t *id, host_t *host, bool up)
-{
- axiom_node_t *request, *result, *node, *node2, *node3, *node4;
- axiom_element_t *el;
- axiom_namespace_t *ns, *ns_meta;
- axiom_attribute_t *attr;
- axiom_text_t *text;
- axutil_qname_t *qname;
- char buf[BUF_LEN], *id_type;
- bool success = FALSE;
-
- /* build publish request */
- ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
- el = axiom_element_create(this->env, NULL, "publish", ns, &request);
- ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
- axiom_element_declare_namespace(el, this->env, request, ns_meta);
- attr = axiom_attribute_create(this->env, "session-id", this->session_id,
- NULL);
- axiom_element_add_attribute(el, this->env, attr, request);
-
- /**
- * update or delete authenticated-as metadata
- */
- if (up)
- {
- el = axiom_element_create(this->env, NULL, "update", NULL, &node);
- axiom_node_add_child(request, this->env, node);
- }
- else
- {
- el = axiom_element_create(this->env, NULL, "delete", NULL, &node);
- axiom_node_add_child(request, this->env, node);
-
- /* add filter */
- snprintf(buf, BUF_LEN, "meta:authenticated-as[@ifmap-publisher-id='%s']",
- this->ifmap_publisher_id);
- attr = axiom_attribute_create(this->env, "filter", buf, NULL);
- axiom_element_add_attribute(el, this->env, attr, node);
- }
-
- /* add access-request */
- el = axiom_element_create(this->env, NULL, "access-request", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
-
- snprintf(buf, BUF_LEN, "%s:%d", this->device_name, ike_sa_id);
- attr = axiom_attribute_create(this->env, "name", buf, NULL);
- axiom_element_add_attribute(el, this->env, attr, node2);
-
- /* add identity */
- el = axiom_element_create(this->env, NULL, "identity", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
-
- snprintf(buf, BUF_LEN, "%Y", id);
- attr = axiom_attribute_create(this->env, "name", buf, NULL);
- axiom_element_add_attribute(el, this->env, attr, node2);
-
- switch (id->get_type(id))
- {
- case ID_FQDN:
- id_type = "dns-name";
- break;
- case ID_RFC822_ADDR:
- id_type = "email-address";
- break;
- case ID_DER_ASN1_DN:
- id_type = "distinguished-name";
- break;
- default:
- id_type = "other";
- }
- attr = axiom_attribute_create(this->env, "type", id_type, NULL);
- axiom_element_add_attribute(el, this->env, attr, node2);
-
- if (up)
- {
- /* add metadata */
- el = axiom_element_create(this->env, NULL, "metadata", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
-
- ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
-
- el = axiom_element_create(this->env, NULL, "authenticated-as", ns_meta,
- &node3);
- axiom_node_add_child(node2, this->env, node3);
- attr = axiom_attribute_create(this->env, "ifmap-cardinality",
- "singleValue", NULL);
- axiom_element_add_attribute(el, this->env, attr, node3);
- }
-
- /**
- * update or delete access-request-ip metadata
- */
- if (up)
- {
- el = axiom_element_create(this->env, NULL, "update", NULL, &node);
- axiom_node_add_child(request, this->env, node);
- }
- else
- {
- el = axiom_element_create(this->env, NULL, "delete", NULL, &node);
- axiom_node_add_child(request, this->env, node);
-
- /* add filter */
- snprintf(buf, BUF_LEN, "meta:access-request-ip[@ifmap-publisher-id='%s']",
- this->ifmap_publisher_id);
- attr = axiom_attribute_create(this->env, "filter", buf, NULL);
- axiom_element_add_attribute(el, this->env, attr, node);
- }
-
- /* add access-request */
- el = axiom_element_create(this->env, NULL, "access-request", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
-
- snprintf(buf, BUF_LEN, "%s:%d", this->device_name, ike_sa_id);
- attr = axiom_attribute_create(this->env, "name", buf, NULL);
- axiom_element_add_attribute(el, this->env, attr, node2);
-
- /* add ip-address */
- el = axiom_element_create(this->env, NULL, "ip-address", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
-
- snprintf(buf, BUF_LEN, "%H", host);
- attr = axiom_attribute_create(this->env, "value", buf, NULL);
- axiom_element_add_attribute(el, this->env, attr, node2);
-
- attr = axiom_attribute_create(this->env, "type",
- host->get_family(host) == AF_INET ? "IPv4" : "IPv6", NULL);
- axiom_element_add_attribute(el, this->env, attr, node2);
-
- if (up)
- {
- /* add metadata */
- el = axiom_element_create(this->env, NULL, "metadata", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
- ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
- el = axiom_element_create(this->env, NULL, "access-request-ip", ns_meta,
- &node3);
- axiom_node_add_child(node2, this->env, node3);
- attr = axiom_attribute_create(this->env, "ifmap-cardinality",
- "singleValue", NULL);
- axiom_element_add_attribute(el, this->env, attr, node3);
- }
-
- /**
- * update or delete authenticated-by metadata
- */
- if (up)
- {
- el = axiom_element_create(this->env, NULL, "update", NULL, &node);
- axiom_node_add_child(request, this->env, node);
- }
- else
- {
- el = axiom_element_create(this->env, NULL, "delete", NULL, &node);
- axiom_node_add_child(request, this->env, node);
-
- /* add filter */
- snprintf(buf, BUF_LEN, "meta:authenticated-by[@ifmap-publisher-id='%s']",
- this->ifmap_publisher_id);
- attr = axiom_attribute_create(this->env, "filter", buf, NULL);
- axiom_element_add_attribute(el, this->env, attr, node);
- }
-
- /* add access-request */
- el = axiom_element_create(this->env, NULL, "access-request", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
-
- snprintf(buf, BUF_LEN, "%s:%d", this->device_name, ike_sa_id);
- attr = axiom_attribute_create(this->env, "name", buf, NULL);
- axiom_element_add_attribute(el, this->env, attr, node2);
-
- /* add device */
- el = axiom_element_create(this->env, NULL, "device", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
- el = axiom_element_create(this->env, NULL, "name", NULL, &node3);
- axiom_node_add_child(node2, this->env, node3);
- text = axiom_text_create(this->env, node3, this->device_name, &node4);
-
- if (up)
- {
- /* add metadata */
- el = axiom_element_create(this->env, NULL, "metadata", NULL, &node2);
- axiom_node_add_child(node, this->env, node2);
- ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
- el = axiom_element_create(this->env, NULL, "authenticated-by", ns_meta,
- &node3);
- axiom_node_add_child(node2, this->env, node3);
- attr = axiom_attribute_create(this->env, "ifmap-cardinality",
- "singleValue", NULL);
- axiom_element_add_attribute(el, this->env, attr, node3);
- }
-
- /* send publish request */
- result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
- if (!result)
- {
- return FALSE;
- }
-
- /* process publishReceived */
- node = axiom_node_get_first_child(result, this->env);
- if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
- {
- el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
- qname = axiom_element_get_qname(el, this->env, node);
- success = streq("publishReceived",
- axutil_qname_to_string(qname, this->env));
- if (!success)
- {
- DBG1(DBG_TNC, "%s", axiom_element_to_string(el, this->env, node));
- }
- }
- axiom_node_free_tree(result, this->env);
-
- return TRUE;
-}
-
-static bool endSession(private_tnc_ifmap_listener_t *this)
-{
- axiom_node_t *request, *result, *node;
- axiom_element_t *el;
- axiom_namespace_t *ns;
- axiom_attribute_t *attr;
- axutil_qname_t *qname;
- bool success = FALSE;
-
- /* build endSession request */
- ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
- el = axiom_element_create(this->env, NULL, "endSession", ns, &request);
- attr = axiom_attribute_create(this->env, "session-id", this->session_id, NULL);
- axiom_element_add_attribute(el, this->env, attr, request);
-
- /* send endSession request */
- result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
- if (!result)
- {
- return FALSE;
- }
-
- /* process endSessionResult */
- node = axiom_node_get_first_child(result, this->env);
- if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
- {
- el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
- qname = axiom_element_get_qname(el, this->env, node);
- success = streq("endSessionResult",
- axutil_qname_to_string(qname, this->env));
- if (!success)
- {
- DBG1(DBG_TNC, "%s", axiom_element_to_string(el, this->env, node));
- }
- }
- axiom_node_free_tree(result, this->env);
-
- return success;
-
- return TRUE;
-}
-
METHOD(listener_t, ike_updown, bool,
private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, bool up)
{
@@ -446,10 +49,10 @@ METHOD(listener_t, ike_updown, bool,
id = ike_sa->get_other_id(ike_sa);
host = ike_sa->get_other_host(ike_sa);
- DBG2(DBG_TNC, "sending publish");
- if (!publish(this, ike_sa_id, id, host, up))
+ DBG2(DBG_TNC, "sending ifmap->publish");
+ if (!this->ifmap->publish(this->ifmap, ike_sa_id, id, host, up))
{
- DBG1(DBG_TNC, "publish with MAP server failed");
+ DBG1(DBG_TNC, "ifmap->publish with MAP server failed");
}
return TRUE;
@@ -458,25 +61,7 @@ METHOD(listener_t, ike_updown, bool,
METHOD(tnc_ifmap_listener_t, destroy, void,
private_tnc_ifmap_listener_t *this)
{
- if (this->session_id)
- {
- DBG2(DBG_TNC, "sending endSession");
- if (!endSession(this))
- {
- DBG1(DBG_TNC, "endSession with MAP server failed");
- }
- free(this->session_id);
- free(this->ifmap_publisher_id);
- free(this->device_name);
- }
- if (this->svc_client)
- {
- axis2_svc_client_free(this->svc_client, this->env);
- }
- if (this->env)
- {
- axutil_env_free(this->env);
- }
+ DESTROY_IF(this->ifmap);
free(this);
}
@@ -486,29 +71,6 @@ METHOD(tnc_ifmap_listener_t, destroy, void,
tnc_ifmap_listener_t *tnc_ifmap_listener_create()
{
private_tnc_ifmap_listener_t *this;
- axis2_char_t *server, *client_home, *username, *password, *auth_type;
- axis2_endpoint_ref_t* endpoint_ref = NULL;
- axis2_options_t *options = NULL;
-
- client_home = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-ifmap.client_home",
- AXIS2_GETENV("AXIS2C_HOME"));
- server = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-ifmap.server", IFMAP_SERVER);
- auth_type = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-ifmap.auth_type", "Basic");
- username = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-ifmap.username", NULL);
- password = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-ifmap.password", NULL);
-
- if (!username || !password)
- {
- DBG1(DBG_TNC, "MAP client %s%s%s not defined",
- (!username) ? "username" : "",
- (!username && ! password) ? " and " : "",
- (!password) ? "password" : "");
- }
INIT(this,
.public = {
@@ -517,52 +79,27 @@ tnc_ifmap_listener_t *tnc_ifmap_listener_create()
},
.destroy = _destroy,
},
+ .ifmap = tnc_ifmap_soap_create(),
);
- /* Create Axis2/C environment and options */
- this->env = axutil_env_create_all(IFMAP_LOGFILE, AXIS2_LOG_LEVEL_TRACE);
- options = axis2_options_create(this->env);
-
- /* Define the IF-MAP server as the to endpoint reference */
- endpoint_ref = axis2_endpoint_ref_create(this->env, server);
- axis2_options_set_to(options, this->env, endpoint_ref);
-
- /* Create the axis2 service client */
- this->svc_client = axis2_svc_client_create(this->env, client_home);
- if (!this->svc_client)
+ if (!this->ifmap)
{
- DBG1(DBG_TNC, "Error creating axis2 service client");
- AXIS2_LOG_ERROR(this->env->log, AXIS2_LOG_SI,
- "Stub invoke FAILED: Error code: %d :: %s",
- this->env->error->error_number,
- AXIS2_ERROR_GET_MESSAGE(this->env->error));
destroy(this);
return NULL;
}
- axis2_svc_client_set_options(this->svc_client, this->env, options);
- axis2_options_set_http_auth_info(options, this->env, username, password,
- auth_type);
- DBG1(DBG_TNC, "connecting as MAP client '%s' to MAP server at '%s'",
- username, server);
-
- DBG2(DBG_TNC, "sending newSession");
- if (!newSession(this))
+ DBG2(DBG_TNC, "sending ifmap->newSession");
+ if (!this->ifmap->newSession(this->ifmap))
{
- DBG1(DBG_TNC, "newSession with MAP server failed");
+ DBG1(DBG_TNC, "ifmap->newSession with MAP server failed");
destroy(this);
return NULL;
}
- /* set PEP and PDP device name (defaults to IF-MAP Publisher ID) */
- this->device_name = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-ifmap.device_name", this->ifmap_publisher_id);
- this->device_name = strdup(this->device_name);
-
- DBG2(DBG_TNC, "sending purgePublisher");
- if (!purgePublisher(this))
+ DBG2(DBG_TNC, "sending ifmap->purgePublisher");
+ if (!this->ifmap->purgePublisher(this->ifmap))
{
- DBG1(DBG_TNC, "purgePublisher with MAP server failed");
+ DBG1(DBG_TNC, "ifmap->purgePublisher with MAP server failed");
destroy(this);
return NULL;
}
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h
index 19e354abc..4a2c5e8a1 100644
--- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h
@@ -26,7 +26,7 @@
typedef struct tnc_ifmap_listener_t tnc_ifmap_listener_t;
/**
- * Listener which collects information on IKE_SAs and CHILD_SAs.
+ * Listener which collects information on IKE_SAs
*/
struct tnc_ifmap_listener_t {
@@ -36,7 +36,7 @@ struct tnc_ifmap_listener_t {
listener_t listener;
/**
- * Destroy a updown_listener_t.
+ * Destroy a tnc_ifmap_listener_t.
*/
void (*destroy)(tnc_ifmap_listener_t *this);
};
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
index 000000000..5fae6eab4
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2011 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 <debug.h>
+
+#include <axis2_util.h>
+#include <axis2_client.h>
+#include <axiom_soap.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_LOGFILE "strongswan_ifmap.log"
+#define IFMAP_SERVER "https://localhost:8443/"
+
+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;
+
+ /**
+ * Axis2/C environment
+ */
+ axutil_env_t *env;
+
+ /**
+ * Axis2 service client
+ */
+ axis2_svc_client_t* svc_client;
+
+ /**
+ * SOAP Session ID
+ */
+ char *session_id;
+
+ /**
+ * IF-MAP Publisher ID
+ */
+ char *ifmap_publisher_id;
+
+ /**
+ * PEP and PDP device name
+ */
+ char *device_name;
+
+};
+
+METHOD(tnc_ifmap_soap_t, newSession, bool,
+ private_tnc_ifmap_soap_t *this)
+{
+ axiom_node_t *request, *result, *node;
+ axiom_element_t *el;
+ axiom_namespace_t *ns;
+ axiom_attribute_t *attr;
+ axis2_char_t *value;
+ axutil_qname_t *qname;
+
+ bool success = FALSE;
+
+ /* build newSession request */
+ ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
+ el = axiom_element_create(this->env, NULL, "newSession", ns, &request);
+ attr = axiom_attribute_create(this->env, "max-poll-result-size", "1000000", NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+
+ /* send newSession request */
+ result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
+ if (!result)
+ {
+ return FALSE;
+ }
+
+ /* process newSessionResult */
+ node = axiom_node_get_first_child(result, this->env);
+ if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
+ {
+ el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
+ qname = axiom_element_get_qname(el, this->env, node);
+ success = streq("newSessionResult",
+ axutil_qname_to_string(qname, this->env));
+
+ /* process the attributes */
+ if (success)
+ {
+ value = axiom_element_get_attribute_value_by_name(el, this->env,
+ "session-id");
+ this->session_id = strdup(value);
+ value = axiom_element_get_attribute_value_by_name(el, this->env,
+ "ifmap-publisher-id");
+ this->ifmap_publisher_id = strdup(value);
+
+ DBG1(DBG_TNC, "session-id: %s, ifmap-publisher-id: %s",
+ this->session_id, this->ifmap_publisher_id);
+ success = this->session_id && this->ifmap_publisher_id;
+
+ value = axiom_element_get_attribute_value_by_name(el, this->env,
+ "max-poll-result-size");
+ if (value)
+ {
+ DBG1(DBG_TNC, "max-poll-result-size: %s", value);
+ }
+
+ /* set PEP and PDP device name (defaults to IF-MAP Publisher ID) */
+ this->device_name = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.device_name",
+ this->ifmap_publisher_id);
+ this->device_name = strdup(this->device_name);
+ }
+ else
+ {
+ DBG1(DBG_TNC, "%s", axiom_element_to_string(el, this->env, node));
+ }
+ }
+ axiom_node_free_tree(result, this->env);
+
+ return success;
+}
+
+METHOD(tnc_ifmap_soap_t, purgePublisher, bool,
+ private_tnc_ifmap_soap_t *this)
+{
+ axiom_node_t *request, *result, *node;
+ axiom_element_t *el;
+ axiom_namespace_t *ns;
+ axiom_attribute_t *attr;
+ axutil_qname_t *qname;
+ bool success = FALSE;
+
+ /* build purgePublisher request */
+ ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
+ el = axiom_element_create(this->env, NULL, "purgePublisher", ns,
+ &request);
+ attr = axiom_attribute_create(this->env, "session-id",
+ this->session_id, NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+ attr = axiom_attribute_create(this->env, "ifmap-publisher-id",
+ this->ifmap_publisher_id, NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+
+ /* send purgePublisher request */
+ result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
+ if (!result)
+ {
+ return FALSE;
+ }
+
+ /* process purgePublisherReceived */
+ node = axiom_node_get_first_child(result, this->env);
+ if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
+ {
+ el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
+ qname = axiom_element_get_qname(el, this->env, node);
+ success = streq("purgePublisherReceived",
+ axutil_qname_to_string(qname, this->env));
+ if (!success)
+ {
+ DBG1(DBG_TNC, "%s", axiom_element_to_string(el, this->env, node));
+ }
+ }
+ axiom_node_free_tree(result, this->env);
+
+ return success;
+}
+
+METHOD(tnc_ifmap_soap_t, publish, bool,
+ private_tnc_ifmap_soap_t *this, u_int32_t ike_sa_id, identification_t *id,
+ host_t *host, bool up)
+{
+ axiom_node_t *request, *result, *node, *node2, *node3, *node4;
+ axiom_element_t *el;
+ axiom_namespace_t *ns, *ns_meta;
+ axiom_attribute_t *attr;
+ axiom_text_t *text;
+ axutil_qname_t *qname;
+ char buf[BUF_LEN], *id_type;
+ bool success = FALSE;
+
+ /* build publish request */
+ ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
+ el = axiom_element_create(this->env, NULL, "publish", ns, &request);
+ ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
+ axiom_element_declare_namespace(el, this->env, request, ns_meta);
+ attr = axiom_attribute_create(this->env, "session-id", this->session_id,
+ NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+
+ /**
+ * update or delete authenticated-as metadata
+ */
+ if (up)
+ {
+ el = axiom_element_create(this->env, NULL, "update", NULL, &node);
+ axiom_node_add_child(request, this->env, node);
+ }
+ else
+ {
+ el = axiom_element_create(this->env, NULL, "delete", NULL, &node);
+ axiom_node_add_child(request, this->env, node);
+
+ /* add filter */
+ snprintf(buf, BUF_LEN, "meta:authenticated-as[@ifmap-publisher-id='%s']",
+ this->ifmap_publisher_id);
+ attr = axiom_attribute_create(this->env, "filter", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+ }
+
+ /* add access-request */
+ el = axiom_element_create(this->env, NULL, "access-request", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+
+ snprintf(buf, BUF_LEN, "%s:%d", this->device_name, ike_sa_id);
+ attr = axiom_attribute_create(this->env, "name", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+
+ /* add identity */
+ el = axiom_element_create(this->env, NULL, "identity", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+
+ snprintf(buf, BUF_LEN, "%Y", id);
+ attr = axiom_attribute_create(this->env, "name", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+
+ switch (id->get_type(id))
+ {
+ case ID_FQDN:
+ id_type = "dns-name";
+ break;
+ case ID_RFC822_ADDR:
+ id_type = "email-address";
+ break;
+ case ID_DER_ASN1_DN:
+ id_type = "distinguished-name";
+ break;
+ default:
+ id_type = "other";
+ }
+ attr = axiom_attribute_create(this->env, "type", id_type, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+
+ if (up)
+ {
+ /* add metadata */
+ el = axiom_element_create(this->env, NULL, "metadata", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+
+ ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
+
+ el = axiom_element_create(this->env, NULL, "authenticated-as", ns_meta,
+ &node3);
+ axiom_node_add_child(node2, this->env, node3);
+ attr = axiom_attribute_create(this->env, "ifmap-cardinality",
+ "singleValue", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node3);
+ }
+
+ /**
+ * update or delete access-request-ip metadata
+ */
+ if (up)
+ {
+ el = axiom_element_create(this->env, NULL, "update", NULL, &node);
+ axiom_node_add_child(request, this->env, node);
+ }
+ else
+ {
+ el = axiom_element_create(this->env, NULL, "delete", NULL, &node);
+ axiom_node_add_child(request, this->env, node);
+
+ /* add filter */
+ snprintf(buf, BUF_LEN, "meta:access-request-ip[@ifmap-publisher-id='%s']",
+ this->ifmap_publisher_id);
+ attr = axiom_attribute_create(this->env, "filter", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+ }
+
+ /* add access-request */
+ el = axiom_element_create(this->env, NULL, "access-request", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+
+ snprintf(buf, BUF_LEN, "%s:%d", this->device_name, ike_sa_id);
+ attr = axiom_attribute_create(this->env, "name", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+
+ /* add ip-address */
+ el = axiom_element_create(this->env, NULL, "ip-address", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+
+ snprintf(buf, BUF_LEN, "%H", host);
+ attr = axiom_attribute_create(this->env, "value", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+
+ attr = axiom_attribute_create(this->env, "type",
+ host->get_family(host) == AF_INET ? "IPv4" : "IPv6", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+
+ if (up)
+ {
+ /* add metadata */
+ el = axiom_element_create(this->env, NULL, "metadata", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+ ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
+ el = axiom_element_create(this->env, NULL, "access-request-ip", ns_meta,
+ &node3);
+ axiom_node_add_child(node2, this->env, node3);
+ attr = axiom_attribute_create(this->env, "ifmap-cardinality",
+ "singleValue", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node3);
+ }
+
+ /**
+ * update or delete authenticated-by metadata
+ */
+ if (up)
+ {
+ el = axiom_element_create(this->env, NULL, "update", NULL, &node);
+ axiom_node_add_child(request, this->env, node);
+ }
+ else
+ {
+ el = axiom_element_create(this->env, NULL, "delete", NULL, &node);
+ axiom_node_add_child(request, this->env, node);
+
+ /* add filter */
+ snprintf(buf, BUF_LEN, "meta:authenticated-by[@ifmap-publisher-id='%s']",
+ this->ifmap_publisher_id);
+ attr = axiom_attribute_create(this->env, "filter", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+ }
+
+ /* add access-request */
+ el = axiom_element_create(this->env, NULL, "access-request", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+
+ snprintf(buf, BUF_LEN, "%s:%d", this->device_name, ike_sa_id);
+ attr = axiom_attribute_create(this->env, "name", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+
+ /* add device */
+ el = axiom_element_create(this->env, NULL, "device", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+ el = axiom_element_create(this->env, NULL, "name", NULL, &node3);
+ axiom_node_add_child(node2, this->env, node3);
+ text = axiom_text_create(this->env, node3, this->device_name, &node4);
+
+ if (up)
+ {
+ /* add metadata */
+ el = axiom_element_create(this->env, NULL, "metadata", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+ ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
+ el = axiom_element_create(this->env, NULL, "authenticated-by", ns_meta,
+ &node3);
+ axiom_node_add_child(node2, this->env, node3);
+ attr = axiom_attribute_create(this->env, "ifmap-cardinality",
+ "singleValue", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node3);
+ }
+
+ /* send publish request */
+ result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
+ if (!result)
+ {
+ return FALSE;
+ }
+
+ /* process publishReceived */
+ node = axiom_node_get_first_child(result, this->env);
+ if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
+ {
+ el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
+ qname = axiom_element_get_qname(el, this->env, node);
+ success = streq("publishReceived",
+ axutil_qname_to_string(qname, this->env));
+ if (!success)
+ {
+ DBG1(DBG_TNC, "%s", axiom_element_to_string(el, this->env, node));
+ }
+ }
+ axiom_node_free_tree(result, this->env);
+
+ return TRUE;
+}
+
+METHOD(tnc_ifmap_soap_t, endSession, bool,
+ private_tnc_ifmap_soap_t *this)
+{
+ axiom_node_t *request, *result, *node;
+ axiom_element_t *el;
+ axiom_namespace_t *ns;
+ axiom_attribute_t *attr;
+ axutil_qname_t *qname;
+ bool success = FALSE;
+
+ /* build endSession request */
+ ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
+ el = axiom_element_create(this->env, NULL, "endSession", ns, &request);
+ attr = axiom_attribute_create(this->env, "session-id", this->session_id, NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+
+ /* send endSession request */
+ result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
+ if (!result)
+ {
+ return FALSE;
+ }
+
+ /* process endSessionResult */
+ node = axiom_node_get_first_child(result, this->env);
+ if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
+ {
+ el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
+ qname = axiom_element_get_qname(el, this->env, node);
+ success = streq("endSessionResult",
+ axutil_qname_to_string(qname, this->env));
+ if (!success)
+ {
+ DBG1(DBG_TNC, "%s", axiom_element_to_string(el, this->env, node));
+ }
+ }
+ axiom_node_free_tree(result, this->env);
+
+ return success;
+
+ return TRUE;
+}
+
+METHOD(tnc_ifmap_soap_t, destroy, void,
+ private_tnc_ifmap_soap_t *this)
+{
+ if (this->session_id)
+ {
+ DBG2(DBG_TNC, "sending ifmap->endSession");
+ if (!endSession(this))
+ {
+ DBG1(DBG_TNC, "ifmap->endSession with MAP server failed");
+ }
+ free(this->session_id);
+ free(this->ifmap_publisher_id);
+ free(this->device_name);
+ }
+ if (this->svc_client)
+ {
+ axis2_svc_client_free(this->svc_client, this->env);
+ }
+ if (this->env)
+ {
+ axutil_env_free(this->env);
+ }
+ free(this);
+}
+
+/**
+ * See header
+ */
+tnc_ifmap_soap_t *tnc_ifmap_soap_create()
+{
+ private_tnc_ifmap_soap_t *this;
+ axis2_char_t *server, *client_home, *username, *password, *auth_type;
+ axis2_endpoint_ref_t* endpoint_ref = NULL;
+ axis2_options_t *options = NULL;
+
+ client_home = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.client_home",
+ AXIS2_GETENV("AXIS2C_HOME"));
+ server = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.server", IFMAP_SERVER);
+ auth_type = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.auth_type", "Basic");
+ username = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.username", NULL);
+ password = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.password", NULL);
+
+ if (!username || !password)
+ {
+ DBG1(DBG_TNC, "MAP client %s%s%s not defined",
+ (!username) ? "username" : "",
+ (!username && ! password) ? " and " : "",
+ (!password) ? "password" : "");
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .newSession = _newSession,
+ .purgePublisher = _purgePublisher,
+ .publish = _publish,
+ .endSession = _endSession,
+ .destroy = _destroy,
+ },
+ );
+
+ /* Create Axis2/C environment and options */
+ this->env = axutil_env_create_all(IFMAP_LOGFILE, AXIS2_LOG_LEVEL_TRACE);
+ options = axis2_options_create(this->env);
+
+ /* Define the IF-MAP server as the to endpoint reference */
+ endpoint_ref = axis2_endpoint_ref_create(this->env, server);
+ axis2_options_set_to(options, this->env, endpoint_ref);
+
+ /* Create the axis2 service client */
+ this->svc_client = axis2_svc_client_create(this->env, client_home);
+ if (!this->svc_client)
+ {
+ DBG1(DBG_TNC, "could not create axis2 service client");
+ AXIS2_LOG_ERROR(this->env->log, AXIS2_LOG_SI,
+ "Stub invoke FAILED: Error code: %d :: %s",
+ this->env->error->error_number,
+ AXIS2_ERROR_GET_MESSAGE(this->env->error));
+ destroy(this);
+ return NULL;
+ }
+
+ axis2_svc_client_set_options(this->svc_client, this->env, options);
+ axis2_options_set_http_auth_info(options, this->env, username, password,
+ auth_type);
+ DBG1(DBG_TNC, "connecting as MAP client '%s' to MAP server at '%s'",
+ username, server);
+
+ 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
index 000000000..ca4301175
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 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 <utils/host.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_id unique IKE_SA id
+ * @param id id of remote endpoint
+ * @param host IP address of remote endpoint
+ * @param up TRUE if IKE_SEA is up, FALSE if down
+ * @return TRUE if command was successful
+ */
+
+ bool (*publish)(tnc_ifmap_soap_t *this, u_int32_t ike_sa_id,
+ identification_t *id, host_t *host, bool up);
+
+ /**
+ * 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_ @}*/