6d20a59d3f75238353adc240543572630b482496
[strongswan.git] / src / libcharon / plugins / tnc_ifmap / tnc_ifmap_listener.c
1 /*
2 * Copyright (C) 2011 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "tnc_ifmap_listener.h"
17
18 #include <daemon.h>
19 #include <config/child_cfg.h>
20
21 #include <axis2_util.h>
22 #include <axis2_client.h>
23 #include <axiom_soap.h>
24
25 #define IFMAP_NAMESPACE "http://www.trustedcomputinggroup.org/2010/IFMAP/2"
26 #define IFMAP_LOGFILE "strongswan_ifmap.log"
27 #define IFMAP_SERVER "https://localhost:8443/"
28
29 typedef struct private_tnc_ifmap_listener_t private_tnc_ifmap_listener_t;
30
31 /**
32 * Private data of an tnc_ifmap_listener_t object.
33 */
34 struct private_tnc_ifmap_listener_t {
35
36 /**
37 * Public tnc_ifmap_listener_t interface.
38 */
39 tnc_ifmap_listener_t public;
40
41 /**
42 * Axis2/C environment
43 */
44 axutil_env_t *env;
45
46 /**
47 * Axis2 service client
48 */
49 axis2_svc_client_t* svc_client;
50
51 /**
52 * SOAP Session ID
53 */
54 char *session_id;
55
56 /**
57 * IF-MAP Publisher ID
58 */
59 char *ifmap_publisher_id;
60
61 };
62
63 static bool newSession(private_tnc_ifmap_listener_t *this)
64 {
65 axiom_node_t *request, *result, *node;
66 axiom_element_t *el;
67 axiom_namespace_t *ns;
68 axiom_attribute_t *attr;
69 axis2_char_t *value;
70 bool success = FALSE;
71
72 /* build newSession request */
73 ns = axiom_namespace_create(this->env, IFMAP_NAMESPACE, "ifmap");
74 el = axiom_element_create(this->env, NULL, "newSession", ns, &request);
75 attr = axiom_attribute_create(this->env, "max-poll-result-size", "1000000", NULL);
76 axiom_element_add_attribute(el, this->env, attr, request);
77
78 /* send newSession request */
79 result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
80 if (!result)
81 {
82 return FALSE;
83 }
84
85 /* process newSessionResult */
86 node = axiom_node_get_first_child(result, this->env);
87 if (node && axiom_node_get_node_type(node, this->env) == AXIOM_ELEMENT)
88 {
89 el = (axiom_element_t *)axiom_node_get_data_element(node, this->env);
90 value = axiom_element_get_attribute_value_by_name(el, this->env,
91 "session-id");
92 this->session_id = strdup(value);
93 value = axiom_element_get_attribute_value_by_name(el, this->env,
94 "ifmap-publisher-id");
95 this->ifmap_publisher_id = strdup(value);
96
97 DBG1(DBG_TNC, "session-id: %s, ifmap-publisher-id: %s",
98 this->session_id, this->ifmap_publisher_id);
99 success = this->session_id && this->ifmap_publisher_id;
100
101 value = axiom_element_get_attribute_value_by_name(el, this->env,
102 "max-poll-result-size");
103 if (value)
104 {
105 DBG1(DBG_TNC, "max-poll-result-size: %s", value);
106 }
107 }
108 axiom_node_free_tree(result, this->env);
109
110 return success;
111 }
112
113 static bool purgePublisher(private_tnc_ifmap_listener_t *this)
114 {
115 axiom_node_t *request, *result, *node;
116 axiom_element_t *el;
117 axiom_namespace_t *ns;
118 axiom_attribute_t *attr;
119
120 /* build purgePublisher request */
121 ns = axiom_namespace_create(this->env, IFMAP_NAMESPACE, "ifmap");
122 el = axiom_element_create(this->env, NULL, "purgePublisher", ns,
123 &request);
124 attr = axiom_attribute_create(this->env, "session-id",
125 this->session_id, NULL);
126 axiom_element_add_attribute(el, this->env, attr, request);
127 attr = axiom_attribute_create(this->env, "ifmap-publisher-id",
128 this->ifmap_publisher_id, NULL);
129 axiom_element_add_attribute(el, this->env, attr, request);
130
131 /* send purgePublisher request */
132 result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
133 if (!result)
134 {
135 return FALSE;
136 }
137
138 /* process purgePublisherReceived */
139 node = axiom_node_get_first_child(result, this->env);
140 axiom_node_free_tree(result, this->env);
141
142 return TRUE;
143 }
144
145 static bool endSession(private_tnc_ifmap_listener_t *this)
146 {
147 axiom_node_t *request, *result, *node;
148 axiom_element_t *el;
149 axiom_namespace_t *ns;
150 axiom_attribute_t *attr;
151
152 /* build endSession request */
153 ns = axiom_namespace_create(this->env, IFMAP_NAMESPACE, "ifmap");
154 el = axiom_element_create(this->env, NULL, "endSession", ns, &request);
155 attr = axiom_attribute_create(this->env, "session-id", this->session_id, NULL);
156 axiom_element_add_attribute(el, this->env, attr, request);
157
158 /* send endSession request */
159 result = axis2_svc_client_send_receive(this->svc_client, this->env, request);
160 if (!result)
161 {
162 return FALSE;
163 }
164
165 /* process endSessionResult */
166 node = axiom_node_get_first_child(result, this->env);
167 axiom_node_free_tree(result, this->env);
168
169 return TRUE;
170 }
171
172 METHOD(listener_t, child_updown, bool,
173 private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
174 bool up)
175 {
176 traffic_selector_t *my_ts, *other_ts;
177 enumerator_t *enumerator;
178 child_cfg_t *config;
179 host_t *vip, *me, *other;
180
181 config = child_sa->get_config(child_sa);
182 vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
183 me = ike_sa->get_my_host(ike_sa);
184 other = ike_sa->get_other_host(ike_sa);
185
186 return TRUE;
187 }
188
189 METHOD(tnc_ifmap_listener_t, destroy, void,
190 private_tnc_ifmap_listener_t *this)
191 {
192 if (this->session_id)
193 {
194 DBG2(DBG_TNC, "sending endSession");
195 if (!endSession(this))
196 {
197 DBG1(DBG_TNC, "endSession with MAP server failed");
198 }
199 free(this->session_id);
200 free(this->ifmap_publisher_id);
201 }
202 if (this->svc_client)
203 {
204 axis2_svc_client_free(this->svc_client, this->env);
205 }
206 if (this->env)
207 {
208 axutil_env_free(this->env);
209 }
210 free(this);
211 }
212
213 /**
214 * See header
215 */
216 tnc_ifmap_listener_t *tnc_ifmap_listener_create()
217 {
218 private_tnc_ifmap_listener_t *this;
219 axis2_char_t *server, *client_home, *username, *password, *auth_type;
220 axis2_endpoint_ref_t* endpoint_ref = NULL;
221 axis2_options_t *options = NULL;
222
223 client_home = lib->settings->get_str(lib->settings,
224 "charon.plugins.tnc-ifmap.client_home",
225 AXIS2_GETENV("AXIS2C_HOME"));
226 server = lib->settings->get_str(lib->settings,
227 "charon.plugins.tnc-ifmap.server", IFMAP_SERVER);
228 auth_type = lib->settings->get_str(lib->settings,
229 "charon.plugins.tnc-ifmap.auth_type", "Basic");
230 username = lib->settings->get_str(lib->settings,
231 "charon.plugins.tnc-ifmap.username", NULL);
232 password = lib->settings->get_str(lib->settings,
233 "charon.plugins.tnc-ifmap.password", NULL);
234
235 if (!username || !password)
236 {
237 DBG1(DBG_TNC, "MAP client %s%s%s not defined",
238 (!username) ? "username" : "",
239 (!username && ! password) ? " and " : "",
240 (!password) ? "password" : "");
241 }
242
243 INIT(this,
244 .public = {
245 .listener = {
246 .child_updown = _child_updown,
247 },
248 .destroy = _destroy,
249 },
250 );
251
252 /* Create Axis2/C environment and options */
253 this->env = axutil_env_create_all(IFMAP_LOGFILE, AXIS2_LOG_LEVEL_TRACE);
254 options = axis2_options_create(this->env);
255
256 /* Define the IF-MAP server as the to endpoint reference */
257 endpoint_ref = axis2_endpoint_ref_create(this->env, server);
258 axis2_options_set_to(options, this->env, endpoint_ref);
259
260 /* Create the axis2 service client */
261 this->svc_client = axis2_svc_client_create(this->env, client_home);
262 if (!this->svc_client)
263 {
264 DBG1(DBG_TNC, "Error creating axis2 service client");
265 AXIS2_LOG_ERROR(this->env->log, AXIS2_LOG_SI,
266 "Stub invoke FAILED: Error code: %d :: %s",
267 this->env->error->error_number,
268 AXIS2_ERROR_GET_MESSAGE(this->env->error));
269 destroy(this);
270 return NULL;
271 }
272
273 axis2_svc_client_set_options(this->svc_client, this->env, options);
274 axis2_options_set_http_auth_info(options, this->env, username, password,
275 auth_type);
276 DBG1(DBG_TNC, "connecting as MAP client '%s' to MAP server at '%s'",
277 username, server);
278
279 DBG2(DBG_TNC, "sending newSession");
280 if (!newSession(this))
281 {
282 DBG1(DBG_TNC, "newSession with MAP server failed");
283 destroy(this);
284 return NULL;
285 }
286 DBG2(DBG_TNC, "sending purgePublisher");
287 if (!purgePublisher(this))
288 {
289 DBG1(DBG_TNC, "purgePublisher with MAP server failed");
290 destroy(this);
291 return NULL;
292 }
293
294 return &this->public;
295 }
296